python cnn 实例_Grad cam(CNN可视化)Python示例,GradCAMCNN

论文:ICCV 2017《Grad-CAM:Visual Explanations from Deep Networks via Gradient-based Localization》

代码:https://github.com/yizt/Grad-CAM.pytorch/blob/master/main.py

https://github.com/jacobgil/pytorch-grad-cam/blob/master/grad-cam.py

1、首先定义并训练好CNN网络,原网络结构不用调整。假设网路训练好,得到一个best_net。

class GradCAM(object):

"""

1: gradients update when input

2: backpropatation by the high scores of class

"""

def __init__(self, net, layer_name):

self.net = net

self.layer_name = layer_name

self.feature = None

self.gradient = None

self.net.eval()

self.handlers = []

self._register_hook()

def _get_features_hook(self, module, input, output):

self.feature = output

#print("feature shape:{}".format(output.size()))

def _get_grads_hook(self, module, input_grad, output_grad):

"""

:param input_grad: tuple, input_grad[0]: None

input_grad[1]: weight

input_grad[2]: bias

:param output_grad:tuple,length = 1

:return:

"""

self.gradient = output_grad[0]

def _register_hook(self):

for (name, module) in self.net.named_modules():

if name == self.layer_name:

self.handlers.append(module.register_forward_hook(self._get_features_hook))

self.handlers.append(module.register_backward_hook(self._get_grads_hook))

def remove_handlers(self):

for handle in self.handlers:

handle.remove()

def __call__(self, inputs, index=None):

"""

:param inputs: [1,3,H,W]

:param index: class id

:return:

"""

self.net.zero_grad()

output = self.net(inputs) # [1,num_classes]

if index is None:

index = np.argmax(output.cpu().data.numpy())

target = output[0][index]

target.backward()

gradient = self.gradient[0].cpu().data.numpy() # [C,H,W]

weight = np.mean(gradient, axis=(1, 2)) # [C]

feature = self.feature[0].cpu().data.numpy() # [C,H,W]

cam = feature * weight[:, np.newaxis, np.newaxis] # [C,H,W]

cam = np.sum(cam, axis=0) # [H,W]

cam = np.maximum(cam, 0) # ReLU

# nomalization

cam -= np.min(cam)

cam /= np.max(cam)

# resize to 256*256

cam = cv2.resize(cam, (256, 256))

return cam

class GradCamPlusPlus(GradCAM):

def __init__(self, net, layer_name):

super(GradCamPlusPlus, self).__init__(net, layer_name)

def __call__(self, inputs, index=None):

"""

:param inputs: [1,3,H,W]

:param index: class id

:return:

"""

self.net.zero_grad()

output = self.net(inputs) # [1,num_classes]

if index is None:

index = np.argmax(output.cpu().data.numpy())

target = output[0][index]

target.backward()

gradient = self.gradient[0].cpu().data.numpy() # [C,H,W]

gradient = np.maximum(gradient, 0.) # ReLU

indicate = np.where(gradient > 0, 1., 0.) # 示性函数

norm_factor = np.sum(gradient, axis=(1, 2)) # [C]归一化

for i in range(len(norm_factor)):

norm_factor[i] = 1. / norm_factor[i] if norm_factor[i] > 0. else 0. # 避免除零

alpha = indicate * norm_factor[:, np.newaxis, np.newaxis] # [C,H,W]

weight = np.sum(gradient * alpha, axis=(1, 2)) # [C] alpha*ReLU(gradient)

feature = self.feature[0].cpu().data.numpy() # [C,H,W]

cam = feature * weight[:, np.newaxis, np.newaxis] # [C,H,W]

cam = np.sum(cam, axis=0) # [H,W]

# cam = np.maximum(cam, 0) # ReLU

# nomalization

cam -= np.min(cam)

cam /= np.max(cam)

# resize

cam = cv2.resize(cam, (256, 256))

return cam

class GuidedBackPropagation(object):

def __init__(self, net):

self.net = net

for (name, module) in self.net.named_modules():

if isinstance(module, nn.ReLU):

module.register_backward_hook(self.backward_hook)

self.net.eval()

@classmethod

def backward_hook(cls, module, grad_in, grad_out):

"""

:param module:

:param grad_in: tuple,length=1

:param grad_out: tuple,length=1

:return: tuple(new_grad_in,)

"""

return torch.clamp(grad_in[0], min=0.0),

def __call__(self, inputs, index=None):

"""

:param inputs: [1,3,H,W]

:param index: class_id

:return:

"""

self.net.zero_grad()

output = self.net(inputs) # [1,num_classes]

if index is None:

index = np.argmax(output.cpu().data.numpy())

target = output[0][index]

target.backward()

return inputs.grad[0] # [3,H,W]

def show_cam_on_image(img, mask):

heatmap = cv2.applyColorMap(np.uint8(255 * mask), cv2.COLORMAP_JET)

heatmap = np.float32(heatmap) / 255

cam = heatmap + np.float32(img)

cam = cam / np.max(cam)

cv2.imwrite("cam.jpg", np.uint8(255 * cam))

root='/data/fjsdata/qtsys/img/sz.002509-20200325.png'

img_list = []

img_list.append( cv2.resize(cv2.imread(root).astype(np.float32), (256, 256)))#(256, 256) is the model input size

inputs = torch.from_numpy(np.array(img_list)).type(torch.FloatTensor).cuda()

# Grad-CAM

#grad_cam = GradCAM(net=best_net, layer_name='conv3')

#mask = grad_cam(inputs.permute(0, 3, 1, 2)) # cam mask

#show_cam_on_image(img_list[0], mask)

#grad_cam.remove_handlers()

# Grad-CAM++

#grad_cam_plus_plus = GradCamPlusPlus(net=best_net, layer_name='conv3')

#mask_plus_plus = grad_cam_plus_plus(inputs.permute(0, 3, 1, 2)) # cam mask

#show_cam_on_image(img_list[0], mask)

#grad_cam_plus_plus.remove_handlers()

# GuidedBackPropagation

gbp = GuidedBackPropagation(best_net)

inputs = inputs.requires_grad_(True)

inputs.grad.zero_()

grad = gbp(inputs.permute(0, 3, 1, 2))

print(grad)

最后GuidedBackPropagation没完全调通,详细阅读论文后再处理。前面Grad-CAM 和Grad-CAM++可以。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于CNN回归的GradCam可视化的pytorch代码: ```python import torch import torch.nn.functional as F import cv2 import numpy as np # Load the pre-trained model model = YourCNNRegressionModel() # Define the image preprocessing function def preprocess_image(img_path): img = cv2.imread(img_path) img = cv2.resize(img, (224, 224)) img = np.float32(img) / 255 img = np.transpose(img, (2, 0, 1)) img = np.expand_dims(img, axis=0) return img # Define the GradCam function def GradCam(model, input_image, target_layer): # Set model to evaluation mode model.eval() # Get the model's output and feature maps output, features = model(input_image) # Zero the gradients model.zero_grad() # Compute the gradients of the output with respect to the feature maps output.backward(torch.ones_like(output)) # Get the gradients gradients = target_layer.grad # Get the weights of the target layer weights = torch.mean(gradients, axis=(2, 3)) # Get the feature maps of the target layer maps = features.detach() # Compute the cam cams = F.relu(torch.sum(weights[:, :, None, None] * maps, axis=1)) # Resize the cam to match the input image size cams = F.interpolate(cams, size=input_image.shape[2:], mode='bilinear', align_corners=False) # Normalize the cam cams = F.normalize(cams, p=2, dim=1) return cams # Load the input image img_path = 'path/to/image.jpg' input_image = preprocess_image(img_path) # Get the target layer target_layer = model.layer_name # Compute the GradCam cam = GradCam(model, input_image, target_layer) # Convert the cam to a numpy array cam = cam.squeeze().cpu().numpy() # Rescale the cam to be between 0 and 255 cam = np.uint8(255 * cam) # Apply the cam as an overlay on the input image overlay = cv2.applyColorMap(cam, cv2.COLORMAP_JET) output_image = cv2.addWeighted(cv2.cvtColor(input_image.squeeze().transpose(1, 2, 0) * 255, cv2.COLOR_BGR2RGB), 0.5, overlay, 0.5, 0) # Show the output image cv2.imshow('GradCam', output_image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上面的代码中,你需要替换以下内容: - `YourCNNRegressionModel()`:你使用的CNN回归模型。 - `preprocess_image()`:你的图像预处理函数。 - `model.layer_name`:你希望可视化的目标层的名称。可以在模型的定义中找到。 - `cv2.applyColorMap()`:你希望使用的颜色映射。在这里,我们使用了Jet颜色映射。 运行代码后,你应该能够看到一个窗口,显示输入图像和可视化GradCam结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值