我认为这个社会发展地很快,但对于小孩以及青少年的保护也越来越弱了。因此,我觉得社会有必要也有义务去设立一些规则使小朋友尽可能少受到不良信息的伤害。我觉得小事先从我做起,我先来开发一款屏蔽黄图的浏览器扩展产品。
当大家看到这个标题时可能会问:什么是负体验的产品?
其实很简单:就是用了这款产品,在某些场景下你可能得到不良的体验。大家心里可能会有100个问号,那你开发这款产品出来干嘛?
答案也很简单,我觉得开发这款产品是一件非常有必要的事情。
今年我大部分的时间都花在研究人工智能和写书上,在快要到10月份的时候,我大学毕业时立下的“一年开发一个产品”目标还没开始实现,我觉得不能再这样拖下去了,于是开始构思今年要做什么。
我认为独立完成一个项目是一个很好的学习机会,而且我不愿意错过人工智能这个浪潮,所以我决定今年的产品是跟人工智能有关的。在10月的时候我开始去学习深度学习相关内容,在这里要推荐一本非常不错的书籍,名叫《Python深度学习》,它是Keras之父的最新之作,深入浅出地介绍了深度学习的相关知识和工程。
从10月份到现在,虽然我的知识还是只有半桶水,但我深深觉得,深度学习比前端开发和手机开发有趣多了,如果5年前已有相关知识的话,我现在应该不是一名交互设计师了……
Python深度学习
我究竟要做什么产品?
这个问题困扰了我好几天。
我希望这款产品开发成本不是很高而且是有意义的;目前Google已经开源了Tensorflow.JS,它可以让开发者在浏览器上进行深度学习的运算和开发,基于这三个原因我把目标锁定在开发一款浏览器扩展上(因为我认为从零开发一款手机AI应用不太实际,而且没有人会因为AI两个字而去使用你的产品)。
目前Tensorflow.JS已经逐渐完善,并且提供了人脸识别、肢体识别等API,但精度不是很高,而且每个用户的电脑前置摄像头拍摄效果很差,所以我想象不出这些API对我来说有什么用;在某天和别人聊到鉴黄技术的时候,我灵机一动并确定了这个产品要做什么:我要做一款AI鉴黄浏览器扩展,它能屏蔽掉网页上的黄图。
现在大家应该知道这为什么是一款负体验的产品了,因为它很可能会让某些用户在浏览网页过程中产生负面体验:黄图被屏蔽了。
为什么我要做这款产品?
回想过去,我们以前获取信息是很不方便的,没有相关途径可能都不知道怎么去找张黄图(我认为这对于一个处于青春期的青少年来说是件非常正常而且能够理解的事情),我猜这对大部分青年的成长也是有好处的。但是现在的社会太开放了,而且很容易就能找到想找的内容。
先不说各种网络暴力充斥着这个社会,更重要的是有些不法分子会利用黄色、暴力内容以及青少年的冲动和好奇心理去毒害青少年的思想。
例如:通过一个含有黄图的小广告引导用户去浏览黄色、暴力、赌博等非法网站,一些无知的青少年可能因为一时冲动而沾染上不良的嗜好,比如黄赌毒等。而父母亲也很难发现自家小孩发生的变化(毕竟现在的小朋友每个人都有一台手机,偷偷看个黄色网站父母是很难发现的),最后的结局就是覆水难收。
我认为:这个社会是发展得很快,但对于小孩以及青少年的保护也越来越弱了。
因此,我觉得社会有必要而且有义务去设立一些规则使小朋友尽可能少受到不良信息的伤害,所以我觉得小事先从我做起,我先来开发一款屏蔽黄图的浏览器扩展产品。(深度学习+鉴黄+客户端开发可以说是天作之合,既然我们不能从源头铲除相关的产业,那我们就从离小朋友最近的屏幕进行屏蔽。当AI鉴黄引擎识别到网页内容有黄色图片时,浏览器可以第一时间将此屏蔽。)
整个项目开发时间大概花了两周左右,期间最花时间的是如何提高整个扩展的性能。由于图片识别需要一定的时间,为了尽可能降低整个图像识别时间,提升用户浏览网页的体验,我在整个项目中考虑了以下方案:
为了解决图片因为跨域而无法识别这个问题,我在前期使用了Canvas重绘img元素这个方案,但重绘每张图会多带来500ms,后面优化时改用了XHR方式将图片转换为Base64格式进行识别,前期准备时间降至10ms。
由于各种正常途径都无法将识别模型放在本地,用户在清除完缓存的情况下打开浏览器都需要从服务器重新获取模型数据(Inception V3模型约为90M,MobileNet模型约为9M,最后采用了后者),这样不仅增加了服务器成本,同时用户的体验会大大降低。在经历了多次尝试后,我通过一些小聪明成功地将本地模型路径转换为URL,用户安装扩展后可以立即使用,这里使下载模型的时间成本降至为0。
由于网页是单线程的,这意味着网页加载和图片识别不能同时进行。在这里我尝试了Web Worker的方案,它能够在浏览器内多线程运行其他程序。很可惜的是,Tensorflow.JS涉及到DOM操作,导致在Web Worker内Tensorflow无法使用,整个网页浏览体验无法继续提升。
每张图片的识别需要90ms左右,一个包含了上百张图的大型网站可能要识别很久时间,为了解决这个问题,我会在未来的迭代中考虑将图片打包成Batch进行识别(由于现在还没学会……),听说这个方案能使32张图片的识别时间降至几百毫秒。
在深度学习方面我采用迁移学习的方式对MobileNet上层结构进行重写,当我把项目快做完的时候才发现鉴黄没有想象中那么简单,原来这是一个困扰计算机科学家十几年的难题Orz!
在这里我总结一下项目里遇到的坑:
我在12.17号前上Tumblr爬了数万张照片,并辛辛苦苦将数千张图分门别类。但要进行分类?是根据实体还是动作进行分类?项目前期我采用了后者方案,当时我天真的认为动作是抽象的,搞定体位动作识别就应该没问题了,最后识别出来的效果非常差,有些时候模型会把一只可爱小狗识别成黄图,为了提高整体的准确率我后续很苦逼地把图片按照实体重新进行分类,效果有所提升。
由于第一次生成的模型识别效果太差,我反思了一下有可能是照片太花哨的缘故导致机器不能识别重点,所以我又辛辛苦苦地将所有照片的重点内容给裁剪出来,最后识别效果大幅度提升。
在项目的最后期间,我找到了雅虎提供的NSFW开源模型(NSFW, Not Safe For Work),它的准确度比我的模型高很多,可惜的是在模型转换为JavaScript版本时由于API缺失导致模型转换失败。
项目前期我曾考虑过先把网页的全部图片识别完再呈现给用户,但由于性能问题会严重影响到整个的网页浏览体验,所以我最终还是放弃了该想法,策略改为优先显示图片,识别到黄图时将之模糊。
在整个项目做完后,我认为这个项目的最终结果是很不完美的。除了我个人能力有限以外,我认为更多是现有条件不足而导致的,例如Tensorflow不能在Web Worker内运行,导致不能脱离主线程,在多线程内进行识别图片。
还有就是整个模型的识别效果真的差强人意,我反思了一下为什么效果这么差,我认为有以下几个原因:
人类更多是通过经验和语义进行思考的(人类可以通过衣着打扮、裸露程度、姿势动作、场景氛围、表情等方式判断这张图是否包含色情内容),而机器只能根据经验进行识别(经验就是指你喂给机器的图片)。
关于色情和情色,这是非常不一样的。我认为人类在这里的判断多是主观判断,这对于机器来说就更难了。
图片分类可以认为是整个黄图鉴别框架的设计,稍微把握不慎可能产生巨大的影响。
举例:
全裸不一定是黄图,如果机器把全裸的婴儿照片或者世界艺术作品当做色情图片就会很尴尬了,因此在设计分类时需要找到一些正常的分类来做训练对抗。
如果每个分类都是单独的器官,会不会对整张图片的识别带来影响?这影响是很明显的,因为色情更多是氛围,一个器官无法撑起整个色情氛围,但采用器官分类这个方案能很大程度上提高某些图片的识别准确度,但对于范围更广的色情图片来说作用不是很大。
如果每个分类都是不同的动作,会不会对整张图片的识别带来影响?这个影响会更大。因为动作是抽象的,而画面里的人物特点都不一样,导致机器看不懂图里的固定特征究竟是什么,最终得出来的模型效果会非常差。
雅虎的NSFW模型会把图片分成Safe和Not Safe两个维度,如果按照雅虎的NSFW模式来设计分类的话,在没有海量图片的情况下最终的效果是一定最差的。
数据量小的情况下应该会降低分类的作用。
虽然产品的最终效果不怎么样,但我觉得这个项目还是很有意义的,起码我能学到很多新的知识,如果这个项目能延续下去帮助到别人就好了。
我真的希望这项功能可以迁移到手机端,成为儿童安全模式的必备功能,因为现在的小孩更多是使用手机去获取资讯,鉴黄技术在手机端能起到更多的作用。同时,越来越多的手机拥有AI芯片,如果能在手机底层使用图像识别技术将大大提高整个识别速度,体验会更佳。
明年我会持续迭代优化整个项目,除了增加数据优化模型外,我还会尝试加入文字内容识别和黄图链接索引,也会考虑增加暴力、毒品、赌博等内容识别,希望能更全面地保障儿童的上网体验。如果有朋友愿意加入这个开源项目,请随时联系我。
2018年就要过去了,为了打破事业上的瓶颈我付出了不少的努力,同时收获也蛮多的,希望明年自己会变得更好。最后衷心地祝福每位读者圣诞节快乐,明年又是开心顺利的一年:-)