特徵圖可視化爲類激活圖(CAM)--簡化版

本篇博客是簡化版本的CAM,針對於不同特徵圖進行可視化。

其餘兩篇:
CAM實現的流程(pytorch)
Grad-Cam實現流程(pytorch)

在圖像分類領域的論文中,經常看到如下所示的可視化圖片。將特徵圖的響應大小,映射到了原圖,能讓讀者更直觀的瞭解模型的效果。這類圖,通常被稱爲類激活圖(CAM, Class Activation Map),或者注意力圖、熱圖。

在這裏插入圖片描述
其實,繪製這種圖片並不難,通過opencv就可以實現,並且,不限於你的深度學習框架,tensorflow,pytorch,keras都可以,前提是你能夠提取出特徵圖。上一張圖,是我使用訓練好的細粒度分類模型(網絡結構源於Mutual-Channel Loss )可視化的結果。
用到的函數爲:cv2.applyColorMap(),cv2.addWeighted()
cv2.applyColorMap()函數的功能是將矩陣轉化爲僞彩色圖(可以把僞彩色圖近似於熱力圖)。
cv2.addWeighted()函數是將兩張圖片融合。

上圖繪製的思想是:

  1. 將一張圖片輸入訓練好的模型,預測分類結果。然後獲取我們想要可視化那一層的特徵圖。
  2. 可以通過切片方式,選擇單個通道或者多通道的第一步得到的特徵圖。
  3. 將特徵圖resize爲原始圖片大小,以便能夠與原始圖片疊加。
  4. 將特徵圖按照每個元素的大小生成僞彩色圖片。
  5. 原始圖片與僞彩色圖片疊加。

代碼示例:

import numpy as np
import cv2
import matplotlib.pyplot as plt
# heat 爲某層的特徵圖,自己手動獲取
heat = heat.data.cpu().numpy()	     # 將tensor格式的feature map轉爲numpy格式
heat = np.squeeze(heat, 0)	         # 0維爲batch維度,由於是單張圖片,所以batch=1,將這一維度刪除
heat = heat[145*3:145*3+3,:]        # 切片獲取某幾個通道的特徵圖
heatmap = np.maximum(heat, 0)        # heatmap與0比較
heatmap = np.mean(heatmap, axis=0)  # 多通道時,取均值
heatmap /= np.max(heatmap)          # 正則化到 [0,1] 區間,爲後續轉爲uint8格式圖做準備
#plt.matshow(heatmap)				# 可以通過 plt.matshow 顯示熱力圖
#plt.show()

# 用cv2加載原始圖像
img = cv2.imread('./Forsters_Tern_0016_152463.jpg')
heatmap = cv2.resize(heatmap, (img.shape[1], img.shape[0]))  # 特徵圖的大小調整爲與原始圖像相同
heatmap = np.uint8(255 * heatmap)               # 將特徵圖轉換爲uint8格式
heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET)  # 將特徵圖轉爲僞彩色圖
heat_img = cv2.addWeighted(img, 1, heatmap, 0.5, 0)     # 將僞彩色圖與原始圖片融合
#heat_img = heatmap * 0.5 + img       		      # 也可以用這種方式融合
cv2.imwrite('./heat_all_3.jpg', heat_img)          # 將圖像保存

opencv中一共有12種模式。其中能夠用於繪製CAM的有cv2.COLORMAP_JETcv2.COLORMAP_RAINBOWcv2.COLORMAP_HSV這三種模式,其餘效果不太好。12種模式可參考:cv2僞彩色applyColorMap()函數

12種彩色模式效果:
在這裏插入圖片描述
參考鏈接:
https://blog.csdn.net/C_chuxin/article/details/85265082

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章