【2022阿里安全】真实场景篡改图像检测挑战赛 决赛rank17方案分享

最近刚结束阿里安全部门组织的比赛,比赛链接:真实场景篡改图像检测挑战赛。
训练、推理包括数据增强的代码都在ImageChallenge。

一、比赛是干嘛的

简单来说就是原始的图像被篡改了,比如复制粘贴、ps、水印、马赛克等等,然后你用二值图像(也就是黑白、0和255)标记出来,是图像异常检测,也可以理解是图像分割任务。

二、为啥参加这个比赛

因为我本人平常一直在学图神经网络和自然语言处理,没接触过CV,想着CV也是机器学习领域很大的一个方向很有必要去涉猎了解一下,抱着这样学习的心态就去参加了这个比赛。很感谢在这次比赛中认识了本校另外一个学院的lyx同学,非常可靠优秀的队友,后来两个人简单组了个队抱着摆烂的心态混进了top20,因为我们两个人的其他事情实在太多(课程作业、导师安排的学习任务等等),实在没有精力投入到比赛上,也导致了很多我们觉得有用的方案没来及验证,蛮可惜的。。。。

三、如何从小白的角度去考虑CV策略

一开始的话想着如何检测图像异常呢?简单来说就是以像素点为单位,然后做二分类,所以最早我自己用CNN搭建了一个很简单的识别模型,把所有比赛图像直接resize成512x512,模型输出为512x512大小的概率矩阵,表示每个像素点异常的概率程度,然后再根据每张图像的原始尺寸resize回去,这样想没问题,模型也正常训练,可惜很不巧的是,模型我训练使用的二分类交叉熵损失函数,训练过程损失loss一直下降,但是分数IOU却也在下降,没有上升,究其原因是样本分布差距太大,因为正常的像素点数目明显比异常的像素点数目要多很多,后来看到了一个专门针对这种标签分布差异很大的二分类的损失函数dice_loss函数,感觉学到了一个很有用的知识,这个损失函数不了解的同学最好学习下,很有用,然后我复现了这个损失函数,去训练模型,效果得到了明显提升,提交了下预测结果,分数凑合就1500左右。

当然我是抱着学习的心态,至少大体了解到了图像任务的一些基本流程操作。

那后来是看到了其他大神开源的一个baseline,用的efficient和unet搭建的模型,训练效果可以上2300,毫不犹豫直接拿别人的baseline来训练了。

这里也是一个比较中肯的建议,如果别人有开源比较好的方案,直接去看懂别人的方案要好很多,自己从0去搭建一个自己不擅长领域的东西很麻烦,而且容易走一些弯路。

四、比赛的难点和方案

也不能说是比赛的难点,是图像分割一直存在的难点,就是图像的尺寸问题,每个图像的大小不一样,怎么训练呢?要考虑图像的尺寸归一,还要考虑大图直接resize成小图不然会爆显存。

图像直接resize:保留了图像整体的信息,但是直接破坏了图像的局部信息,导致直接resize后模型训练的效果很好,但是还原回原始图像尺寸分数带来一定偏差。

图像切片:完整保留了图像的局部信息,但是破坏了图像整体的信息,使得整体的识别效果较差。

为了规避上面的问题,我们索性直接训练两个模型,一个模型单独训练直接resize成768x768大小的图像,另外一个模型单独训练滑动切片成512x512大小的图像,预测的时候再拼接回去。训练512滑动切片的模型还需要注意的是重叠,不能切片出来的每张图像都是完全独立的,这样对原始图像的整体信息保留不好,所以刻意设置滑动切片,每个切片之间保留128个像素单位的重复。

最终预测的结果就是两个模型融合结果。

后来队友lyx发现,512切片训练的模型,如果把图像直接resize成512预测的概率矩阵0.2+滑动切片512预测的概率矩阵0.8效果会更好,于是又做了这个改进。

我们引入了其他数据,我们找到了阿里安全部门举办的上届的图像异常检测的比赛,找到了上届的数据集丢入训练,分数提高了40-80分左右。我们还做了额外的数据增强,数据增强是参考了当时一个大神开源的方案,不过很可惜的是这个大神初赛前几,复赛变成了倒数前几,很诧异,因为复赛是主办方运行我们提交的docker模型,拿不到测试集,也就存在了一定的运气问题,所以可能这个大神初赛用了一些方法很好的将训练集和测试集图像内容进行了对齐,导致了模型出现了一定测试集上的过拟合,蛮可惜的。

另外一个问题就是,动态阈值的判断,我们训练模型是以0.5为分界线,但是好几次输出的结果都是,有几百张图像没有检测出任何异常,后来调整到0.4为异常分界线,分数上升了一截。

我们还做了哪些尝试,因为很大程度上,图像的直接resize或者滑动切片训练,都破坏了原始图像的完整信息,所以我们希望最好是有一种模型,输入的图像尺寸是多少,输出的概率矩阵尺寸是多少,保证图像的原汁原味,于是乎,我们发现了一个神奇的模型RRUNET就可以实现这样的功能,但是这个模型是前几年提出来的了,然后整个模型结构比较简单,只有16M大小,训练只能一张一张训练,非常非常非常慢,最后训练出来的效果,因为模型太小了,而且没有预训练模型可以直接加载使用,我曾经想过用9个RRUNET搭建一个比较复杂的大模型训练,然后用比赛数据集疯狂的训练几天几夜希望能训练一个预训练模型出来,但是后来时间成本和机器成本都太高就放弃了。

最后的话就是2折交叉训练了,因为时间成本比较高,没有5折,我们只是简单的分成5份,768resize和512切片分别训练了两个模型,总共4个模型,然后4个模型融合提交。

简单来说我们的方案就是这样了,剩下的就是拼命训练融合模型提交。

你可能感兴趣的:(深度学习,算法,人工智能,计算机视觉)