使用Keras版本的Yolov3训练自己的数据集和进行目标检测时,需要注意的一些问题

最近因为工作需要,使用了Yolo v3做目标检测。由于它自带的数据集完全不能够满足需要,只能从头开始自己训练。当然这必须要用python来做了,不能用C语言。。。

首先,我发现那个著名的Keras版本非常好:https://github.com/qqwweee/keras-yolo3 但它的一些地方很麻烦,尤其是关于训练,作者给出的方法太粗糙了,甚至没有使用标注软件。。。

于是我在网上搜索了一下,发现有个网页确实讲得很具体,值得学习啊,感谢 鸡立鹤群的大愚弱智 为大家所做的贡献:https://blog.csdn.net/u012746060/article/details/81183006

但其中还是有一些问题没有讲清楚,以至于网页下方有很多人在提问,始终没有收到回复。因为我已经基本搞明白了,所以这里补充说明几个关键点,希望对大家有用:

  1. 文件夹叫什么名字其实无所谓,不一定要叫VOC2007,只需要在后面的各项设置中把名字对应上就行。

  2. logs/000/目录也不是一定要存在,如果想放在别的路径,记得训练之前去train.py里,把log_dir = ‘logs/000/’ 改掉;训练之后去yolo.py里,把"model_path": ‘logs/000/trained_weights.h5’ 改掉。

  3. 就如同一些人发现的那样,使用python yolo.py实际上是无法实现图片检测的,只会显示Using TensorFlow backend,然后立即退出。正确的办法应该是使用python yolo_video.py --image。
    PS:如果直接去原作者的Github页面看他的介绍,会发现他描述的用法也是用yolo_video.py,而不是yolo.py。

  4. 我看到有些人反映说,运行之后出现了类似于这样的提示:
    2019-07-09 13:48:45.569398: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:502] shape_optimizer failed: Invalid argument: Subshape must ha ve computed start >= end since stride is negative, but is 0 and 2 (computed from start 0 and end 9223372036854775807 over shape with rank 2 and str ide-1)
    2019-07-09 13:48:46.972414: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:502] remapper failed: Invalid argument: Subshape must have comp uted start >= end since stride is negative, but is 0 and 2 (computed from start 0 and end 9223372036854775807 over shape with rank 2 and stride-1)
    2019-07-09 13:48:47.816976: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:502] layout failed: Invalid argument: Subshape must have comput ed start >= end since stride is negative, but is 0 and 2 (computed from start 0 and end 9223372036854775807 over shape with rank 2 and stride-1)
    这个没有关系的,这个提示完全不妨碍正确的检测结果,我这边也有这类提示。

  5. 不用GPU的话,训练速度当然很慢,各位只能自己想办法了。如果现实中找不到好电脑,可以考虑网上云端运行。至于有人说“这个程序不能用GPU运行”,这个情况我完全没有遇到,不知道为何。

  6. 修改iou和score的值非常简单,去yolo.py里面,修改第27和第28行即可。不过个人感觉系统默认值其实是挺合理的。

  7. 关于如何修改学习率,这边有一个细节。在 鸡立鹤群的大愚弱智 的网页上,他是把train.py重写了,这样就和原始的train.py很不一样了。
    如果大家去看原始的文件,会在第53行看到optimizer=Adam(lr=1e-3),第73行看到optimizer=Adam(lr=1e-4),它的意思是分成两个阶段训练,第一阶段使用较大的学习率去探索,到后面第二阶段开始微调了,就改成较小的学习率,所以本身Yolo v3的学习率一定是可以设定的。
    但是在重写的文件里,这两行都没了,只剩下第22行的optimizer=‘adam’, 意思应该是从头到尾学习率不变,不分阶段。所以我甚至不确定这个版本的Yolo v3到底用了多大的学习率?系统默认学习率是多少我也不知道。。。
    总之如果想手动修改lr,应该就是在这个地方附近吧。我没改过,感觉没有必要。

  8. 有一个细节虽然不影响程序正常运行,但其实是 的一个失误。在他的第3步里,他生成了4个txt文件,包括了初步的验证集val.txt,并且在第4步生成了最终的验证集2007_val.txt。但是到了他的第7步,他又在最终的训练集2007_train.txt里面划出10%的数据作为验证集,并且他第7步的train.py里面,根本就没有读取2007_val.txt。换言之,他的2007_val.txt白做了,所有的数据都浪费了,最终的验证集数据其实还是来源于训练集。
    对这种情况最简单的处理办法就是,在他第3步里,设置trainval_percent = 0,train_percent = 1,这样最后就没有2007_val.txt了,所有的数据都会进入2007_train.txt,都不浪费。

  9. loss值运行很久之后不下降,或者loss值变得很小之后,检测效果仍然不好,那么有很多种可能性,无法几句话概括。最大的可能性之一是:你的数据太少了。我看到有人说,训练集用了100多张照片,这可不太够。。。

  10. 这个程序确实没有输出训练日志文件,没法直接画loss曲线之类的。但实现这一步其实很简单,因为训练数据会展示出来,比如在cmd里或者jupyter notebook里。我们直接把这些数据拷贝出来,粘贴到记事本里就行了。然后你可以用excel读取这个文本文件,转化为excel格式(比如把空格作为分隔符读取),接下来怎么画图都可以。

  11. Yolo v3确实没有自带的“用测试集评估模型的代码”,这是目标检测本身的原理导致的,所以你只能人工评估。比如你图上有10个目标,结果检测出来9个,有1个是错误的,8个是正确的,那么你的precision就是8/9=0.89,recall就是8/10=0.8,F1 score可以算出来是0.84。这个你只能手动算。。。
    你要想让Yolo v3和你标注的结果(比如LabelImg的xml文件)做对比,然后自动输出统计结果,这不现实,它目前还没这个功能呢。
    这也就是8里为什么我提议设置trainval_percent = 0,train_percent = 1的原因,因为这个程序里根本不包含测试代码,test.txt和2007_test.txt的数据说白了也是被浪费的,不如不要。

  12. 最最重要的一点:很多人都反映了同一个问题,即一张图片最多只能识别20个对象。事实上我做的时候,有2类,一开始就最多只能识别40个对象,所以是遇到了同一个问题(大家都是做小物体检测的吧?)。
    这个问题的答案其实非常简单,我最终是在这个程序Github网页的某个issue里找到答案的。。。外国人A问了这个问题,外国人B给出了答案:
    20是这个程序预设的一个参数(超参数),意思是每张图片最多只能识别20个,所以把这个参数改掉就行了!
    要改的地方有两个:
    (1)训练时,要在yolo3文件夹下面的utils.py里,修改get_random_data()函数,有一个默认参数是max_boxes=20,改成很大的数值就行了。
    (2)检测时,要在yolo3文件夹下面的model.py里,修改yolo_eval()函数,有一个默认参数是max_boxes=20,改成很大的数值就行了。
    (1)是外国人B说的,(2)是我后来自己摸索出来的。(2)很重要,但其实(1)也很关键,要是不改的话,你在一张图里的标注,最多就只有20个被系统输入了,别的都浪费了。

  13. 最后总结一下:这个Keras版本的Yolo v3程序肯定是没问题的;如果有问题,都是可以解决和克服的;实在解决不了,网上中文和英文资源那么多,搜一搜就好啦。

PS:过段时间我会把我做的小物体检测程序和训练结果上传Github,欢迎大家指点。

你可能感兴趣的:(使用Keras版本的Yolov3训练自己的数据集和进行目标检测时,需要注意的一些问题)