窥探黑盒-卷积神经网络的可视化
??????? 這是筆者第N+1次聽到專家說,深度學習模型是“黑盒”。這個說法不能說他對,也不能說他錯。但是這句話從專家那里說出來,感覺就有點不嚴謹了,想必專家應該長時間不在科研一線了...? 對于某些類型的深度學習模型來說,確實通過可視化中間節點很難獲取到直接判別的有效信息,但對于卷積神經網絡來說,可不是這樣子的。 因為卷積神經網絡學習到的表示 learned representation 非常適合可視化。這很大程度上得益于卷積神經網絡是基于視覺概念的表示。
1. 目前卷積深度表示的可視化/解釋方法
- 中間激活態/特征圖可視化。也就是對卷積神經網絡的中間輸出特征圖進行可視化,這有助于理解卷積神經網絡連續的層如何對輸入的數據進行展開變化,也有注意了解卷及神經網絡每個過濾器的含義。 更深入的, 筆者曾經講中間激活態結合‘注意力機制’進行聯合學習,確實顯著提高了算法的精度。
- 空間濾波器組可視化。卷積神經網絡學習的實質可以簡單理解為學習一系列空間濾波器組的參數??梢暬癁V波器組有助于理解視覺模式/視覺概念。 更深入的,筆者曾經思考過,如何才能引導dropout趨向各項同性空間濾波器。因為從視覺感知對信息的捕捉效果來看,更傾向于捕捉高頻成分,諸如邊緣特征、紋理等。
- 原始圖像中各組分貢獻熱力圖。我們都知道,卷積神經網絡是基于感受野以及感受野再次組合進行特征提取的。但是我們需要了解圖像中各個部分對于目標識別的貢獻如何?這里將會介紹一種hotmap的形式,判斷圖像中各個成分對識別結果的貢獻度概率。
2. 中間特征圖可視化
??????? 可視化卷積神經網絡的中間層輸出,可以讓我們看到輸入圖像經過learned filters之后的輸出結果(更習慣稱之為中間激活態/特征圖)。卷積神經網絡每層都包含了N個learned filters,所以每個中間層的輸出將會是N張特征圖(每一個濾波器filters都會對輸入圖像進行濾波,N也成為中間特征圖的深度/通道)。一般來說,每個通道特征圖都對應著獨立的特征,這些特征恰恰就是對應的learned filter 賦予的。通過對所有通道特征圖進行可視化,我們可以很容易判斷每個濾波器的性能。
我們使用 ‘特征層次分析、視覺特征語義探索’ 中訓練好的卷積神經網絡進行測試[用于特征圖/卷積核/響應圖可視化的網絡 ],其神經網絡結構為:
核心代碼:
model = load_model('cats_and_dogs_small_2.h5') # 加載已經訓練好的模型 img_path = 'cats_dags_small/test/cats/cat.1535.jpg' # 提取實驗圖像 img = image.load_img(img_path, target_size = (150,150)) img_tensor = image.img_to_array(img) img_tensor = np.expand_dims(img_tensor, axis = 0) # 圖像維度拓展,輸入網絡 (1,150,150,3) img_tensor /= 255.#----------------------------------- layer_outputs = [ layer.output for layer in model.layers[0:8] ] # 獲取模型節點輸出 # 構造節點測試模型,對實驗數據進行測試 activation_model = models.Model(inputs = model.input, outputs = layer_outputs) # 8個激活模型 activations = activation_model.predict(img_tensor) # 8個激活層輸出,即8個層輸出的特征圖layer_names = [] # 讀取各個輸出節點對應的層名稱 for layer in model.layers[0:8]:layer_names.append(layer.name) images_per_row = 16 # 每行現實的特征圖數量 for layer_name, layer_activation in zip(layer_names, activations): # 每層名稱+特征圖輸出n_features = layer_activation.shape[-1]size = layer_activation.shape[1] # feature_map = [1, size, size, n_features]n_cols = n_features // images_per_rowdisplay_grid = np.zeros((size * n_cols, images_per_row * size))for col in range (n_cols):for row in range(images_per_row):channel_image = layer_activation[:,:,col*images_per_row + row]channel_image = np.clip(channel_image, 0, 255).astype('uint8')display_grid[col * size : (col + 1) * size,row * size : (row + 1) * size] = channel_image # Display the gridscale = 1. / sizeplt.figure(figsize=(scale * display_grid.shape[1],scale * display_grid.shape[0]))plt.title(layer_name)plt.imshow(display_grid, aspect='auto', cmap='viridis')以第1-4卷積層為例,網絡中間輸出的激活態為:
總結:
- 通過檢查卷積濾波器的中間輸出,我們發現:靠近底層的CNN提取的是基礎視覺特征,這些視覺特征是很容易被理解的,也是非常通用的。 靠近頂層的CNN提取的是綜合高級語義信息,這些信息是對底層視覺特征的綜合,更加有利于對識別、分類任務等決策任務形成貢獻。
- 隨著層數的加深,中間特征層變得越來越抽象,難以用視覺信息直觀進行解釋,但是明顯可以感受到,確實在表征高層次的視覺概念。例如,響應圖大的地方往往對應貓的耳朵、胡須、眼睛等生理結構。
- 頂層的輸出告訴我們一個道理,其實CNN學習到的特征圖并不都是有用的。隨著CNN越深,有效的特征逐漸變得稀疏化。很多特征圖[其對應的就是卷積濾波器]是沒有效果的。這個時候就需要我們引入‘attention’的機制去弱化貢獻度小的特征圖,強化貢獻度大的特征圖。這也是我碩士期間一直努力的方向。
- 在keras中,Model模型和Sequential模型一樣,可以將特定輸入映射為特定輸出。不同的是,Model模型允許有多個輸出。
- 結合人體視覺系統更好解釋。我們憑借記憶記住的貓狗等圖像,僅僅是一個概念圖/抽象圖。很難畫出像攝像機圖像一樣真實,這是因為我們大腦早就學會了將輸入信息完全抽象化,進而轉為更高層次的視覺概念,慮除掉不相關的視覺細節。
3. 空間濾波器組可視化
????? 直接可視化3x3 5x5的濾波器模板并沒有收益。學習過信號系統處理的同學應該知道,沖激信號最頻繁用于測試系統,其響應直接表征了系統的特征。這里我也是通過可視化濾波器的響應,進而推斷卷積核的作用。整個過程可以通過在輸入空間中進行梯度上升實現:從空白輸入圖像開始,將梯度下降應用于卷積神經網絡輸入圖像的值,目的就是為了讓某個濾波器的響應最大化。這樣得到的響應圖像直接反映了濾波器視覺表征特征(變邊緣提取描述子? 紋理提取描述子? or 色度信息提取描述子?)
- 補充知識【信號系統中,如何獲取未知系統的性能】:
白噪聲(自相關)->沖激信號->與系統進行卷積->得到響應(該響應可以表征系統的所有特性)
核心代碼:
def generate_pattern(layer_name, filter_index, size = 150):# 為濾波器的可視化定義損失張量layer_output = model.get_layer(layer_name).outputloss = K.mean( layer_output[:,:,:,filter_index] )# 獲取損失相對于輸入的梯度grads = K.gradients(loss, model.input)[0]grads /= (K.sqrt( K.mean( K.square(grads) ) ) + 1e-5 )iterate = K.function([model.input], [loss, grads])# 通過梯度下降讓損失最大化input_img_data = np.random.random((1,size,size,3))*20 + 128step = 1for i in range(100):loss_value, grads_value = iterate([input_img_data])input_img_data += grads_value * stepimg = input_img_data[0]return deprocess_image(img)這里對VGG16中 1-4 CNN層濾波器進行響應可視化,實驗結果如下:
總結:
- 深度學習過程類似于傅里葉變換講信號分解為一組余弦函數的過程。隨著層數的加深,濾波器變得越來越復雜,提取的特征也越來越精細。
- 底層提取的確實是通用特征,更多的是邊緣、紋理特征。
4. 組分貢獻度可視化
????? 由卷積神經網絡構成的深度框架,如VGG16、VGG19、Xception、ResNet101等,在目標識別任務中取得了非常好的結果。特別的,我們知道卷積操作是存在感受野的,那么很自然的,我們想知道每個感受野對最終識別/分類/定位等決策結果的貢獻程度。本節主要可視化這個過程,該過程也稱之為類激活圖[1](CAM,Class Activation Map)。
????? 該方法[1]綜述為: 給定一張圖像,對于一個卷積層的輸出特征圖,用類別相對于通道的梯度對這個特征圖中的每個通告進行加權。其實質就是,用‘每個通道對類別的重要程度’對‘輸入圖像對不同通道的激活強度’的空間圖進行加權,從而得到‘輸入圖像對類別的激活強度’的空間圖。
????? 舉例來說,對于輸入到貓狗分類卷積神經網絡的一張圖像,CAM可視化可以生成類別‘貓’的熱力圖,該圖熱力圖顏色深淺表示感受野對決策為'貓'的貢獻;當然CAM也會生成類別為‘狗’的熱力圖。畢竟卷積神經網絡通過概率進行決策。
?????
vvvv
結論:
通過實驗我們可以發現,之所以算法可以定位到目標,或者是識別出這是一只貴族犬,原因在于狗頭部貢獻了大量的信息。
5. 總結+參考文獻
總結:
- 通過前面一系列可視化,我們可以發現深度學習之所以強,很大程度上是因為空間濾波器組的數量大、特征層次符合視覺系統。這能夠解釋卷積神經網絡的效果往往比遞歸神經網絡在解決視覺問題效果更好。
- 我們也能發現,其實相當大一部分卷積濾波器的效果是沒有那么明顯的。如何能夠弱化低響應濾波器,強化高響應濾波器應該引起足夠重視。目前,從我的工作中發現,Attention機制是一個非常好的解決方案。
- 定制化的網絡裁剪也是一個很有潛力的方向,這實際上是對Attention機制的補充,此外,定制化裁剪可以提高網絡的響應速度,這對于實際應用是非常有意義的。
[1] Selvaraju R R, Cogswell M, Das A, et al. Grad-CAM: Visual Explanations from Deep Networks via Gradient-Based Localization[J]. international conference on computer vision, 2017: 618-626.
[2] python-with-deep-learning,2018.
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的窥探黑盒-卷积神经网络的可视化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 特征层次分析、视觉特征语义探索(微调+预
- 下一篇: 聚焦和增强卷积神经网络