面向图像分割的数据增广需要注意的几个细节,以肺结节检测为例

因为毕设题目是肺结节检测,我最近一段时间一直在做图像分割。不过,肺结节检测现在已经非常成熟,甚至很多地方都已经投入实际应用,所以这个时候只简单地完成“检测”这个任务,老师肯定是不买账的。

学长的建议是做肺结节的同时沾一点迁移学习的边,因为我不在本校读研实验室的资源不可能给我占着,所以就不用指望上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。

很简单的一个问题,结果写了这么多废话。应该还是疫情原因呆在家里闲的。

原文地址:https://www.cnblogs.com/samwoog/p/faster-rcnn_with_augumentation.html

时间: 2024-07-30 22:14:59

面向图像分割的数据增广需要注意的几个细节,以肺结节检测为例的相关文章

【BZOJ-3638&3272&3267&3502】k-Maximum Subsequence Sum 费用流构图 + 线段树手动增广

3638: Cf172 k-Maximum Subsequence Sum Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 174  Solved: 92[Submit][Status][Discuss] Description 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. Input The first line contains integer n (1 ≤ n 

一步一步学习S-MSCKF(一)状态向量预测及其增广

1 状态向量预测 为了处理离散时间的IMU数据,采用四阶Runge-Kutta数值积分方法对以下方程离散化,从而对IMU的估计量进行预测. \[_{G}^{I}{\dot{\hat q}}=\frac{1}{2}\Omega(\hat w)_{G}^{I}\hat q, \dot {\hat b}_{g}(t)=0_{3\times1},\^{G}\dot {\hat v}_{I}=C(_{G}^{I}\hat q)^{T}{\hat a}+{^{G}g}, \dot {\hat b}_{a}=

关于增广算法中反向边引入的理解

首先上一张常见的图: 考虑不引入反向边的情形: 如果执行bfs一次扫描到增广路1-2-4-6,流量总量累加10,得到的残量网络无法继续进行增广,那么算法返回最大流为10. 然而实际上最大流是20,显然该算法是有问题的. 最大流算法都是基于最大流最小割定理的,即网络流中任意可行流必然不超过任意S-T割容量,并且若流f等于某S-T割容量, 该流为最大流,该割为最小割. 这里S-T割容量指sigma(capbility(u, v)),u ∈ S,v ∈ T. 严谨的叙述及证明参考wiki. 而上述算法

《增广贤文》以及解释

昔时贤文,诲汝谆谆. 集韵增广,多见多闻. 观今宜鉴古,无古不成今. [解释]用以前圣贤们的言论,来谆谆教诲你.广泛搜集押韵的文字汇编成“增广”,使你见多识广.应该借鉴古人的经验教训,来指导今天的行为,因为今天是古代的延续. 知己知彼,将心比心. [解释]知道自己怎么想的,也应该知道别人是怎样想的,所以要用自己的心,体谅别人的心,设身处地为别人着想. 酒逢知己饮,诗向会人吟. 相识满天下,知心能几人. [解释]酒要和了解自己的人一起喝,诗要与懂得它的人一起吟.认识的人可以很多,但真正了解,并达到

hdu 1281 二分图残量增广

http://acm.hdu.edu.cn/showproblem.php?pid=1281 每行每列最多放置一个车,所以可以把行号和列号当成点,给定的点当成边进行最大匹配,得到的答案就是最大放置数了 然后,还要求重要点——转化为删除边后得到的最大匹配数是否发生变化的问题 易知重要点一定是模型中产生最大匹配时的边,所以我们枚举这样的边,尝试着删除判断情况 较优的做法是删边时将两个标号标记为未匹配,然后禁用这条边,在原有的基础上进行增广,若没有找到新的增广路,则重要点数+1,把两个标记复原 若找到

增广贤文

<增广贤文>为中国古代儿童启蒙书目.又名<昔时贤文>.<古今贤文>.书名最早见之于明代万历年间的戏曲<牡丹亭>,据此可推知此书最迟写成于万历年间.后来,经过明.清两代文人的不断增补,才改成现在这个模样,称<增广昔时贤文>,通称<增广贤文>.作者一直未见任何书载,只知道清代同治年间儒生周希陶曾进行过重订,很可能是民间创作的结晶. 作者:佚名 昔时贤文,诲汝谆谆.集韵增广,多见多闻.观今宜鉴古,无古不成今.知己知彼,将心比心.酒逢知己饮,

最大流——增广路算法

关于网络流的增广路算法,网上有很多详细介绍,这里是摘录的模板.详细请见:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 1 #include<iostream> 2 #include<iomanip> 3 #include<ctime> 4 #include<climits> 5 #include<algorithm> 6 #include<queue>

增广路径求解最大流

关于什么是最大流.我说不清楚,而且也没有别人的比喻生动. [主要是我懒,不想画图] 算法的核心在于:找到增广路径,修改它,继续找,直到没有. While ( findAugmentPath() ) // 判断是否有增广路 maxFlow = maxFlow + delta // 最大流增加 modifyGraph() // 对增广路进行修改 End While 最近智商有点不够用.想了很久才想通findAugmentPath()函数.利用的是BFS. 1 int i,j,u,v; 2 int f

Salesforce零基础(三)简单的数据增删改查页面的构建(Ajax样式)

VisualForce封装了很多的标签用来进行页面设计 下面以一个单一的表进行数据增删改查.表结构如图1所示.通过图可以看出GOODS表自己定义的参数主要包括以下: GoodsName__c,GoodsType__c,GoodsBrand__c,GoodsDescribe__c,GoodsPrice__c. 图1 VF每个页面都是以<apex:page>标签起始</apex:page>结束,每个VF页面都有一个Controller用来控制其业务逻辑.本篇例子中主要用到的控件包括如下