基于CNN回归模型的GradCam可视化,生成pytorch代码
时间: 2024-02-13 10:02:26 浏览: 176
基于pytorch实现Grad-CAM和Grad-CAM++项目源码,可以可视化任意分类网络的CAM图
5星 · 资源好评率100%
好的,以下是基于CNN回归模型的GradCam可视化的pytorch代码:
```python
import torch
from torch import nn
import torchvision
from torchvision import models
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import cv2
# 定义模型
class CNNRegressor(nn.Module):
def __init__(self):
super(CNNRegressor, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(128, 128, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(128, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(256, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
self.classifier = nn.Sequential(
nn.Linear(512 * 7 * 7, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 1),
)
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = torch.flatten(x, 1)
x = self.classifier(x)
return x
# 加载模型
model = CNNRegressor()
model.load_state_dict(torch.load('model.pth'))
model.eval()
# 加载图片
img_path = 'test.jpg'
img = Image.open(img_path)
img = torchvision.transforms.functional.resize(img, (224, 224))
img_tensor = torchvision.transforms.functional.to_tensor(img)
img_tensor = img_tensor.unsqueeze(0)
# GradCam
class GradCam:
def __init__(self, model, target_layer):
self.model = model
self.target_layer = target_layer
self.feature_maps = None
self.gradient = None
self.model.eval()
self.register_hooks()
def register_hooks(self):
def forward_hook(module, input, output):
self.feature_maps = output.detach()
def backward_hook(module, grad_in, grad_out):
self.gradient = grad_out[0].detach()
for name, module in self.model.named_modules():
if name == self.target_layer:
module.register_forward_hook(forward_hook)
module.register_backward_hook(backward_hook)
def __call__(self, x):
output = self.model(x)
output.backward()
gradient = self.gradient.mean(dim=(2, 3), keepdim=True)
feature_maps = self.feature_maps
weights = torch.mean(gradient * feature_maps, dim=(0, 2, 3), keepdim=True)
cam = torch.sum(weights * feature_maps, dim=1, keepdim=True)
cam = torch.clamp(cam, min=0)
cam = cam / torch.max(cam)
return cam
# 可视化
grad_cam = GradCam(model, 'features.29')
cam = grad_cam(img_tensor)
cam = cam.squeeze().numpy()
img = cv2.imread(img_path)
img = cv2.resize(img, (224, 224))
heatmap = cv2.applyColorMap(np.uint8(255 * cam), cv2.COLORMAP_JET)
heatmap = np.float32(heatmap) / 255
heatmap = heatmap[..., ::-1]
superimposed_img = np.clip((heatmap + np.float32(img)), 0, 1)
plt.imshow(superimposed_img)
plt.show()
```
其中,`CNNRegressor`定义了一个基于卷积神经网络的回归模型,`GradCam`定义了GradCam可视化的类,`__call__`方法实现了GradCam的计算,`grad_cam`实例化了GradCam类,`cam`计算了GradCam热力图,`superimposed_img`将热力图叠加在原图上,得到可视化效果。
阅读全文