日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PyTorch 实现 GradCAM

發布時間:2023/12/31 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PyTorch 实现 GradCAM 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Grad-CAM 概述:給定圖像和感興趣的類別作為輸入,我們通過模型的 CNN 部分前向傳播圖像,然后通過特定于任務的計算獲得該類別的原始分數。 除了期望的類別(虎),所有類別的梯度都設置為零,該類別設置為 1。然后將該信號反向傳播到卷積特征圖,我們將其結合起來計算粗略的 Grad-CAM 定位( 藍色熱圖)它表示模型在做出特定決策時必須查看的位置。 最后,我們將熱圖與反向傳播逐點相乘,以獲得高分辨率和特定于概念的引導式 Grad-CAM 可視化。

在本文中,我們將學習如何在 PyTorch 中繪制 GradCam [1]。

為了獲得 GradCam 輸出,我們需要激活圖和這些激活圖的梯度。

讓我們直接跳到代碼中!!

引入相應的包

import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import torch import torch.nn as nn from torchvision import models from skimage.io import imread from skimage.transform import resize

我們將使用鉤子函數從所需的層和張量獲得激活映射和梯度。在本教程中,我們將從ResNet50的layer4中獲取激活映射,并對相同的輸出張量進行梯度。

class GradCamModel(nn.Module):def __init__(self):super().__init__()self.gradients = Noneself.tensorhook = []self.layerhook = []self.selected_out = None#PRETRAINED MODELself.pretrained = models.resnet50(pretrained=True)self.layerhook.append(self.pretrained.layer4.register_forward_hook(self.forward_hook()))for p in self.pretrained.parameters():p.requires_grad = Truedef activations_hook(self,grad):self.gradients = graddef get_act_grads(self):return self.gradientsdef forward_hook(self):def hook(module, inp, out):self.selected_out = outself.tensorhook.append(out.register_hook(self.activations_hook))return hookdef forward(self,x):out = self.pretrained(x)return out, self.selected_out

我們向ResNet50模型的層添加一個前向鉤子。前向鉤子接受該層的輸入和該層的輸出作為參數。對于輸出張量,我們使用register_hook方法注冊一個鉤子。這個方法注冊一個向后掛鉤到一個張量,并且每次計算梯度時調用這個張量。它的輸入參數是相對于輸出張量的梯度。

以下是聲明模型實例

gcmodel = GradCamModel().to(‘cuda:0’)

讀取圖片


img = imread(‘/content/tiger.jfif’) #'bulbul.jpg' img = resize(img, (224,224), preserve_range = True) img = np.expand_dims(img.transpose((2,0,1)),0) img /= 255.0 mean = np.array([0.485, 0.456, 0.406]).reshape((1,3,1,1)) std = np.array([0.229, 0.224, 0.225]).reshape((1,3,1,1)) img = (img — mean)/std inpimg = torch.from_numpy(img).to(‘cuda:0’, torch.float32)

計算類梯度激活映射

out, acts = gcmodel(inpimg) acts = acts.detach().cpu()loss = nn.CrossEntropyLoss()(out,torch.from_numpy(np.array([600])).to(‘cuda:0’)) loss.backward() grads = gcmodel.get_act_grads().detach().cpu() pooled_grads = torch.mean(grads, dim=[0,2,3]).detach().cpu() for i in range(acts.shape[1]):acts[:,i,:,:] += pooled_grads[i]heatmap_j = torch.mean(acts, dim = 1).squeeze() heatmap_j_max = heatmap_j.max(axis = 0)[0] heatmap_j /= heatmap_j_max

現在,需要調整熱圖的大小和顏色。

調整大小

heatmap_j = resize(heatmap_j,(224,224),preserve_range=True)

顏色映射

cmap = mpl.cm.get_cmap(‘jet’,256) heatmap_j2 = cmap(heatmap_j,alpha = 0.2)

可視化

fig, axs = plt.subplots(1,1,figsize = (5,5)) axs.imshow((img*std+mean)[0].transpose(1,2,0)) axs.imshow(heatmap_j2) plt.show()

結果如下


我們換一種更清晰的方式查看熱圖

heatmap_j3 = (heatmap_j > 0.75)

可視化

fig, axs = plt.subplots(1,1,figsize = (5,5)) axs.imshow(((img*std+mean)[0].transpose(1,2,0))*heatmap_j3) plt.show()

結果


最后我們移除剛才設置的鉤子

for h in gcmodel.layerhook:h.remove() for h in gcmodel.tensorhook:h.remove()

引用

[1] R. R. Selvaraju, M. Cogswell, A. Das, R. Vedantam, D. Parikh and D. Batra, “Grad-CAM: Visual Explanations from Deep Networks via Gradient-Based Localization,” 2017 IEEE International Conference on Computer Vision (ICCV), 2017, pp. 618–626, doi: 10.1109/ICCV.2017.74.

本文作者: the owl

總結

以上是生活随笔為你收集整理的PyTorch 实现 GradCAM的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。