前言
在用darknet框架训练分类模型时遇到了不停打印Too many or too few labels的错误提示信息,如下所示:
分析
打印该错误提示信息的相关代码在src/data.c中,如下所示
void fill_truth(char *path, char **labels, int k, float *truth)
{
int i;
memset(truth, 0, k*sizeof(float));
int count = 0;
for(i = 0; i < k; ++i){
if(strstr(path, labels[i])){
truth[i] = 1;
++count;
//printf("%s %s %d\n", path, labels[i], i);
}
}
if(count != 1 && (k != 1 || count != 0)) printf("Too many or too few labels: %d, %s\n", count, path);
}
把代码中的 printf("%s %s %d\n", path, labels[i], i);放开就能看到前言所示的log:前面是jpg文件路径,后面是根据该路径所找到的label。
该函数中for循环的意思是 , 对于每个label(我这里label刚好是0, 1,2,...19之类的数字字符),去对应文件路径匹配到对应的label。 换句话说,对于分类模型而言,每张样本图片会对应一个数字(0~19)label,那么它是怎么知道找到对应label呢? 刚才说了, 就是去文件路径字符串里面来匹配label。
那么问题来了,如果该文件路径刚好带多个数字,那么就会找到对应的多个label,如下所示,这显然和我们的最初设计相悖,毕竟每张图片只可能对应一个label。
解决办法
网上很多解决办法是,直接修改jpg文件路径和文件名,使得它们刚好只含有一个对应label的数字。 我这里的不想修改文件路径和名字,直接根据实际情况来修改代码。
其原理是在文件路径和名字 字符串中去匹配 "/label/"而不是"label",因为在这里,每个字符串中只有/label/才是唯一和label对应的。代码修改如下所示。