面向图像分割的数据增广需要注意的几个细节,以肺结节检测为例
Posted samwoog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向图像分割的数据增广需要注意的几个细节,以肺结节检测为例相关的知识,希望对你有一定的参考价值。
因为毕设题目是肺结节检测,我最近一段时间一直在做图像分割。不过,肺结节检测现在已经非常成熟,甚至很多地方都已经投入实际应用,所以这个时候只简单地完成“检测”这个任务,老师肯定是不买账的。
学长的建议是做肺结节的同时沾一点迁移学习的边,因为我不在本校读研实验室的资源不可能给我占着,所以就不用指望上trick冲性能;真正能做的只有想方设法提高训练好的模型在其他测试集上的性能,实现一种“弱迁移学习”——因为尽管数据集不同,但人的肺部还是大同小异的,因此要实现这样的目标困难是会少很多的。
本来开题时是计划自己写一个faster-rcnn出来的,但是后来看到github上facebook现成的框架、而且人家又写得那么漂亮,于是还是没忍住直接下下来就直奔主题了(捂脸)。
框架安装时费了点事,但都一个个解决了。结果最后运行时老是报cude unknown error,差点给我搞崩溃。因为你有错就有错,但你说unknown error叫我怎么下手?折腾了一段时间差点都想放弃,结果下了个Geforce Experience(是真的,为了科研下的……)更新了下驱动就好了,给我搞得苦笑不得。
之后一段时间就是着手处理CT数据集。因为我是用的自己的笔记本,所以我只能采用2D方案。我选用的数据集是LUNA和天池,本来说好的还会给我南京军区医院和哈尔滨胸科医院的数据,结果我好像把学长的硬盘分区格式搞坏了,最后就不了了之了。说起来那个硬盘也是真的破,SATA口塑料片都是断的,完全就靠那个金属触点读数据,一不小心碰到立马就掉,真的强烈建议老师给点经费让学长换一个体面点的盘。
说了这么多好像还没说到题目上。实际上,我真正做的事情无非就是写好处理CT的代码,然后把2D图像组织成VOC的数据集格式(因为框架的输入是VOC)。LUNA和天池都是mhd格式的数据,切片间距离都在mhd文件中给出了,所以通过标注的结节中心和直径可以很快找出是哪一张图像上出现了结节(z),并且同时找到圆心在图像中的坐标(x,y)。这样就可以绘制出bbox了。我采用的方案是找到结节中心所在切片后将该切片的上下两个相邻切片也一并保存,因为它们上面也很有可能有结节的另一截面。
然后就是真正的数据增广部分了,这部分我一开始没注意导致训练时loss一直为nan。现在性能最好的数据增广方法应该是GridMask,其实说白了就是往图像上增添规则的棋盘式黑方块,但这个方法不适合图像分割,因为很有可能mask一放上去结节就没了;另一种方案是Google的AutoAugument,实际上也很简单,就是集合变换分组后随机应用。这个方法是可以用到分割上的,但对于肺结节这种一般小说都很小的目标,有几种几何变化是不适合的,比如横纵拉伸,倾斜(不是旋转,旋转是可以的),以及色彩上的变换等等,这些变换很可能影响结节的图像特征最后反而导致训练出来的模型一团糟。
所以我实际上就是采用的最简单的,随机上下翻转或旋转,而且为了避免数据集太大导致训练20个epoch都要三四天(毕竟我其他事情也是在这台电脑上做啊),我增广的数据集大小只是原来的两倍。就在这其中,我犯了个小错误,那就是想当然的把翻转后的bbox坐标直接用图像宽度去减了。因为这个想法太自然所以后面出了那个nan的问题我找了很久都没找到。
实际上,如果我画个图出来就很简单了。bbox是用左上角和右下角的两个点的xy坐标标注的,因为如果水平旋转后直接将纵坐标不变,横坐标置为图像宽度减去原来的横坐标,将导致框定bbox的两个点变成右上角和左下角,虽说框定的区域还是一样的,但模型就认不出来了。因此,正确的做法应该是,用图像宽度减去另一点的横坐标,这样就完全正常了。
符号上来说,x1,y1是左上角,x2,y2是右下角。
现在水平翻转后,新的bbox应该是width-x2,y1和width-x1,y2。
很简单的一个问题,结果写了这么多废话。应该还是疫情原因呆在家里闲的。
以上是关于面向图像分割的数据增广需要注意的几个细节,以肺结节检测为例的主要内容,如果未能解决你的问题,请参考以下文章