6.2 CNN卷積核與特徵圖視覺化

眾所周知,深度學習仍是一個黑盒子,模型內部的邏輯含義仍舊無法解釋,越是未知的東西,越能激起人們的好奇心。

在卷積神經網路中,有時會對卷積核以及特徵圖進行視覺化,以此觀察卷積神經網路學習到了何種模式

作為深度卷積神經網路的開山之作,AlexNet2012年)就已經對卷積核的模式進行了分析,論文中發現卷積核的學習具有偏向性,一部分學習顏色特徵,一部分學習邊緣特徵,詳見下圖:

<<AI人工智慧 PyTorch自學>> 6.2 CNN卷積

緊接著AlexNet之後的2013年,ZFNetCNN的特徵圖進行了視覺化,進一步的探究卷積神經網路的奧秘。

<<AI人工智慧 PyTorch自學>> 6.2 CNN卷積

 

AlexNet:《ImageNet Classification with Deep Convolutional Neural Networks

ZFNet:《Visualizing and understanding convolutional networks

本節就利用tensorboard以及pytorch的函數對AlexNet的卷積核與特徵圖進行視覺化。

make_grid 函數

在圖像任務中,往往需要人眼審核、觀察大批量圖像資料,如果一張一張的觀察,效率會非常低。

通常會將一批資料繪製成網格圖片,類似大排檔的功能表一樣,這樣便於觀察。

pytorchtorchvision庫中,提供了make_grid函數説明大家完成網格圖片製作。下面先學習make_grid函數,再用它繪製卷積核與特徵圖。

`torchvision.utils.make_grid(tensor: Union[torch.Tensor, List[torch.Tensor]]nrow: int = 8padding: int = 2normalize: bool = Falsevalue_range: Optional[Tuple[intint]] = Nonescale_each: bool = Falsepad_value: float = 0.0**kwargs)

功能:

將一組圖片拼接成一張網格圖片,便於視覺化。

參數:

tensor(Tensor or list)- 需視覺化的數據,shape:(B x C x H x W) ,B表示batch數,即幾張圖片

nrow(int)- 一行顯示幾張圖,預設值為8

padding(int)- 每張圖片之間的間隔,預設值為2

normalize(bool)- 是否進行歸一化至(0,1)

value_range(tuple)- 設置歸一化的minmax,若不設置,默認從tensor中找minmax

scale_each(bool)- 每張圖片是否單獨進行歸一化,還是minmax的一個選擇。

pad_value(float)- 填充部分的圖元值,預設為0,即黑色。

關於輸入make_grid的輸入可以分為兩種:

  • 一種是4D張量,函數自動將第一維度作為圖片數量進行拆解。
  • 一種是list,元素必須是張量形式,並且張量的shape必須一致。

這兩種輸入分別對應兩種常用場景:

  • 4D張量:卷積核大小與特徵圖張量都適合用這種形式。
  • list:對普通圖片進行視覺化觀察,一次載入一張圖片時使用。

另外,對於圖元的轉換也需要注意相應策略,對於float類型的資料,需要設置歸一化的策略,策略由value_rangescale_each構成,請自行調整觀察變化。

請看代碼使用效果:

<<AI人工智慧 PyTorch自學>> 6.2 CNN卷積

Alexnet卷積核視覺化

要對卷積核進行視覺化,就需要對pytorchnn.Module類非常熟悉,要瞭解卷積核以怎樣的形式?存儲在哪裡?

2D卷積的卷積核權重是一個4D張量,包含輸入通道,輸出通道,高,寬。

注意:除了第一層可以將 輸入通道 **寬作為 RGB圖像進行視覺化之外,其餘網路層只能將高*寬作為灰度圖像(2D)進行視覺化。

卷積核存儲在nn.Conv2Dweight變數中,下面就可以通過如下代碼獲得。

    for sub_module in alexnet.modules():

        # 非卷積層則跳過

        if isinstance(sub_module, nn.Conv2d):

            # 獲取conv2d層的權重,即卷積核權重

            kernels = sub_module.weight

Copy

有了4D張量,剩下就按部就班的繪製到grid中視覺化即可,完整代碼生成的視覺化圖像如下所示:

<<AI人工智慧 PyTorch自學>> 6.2 CNN卷積

可以看到,alexnet模型的第一層的卷積核確實學習到了不同模式,有邊緣模式,有色彩模式。

Alexnet特徵圖視覺化

特徵圖視覺化與卷積核視覺化類似,需要知道特徵圖以怎樣的形式?從哪裡獲得?

常規任務中,特徵圖是4D張量(BCHW)。

但是獲得就沒有那麼簡單,因為特徵圖是中間資料,通常不會保留,在前向運算過程中,不再使用的特徵圖會被捨棄。

因此需要特殊方法獲得特徵圖,本節介紹一種笨辦法,但容易理解,就是將對應層(仍舊是一個nn.Module)拿出來,然後把圖片仍給網路層(仍舊是一個nn.Module),其輸出的就是特徵圖了。

更高級的方法是利用hook函數機制完成中間特徵圖的獲取,這個在本章的後半部分會介紹。

請看核心代碼

alexnet = models.alexnet(pretrained=True)

# forward

convlayer1 = alexnet.features[0]

fmap_1 = convlayer1(img_tensor)

Copy

這樣就獲得了(1, 64, 55, 55)4D張量(fmap_1),然後將其轉換成能視覺化的形式,再利用tensorboard繪製。

完整代碼生成的視覺化圖像如下所示:

<<AI人工智慧 PyTorch自學>> 6.2 CNN卷積

小結

本節介紹了tensorboard對卷積核與特徵圖的繪製,其中涉及非常實用的函數make_gridmake_grid可以説明開發人員高效的審核圖片,人眼看圖是演算法工程師最重要的一步,因為模型是沒辦法知道哪張圖片的標籤搞錯了!

下一小節將介紹在模型訓練過程中,如何基於tensorboard進行監控模型狀態。

最後留一個思考題,將卷積核與特徵圖放到一起去比較,大家能否找到什麼規律?

邊緣模式的卷積核似乎能過濾掉大部分細節,僅留下邊緣;還能看到清晰原圖資訊的特徵圖所對應的卷積核,都是顏色卷積核。

<<AI人工智慧 PyTorch自學>> 6.2 CNN卷積

 

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 HCHUNGW 的頭像
    HCHUNGW

    HCHUNGW的部落格

    HCHUNGW 發表在 痞客邦 留言(0) 人氣()