YOLOv5
复现代码过程,主要的坑存在于数据集上。拿yolo v5来说,它需要yolo格式的标签,但实验室制作的数据集都打了VOC格式的标签。在将xml转化为txt格式的过程中,存在很多问题。首先,发现xml文件中有部分的size(长宽高)为0,这就导致在转换为txt格式的过程中,计算的分母为0,导致无法转化。
目前这个问题的根本原因还是没有找到,检查了打标签的过程,没有问题(小建议:在为自己即将训练的图像打标签前,最好把图像resize成一个尺寸,这样可以最大程度地避免标签的问题)。解决方法就是把size为0的标签和对应图片删掉,转换成功。
成功转换标签后,在训练的过程中,出现了txt文件中存在负值的情况。在yolo v5项目中datasets.py中,有这样一段代码:
这段代码的第六行原始为assert(l>=0).all(),也就是对于标签中的所有数值,都必须为>=0的数,这也是为什么标签中有负值报错。在将其修改为上图所示的代码后,代码跑通。但还存在一个疑惑点,因为yolo标签中(以下图为例)第一个数值代表类别,比如下图代表第五类目标,而后面四个数值则代表中心点x(比例)、中心点y(比例)、box宽(比例)、box高(比例),四个比例值为什么会出现负数呢?这一点我没有搞懂,有经验的朋友可以为我解答一下。
总之,在解决种种数据集相关的问题后,训练开始,不到两万张图片,调用4GPU训练了两天,最终的结果还是很可喜的。
在可见光目标训练、测试完毕后,还要测试一下对红外目标的检测效果,因此用原来的网络,只是把数据换成了一类红外目标(注意这一类),刚开始我没拿这个测试当回事,网络没问题,换个数据集而已。但训练过程中却报错:mlc(最大类别值) = nc (类别数),询问大师兄才明白,在计算机网络中,一般都用0来表示“第一”,所以,mlc的值一定是比nc小1,检查标签发现,果然标签的类别数是1,替换为0后,问题解决。
这个经历也让我意识到,自己对于很多最基础的概念理解还不够深刻,在遇到问题后如何去发现关键的点,继而解决问题才是能力的体现。
数据集
还是想接着谈谈数据集的问题,个人觉得,数据集在一个算法的实现过程中起着至关重要的作用,一个好的数据集不仅可能提升算法的表现力,更关键的是,有些算法功能的实现,是离不开一个合适的、质量高、符合要求的数据集的。举两个例子。
配准
在研究红外可见光配准过程中,需要把一对可见光图及其对应的红外图像放入网络中训练,就我选择的这个算法而言,选择的图像对视场越接近,红外目标的轮廓越清晰,最终配准的效果就越好。(恕我能力有限,目前只能实现这种对数据要求比较高的算法。红外可见光的相关网络理解程度远远不够)所以选图的过程就耗费了不少时间,不过最后选择了一对实验室之前拍的图,效果喜人。
三维图像生成
说到三维图像生成,就不得不说数据增强这个概念。在之前数据集的构建过程中,我们使用了10种相对传统的图像处理方法,包括加噪,旋转,cutout等,之前尝试过利用马赛克进行数据扩充,但每次智能生成一张组合图,效率太慢,针对这个问题也咨询过中科大的一个大佬,他表示实现起来应该不难,不过(我)能力所限,无法修改为批量组合的代码,因为本身对马赛克的理解也不够深入,还是没有采用这个办法。
出于对数据的完善的想法,想到用GAN网络进行图像处理,不过想到我们研究的目标多数都是遥感图像,所以例如风格迁移,styleGAN等应用于人脸、动物变换的对抗网络,我是认为意义不大。这就想到了三维图像生成,最开始想的是,在给某一目标的两个角度后,可以通过对抗网络生成它的三维模型,不过在经过一定时间的研究后,我还是把问题想的太简单了。这个过程中,也看了很多三维生成的代码,但遗憾的是,之前最靠谱的DIB-R缺少最关键的train.txt,压根无法训练。况且即使可以训练,也是生成项目原有的目标,对我们的目标来说,需要符合条件的模型、标签……
在思考若干天,浏览很多GitHub上的项目后,我发现meshroom是一个很靠谱的选择。现在,我们的小标题,“数据集”的重要性就体现出来了。我最开始选取了我们数据集中的40余张某某目标的图片,训练出错,总是卡在倒数第三步,提示bounding box过小。分析一波发现,我放进去的这些图片,尽管目标相似,但背景却各不相同,bounding box过小,也就是这些图像之间的可匹配性太小。
话不多说,赶紧找三维生成的数据集,看看人家的是啥样的,上图:
用了人家的数据集,果然生成了能看的三维效果:
可见,三维生成对数据的精细程度要求是很严格的,对于水塔这种细节较少的目标,需要各个角度、远近不同的图像;而对像舰船这样细节很多的目标来说,尽可能地捕捉细节,就成为决定生成三维图像效果好坏的关键。
配环境
说起跑算法,配环境肯定是最基础,也比较关键的一步了。yolo v5的环境比较好配,没有遇到太多的问题。后面跑图像配准算法时,由于它使用python2.7的环境,所以当时遇到了包与python版本不相容的问题(包括numpy,enum(要用enum34替换)等)。到了后来,涉及到一些基础环境的修改,我干脆直接把之前配的乱七八糟的环境删除,从0开始配,最终问题解决。在此也告诫像我一样的初学者们,配环境过程中,一定要慎重对待涉及到root权限的指令(sudo等)。
另外,说一嘴conda install 和pip install,之前一直习惯用 pip install (插一个豆瓣源安装指令,超快:pip install pillow -i http://pypi.douban.com/simple --trusted-host pypi.douban.com ,下载所需包时,把名字替换即可),但到了后面意识到,如果没有conda install ,到了后面会导致环境和安装的包发生冲突,由于我是在anaconda环境中跑算法,所以干脆就养成了conda install 的习惯。
但有一个玄学的问题就是,我在配配准环境时,遇到一个lap包,在conda install后,还是提示不存在,卸载再重装还是报错。最后直接卸载conda下的lap,用pip安装,通了。这个原理也不是很理解,暂时按照玄学处理吧。(有小伙伴懂的可以说一下)
问题查找
yolo v5训练红外数据出错找问题,看大师兄找问题的过程受益匪浅,小结一下:
有时候想知道网络的某一部分是否有问题,一个好办法就是把某个值print一下,比如之前提到的mlc 和 nc,在分别print了红外单类(mlc = 1.0 nc = 1)和无问题的9类可见光(mlc = 8.0 nc = 9)后,问题也就浮现出来了。
linux系统的使用
看了大师兄的操作之后,我意识到熟练使用linux系统是解决问题的关键,如vim、pdb断点调试等,这些技巧我现在还不能为我所用,解决问题。我也反省到,自己只把尽快把代码跑通当成最要紧的任务,却忽略了一些基本技能的学习和熟悉,这样的话,后面的创新提都不要提了。