Saliency Maps
這部分想探究一下 CNN 內部的原理,參考論文 Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps.
一般我們反向傳播 CNN 的時候,是可以得到圖片的梯度(Image
Gradient)的,但是因為網絡要學習的參數是權重 W,因此都不會用到這個梯度。這篇論文可視化了一下圖片的梯度,稱作是 saliency map,發現其實是網絡對不同處像素值關注的權重。得到的結果甚至可以輔助做 segmentation 問題。
通俗來說就是,給定一張圖片X,我們想要知道到底是圖片中的哪些部分決定了該圖片的最終分類結果,我們可以通過反向傳播求出X關於loss function的偏導矩陣,這個偏導矩陣就是該圖片的
圖像梯度,然后計算出
類顯著度圖(class saliency map, csm)。
Karen Simonyan論文的3.1節給出了計算方法:如果圖片是灰度圖,那么csm就取圖像梯度的絕對值;如果是RGB圖,csm就取圖像梯度3個通道中絕對值最大的那個通道。csm中元素值的大小表示對應位置的圖片像素對最終分類結果的影響程度。
from cs231n.layers import softmax_loss
def compute_saliency_maps(X, y, model):
"""
Compute a class saliency map using the model for images X and labels y.
Input:
- X: Input images, of shape (N, 3, H, W)
- y: Labels for X, of shape (N,)
- model: A PretrainedCNN that will be used to compute the saliency map.
Returns:
- saliency: An array of shape (N, H, W) giving the saliency maps for the input
images.
"""
saliency = None
##############################################################################
# TODO: Implement this function. You should use the forward and backward #
# methods of the PretrainedCNN class, and compute gradients with respect to #
# the unnormalized class score of the ground-truth classes in y. #
##############################################################################
scores, cache = model.forward(X)
loss, dscores = softmax_loss(scores, y)
dX, grads = model.backward(dscores, cache)
saliency = dX.max(axis=1)
return saliency
Fooling Images
給定一個類別標簽,CNN 希望對應能輸入什么樣的圖片呢?可以考慮把圖片當做變量,固定模型中的權重,來優化下面的目標函數,

其中
是給定類標簽 y 時模型的評分。
def make_fooling_image(X, target_y, model):
"""
Generate a fooling image that is close to X, but that the model classifies
as target_y.
Inputs:
- X: Input image, of shape (1, 3, 64, 64)
- target_y: An integer in the range [0, 100)
- model: A PretrainedCNN
Returns:
- X_fooling: An image that is close to X, but that is classifed as target_y
by the model.
"""
X_fooling = X.copy()
##############################################################################
# TODO: Generate a fooling image X_fooling that the model will classify as #
# the class target_y. Use gradient ascent on the target class score, using #
# the model.forward method to compute scores and the model.backward method #
# to compute image gradients. #
# #
# HINT: For most examples, you should be able to generate a fooling image #
# in fewer than 100 iterations of gradient ascent. #
##############################################################################
while True:
print i
scores, cache = model.forward(X_fooling, mode='test')
if scores[0].argmax() == target_y:
break
loss, dscores = softmax_loss(scores, target_y) # 使用目標分類計算分類層梯度
dX, grads = model.backward(dscores, cache) # 逆向傳播推導圖片梯度
X_fooling -= dX * 1000 # 修改圖片,為了fooling的目的學習率設定的超大
return X_fooling
