使用 YOLO 做些好玩的事情

源码获取与安装

GitHub 上搜索 YOLO 可以找到很多平台的包,如: Tensorflow, pyTorch 等等;本文使用 darknet 原因:方便把玩。请参考如下页面安装测试:

实测

自带图

dog等

其他任选

简单场景

西安国际汽车展.png

西电花季开放日

中等复杂

盆栽(potted plant)都可以, 当然花瓶是没有的
charms于2017年4月4日摄于青龙寺

复杂场景

注意下图中的包和伞都能检测出来:
人群密集的樱花祭

还有这个图,不是偶然
人群密集的樱花祭

恶劣环境

下面的环境有点恶劣,不过还不错,虽然漏了个车和路灯
xidianbeimen.png

失败例子

哈哈,画的画果然还是不行,难道画技太差,哈哈:

charms 原创画作

训练

样本

标记样本

  • 工具:Yolo_mark或者自写,本人自己写了个脚本
  • 格式:类标从0开始,没有背景(与训练与微调均是)

其它说明见以下各自部分。

预训练

准备训练样本

darknet 这个

cifar训练样本示例

微调

准备训练样本

训练样本标签文件信息如下:

<object-class> <x> <y> <width> <height>
<object-class> <x> <y> <width> <height>
...

对应于:

<类别标签数字> <物体中心水平方向坐标/宽度> <物体中心垂直方向坐标/高度> <物体区域宽度> <物体区域高度>

如对于 VOC2012中的一幅飞机的图像,对应的训练样本标签信息如下:

0 0.578 0.474474474474 0.744 0.588588588589

其中,0 表示类别,0.578 0.474474474474 为中心坐标,0.744 0.588588588589 分别为宽度和高度,如下图所示:

训练样本标签图解

训练配置

learning_rate=0.0001
max_batches = 3 # 训练代数 epoches
policy=steps
steps=1,2,3 # 每训练step,保存一次
scales=10,.1,.1

开始微调训练

./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23 -gpus 0,1,2,3 >> backup/training.log

可视化训练

参考:

问题解决

不画框

是图像长宽比太大导致不画框,通过查看相关源码发现,在 image.c 函数中含有如下代码:

int width = im.h * .006; 

可见源码有BUG,对于高度过小的图像,导致不画框,因为在 draw_box_width 函数里:

for(i = 0; i < w; ++i){
    draw_box(a, x1+i, y1+i, x2-i, y2-i, r, g, b);

所以解决方法是:

        if(class >= 0){
            int width = im.h * .006;
            //============================Added by LiuZhi===========================//
            if(width < 1) width = 1; 
            //============================Added by LiuZhi===========================//

            /*
               if(0){
               width = pow(prob, 1./2.)*10+1;
               alphabet = 0;
               }
             */

            //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];

训练时错误

Assertion `0’ failed

提示如下错误,试了网上的几个方法,如改Makefile文件中的GPU ARCH,使用sudo 运行,等等均不行。后来想起自己曾改了batchsize为64,于是将其改小为8,该完后,重新运行,一切正常,是内存不足的问题。

darknet: ./src/cuda.c:36: check_error: Assertion `0' failed.
./train.sh: line 3: 12389 Aborted                 (core dumped) 

测试

输出类别与自定义的不同

自定义二分类任务,训练后测试发现,目标种类始终为 “Person” 这应该是VOC和COCO里的类别,网上查了好久,无果。第二天睡醒后,决定自己看看源码,追根溯源,很快,不到5分钟,找到了问题所在,看到下面代码段中的最后一行了吗(约在源文件440行),是的输入的配置文件是 “cfg/coco.data” , .

终端执行代码: ./darknet detect cfg/yolov3-tiny-lpd.cfg backup/yolov3-tiny-lpd_800.weights data/002001.jpg -thresh 0.0000

文件: “darknet.c”

    if (0 == strcmp(argv[1], "average")){
        average(argc, argv);
    } else if (0 == strcmp(argv[1], "yolo")){
        run_yolo(argc, argv);
    } else if (0 == strcmp(argv[1], "super")){
        run_super(argc, argv);
    } else if (0 == strcmp(argv[1], "lsd")){
        run_lsd(argc, argv);
    } else if (0 == strcmp(argv[1], "detector")){
        run_detector(argc, argv);
    } else if (0 == strcmp(argv[1], "detect")){
        float thresh = find_float_arg(argc, argv, "-thresh", .5);
        char *filename = (argc > 4) ? argv[4]: 0;
        char *outfile = find_char_arg(argc, argv, "-out", 0);
        int fullscreen = find_arg(argc, argv, "-fullscreen");
        test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, .5, outfile, fullscreen);

你可以把"cfg/coco.data"换成你的,但是得重新编译,注意看有个 “detector” ,在"detector.c"这个文件里有:

void run_detector(int argc, char **argv)
{
...
    char *datacfg = argv[3];
    char *cfg = argv[4];
    char *weights = (argc > 5) ? argv[5] : 0;
    char *filename = (argc > 6) ? argv[6]: 0;
    if(0==strcmp(argv[2], "test")) test_detector(datacfg, cfg, weights, filename, thresh, hier_thresh, outfile, fullscreen);
    else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear);
    else if(0==strcmp(argv[2], "valid")) validate_detector(datacfg, cfg, weights, outfile);
    else if(0==strcmp(argv[2], "valid2")) validate_detector_flip(datacfg, cfg, weights, outfile);
    else if(0==strcmp(argv[2], "recall")) validate_detector_recall(cfg, weights);
    else if(0==strcmp(argv[2], "demo")) {
        list *options = read_data_cfg(datacfg);
        int classes = option_find_int(options, "classes", 20);
        char *name_list = option_find_str(options, "names", "data/names.list");
        char **names = get_labels(name_list);
        demo(cfg, weights, thresh, cam_index, filename, names, classes, frame_skip, prefix, avg, hier_thresh, width, height, fps, fullscreen);

看到了吧:test_detector(datacfg,于是决定 调用detector(这样不用改代码了),如下:

./darknet detector test cfg/data/lpd/lpd.data cfg/yolov3-tiny-lpd.cfg backup/yolov3-tiny-lpd_600.weights data/002003.jpg -thresh -0

发布了84 篇原创文章 · 获赞 130 · 访问量 41万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览