编者按:本文作者 Andrej Karpathy,由阅面科技翻译整理。
卷积神经网络是非常强大的,它能在你的个人照片里识别出物体,地点和人物,又能在自动驾驶汽车里能识别出路标,行人和交通灯,还能在航空影像中识别出庄稼,森林和道路,在医疗图像中识别出多种异常,诸如此类,不胜枚举。在这些严肃的问题之外,这种高大上的视觉识别模型也可以用在消遣和娱乐上,博众一笑。
在接下来我要给大家介绍的这个趣味实验中,我们要做这样一件事:我们从网络中收集了2百万张自拍图,并将它们作为一个具有1亿4千万个参数,当今世界最先进的卷积神经网络模型的输入,来训练一个分类器用以识别好的自拍和差的自拍。这么做的原因仅仅是因为这很简单,而且我们也能轻松实现。读完本文,你将会学到如何自拍的法门。
卷积神经网络
在我们深入介绍这个实验之前,我们先来简单介绍一下卷积神经网络是什么,这样能让更多的受好奇心驱使阅读本文的读者不至于始终处于云山雾罩的状态。用通俗一点的话来说,卷积神经网络是一把大锤,而计算机视觉问题不过是一些钉子。假如你在2015年听说过或者阅读过一些关于计算机如何识别图像或者视频中的物体的文章,大部分文章都会提到卷积神经网络。下面就是一些例子:
卷积神经网络众多成功案例中的一部分。从上到下,从左到右依次是:街景图片中识别门牌号,医疗图像中识别坏东西,中文识别,路牌识别以及人脸识别。
卷积神经网络恰好有着一段有趣的背景故事。卷积神经网络最早是由Yann Lecun等人于上世纪80年代发展出来的技术(当然,还是基于前人,像是Fukushima的工作)。当时的卷积神经网络被叫做LeNet 1,其中一个有趣的应用是在1993年用来识别数字。可惜的是,这类模型并不被当时的计算机视觉界接受,因为大家普遍认为这些模型没办法处理“真实世界”中的海量图片。
这种观念一直到2012年才被扭转过来,那一年开始我们总算有了足够的计算能力(特指GPU计算)以及足够的数据(ImageNet),使得我们能够真正地将这类模型应用到大规模的图像上。首先取得突破的是Alex Krizhevsky,Ilya Sutskever和Geoff Hinton的工作,他们在2012年的ImageNet挑战赛(把它当成计算机视觉界的世界杯即可)上取得了压倒性的胜利(16.4%的错误率,远低于第二名的26.2%的错误率)。
由于过去几年的ImageNet挑战赛是由Fei-Fei Li的实验室组织的,恰好我就在她实验室工作,因此我得以亲眼见证了这一历史的转折点。我还记得当Hinton组的结果提交上来后,实验室的一个妹子那一脸什么鬼的表情(因为实在太强了)。后来,我们大家都注意到了这个结果,纷纷站了起来,从实验室的一头走到另一头,试图去弄清楚刚才发生的一切。
在接下来的几个月中,卷积神经网络从一个备受质疑的晦涩模型一跃成为了计算机视觉界的香饽饽,几乎所有新发表的计算机视觉论文都讲其作为核心模型。ImageNet挑战赛也反映出了这个趋势——2012年的时候,只有Hinton一家用卷积神经网络模型参赛,在那之后的2013年和2014年挑战赛中,几乎所有的参赛者都采用了卷积神经网络模型。另一个有趣的现象是,每一年的冠军小组都立刻被某一公司吸纳。
这几年里,比起2012年的AlexNet(这些模型名称),我们见到了更加完美,简洁并且处理更大规模的模型。2013年是ZFNet,2014年是GoogLeNet(这是Google版的LeNet,)和VGGNet。总之,现在我们知道卷积神经网络有如下优点:
简单:同一个操作在原始图像上会被一遍一遍的重复数十次。
快速:在几十毫秒内处理一个图像。
有效:他们的工作原理在某些方面和我们组的视觉皮层工作很类似。
深入内部
那么,卷积神经网络模型到底是怎么做的呢?如果你看一下模型的细节,你将会发现一种极为简洁的计算思想被重复了一遍又一遍。下面这张动图描述了一个小型卷积神经网络的整个计算过程:
ConvNet推理过程的说明
在最左边是我们的输入,原始的图像像素,我们可以用一个3维矩阵来表示它。例如,一个分辨率为256×256的图像可以用一个256x256x3的矩阵来表示(这里的3表示RGB三个颜色)。接下去,我们就开始做卷积,听上去很神奇,但实际上就是我们用一个小型滤波器从图像的一头滑动到另一头,一行滑动到另一行。不同的滤波器对图像中不同的特征有不同的反应:有一些滤波器看到一个很小的水平边缘就会很激动,还有一些会对红色的区域很敏感,等等等等。
假设,我们有10种不同的滤波器,通过这种方式我们可以将原始(256,256,3)的图像转换成另一个(256,256,10)的“图像”。在这个经过变换后的“图像”中,我们已经将原始图像中的信息舍去了,留下的是原始图像每一个位置上对这10个滤波器的响应。这就好像是我们将原始图像的3个颜色通道(红绿蓝)变成10个滤波响应通道(在动图中,原始图像的右侧第一列就是经过变换后的图像)。
上面解释了原始图像右侧第一列是怎么来的,那么,后面这些列又是怎么出来的呢?很简单,继续用滤波器对第一列的结果进行滤波得到第二列,对第二列滤波得到第三列,以此类推。不同的列会使用不同的滤波器组合对上一列进行操作,目的是渐进地去发现越来越复杂的视觉模式,而最后一组滤波器则是用来计算图片的视觉分类概率(是汪星人还是癞蛤蟆)。当然,中间省略了一些细节,只保留了基本思想:将卷积进行到底。
刚才介绍了卷积神经网络就是一个大型滤波器叠滤波器的集合。一个问题是,我们怎么知道该用什么样的滤波器组合才能达到目的呢?实际上我们并不知道——最开始的时候我们完全随机地选择滤波器,然后一遍遍地训练他们,让他们变得更好。
下面开始举例,我们给一个采用随机滤波器的卷积神经网络输入一张图片,最后它会告诉我们这个图里有54%的可能含有狗。接着,我们可以告诉它,这实际是一只癞蛤蟆,通过一个数学过程,这个卷积神经网络会小幅度地去调整它使用的滤波器,目的是为了当它下一次看到相同的图是会告诉我们这张图更可能有癞蛤蟆。我们要做的就是用数百万的图像重复这个过程数千万次甚至数亿次。下面就是见证奇迹的时刻,在卷积计算过程中所使用的不同滤波器会渐渐地调整自己去响应图像中重要的东西,例如眼睛,头部,甚至整个身体等等。
上图是从一个经过训练后的卷积神经网络中随机选出12个滤波器,可以看看它们对图像的什么部分响应强烈。图是从Matthew Zeiler的Visualizing and Understanding Convolutional Networks里借来的。这里展示的滤波器处于卷积的第三阶段,看上去像是在寻找蜂窝状的模式,或者是轮子/躯干/文字等等。再次强调,这并不是我们特意设置的。一切都是模型自发形成的,我们只能来检视。
另一组非常优秀的卷积神经网络可视化的例子可以从Jason Yosinki等人的Deepvis项目中找到。其中包含了一个非常有趣的演示,用你电脑上的摄像头来实时地演示卷积神经网络的工作原理,Jason在下面这个视频中还配上了非常棒的解说:
深度可视化工具箱
总结一下,卷积神经网络的整个训练过程就好像是给一个小孩看许多物体的图像,然后小孩要从中逐渐发现该在图像中看什么以及怎么把这些物体找到。假如你更喜欢技术一点说法,那卷积神经网络是一个从图像像素到分类概率的函数,滤波器是它的参数,我们采用随机梯度下降法来优化一个分类损失函数。如果你对什么人工智能,大脑,奇点着迷,那可以把这个函数说成是一个“深度神经网络”,这些滤波器是神经元,而整个卷积神经网络就是一种自适应的模拟视觉皮层组织。
训练 ConvNet
卷积神经网络的一个优点就是你可以输入任何图像,只要你喜欢(带上一些标签),然后它们就开始学习如何识别这些标签了。在这个例子里,我们将一些好的自拍和差的自拍作为卷积神经网络的输入,接着它将神奇的发现如何区分一张自拍照是好的还是差的。让我们先搞点自拍图:
我写了一个小脚本来抓取带有#selfie标签的图片。最后我抓了大概500万张图片(在卷积神经网络中,图片总是多多益善)。
我用另一个卷积神经网络将这500万张图中不带人脸的图片扔了,最后还剩下200万张图片。
接下去就是去挑选哪些自拍是好的,哪些自拍是差的。直观上讲,我们需要去计算一张自拍有多少人看过,然后将点赞的人数和粉丝群体的大小用一个函数关联起来。首先,我拿了所有的自拍用户,并将他们按照粉丝的数量进行排序,排序时,我会给图片上每一个额外的标签加一些些分,因为额外的标签也许能吸引更多的目光。
接下来,我将这些排好序用户以100为大小分组,根据点赞的数量对这100张自拍图进行排序。这里我只选用了已经在网上挂了超过一个月的图,目的是得到一个比较稳定的点赞数。我将排在前面的50张自拍作为好的自拍,排在后50张的自拍作为差的自拍。最终,我们将整个200万张图一分为二,一半是好的自拍一半是差的自拍,然后我们又对可能看过所有自拍的人数做了一次归一化处理。我还将那些粉丝数量太少或者太多的用户过滤掉了,还有一些图片上有太多标签的也被过滤了。
用上面这个100万好自拍,100万差自拍的数据集来训练一个卷积神经网络。
到这里,你可能会反对我判断一张自拍是好是差的方法——比如说,有人上传了一张非常棒的自拍,但是上传时间是半夜,因此可能不会有很多人看到它,那它得到的点赞也就少了,这时候该怎么办?你说的对——我的这种分类方法肯定有问题,不过没关系,只要这100万张好自拍中真正好的自拍更多就行了,卷积神经网络可以处理这种事情。它不会因此而迷惑或者气馁,它只是尽自己的全力去解读这些输入。为了让大家对区分好差自拍这个问题的难度有一个感性认识,我把一些训练用的图像贴在下面。假如我给你任意一张图,你能很准确的回答它是好自拍还是差自拍吗?
在我们的训练数据中显示好和坏自拍的示例图像。 这些将作为数据提供给ConvNe
简单介绍一些实现细节,我用了Caffe来训练这个卷积神经网络。我用了一个在ImageNet预训练过的VGGNet,并针对这次的自拍数据集精调了参数。我用一块英伟达K40GPU花了一个通宵来训练这个模型。我禁用了模型中的 dropout选项,因为我发现禁用的结果更好一些。我还试着用一个在人脸数据集上预训练的VGGNet,不过结果并不比ImageNet预训练的好。最终,模型在测试集上达到了60%的准确率 (比随机猜50%的准确率好一些)。
怎么拍出好自拍?
刚才说道,我们收集了200万的自拍图,又根据它们接受到的点赞数(对粉丝数量做了控制)将他们分成了好的自拍和差的自拍,然后将它们扔进Caffe来训练一个卷积神经网络。这个卷积神经网络将每一张自拍都了“看”数十次,以此来调整它使用的滤波器,为了找到一种最佳的方式来区分好自拍和差自拍。我们没办法去确切地检查它找出来的东西(这些滤波器的参数总共有1亿4千万个)。不过呢,我可以用它没见过的自拍图问它是好是差,进而去理解它是通过什么来判断一张自拍的好与差的。
我用了5万张自拍图作为我的测试数据(这些自拍图是这个卷积神经网络没见过的)。作为第一个可视化结果,下面这张图里我将这些自拍图按照从好到差的顺序排列出来,最好的自拍在最上面一排,最差的自拍在最下面一排:
从最佳(顶部)到最差(底部)自拍的连续体,由ConvNet判断。
挺有趣的,是吧?下面让我们看看这个卷积神经网络认为的最好的100张自拍图(从5万张图的测试集中选出)是什么样子的:
最好的100张自拍照,由卷积神经网络判断
要拍出一张好自拍,有如下要点:
1.首先你得是个女人. 女性的自拍一致地比男的自拍要好。特别是在前100张好自拍中,无一例外全是女性。
2.其次你的脸得占整个自拍的三分之一。注意到没有,在排名靠前的自拍图中,脸的位置和姿态出奇的一致。脸总是占据了整个图片的1/3,脸要微微侧过来一些,位置要在图片的中上方。
3.将你的额头截掉。至少对于女性来说它看起来像一个非常流行的策略。
4.展示你的长发,披肩长发能给你的自拍加分不少。
5.脸部要过饱和。光线过饱和在好自拍中经常出现, 这能让脸部看来更加光滑白皙。
6.要使用滤镜。黑白照看起来能加分, 大部分排名靠前的自拍看起来都用了某种滤镜是的整个图片带有淡出效果并能降低对比度。
7.加上边框。好自拍通常都会加上水平或者垂直的白边。
有趣的是,这里的有些原则在男性身上就行不通了。我从前2000张自拍中找出了所有男性自拍,如下图:
从2000自拍中选出来的几个最好的男性自拍
很明显,额头截断的情况没有出现。相反,大部分自拍都会用稍广的角度将整个脑袋都拍进去,还要露出肩膀。还有,大多数的男性头发稍长,发型浮夸,还精心把头发往上梳。不过,脸部过饱和这个特点还是能够看得出来。
看过了好自拍,让我们再来看看坏自拍是啥样的。这次,我把图片缩的很小让大家看不出来是谁,因为我的目的是让大家发现降低自拍质量的普遍模式是什么,而不是让大家看看拍了差自拍的都有谁。下图是卷积神经网络认为比较差的自拍,很显然,它们的点赞数一定很低:
由卷积神经网络判断出的最糟糕的300万自拍
即便在这么低的分辨率下,我们还是能看出一些道道的。自拍时千万不要:
1.在弱光环境下自拍。非常明显, 那些很暗的照片 (通常也带有大量噪点) 肯定会被卷积神经网络打一个很低的分数。
2.把你的脑袋放太大。 这一条大概是因为没人愿意凑这么近看你的脸。
3.拍合照。和小伙伴们一起自拍是很有趣,不过这会让你的自拍减分。构图要简洁,你一个人出镜就够了,但也别占据镜头太多。
4.最后,区分一张自拍的好与差,很大程度上是看图片的风格,而不是看本人长得好不好。还有一点让我感到欣慰的是,那些露肉很多的自拍并不能让它们的得分变高。最开始的时候,我还担心这个屌炸天的卷积神经网络会变成一个露肉分辨器。看来是我想多了。
那么作为明星们的自拍又是如何呢?作为最后一个有意思的实验, 我试着让这个卷积神经网络给一些明星的自拍打个分。下图中,得分从上到下,从左至右依次减少:
卷积神经网络为名人自拍做出的判断。最有吸引力的自拍:左上方
神奇的是,我们之前总结出来的一条经验规律(不要拍合照)在这次实验中不再有效了,像是艾伦·狄珍妮的知名合照,还有一些奥斯卡颁奖时候的合照得分都很高,排在了第二排。棒!
另一条经验规律(男的自拍都不行)被克里斯·帕拉特的裸上身自拍(也排在第二排)妥妥地打破了,还有一些男明星的自拍得分也很高,像是丁日的挑眉照,扣扣熊和肥伦的合照(排在第三排)。然而詹姆斯·弗兰科那近乎限制级的自拍(排在第四排)却并没有让我们的卷积神经网络留下很好的印象。
最后强调一点,图片的风格很重要。有几个长得绝对好看的人依旧排在了榜单的末尾,就是因为构图不行,或者是光线不行等等。
探索自拍空间
我们还尝试了另一种有趣的可视化方法t-SNE,来展示这些自拍图。t-SNE是一种非常美妙的算法,由于它非常通用而且高效,我喜欢在几乎所有数据上先试试用这个来一次。它需要输入一些东西(这个例子里就是图片),然后将他们按照相似相邻的原则排列。
事实上,用t-SNE可以排列很多东西,像是Netflix的电影,单词,Twitter的个人资料,ImageNet的图片,任何东西只要量足够而且可比较就行。在这里,我们将自拍图按照卷积神经网络认为的相似程度来排列。用专业术语来说,我们采用了最后一个全连接层中的fc7激活的L2范数来确定每张图的得分进而比较其相似程度。下面是可视化结果:
自拍 t-SNE可视化
从而大家可以看出自拍图以一种有趣的方式聚成了组:比如说,左上方是自拍合照,中左方是戴太阳镜/眼镜的自拍,左下是大头照,右上有不少是对着镜子来的全身照。我觉得这种现象还挺有趣的。
如何对自拍图做最优剪裁?
我们还做了另一个有趣的实验,用卷积神经网络自动找出一张自拍图的最优裁剪。我们先拍一张照片,随机对其进行许多种可能的裁剪,然后把卷积神经网络认为最好的一张选出来。下面是4组实验结果,左侧是原图,右侧是最好的裁剪图:
四个对中的每一对显示原始图像(左)和ConvNet选择为最佳(右)的图像
注意到没有,卷积神经网络还是喜欢那种头占据图片1/3大小,额头被切掉一部分的自拍。有趣的是,在右下这组实验中,卷积神经网络觉得没有人的图反而好,完全不对劲了有没有。下面还有一些类似的例子,卷积神经网络做出了不讲道理的选择:
原图在左,裁剪图在右
在一些行家提问之前,我先回答了:是的,我试过在原始图像之后,卷积神经网络之前插入一层空域变换层。我希望能得到了一个用6个参数表达任意裁剪的模型。不幸的是,这种方法不可行——优化有时候会卡住,或者任意偏向一个位置。我还尝试过对变换加一些约束,只做放缩和平移,可惜还是没用。幸运的是,如果这变换有三个有界的参数,那我们还是可以承受得起全局搜索最优解的。
你的自拍能打几分?
是不是想看看你的自拍能得几分?我们已经将这个网络做成了一个Twitter机器人,方便大家来自测。(这个机器人大概只有150行的Python代码,还包括了所有用到的Caffe/Tweepy代码)。将你的图片(或者链接)放在推文中,在推文的任意位置加上@deepselfie。
机器人会看下你的照片给出一个打分!为了得到最佳结果,自拍图最好是正方形的,否则机器人会先将它压成正方形,这会让最终的得分变低。机器人会在一分钟内回复你,如果没出问题的话(出问题的时候,等一会儿再试一次)。
延伸阅读:
科大讯飞创始人刘庆峰:17年AI从业经验,从这10000字长文中一窥
谷歌翻译里程碑:基于单一模型的 Zero-Shot 系统正式上线
雷峰网原创文章,未经授权禁止转载。详情见。
原创文章,作者:3628473679,如若转载,请注明出处:https://blog.ytso.com/industrynews/216878.html