当看裸体的时候,卷积神经网络会看到什么

作者 RYAN COMPTON时间2016.04.19 发表于ENGINEERING

我们上周在Clarifai正式宣布不安全的工作(NSFW)成人内容识别模型。本周,我们的一个数据科学家将指导您完成一个技术探索:他如何教电脑看到裸体的人。

警告和免责声明:这篇文章包含科学目的的裸露的可视化。我们要求你别再读下去如果你未满18岁,或者如果你会被裸体冒犯。

到现在20年以来,裸照发现的自动化一直是计算机视觉的一个核心问题,因为它的丰富的历史和简单直接的目标,一直是这个领域如何演化的一个很好的例子。在这篇文章中,我将使用探测裸照来说明现代卷积神经网络训练(回旋网)如何不同于过去的研究。

*警告:这篇文章包含可视化对应非常明确的裸照,小心行事!

早在1996年……

在这个领域内的开创性工作是由Fleck等人巧妙命名的“发现裸体者”。它发表在90年代中期,并提供了一个很好的这种工作的先例,即计算机视觉研究人员优先做卷积神经网络接管。在论文的第二部分,他们总结了技巧:

算法:

-首先定位包含肤色区域的大部分面积的图像;

-其次,在这些区域中,找到细长的区域,用专门的包含了大量关于物体结构信息的分类器,把他们分组到可能的人体的四肢和相连的人体四肢组。

肤色检测是通过过滤颜色空间,分组肤色区域是通过给人体图建模,“作为近圆柱形零件的组装,两个人几何零件和零件之间的关系受几何骨架得到约束”(参看第二节)。为了更好地了解的构建一个这样的算法的工程,我们转向论文的图1,作者说明的几个手建的分组规则:

这篇文章报道“60%精度和52%召回测试集的138张不受控制的裸照。”他们也为真阳性和假阳性的例子提供可视化的用覆盖算法发现的特点:

手工构建特性的一个主要问题是其复杂性受研究人员的耐心和想象力的限制。在下一节中,我们将看到卷积神经网络训练如何来执行相同的任务却可以学习相同的数据的更复杂的表现。

然后在2014年……

深度学习研究者设计网络架构和数据集使得人工智能系统可以直接从数据学习表现,而不是发明正式规则来描述应该如何代表输入的数据。然而,由于深度学习研究者没有明确指明网络对于给定输入应该如何表现,一个新的问题出现了:一个人怎么能理解卷积网络的活动?

理解的卷积神经网络的操作需要解释在各层的特征活动。在本文剩下的部分里,我们将检查一个早期版本的NSFW模型,通过映射活动从顶层回到输入像素空间。这将使我们能够看到原始输入模式对给定的特征图造成了什么样的激活。(即,为什么一个图像被标记为“NSFW”)。

闭塞敏感性

下图显示了丽娜的照片索德伯格后64 x64的3步的脚步滑动窗口,运用了NSFW模型于裁剪/阻挡版本的原始图像。

为了构建左边的热力图,我们发送每一个窗口到卷积神经网络,并在每个像素上平均NSFW模型的得分。当卷积神经网络遇到一个充满皮肤的物体时,它往往会趋向于预测“NSFW”,这会导致在丽娜的身体出现大块的红色区域。为了建立右边的热力图,我们系统地挡住部分原始图像并报告1 减去“NSFW”平均得分(即“SFW”分数)。当大部分NSFW地区被阻挡的时候,“SFW”分数增加,我们看到更高的热图中的值。需要澄清的是,下面这些图包含什么样的图片被送入卷积神经网络的例子,对于上面两个实验的每一个:

一个关于闭塞实验的好处是他们可能会展现当分类器是一个完全的黑箱。下面是通过我们的API重新生成这些结果的代码片段:

# NSFW occlusion experiment
fromStringIOimportStringIO
importmatplotlib.pyplotasplt
importnumpyasnp
fromPILimport Image, ImageDraw
importrequests
importscipy.sparseassp
fromclarifai.clientimportClarifaiApi
CLARIFAI_APP_ID ='…'
CLARIFAI_APP_SECRET ='…'
clarifai=ClarifaiApi(app_id=CLARIFAI_APP_ID,
app_secret=CLARIFAI_APP_SECRET,
base_url='https://api.clarifai.com')
defbatch_request(imgs, bboxes):
"""use the API to tag a batch of occulded images"""
assertlen(bboxes) <128
#convert to image bytes
stringios= []
forimginimgs:
stringio=StringIO()
img.save(stringio, format='JPEG')
stringios.append(stringio)
#call api and parse response
output= []
response=clarifai.tag_images(stringios, model='nsfw-v1.0')
forresult,bboxinzip(response[‘results’], bboxes):
nsfw_idx=result[‘result’][‘tag’][‘classes’].index("sfw")
nsfw_score=result[‘result’][‘tag’][‘probs’][nsfw_idx]
output.append((nsfw_score, bbox))
return output
defbuild_bboxes(img, boxsize=72, stride=25):
"""Generate all the bboxes used in the experiment"""
width=boxsize
height=boxsize
bboxes= []
for top inrange(0, img.size[1], stride):
for left inrange(0, img.size[0], stride):
bboxes.append((left, top, left+width, top+height))
returnbboxes
defdraw_occulsions(img, bboxes):
"""Overlay bboxes on the test image"""
images= []
forbboxinbboxes:
    img2 =img.copy()
draw=ImageDraw.Draw(img2)
draw.rectangle(bbox, fill=True)
images.append(img2)
return images
defalpha_composite(img, heatmap):
"""Blend a PIL image and a numpy array corresponding to a heatmap in a nice way"""
ifimg.mode=='RBG':
img.putalpha(100)
cmap=plt.get_cmap('jet')
rgba_img=cmap(heatmap)
rgba_img[:,:,:][:] =0.7#alpha overlay
rgba_img=Image.fromarray(np.uint8(cmap(heatmap)*255))
returnImage.blend(img, rgba_img, 0.8)
defget_nsfw_occlude_mask(img, boxsize=64, stride=25):
"""generatebboxes and occluded images, call the API, blend the results together"""
bboxes=build_bboxes(img, boxsize=boxsize, stride=stride)
print'api calls needed:{}'.format(len(bboxes))
scored_bboxes= []
batch_size=125
foriinrange(0, len(bboxes), batch_size):
bbox_batch=bboxes[i:i+batch_size]
occluded_images=draw_occulsions(img, bbox_batch)
results=batch_request(occluded_images, bbox_batch)
scored_bboxes.extend(results)
heatmap=np.zeros(img.size)
sparse_masks= []
foridx, (nsfw_score, bbox) inenumerate(scored_bboxes):
mask=np.zeros(img.size)
mask[bbox[0]:bbox[2], bbox[1]:bbox[3]] =nsfw_score
    Asp =sp.csr_matrix(mask)
sparse_masks.append(Asp)
heatmap=heatmap+ (mask -heatmap)/(idx+1)   
returnalpha_composite(img, 80*np.transpose(heatmap)), np.stack(sparse_masks)
#Download full Lena image
r =requests.get('https://clarifai-img.s3.amazonaws.com/blog/len_full.jpeg')
stringio=StringIO(r.content)
img=Image.open(stringio, 'r')
img.putalpha(1000)
#set boxsize and stride (warning! a low stride will lead to thousands of API calls)
boxsize=64
stride=48
blended, masks =get_nsfw_occlude_mask(img, boxsize=boxsize, stride=stride)
#viz
blended.show()

尽管这些类型的实验提供了一个简单直接的展示分类器输出结果的方法,但是他们有一个缺点:生成的可视化图像非常模糊。这妨碍了我们获得有意义的洞察神经网络实际上在做什么以及理解可能在训练过程中出现的错误。

深度卷积网络Deconvolutional Networks

一旦我们在给定的数据集上训练成了一个网络,我们就能够取定一张图片和一个类,然后可以要求卷积神经网络做些事情,比如“我们应该如何改变这张图片以使它看起来更像给定的类?”对于这种情况,我们用深度卷积神经网络(deconvnet),请参考Zeiler和Fergus 2014年写的第二节:

深度卷积神经网络可以被看作用了相同组件但是相反的卷积神经网络,所以与把像素映射到特征上相反。为了检测到一个给定的卷积神经网络的激活作用,我们将所有层的激活设置为0,并把特征图作为输入传递给绑定的深度卷积神经网络层。然后我们成功地(i)unpool,(ii)纠正,(iii)过滤重构层中的活动,在它下面引发了选择好的激活。这会被一直重复直到输入像素空间被达到。

【……】 这个过程类似于返回一个强烈的激活的属性(而不是普通的梯度),即,用强烈激活计算 ,其中Xn 是特征映射的元素, 输入图像的位置。

这是用深度卷积神经网络想象我们如何修饰丽娜的图片使得看起来更像色情图片所得出的结果(此处所用的深度卷积神经网络需要一个正方形图使得运行正确-我们填补丽娜的完整图像以得到正确的比例):

芭芭拉是G级别版本的丽娜。根据我们的深度卷积神经网络,我们可以修饰芭芭拉给她的嘴唇添加红色使得看起来更像PG级别的:

这张Ursula Andress 在James Bond 的电影Dr. No中扮演Honey Rider 的图片被票选为“银幕史上最性感的100个时刻中的第一名”,根据2003年英国的一个调查:

上述实验的突出特征就是深度卷积神经网络学习到红嘴唇和肚脐作为“NSFW”模型的说明。这可能意味着我们没有在“SFW”的训练数据中包含足够的红嘴唇和肚脐的的图像。如果我们只通过检测精度/召回和ROC曲线(如下所示-测试集大小:428271)来评估我们的模型,我们将永远不会发现这个问题,因为我们的测试数据有相同的缺点。这突出了训练基于规则的分类器与现代人工智能研究的根本的区别。我们重新设计训练数据直到已发现的功能得到改善,而不是重新设计我们的功能。

最后,作为为了保证周全的检验,我们将深度卷积神经网络用于赤裸裸的情色图片以保证学习到的特征激活确实明显对应到NSFW模型的对象:

在这里,我们可以清楚地看到,事先正确学会了阴茎,肛门,阴户,乳头,屁股——我们的模型应该能标识出的物体。此外,发现的特征远比研究人员用手设计的详细和复杂,这帮助我们解释了用深度卷积神经网络识别NSFW图像得到的重大的改进。

翻译:曾庆福

原文连接:http://blog.clarifai.com/what-convolutional-neural-networks-see-at-when-they-see-nudity/#.Vxwpgn4rLIX

原文发布于微信公众号 - PPV课数据科学社区(ppvke123)

原文发表时间:2016-04-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏悦思悦读

利用逻辑回归模型判断用户提问意图

在之前开发聊天机器人的文章里,我们讲解了如何使用在线工具LUIS (https://luis.ai) 开发Chat bot的自然语言理解模型。 在构造问题解决型...

495140
来自专栏机器学习AI算法工程

基于Kaggle数据的词袋模型文本分类教程

本教程展示了改善文本分类的方法,包括:做一个验证集,为AUC预测概率,用线性模型代替随机森林,使用TF-IDF权衡词汇,留下停用词,加上二元模型或者三元模型等。...

33950
来自专栏数据派THU

一文读懂FM算法优势,并用python实现!(附代码)

作者:ANKIT CHOUDHARY 翻译:张媛 术语校对:冯羽 文字校对:谭佳瑶 本文共3933字,建议阅读9分钟。 本文带大家了解因子分解机算法并解析其优势...

2K80
来自专栏机器学习AI算法工程

用交叉验证改善模型的预测表现(适用于Python和R)

原文作者: Sunil Ray 翻译:王鹏宇 我一直对数据界的编程马拉松(Hackathons)保持关注。通过对比排名榜初期和最终的结果, 我发现了一个有趣的现...

61860
来自专栏PPV课数据科学社区

如何选择Microsoft Azure机器学习算法

编者按:机器学习的算法很多,如何选择一直是初学者的一个痛点。本文给出了机器学习算法选择的方法和实例,不仅适用于Microsoft Azure框架,同样可以应用于...

54460
来自专栏目标检测和深度学习

目标检测入门(四):特征复用、实时性

文章结构 本文的第一部分关注检测模型的头部部分。对与每张图片,深度网络其实是通过级联的映射获得了在某一流形上的一个表征,这个表征相比原图片更有计算机视角下的语义...

44370
来自专栏机器之心

业界 | 谷歌发布TensorFlow 1.4与TensorFlow Lattice:利用先验知识提升模型准确度

29560
来自专栏新智元

计算机视觉中,目前有哪些经典的目标跟踪算法?

【新智元导读】这篇文章将非常详细地介绍计算机视觉领域中的目标跟踪,尤其是相关滤波类方法,分享一些作者认为比较好的算法。 相信很多来这里的人和我第一次到这里一样,...

970100
来自专栏新智元

【CVPR 2018热文】MIT提出“透明设计”网络,揭开视觉黑盒

【新智元导读】MIT和普朗克航空系统公司的研究人员合作,提出了一类“透明设计网络”,在李飞飞等人提出的视觉理解数据库CLEVR上达到了99.1%的准确率,他们设...

35950
来自专栏新智元

超越GAN!OpenAI提出可逆生成模型,AI合成超逼真人像

【新智元导读】OpenAI最新提出的可逆生成模型Glow,可以使用相对少的数据,快速生成高清的逼真图像,具有GAN和VAE所不具备的精确操作潜在变量、需要内存少...

13800

扫码关注云+社区

领取腾讯云代金券