深度学习一直被认为是一个黑盒子,可是试图对模型的理解仍然是很是必要的。先从一个例子来讲明解释神经网络的重要性:古代一个小镇上的一匹马可以作数学题,好比给它一个题目 2+3
,它踏马蹄 5 下后就会停下,这匹马被当地称做神马汉斯。后来人们发现,汉斯其实并不会作数学题,它经过观察主人的反应来判断何时停下。所以当一个训练好的网络模型根据输入来输出他的答案时,有时候虽然也能获得正确的结果,可是咱们更多时候还须要知道网络输出这个结果的缘由,这样可以帮助咱们来判断模型获得的这个结果是否可靠。进一步地,咱们能够凭借解释的结果来进一步优化咱们的模型,而不只仅是从结果层面来进行约束。git
在以前的一篇研究中,网络可以准确地将一幅大熊猫地图片识别为大熊猫,可是当这张图片混有必定的噪声时,网络识别的结果是长臂猿。因而可知,网络有时候只能根据数据集和损失函数来优化它的拟合过程,可是网络具体作出决定依靠的是图像的哪些特征则很难进行判断。就像考试的目的是为了让学生更好地掌握书本知识,而后取得高分,每每咱们会经过题海战术来更方便快捷地总结出题规律,能达到更好的效果,这显然与素质教育的本质背道而驰。github
笔者曾在2021年CVPR上发表过一篇关于图像去噪的文章,里面提到了“提升神经网络的可解释性”,最近在面试中常常被问到相关的问题,可是我回答的老是不能令面试官满意,直到真正了解到针对神经网络可解释性的文章,我才明白其中的区别:面试
Local Explanation主要解释作出决定的缘由,好比一张图片模型输出是猫,那么local explanation的目的就是解释为何它以为这张图片是猫?很容易想到关于Attention机制的一些研究,经过 Attention 机制可以给特征赋予不一样的空间和通道权重,从而使网络更加剧视重要信息。一般在解释Attention的效果时,会采用 Salience Map 来表示。以下图所示:算法
想象一下:若是我对图片的某个区域作干扰,那么若是干扰后影响了网络的判断结果,证实该干扰区域在网络作出判断时是重要的,反之则不重要。数学描述为:对于输入 \(X = [x_{1},x_{2},...x_{n}]\),其中 \(x_{i}\) 表明了每一个输入,对于图片而言就是每一个像素点。若是判断 \(x_{i}\) 对输出 \(y\) 的影响,那么能够给 \(x_{i}\) 增长一个扰动 \(\Delta x_{i}\),相应地输出结果的变化量为 \(\Delta y\),因而 \(x_{i}\) 的重要程度就能够描述为:网络
计算 Salience Map 的PyTorch代码以下:函数
def compute_saliency_maps(X, y, model): """ X表示图片, y表示分类结果, model表示使用的与训练好的分类模型 输出为salience map: A Tensor of shape (N, H, W) """ # 确保model是test模式 model.eval() # 确保X是须要gradient X.requires_grad_() saliency = None logits = model.forward(X) logits.backward(torch.FloatTensor([1.])) # 计算梯度 saliency = abs(X.grad.data) # 返回X的梯度绝对值大小 saliency, _ = torch.max(saliency, dim=1) return saliency.squeeze()
输出结果以下:学习
除了 Salience Map 外,类激活的热力图也能够显示原始图片的不一样区域对某个CNN输出结果的 “贡献” 程度,以下图所示:优化
其实对于神经网络而言,它所看到的只是一堆数据而已,经过损失函数可使模型将这一堆数据映射为咱们想要的值,其实人是没法真正理解机器想的是什么的,这些只是想找一些合理的方法来将机器想的内容合理化为人们所指望的那个样子而已。因此对一些新入门的朋友而言,没必要过度纠结于神经网络究竟是怎么实现特定的功能的,就像一位大佬说过:The question of whether machines could think was “about as relevant as the question of whether Submarines Can Swim. 我的理解就是:思考和游泳都是人类具备的属性,目的可以帮助咱们解决事情或者可以在水里生存,可是反过来不必定成立,解决事情或者在水里生存不必定非要是咱们人类具备的属性,机器也能拥有这些,可是他们在以什么样的方式进行工做,咱们不得而知,讨论这个问题也就没什么意义,咱们只须要关心结果是不是咱们所须要的就好了。ui