Visualizing and Understanding

Visualizing and Understanding

概述

这是cs231N的一个章节,主要讲述的是CNN可视化理解。2014年ECCV上的paper:《Visualizing and Understanding Convolutional Networks》讲述了CNN每一层到底学习到了什么特征,即可视化CNN模型。这里的可视化指的是可视化CNN模型中的卷积核。

利用反卷积实现特征可视化

论文里通过反卷积的方法进行可视化,反卷积就是以各层得到的特征图作为输入,进行反池化、反激活、反卷积的过程。例如一个Alexnet的conv5的特征图,通过这个过程之后,就可以把一个13*13的特征图放大回到一个与原输入图片大小的图片(227*227)。

img

反池化

池化本身是一个不可逆的过程,但我们可以在池化过程中,将最大激活值的坐标位置记录下来。然后在反池化的时候,只把该位置的值激活,然后其它值置为0。这是一种近似的过程。

反激活

在Alexnet中,relu函数是为了保证每层输出的激活值都是正数,因此对于反向过程,我们需要保证每层的特征图为正值。因此也是直接采用relu函数即可。

反卷积

对于反卷积,则是采用转置后的filter(参数一样,只不过把参数矩阵水平和垂直方向翻转了一下)进行卷积。

可视化结果

通过cnn学习之后,layer1和layer2学习到的特征基本是颜色、边缘等低层特征,越往上,学习到的特征将会变得更加完整,有辨别性。

Saliency Maps

Saliency Maps关注的是当我们使用CNN去抓取图片特征或者理解图片的时候,我们神经网络真正关注的区域。而所有的Saliency Map都将一张图片中最核心表意区域勾画出来了。

而计算原理,则是利用类别得分,即最后一层的梯度去计算哪一个像素对于分类的贡献最大,得到Saliency Maps。这里也可以看出像素层次的不同影响。

同样,得到的图也可以用于图像分割。

img

Fooling images

fooling images的思想主要是在一个已经训练好的分类器的基础上,通过选择某一错误分类计算loss,然后更新梯度来更新图片pixel,从而使得分类器对图片错误分类。

  • Start from an arbitrary image
  • Pick an arbitrary class
  • Modify the image to maximize the class
  • Repeat until network is fooled

Class visualization

从随机噪音图像开始并且在目标类上执行梯度上升,我们可以生成这样一个图像,它被网络认为是目标类别。

具体来说,假设\[I\]是一个图像,让\[y\]成为目标类别。假设\(s_y(I)\)是卷积网络初始分配给\(I\)的关于\(y\)的初始分数。最后我们生成一个图片\(I^*\),其将在类别\(y\)上获得高的得分。 \[ I^* = \arg\max_I s_y(I) - R(I) \] R是一个regularizer,一般我们可以用L2正则器: \[ R(I) = \lambda \|I\|_2^2 \]

pytorch知识点

a leaf Variable that requires grad has been used in an in-place operation

这是因为

A “leaf variable” is a variable you create directly, not as the result of some other operation.

For example,

1
2
x = torch.autograd.Variable(torch.Tensor([1, 2, 3, 4]))  # leaf variable
y = x + 1 # not a leaf variable

An in-place operation is something which modifies the data of a variable. For example,

1
2
x += 1  # in-place
y = x + 1 # not in place

PyTorch doesn’t allow in-place operations on variables you create directly (such as parameters of your model) because that usually isn’t correct. You can work around it by either using an operations that’s not in-place or by cloning the variable.

1
2
x2 = x.clone()  # clone the variable
x2 += 1 # in-place operation