文章目录
源码获取与安装
GitHub 上搜索 YOLO
可以找到很多平台的包,如: Tensorflow
, pyTorch
等等;本文使用 darknet
原因:方便把玩。请参考如下页面安装测试:
实测
自带图
其他任选
简单场景
中等复杂
盆栽(potted plant)都可以, 当然花瓶是没有的
复杂场景
注意下图中的包和伞都能检测出来:
还有这个图,不是偶然
恶劣环境
下面的环境有点恶劣,不过还不错,虽然漏了个车和路灯
失败例子
哈哈,画的画果然还是不行,难道画技太差,哈哈:
训练
样本
标记样本
- 工具:Yolo_mark或者自写,本人自己写了个脚本
- 格式:类标从0开始,没有背景(与训练与微调均是)
其它说明见以下各自部分。
预训练
准备训练样本
darknet 这个
微调
准备训练样本
训练样本标签文件信息如下:
<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