Grad Cam實現流程 pytorch

2021-10-06 17:20:19 字數 4475 閱讀 9042

最近感覺類啟用圖視覺化是一件很有趣的事情。

cam(傳送門:cam實現的流程(pytorch))由於對網路結構有定性要求,所以在視覺化一些有多個全連線層的網路時,表現不太友好,於是出現了grad-cam。

引用的博主 g5lorenzo 一句話

grad-cam根據輸出向量,進行backward,求取特徵圖的梯度,得到每個特徵圖上每個畫素點對應的梯度,也就是特徵圖對應的梯度圖,然後再對每個梯度圖求平均,這個平均值就對應於每個特徵圖的權重,然後再將權重與特徵圖進行加權求和,最後經過relu啟用函式就可以得到最終的類啟用圖

先準備、標籤以及模型resnet18:axel -n 51.匯入各種包

import cv2

import os

import numpy as np

import torch

import torchvision.transforms as transforms

from torchvision import models

import json

2.定義一些函式

預處理函式

# 預處理

defimg_preprocess

(img_in)

: img = img_in.copy(

)

img = img[:,

:,::

-1]# 1

img = np.ascontiguousarray(img)

# 2 transform = transforms.compose(

[ transforms.totensor(),

transforms.normalize(

[0.4948052

,0.48568845

,0.44682974],

[0.24580306

,0.24236229

,0.2603115])

])img = transform(img)

img = img.unsqueeze(0)

# 3return img

1.之後讀取會使用opencv讀取,讀取的顏色通道為bgr,為了適應模型,需要將顏色通道轉回為rgb。

2.由於更改通道後,陣列變為不連續,所以需要使用np.ascontiguousarray將img轉為連續陣列,否則無法轉為tensor。

3.增加第一維的batch通道,使得能夠輸入網路

定義獲取梯度和特徵圖的函式

# 定義獲取梯度的函式

defbackward_hook

(module, grad_in, grad_out):0

].detach())

# 定義獲取特徵圖的函式

deffarward_hook

(module,

input

, output)

:

定義計算grad-cam並顯示的函式

# 計算grad-cam並視覺化

4.feature_map.shape[1:] 表示取第一維度及之後的其餘維度的尺寸,如 [512, 14, 14] --> (14, 14)

5-6.計算每個通道的權重均值

7.將梯度權重與特徵圖相乘再累加

3.執行函式

# 只取標籤名

classes =

list

(classes.get(key)

for key in

range

(1000))

# 存放梯度和特徵圖

fmap_block =

list()

grad_block =

list()

# 讀取;網路載入

img = cv2.imread(path_img,1)

img_input = img_preprocess(img)

# 載入 squeezenet1_1 預訓練模型

net = models.squeezenet1_1(pretrained=

false

) pthfile =

'./pretrained/squeezenet1_1-f364aa15.pth'

net.load_state_dict(torch.load(pthfile)

) net.

eval()

# 8print

(net)

# 註冊hook

net.features[-1

].expand3x3.register_forward_hook(farward_hook)

# 9 net.features[-1

].expand3x3.register_backward_hook(backward_hook)

# forward

output = net(img_input)

idx = np.argmax(output.cpu(

).data.numpy())

print

("predict: {}"

.format

(classes[idx]))

# backward

net.zero_grad(

) class_loss = output[

0,idx]

class_loss.backward(

)# 生成cam

grads_val = grad_block[0]

.cpu(

).data.numpy(

).squeeze(

) fmap = fmap_block[0]

.cpu(

).data.numpy(

).squeeze(

)# 儲存cam

cam_show_img(img, fmap, grads_val, output_dir)

8.一定要加上net.eval(),不然深一點的網路(如resnet)就會識別出錯,而且每次執行後的類啟用圖都不一樣。

9.-1索引為features中最後乙個卷積層,看列印的模型就知道了。

squeezenet1_1的grad-cam視覺化效果

vgg16的grad-cam視覺化效果

resnet50的grad-cam視覺化效果

HTTPS 實現流程

https協議其實就是http over tsl,基礎的http通訊是明文的,有三大風險 資訊被竊聽,資訊被篡改,身份的冒充。tsl協議就是為防範這些風險存在的。tsl使用非對稱加密保護下的對稱加密在保證了通訊效率的同時防止竊聽,使用證書體系防止資訊篡改和身份冒認。注意 tsl協議握手階段的通訊是明...

虛擬DOM實現流程

尚未使用虛擬dom 方案一 1 state資料 2 jsx模版 3,資料 模版結合,生成真實的dom,來顯示 4 state發生改變 5.資料 模版結合,生成真實的dom,替換原始的dom 缺陷 第一次生成了 個完整的dom片段 第二次生成了乙個完整的dom片段 第二次的d0m替換第一次的dom,非...

實現敏捷開發流程

最近幫助乙個團隊完成轉型,實現敏捷開發流程。我發現消極因素主要 於兩個方面 員工和管理人員。員工不願意採用敏捷方法主要歸結於意識的缺乏和對未知的恐懼。員工不了解整個專案或者產品的整體規劃,尤其是公司願景和發展路線圖。緊迫感不是來自於使命感,而是來自於專案的時間壓力。工作流程的創新與產品創新同樣重要。...