yolov3的不完整填坑手册

上一讲我们集中讲了如何使用yolov3来进行样本的训练和测试,但是其实这样的测试和训练还是留下了一些坑,现在废话不多说我们现在来面对一个又一个坑,并去解决它吧。

  • 坑一,我们训练的过程中那些输出是什么意思?
    具体解释,在上一篇中已经讲过了,这里就不赘述了,有疑问去查看我上一篇文章,顺便点赞点个关注。
  • 坑二,我们训练到什么样的程度的时候跳出训练。或者说,什么时候跳出训练?
    其实conner在昨天做训练的时候也是一脸懵逼,因为它一直在跑,一直在跑,我的执行又是通过在控制台的输入来完成的,一时不知道该怎么来控制跳出条件,明明两个loss都已经明显小于1了可就是没有办法退出。其实这个时候有两个方案,一个是用backup里每一百步存放的那个weight来用,但是总感觉这种方法不是很好,难道没有可以设置跳出状态的工具吗?其实是有的,我们上一讲中又一个文件:cfg/yolov3-voc.cfg ,里面有关于隐藏层的配置,我们找到这个关键字
max_batches = 50200

设置为你需要的步数,然后当训练这么多步之后就会跳出,并会在你的backup文件中存放这样一个文件


image.png

这个就是你最终的训练结果。

  • 坑三,训练跳出后如何测试
    根据上一章的结果运行
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_final.weights one.jpg

运行结果如下所示:

one.jpg: Predicted in 0.025834 seconds.
xxx: 99%
xxx: 86%
xxx: 69%
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg    4.16s user 0.50s system 99% cpu 4.669 total

conner:诶怎么回事呀,小老弟?我想要的不是告诉我结果是啥,而是我想识别的内容在哪里,我需要的是位置,不是内容,这可怎么办。
yolo:很简单,修改代码
conner:可是c++我不会啊。
yolo:你可是拷贝忍着卡卡西,网上去找吧。
按照yolo的推荐我找到了如下的修改方式(参考博客链接https://blog.csdn.net/qq_36362060/article/details/88895161

  1. 首先修改YOLOV3中src/imge.c中的void draw_detections函数
void draw_detections(char *filename, image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes)
{
    int i,j;
    //将filename的文件名提取出来,即去掉.jpg的后缀,加上.txt的后缀
    char *output = filename;
    int haha = 0;
    for (haha = strlen(filename)-1; haha>=0; haha--){
        if((filename[haha]!='j')&&(filename[haha]!='p')&&(filename[haha]!='g')&&(filename[haha]!='.')){
            break;
        }
        else{
            output[haha] = '\0';
        }
    }
    output = strcat(filename, ".txt");
    //创建保存位置信息txt文档
    FILE *fp;
     if ( (fp = fopen(output, "w+")) == NULL ){
            printf("创建文档失败:\n");
        }
    for(i = 0; i < num; ++i){
        char labelstr[4096] = {0};
        int class = -1;
        for(j = 0; j < classes; ++j){
           //只显示测试图中dog类的信息
          if (strcmp(names[j], "dog") != 0)
             {continue;}
            if (dets[i].prob[j] > thresh){
                if (class < 0) {
                    strcat(labelstr, names[j]);
                    class = j;
                } else {
                    strcat(labelstr, ", ");
                    strcat(labelstr, names[j]);
                }
                printf("%s: %.0f%%\n", names[j], dets[i].prob[j]*100);
            }
        }
        if(class >= 0){
            int width = im.h * .006;
            //printf("%d %s: %.0f%%\n", i, names[class], prob*100);
            int offset = class*123457 % classes;
            float red = get_color(2,offset,classes);
            float green = get_color(1,offset,classes);
            float blue = get_color(0,offset,classes);
            float rgb[3];
            rgb[0] = red;
            rgb[1] = green;
            rgb[2] = blue;
            box b = dets[i].bbox;
            int left  = (b.x-b.w/2.)*im.w;
            int right = (b.x+b.w/2.)*im.w;
            int top   = (b.y-b.h/2.)*im.h;
            int bot   = (b.y+b.h/2.)*im.h;
            if(left < 0) left = 0;
            if(right > im.w-1) right = im.w-1;
            if(top < 0) top = 0;
            if(bot > im.h-1) bot = im.h-1;
            draw_box_width(im, left, top, right, bot, width, red, green, blue);
            printf("left:%d, top:%d, right:%d, bot:%d \n",left,top,right,bot);
            fprintf(fp, "%d %d %d %d\n",left, top, right, bot);
            if (alphabet) {
                image label = get_label(alphabet, labelstr, (im.h*.03));
                draw_label(im, top + width, left, label, rgb);
                free_image(label);
            }
            if (dets[i].mask){
                image mask = float_to_image(14, 14, 1, dets[i].mask);
                image resized_mask = resize_image(mask, b.w*im.w, b.h*im.h);
                image tmask = threshold_image(resized_mask, .5);
                embed_image(tmask, im, left, top);
                free_image(mask);
                free_image(resized_mask);
                free_image(tmask);
            }
        }
    }
  fclose(fp);
}
  1. 修改example中coco.c, yolo.c, detector.c,文件,修改include中darknet.h文件,具体修改如下

coco.c

draw_detections(im, dets, l.side*l.side*l.n, thresh, coco_classes, alphabet, 80);
draw_detections(input, im, dets, l.side*l.side*l.n, thresh, coco_classes, alphabet, 80);

yolo.c

draw_detections( im, dets, l.side*l.side*l.n, thresh, voc_names, alphabet, 20);
draw_detections(input, im, dets, l.side*l.side*l.n, thresh, voc_names, alphabet, 20);

detector.c

draw_detections(im, dets, nboxes, thresh, names, alphabet, l.classes);
draw_detections(input, im, dets, nboxes, thresh, names, alphabet, l.classes);

darknet.h

void draw_detections(image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes);
void draw_detections(char *filename, image im, detection *dets, int num, float thresh, char **names, image **alphabet, int classes);

然后
去到/darknet执行:make clean 再执行make
运行上面那一行测试代码结果如下:

xxx: 100%
left:175, top:19, right:237, bot:104 
xxx: 100%
left:8, top:104, right:92, bot:187 
xxx: 98%
left:177, top:121, right:239, bot:185 
xxx: 85%
left:79, top:211, right:155, bot:278 

OK,完成啦,同时本地还会生成一个predictions.jpg打开看一下,完美。这就是我们想要的结果。

  • 坑四 训练中的样本控制(过拟合与欠拟合)
    说玄乎一点就是一些根据经验来的值,说的难听一点就是我也不知道原因,试出来的我没有办法解释的值。这里先讲值,以后再去关注原理吧。
    训练时候的欠拟合,样本量过少。增加训练的样本量。batch=64,subdivisions=16。前者表示批次,后者表示训练迭代包含的组数
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容