图片啥的都准备好了,也将YOLO格式的标注转换成PascalVOC格式的标注了,结果打开D:\Yolov3_Tensorflow\tensorflow-yolov3\data\dataset
里的voc_test.txt
和voc_train
一看,咋是这个格式的,让人大吃一惊Σ(っ °Д °;)っ
根据我同事小王的提示,在YunYang1994/tensorflow-yolov3 Readme 翻译里面有一句$ python scripts/voc_annotation.py --data_path /home/yang/test/VOC
,会不会就是生成这俩文件的代码?
图片
和train.txt
、test.txt
train.txt
、test.txt
的格式为这样,与作者指定的格式一致,生成方法有两种,第一种使用LabelImg
标定后生成的XML文件,运行作者提供的指令$ python scripts/voc_annotation.py --data_path /home/yang/test/VOC
生成,第二种为从YOLO
的标定文件直接生成,生成方法见此(如何将yolo的标注(annotations).txt 坐标转换成tensorflow-yolov3(YunYang1994)的.txt 标注坐标?):
根据 YunYang1994/tensorflow-yolov3 Readme 翻译 中作者给出的训练自己的数据集流程,将训练VOC数据集的流程转换成训练我们自己的数据集的流程:
class.names
文件以及__C.YOLO.CLASSES
参数路径我在D:\20191031_tensorflow_yolov3\tensorflow-yolov3\data\classes
路径下新建class.names
文件,并在里面写入一个类——object
(因为我们只用识别一个类),然后保存:
接下来打开D:\20191031_tensorflow_yolov3\tensorflow-yolov3\core
路径下的config.py
文件:
将__C.YOLO.CLASSES
路径参数修改成我们刚才创建的class.names
文件路径,保存:
__C.TRAIN.ANNOT_PATH
和__C.TEST.ANNOT_PATH
参数路径还是在config.py
文件里,我们将这俩参数修改成我们train.txt
和test.txt
的文件路径。我想了想,还是把我的train.txt
和test.txt
文件放到作者原路径下算了,方便一点:
以后的步骤就是,train.txt
和test.txt
文件在外部生成,生成好后再扔进去。文件的上级有数据集名以及日期,不怕跟其他数据集混淆。
然后修改train.txt
和test.txt
的文件路径:
__C.YOLO.ORIGINAL_WEIGHT
和__C.YOLO.DEMO_WEIGHT
另外,我们还看到了__C.YOLO.ORIGINAL_WEIGHT = "./checkpoint/yolov3_coco.ckpt"
参数和__C.YOLO.DEMO_WEIGHT = "./checkpoint/yolov3_coco_demo.ckpt"
这两个参数,按ctrl+shift+f
查看__C.YOLO.ORIGINAL_WEIGHT
:
再查看org_weights_path
:
查看__C.YOLO.DEMO_WEIGHT
:
再查看cur_weights_path
:
猜测__C.YOLO.ORIGINAL_WEIGHT
是convert_weights.py
转换权重文件的源文件,__C.YOLO.DEMO_WEIGHT
是转换后生成的目标权重文件(用于将COCO权重文件转换后生成预训练模型,__C.YOLO.DEMO_WEIGHT
就是预训练模型,COCO权重文件(__C.YOLO.ORIGINAL_WEIGHT
)如果不转换则只能用于识别)。
所以,我们训练之前需要将COCO权重转换成预训练模型,作者给出的转换指令为:
python convert_weight.py --train_from_coco
于是我把以前成功转换的COCO预训练模型删除,重新运行该指令,发现出错:
经查,发现是checkpoint文件夹位置错了,本来应该放在tensorflow-yolov3根目录下,不知怎么搞到core文件夹里了(可能是鼠标点击不小心拖进去了!)
把它重新搞出来就好了。
然后重新执行python convert_weight.py --train_from_coco
,就能正常生成了:
训练开始后权重文件会生成在checkpoint
,查看该目录是否有之前训练留下的权重文件,如果有就删除或拷贝到其他文件夹,避免被直接覆盖掉,我把以前训练VOC数据集生成的权重文件拷贝到了checkpoint
目录下的VOC_Weights_Files
文件夹中:
运行python train.py
,不幸的是,又报错了:
看起来像是程序将文件名中的空格当成分隔符读取了,所以报错说没有f_cotton_g_top文件夹,但那只是我们的文件名:
建议将图片序号改成纯数字1、2、3、4、5…的,再重新生成train.txt和test.txt。
文件批量重命名参考:python 将指定路径(目录)下的图片或文本文件按给定序号重新排序,并批量重命名 yolo、tensorflow数据集批量处理
弄完后发现一波小失误,不该把图片放在tensorflow文件夹外部的,这样很容易出问题,以后再改了。。。
再次执行python train.py
:
终于开始正常训练了!
不过这个train loss怎么那么高,像是我把目标坐标上下颠倒了似的,不管了,先训练完测试一下再说。
训练完之后只剩41-50的权重文件了,挑选42作为测试权重。(关于如何修改保留的权重文件数量参见:yunyang tensorfow-yolo3 训练时权重文件消失的原因和解决办法(max_to_keep))
编辑config.py
中的__C.TEST.WEIGHT_FILE
路径参数,将其改成我们测试的权重文件名:
python evaluate.py
测试测试集显示报错:
因为之前输出画框坐标的时候,修改了draw_bbox()函数,向其增添了两个参数,现在因为运行evaluate.py
文件单独调用draw_bbox(),这两个参数没有传递,所以显示出错。
尝试将这俩参数设置成可选参数或none试试。
已经将这俩参数默认设置为None,同时给涉及这里俩参数的代码包裹上if语句:
重新执行python evaluate.py
,能够正常测试:
python main.py -na
生成测试报告video_demo.py
查看识别效果直接运行video_demo.py,发现报错,错误信息:
以前我们遇到过这个问题,参考:YunYang1994/tensorflow-yolov3 IndexError: list index out of range 解决办法
于是我们将num_classes
参数改成了1(因为我们class.names
文件中只有一个类):
but,改成1后,又报错了,显示ValueError: cannot reshape array of size 43095 into shape (6)
:
观察np.concatenate()
函数,可能问题出在这:
concatenate()用法参考这里:Python numpy hstack() vstack() stack() dstack() vsplit() concatenate()函数用法和区别
查看pred_sbbox.shape、pred_mbbox.shape、pred_lbbox.shape的打印数据:
发现出现数字85,这肯定不对,还是5+80=85,按照我们设置的应该是5+1=6才对,猜测可能是权重文件没设置对:
顺藤摸瓜,往上面找,发现了这个pb字样,幡然醒悟:
我们没有将权重转换为.pb文件,.pb文件才是我们最终运行所需要的,现在的.pb还是以前老的.pb。
直接执行convert.py
,报错,猜测不用运行convert.py的,它只有在转换COCO权重和生成预训练文件时用得到,现在我们已经有权重文件了,所以直接运行freeze_graph.py
将我们的权重文件转换成.pb
文件即可:
尝试运行freeze_graph.py
,先修改其中的ckpt_file
:
运行freeze_graph.py
:
运行成功,并且可以看到.pb
文件更新了:
再次运行video_demo.py
,终于不报错能够正常识别了,但是识别效果老差,是不是过拟合了?
看了老久代码,实在找不出问题出在哪儿,于是干脆自己照着evaluate.py
重写一个算了,重写后执行,发现效果不错,
具体代码参见:如何使用yunyang tensorflow-yolov3训练自己的数据集并使用 Intel realsense D435 传输视频流应用于实时检测?
那原因出在哪儿?出在video_demo.py
上?反正我没仔细看它,看也看不懂。。。。
最后执行自己重写的dontla_evaluate_detect.py
效果:
可以说,还行。
下一步,就是要解决如何使用指定序列号调用Intel Realsense摄像头
和多线程调用
的还有深度检测区域采样平均去除黑洞
的问题了。
参考文章1:YunYang1994/tensorflow-yolov3 Readme 翻译
参考文章2:如何使用yunyang tensorflow-yolov3训练自己的数据集并使用 Intel realsense D435 传输视频流应用于实时检测?