当前位置: 首页 > 编程日记 > 正文

到底是什么特征影响着CNN的性能?

640?wx_fmt=jpeg


作者 | 刘畅 

编辑 | Jane
出品 | AI科技大本营(ID:rgznai100)


开门见山。最近阅读了一篇论文,加上看了一些之前的工作。记录一下,CNN 到底学到了什么东西,或者换句话讲。到底是什么样的特征在影响着CNN 的性能?


先放论文:

IMAGENET-TRAINED CNNS ARE BIASED TOWARDS TEXTURE; INCREASING SHAPE BIAS IMPROVES ACCURACY AND ROBUSTNESS

论文地址:

https://openreview.net/pdf?id=Bygh9j09KX


JeremyRifkin 在书《The end of Work》中写道,“时至今日,当科学家们探讨人工智能时,他们通常是在讲一门能执行人们所希望机器表现的智能艺术”。这是我比较喜欢的关于人工智能的定义。因为它避免了大谈特谈如今的人工智能技术离真正的智能化有多远。而是享受当下。不过,作为一名研究人员,我觉得揭开大脑的运作原理和创造真正的智能机器是非常重要的。目前深度学习主要做的研究是关于从数据中学到规则并将其自动化的一个过程。这已经带来了非常多的好处,举一个简单的例子。在医学领域引入深度学习技术,可以将许多诊断过程全自动化,因此可以让贫穷地区或国家的人们享受到顶级的治疗。


开篇完毕,现在进入正题。尽管深度学习技术的到来给人们的生活带来了更多的便利。但是神经网络看待和解释世界的方式仍然是一个黑盒子。因此我们需要尝试更好的理解它,以便我们对深度学习网络做出进一步的改进,以及尝试去解释某些深度学习行为。有两种主要的方法可以尝试理解神经网络。一种是在数据集中查找导致特征图有高激活响应值的图片,另一种是在随机的一张图片中,通过优化像素值来生成模式。接下来,通过一些例子来展示一下,CNN 到底学到了什么?


特征可视化

640?wx_fmt=png


这本书《Deep Learning with Python》里面讲了如何生成模式。包括滤波器是如何响应模式(纹理)等。接下来我们先观察一下这些模式。以 VGG16 为例。


第7层卷积(64,128)

640?wx_fmt=png

滤波器12,16,86,110(从左到右,从上到下)


第14层卷积(128,256)

640?wx_fmt=png

滤波器1, 6,31,32,54, 77(从左到右,从上到下)


第20层卷积(256,256)

640?wx_fmt=png

滤波器3,34,39,55,62,105(从左到右,从上到下)


第30层卷积(512,512)

640?wx_fmt=png

滤波器54,62,67,92,123,141(从左到右,从上到下)


第40层卷积(512,512)——网络顶部

640?wx_fmt=png

256,261,265,277,286,462(从左到右,从上到下)


这些得到的中间结果看着非常漂亮。方法就是在网络中最大化某个激活值就可以得到这些结果。看一下第 40 层的几张图。已经有了明显的形状。比如羽毛、铁链等。接下来我们分析一下这些结果。


模式识别


我们先从下面这张图片开始吧。这张图片看着像是拱门。于是去数据集里面找来了一张拱门的图片,也就是右图。


640?wx_fmt=png


接下来我们来检验一下,是不是由这张图来确定的图片的分类。首先记住,这张图是最后一层的第 286 个滤波器。如何检验呢?我们只需要将这张图片输入进网络,并绘制第 40 层的平均激活响应,如下图。


640?wx_fmt=png


可以看到在特征图第 286 的地方,出现了强烈的飙升。显然它就是检测拱形结构的滤波器。但是注意,这样的形状结构可能对应着几个不同的类别。


那我们再看一个例子吧。左边这个看着像是鸡头(最后一层,第 256 个)。因此找了右边这一张图片来测试。同样的测试方法。


640?wx_fmt=png

640?wx_fmt=png


我们来看一看特征响应图。


640?wx_fmt=png


好像似乎也印证了我的想法,可能是某种形状导致了最后的输出类别。也就是说,影响 CNN 效果的其实是形状特征(猜想)。


不过让我们再关注一个例子,用同样的方法。输入一张鸟类的图。


640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

滤波器172,288,437,495(从左到右,从上到下)


我们发现了多个高响应的特征图。上面的特征图有像是鸟腿、眼睛和喙的东西?但是下面的特征图,看不出来是什么,可能与图像的背景有关,或者一些只有网络能理解的东西。这部分现在仍然是黑匣子。也许之前的猜想是错的。


接下来放一下代码(PyTorch):


1generate_image.py
2class FilterVisualizer():
3    def __init__(self, size=56, upscaling_steps=12, upscaling_factor=1.2):
4        self.size, self.upscaling_steps, self.upscaling_factor = size, upscaling_steps, upscaling_factor
5        self.model = vgg16(pre=True).cuda().eval()
6        set_trainable(self.model, False)
7
8    def visualize(self, layer, filter, lr=0.1, opt_steps=20, blur=None):
9        sz = self.size
10        img = np.uint8(np.random.uniform(150180, (sz, sz, 3)))/255  # generate random image
11        activations = SaveFeatures(list(self.model.children())[layer])  # register hook
12
13        for _ in range(self.upscaling_steps):  # scale the image up upscaling_steps times
14            train_tfms, val_tfms = tfms_from_model(vgg16, sz)
15            img_var = V(val_tfms(img)[None], requires_grad=True)  # convert image to Variable that requires grad
16            optimizer = torch.optim.Adam([img_var], lr=lr, weight_decay=1e-6)
17            for n in range(opt_steps):  # optimize pixel values for opt_steps times
18                optimizer.zero_grad()
19                self.model(img_var)
20                loss = -activations.features[0, filter].mean()
21                loss.backward()
22                optimizer.step()
23            img = val_tfms.denorm(img_var.data.cpu().numpy()[0].transpose(1,2,0))
24            self.output = img
25            sz = int(self.upscaling_factor * sz)  # calculate new image size
26            img = cv2.resize(img, (sz, sz), interpolation = cv2.INTER_CUBIC)  # scale image up
27            if blur is not None: img = cv2.blur(img,(blur,blur))  # blur image to reduce high frequency patterns
28        self.save(layer, filter)
29        activations.close()
30
31    def save(self, layer, filter):
32        plt.imsave("layer_"+str(layer)+"_filter_"+str(filter)+".jpg", np.clip(self.output, 01))
33
34
35pytorch_hook.py
36
37class  SaveFeatures():
38    def  __init__selfmodule):
39        self .hook = module.register_forward_hookself .hook_fn
40    def  hook_fnselfmoduleinputoutput):
41        self .features = torch.tensoroutputrequires_grad = True).cuda()
42    def  closeself):
43        self .hook.remove()
44
45
46filter_visualizer.py
47
48layer = 40
49filter = 265
50FV = FilterVisualizer(size=56, upscaling_steps=12, upscaling_factor=1.2)
51FV.visualize(layer, filter, blur=5)
52


你以为到这里就完了吗?还没到这篇文章的重点内容,新鲜出炉的 2019 ICLR 的论文:《Imagenet-trained CNNs are biased towards texture; Increasing shape bias improves accuracy and robustness》


看标题,就知道。我们之前的猜想是错误的!CNN 学到的应该是纹理特征。真让人头疼!


作者以一个问题入手,一只披着象皮的猫,神经网络会把它识别为大象还是猫?最后根据实验结果得出结论。神经网络应该是根据物体的纹理特征来进行识别,而并非我们以为的形状特征。也就是说我们常了解的一些可视化技术如 Deconv 都是具有误导性的,它们的结果仅仅只是图像的重建部分,而与网络如何做出最后的决策关系不大。


其实接触过图像风格迁移技术的技术人员应该都非常清楚,深度学习模型在里面提取的图像的绘画风格就是纹理特征。贴上一张经典图片,生成的是一张具有梵高《星月夜》图画风格的建筑图片。


640?wx_fmt=jpeg


在论文里面,作者为了更清楚的了解,图像识别到底是基于形状还是基于纹理。做了以下的实验。使用三张生成的图片,分别是带有大象纹理的猫 , 带有钟表纹理的汽车 和 带有水瓶纹理的熊


640?wx_fmt=jpeg


作者通过实验,采用了多个神经网络(AlexNet、VGG-16、GoogLeNet、ResNet-50、ResNet-152、DenseNet-121、SqueezeNet1_1)进行输出结果。为了对照,还召集了大约 100 名人类来做对照实验。这个实验结果就是一只带有象皮纹理的猫被深度神经网络判断为大象,但对人类来说仍然是猫。带有时钟纹理的汽车被深度神经网络判断为时钟,带有水瓶纹理的熊被深度神经网络判断为水瓶。显然!该实验支持了这一说法,即目前用于物体识别的深度学习技术主要依赖纹理,而不是物体形状。


640?wx_fmt=png


当然,作者还做了更多的对比实验。得出了一些具有启发性的结论。比如对于只包含纹理图片的数据集,神经网络能取得特别高的准确率。采用原图和灰度图,神经网络都可以取得非常高的准确率,而对于只包含轮廓和只包含边缘的图片,神经网络的预测准确率则显著降低。


更多的实验细节,可以查看论文。总结一下,有几点结论还是很有启发性的:


第一、回答了影响CNN识别性能的是形状还是纹理的问题。

第二、如何针对性的引导神经网络训练或者学习想要它学习的特征。(有意的抑制某个特征)


原文链接:

https://blog.csdn.net/u012395979/article/details/86651808


(本文为 AI科技大本营投稿文章,转载请微信联系 1092722531 


———————————————  征稿  ————————————————

640?wx_fmt=png


推荐阅读:

  • 2019最新实战!给程序员的7节深度学习必修课,最好还会Python

  • 知否?知否?一文看懂深度文本分类之DPCNN原理与代码

  • PDF翻译神器,再也不担心读不懂英文Paper了

  • Facebook增强版LASER开源:零样本迁移学习,支持93种语言

  • Caicloud 开源 Nirvana:让 API 从对框架的依赖中涅槃重生

  • 程序员有话说 | 那个拒绝加班的程序员后来怎么样了

  • 告别摩拜

  • 6大改进:盘点以太坊的2018冒险之旅

  • 不难!月薪 50K大牛,悉心整理程序员必备技能!

640?wx_fmt=png

相关文章:

Java数据结构与算法(八)-二叉树

一、为什么要使用树 有序数组插入、删除数据慢。链表查找数据慢树可以解决这两个问题二、相关术语 树的结点:包含一个数据元素及若干指向子树的分支;孩子结点:结点的子树的根称为该结点的孩子;双亲结点:B 结点是A 结点…

linux驱动:i2c驱动(四)流程图之注册驱动

二、i2c设备的驱动部分 1、i2c驱动i2c_driver 2、通过i2c_add_driver注册 2、注册过程中 比较i2c_device_id数组中各成员的id与i2c_client中的名字,找到设备 3、执行i2c_driver驱动中的probe

Expression Blend实例中文教程(2) - 界面快速入门

上一篇主要介绍Expression系列产品,另外概述了Blend的强大功能,本篇将用Blend 3创建一个新Silverlight项目,通过创建的过程,对Blend进行快速入门学习。 在开始使用Blend前,首先需要进行Silverlight的开发环境搭建&…

Lua基本语法-书写规范以及自带常用函数

Lua基本语法-书写规范和常用函数本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) 1String Operation —— 字符串操作2Table ——…

linux驱动:音频驱动(一)ALSA

一、【基础知识】 1、J2 《--HPR_OUTHPL_OUT 《-- U13(TLV320AIC3104IRHBR)的HPROUTHPLOUT 2、驱动源码 IPNC_RDK_V3.8.0.1/Source/ti_tools/ipnc_psp_arago/kernel/sound/soc/codecs/tlv320aic3x.c 3、依赖于I2C驱动 4、声卡驱动框架:…

秘籍 | 机器学习数据集网址大全

作者 | Will Badr译者 | Linstancy整理 | Jane出品 | AI科技大本营(ID:rgznai100)要找到一定特定的数据集可以解决各种机器学习问题,是一件很难的事情。越来越多企业或研究机构将自己的数据集公开,已经成为全球的趋势,…

为asa防火墙配置ssh登陆

由于最近事情超多,单位下发某些令人恶心的制度,今天突然说北京分公司和总公司之间要做***的连接,虽然俺是个CCNP,但是对于***来说接触的少之又少,并且工作繁忙,每天头大,北京分公司的安全ie同事…

70.nodejs操作mongodb

转自:https://www.cnblogs.com/whoamme/p/3467374.html 首先安装nodejs mongodb npm install mongodb var mongodb require(mongodb); var server new mongodb.Server(localhost, 27017, {auto_reconnect:true}); var db new mongodb.Db(mydb, server, {saf…

明晚8点公开课 | 用AI给旧时光上色!详解GAN在黑白照片上色中的应用

在改革开放40周年之际,百度联合新华社推出了一个刷屏级的H5应用——用AI技术为黑白老照片上色,浓浓的怀旧风勾起了心底快被遗忘的时光。想了解如何给老照片上色?本次公开课中,我们邀请到了百度高级研发工程师李超,他的…

linux驱动:音频驱动(二)ASoc

五、【ASoC声卡驱动框架】 1、ASoC将嵌入式设备的音频系统从软件层面划分为3个组件 1.1 codec驱动:音频编解码器驱动,与平台无关,实现音频控制项添加、音频接口实现、DAPM(动态音频电源管理)、音频编解码器的IO功能 …

把32位的SharePoint服务器场迁移到64位, 应该怎么做?

总体步骤如下: 1. 迁移已经存在了的数据库服务器到新的数据库服务器. 先迁移这一层的目的是避免可能发生的一些由64位系统对32位系统执行查询或写入操作所引起的性能问题. 2. 迁移WFE服务器到64位环境下. 准备工作: 1. 重新编译已经存在的32位的应用程序和自定义的程序集(web p…

testem方便的web tdd 测试框架使用

备注:单元测试,对于日常的开发是比较重要的,testem 简化了我们的代码编写,以及运行。主要特性:a. 支持的测试框架有:jasmine quint mocha buster.js ,同时也包含一些其他的适配器,支…

程序员老在改Bug,就不能一次改好吗?

作者丨伍杏玲来源 | 程序人生(ID:coder_life)程序员的日常三件事:写Bug、改Bug、背锅。连程序员都自我调侃道,为什么每天都在加班?因为我的眼里常含Bug。但是真的有这么多Bug要改吗?就不能一次改…

一场库文件的远程修复

一场库文件的远程修复系统环境RHEL 4.7一、原因:发现每天早上7点1分备份的数据库文件时间不对,登录上去后date下发现时间是正确。二、尝试解决:1)setup->Timezone configuration-> Asia/Shanghai保存后,发现由原…

linux驱动:音频驱动(四)ASoc之machine设备

linux驱动:音频驱动(四)ASoc之machine设备

Sql server Insert执行的秘密(下) 带外键的INSERT分析

2019独角兽企业重金招聘Python工程师标准>>> 这一篇分析一下带外键表的INSERT的例子。 本文所用的数据表结构如上图所示;其中Blog表上BlogID是自增的主键,并在CreateUserID和CreateTime列上分别建有两个非唯一索引。 我们要往Blog表中插入一…

熬夜写代码,不如换女装入GitHub获上千Star?

作者 | 琥珀出品 | AI科技大本营(ID: rgznai100)程序员如何以合规手段快速获得 GitHub 上千 Star?新年刚过,GitHub Trending 上一个名为“Dress”的开源项目迅速蹿红,并成功掀起了不少程序员及吃瓜群众的热议。项目地址…

CCNp笔记(EIGRP)

EIGRP<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />特性1属于混合路由协议具有距离矢量路由协议的特性&#xff0c;又有链路状态路由协议的特性。2属于高级距离矢量路由协议3快速收敛4保证100%无环路5增量更新6支持默认4条最多…

linux驱动:音频驱动(五)ASoc之codec驱动

linux驱动&#xff1a;音频驱动&#xff08;五&#xff09;ASoc之codec驱动

科大讯飞市值腰斩背后,AI产业集体思考如何落地?

作者丨郭敏本文经授权转载自钛媒体&#xff08;ID&#xff1a;taimeiti&#xff09;【导语】在过去的一年里&#xff0c;科大讯飞受到了多方质疑&#xff0c;质疑的声音不外乎盈利疲软、靠政府补助、技术优势逐渐变弱等&#xff0c;种种质疑背后&#xff0c;其实整个 AI 产业从…

zabbix系列之邮件告警(三)

设置邮件告警有两种方式&#xff1a;1&#xff09;、通过Linux自带的mail发送告警邮件2&#xff09;、通过第三方邮箱发送&#xff08;如QQ邮箱、163邮箱等&#xff09;告警邮件1、修改 zabbx_server.conf 文件,指定脚本路径&#xff0c;没有则添加[rootcentos1 ~]# vim /usr/l…

Python告诉你:为何年终奖多发一元,到手却少两千多?

作者 | shenzhongqiang来源 | Python数据与分析&#xff08;ID&#xff1a;ML_Python&#xff09;年终奖多发一元&#xff0c;到手却要少两千多&#xff0c;甚至更多。听到这个消息的时候&#xff0c;大家是不是觉得有点意外&#xff0c;意外之余还有点淡淡的忧伤&#xff1f;上…

[译]一个系统管理员眼中的DevOps

前言 原文发表在Patrick Debois大神的官网上&#xff0c;传送门>> 通篇围绕运维工作进行阐述&#xff0c;始终是在强调运维人员和开发人员需要通力协作&#xff0c;这大概也是DevOps理念的核心价值所在吧&#xff01;大概是因为作者来自比利时吧&#xff01;翻译的时候还…

linux驱动:音频驱动(六)ASoc之codec设备

linux驱动&#xff1a;音频驱动&#xff08;六&#xff09;ASoc之codec设备

屏蔽“网页上有错误”提示,屏蔽java script 错误的代码

<script>window.onerrorhide_error_message;functionhide_error_message(){returntrue;}</script>代码再简写一点&#xff0c;就是&#xff1a; <script type"text/java script ">window.onerrorfunction(){returntrue;}</script >原来只要让…

linux驱动:音频驱动(七)交叉编译alsa库及工具集alsa-utils

0、编译时用到的库 libunistring0_0.9.3-5_i386.deb libgettextpo0_0.18.1.1-5ubuntu3_i386.deb gettext_0.18.1.1-5ubuntu3_i386.deb 1、下载源码 alsa-lib-1.0.27.tar.bz2 alsa-utils-1.0.27.2.tar.bz2 一、交叉编译alsa lib 1、su 进入root用户 2、进入/home/MY/evm-lin…

Python一键转Java?“Google翻译”你别闹

作者 | 若名出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;近日&#xff0c;Reddit 上有网友放出了一张疑似 Google 翻译添加了能让编程语言间互相转换的图片&#xff0c;立即引发数千名程序员网友的跟帖热议。图片显示&#xff0c;Google 翻译中添加了编程语言进行…

我所感兴趣的iOS10新特性

###SiriKit Siri API 的开放自然是 iOS 10 SDK 中最激动人心也是亮眼的特性。SiriKit 为我们提供一全套从语音识别到代码处理&#xff0c;最后向用户展示结果的流程。Apple 加入了一套全新的框架 Intents.framework 来表示 Siri 获取并解析的结果。你的应用需要提供一些关键字表…

如何将三万行代码从Flow移植到TypeScript?

作者 | David Gomes译者 | 弯月责编 | 郭芮来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;【编者按】在内存安全中&#xff0c;类型安全是很重要的一个命题。为了确保JavaScript项目运行的类型安全&#xff0c;本文的作者介绍了2016年时使用Flow的经历&#xff1…