失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 通过 resnet 实现对色情图片性感图片的识别(代码/调优/数据)

通过 resnet 实现对色情图片性感图片的识别(代码/调优/数据)

时间:2021-02-01 08:31:50

相关推荐

通过 resnet 实现对色情图片性感图片的识别(代码/调优/数据)

零:代码

/yangbisheng/nsfw-resnet(绝对良心代码,欢迎 star)

一、背景

线上海量图片,需要将其中性感图片、色情图片识别出来

比如:

性感

普通图片

二、调研

在经过一些列调研之后,确定了以下几种方案:

机器学习方法,利用p_hash或者图片hog特征或者傅里叶变化、小波变换抽取图片向量特征,采用传统机器学习的方法直接有监督分类直接采用卷积神经网络方法,如 resnet、inception 等方法做有监督分类。或者对于我这种初学者来讲,不用深层卷积神经网络,直接采用 卷积层 + 池化 + 全连接 的基础神经网络结构。

列举了上述两种方法,经过调研大牛们的实现,决定不走弯路,直接上inception、resnet方法。并且最终确定了resnet101 + pytorch的组合(当然了,其它的实现,也有亲自试验,后面会讲到)

三、resnet原理

resnet就是一个做了一些小技巧的多层卷积神经网络,如果对基本的 卷积层-池化层-全连接层 结构不太了解,建议你可以先学习一下基础。我这里会对resnet原理一笔带过,因为网络上也有大批文章做介绍。

前提:深层网络对图片的分类效果好(实践证明,业界公认,尚无理论支撑)

问题:深层网络无法避免的梯度消失问题,导致深层神经网络模型可能效果还不如浅层效果

现在问题梳理清楚了,也就是只要我们能够解决梯度消失问题,那么就可以畅快的使用深层神经网络了。解决这个问题,就用到了残差。

假设现有一个比较浅的网络(Shallow Net)已达到了饱和的准确率,这时在它后面再加上几个恒等映射层(Identity mapping,也即y=x,输出等于输入),这样就增加了网络的深度,并且起码误差不会增加,也即更深的网络不应该带来训练集上误差的上升。通过“shortcut connections(捷径连接)”的方式,直接把输入x传到输出作为初始结果,输出结果为H(x)=F(x)+x,当F(x)=0时,那么H(x)=x,也就是上面所提到的恒等映射。于是,ResNet相当于将学习目标改变了,不再是学习一个完整的输出,而是目标值H(X)和x的差值,也就是所谓的残差F(x) = H(x)-x,因此,后面的训练目标就是要将残差结果逼近于0,使到随着网络加深,准确率不下降。

也就是说,即使我并不知道多少层是最佳,我通过残差模块,即使已经错过最佳深度我至少模型的精度不会有影响。起初看到这种网络模型很是奇怪,如果是一个浅层网络就能达到饱和,那么后面的残差结构目标是学习一个恒等映射,那么学习目标为F(x)接近为0。既然这样,为什么要去学习这个映射?直接写个恒等函数,或者直接设置F(x)=0 输出为x不就行了?残差网络的目的是学到y=x恒等映射函数,那么不就相当于加上的残差网络在最后没起到作用吗?那么为什么会有效呢?

首先这个饱和的浅层网络本身就不好寻找,有可能在达到饱和浅层网络深度之前,由于误差的原因模型精度已经下降。那么为什么持续增加层,让模型学习一个恒等映射就会使得模型表达变好呢?

假设:如果不使用残差网络结构,这一层的输出F'(5)=5.1 期望输出 H(5)=5 ,如果想要学习H函数,使得F'(5)=H(5)=5,这个变化率较低,学习起来是比较困难的。但是如果设计为H(5)=F(5)+5=5.1,进行一种拆分,使得F(5)=0.1,那么学习目标是不是变为F(5)=0,一个映射函数学习使得它输出由0.1变为0,这个是比较简单的。也就是说引入残差后的映射对输出变化更敏感了。

进一步理解:如果F'(5)=5.1 ,现在继续训练模型,使得映射函数F'(5)=5。(5.1-5)/5.1=2%,也许你脑中已经闪现把学习率从0.01设置为0.0000001。浅层还好用,深层的话可能就不太好使了。如果设计为残差结构呢?5.1变化为5,也就是F(5)=0.1变化为F(5)=0.这个变化率增加了100%。引入残差后映射对输出变化变的更加敏感了,这也就是为什么ResNet虽然层数很多但是收敛速度也不会低的原因。明显后者输出变化对权重的调整作用更大,所以效果更好。残差的思想都是去掉相同的主体部分,从而突出微小的变化,看到残差网络我第一反应就是差分放大器。这也就是当网络模型我们已经设计到一定的深度,出现了精准度下降,如果使用残差结构就会很容易的调节到一个更好的效果,即使你不知道此刻的深度是不是最佳,但是起码准确度不会下降。代码实现也比较简单,原本的输出结果由F(x)替换为输出F(x)+X,如果维度相同则直接相加,如果维度不同则利用1*1的卷积核变换。当然残差网络还有很多细节, 比如使用预batch normalize ,ResNet-v1 由relu非线性变换,替换为ResNet-v2恒等变换。

四、具体实现

这是我的代码库,里面有完整的代码实现:/yangbisheng/nsfw-resnet

强烈建议大家使用pytorch来做图像相关的处理呦,性能高、灵活。

我采用加载预训练好的resnet101模型,通过样本数据,做全局finetune(后续你们也可以尝试局部finetune,只把微调深层网络参数)。

数据来源:

好心人提供的开源数据,给个赞:/alexkimxyz/nsfw_data_scraper

数据标签:

porn- 色情hentai- 动漫色情、图画sexy- 性感neutral- 普通drawings- 普通动漫、图画

一些能够提升准召的tips:

尽可能调大batch_size,我在我的P40机器上,设置了512我最终选用了resnet101 pretrained model,它在诸多的方案中,表现最好在整体finetune后,可以lock模型前面的N层,重新finetune一次。为什么这么做能带来更好的效果,我想你们都懂的根据你的数据集、模型选择等因素,动态调整你的learning rate我采用了很多数据增强的方法,如颜色变换、高斯噪声点、旋转、平移、剪切、色调对比度变换。但是结果发现这些方法,并没有太大的卵用(针对这个工程而言),最终只保留一小部分

效果:

五、和其它模型的对比

我尝试了resnet101、resnet50、inceptionv3、手写单层cnn 等三种方法。

resnet101效果最好,但是稍微比resnet50慢一点。但是可以接受

手写单层cnn稍后会把代码放出来,非常有助于大家对图片分类的理解

欢迎留言提问 或者 邮箱联系我: yangbisheng@

如果觉得《通过 resnet 实现对色情图片性感图片的识别(代码/调优/数据)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。