def main(args): # 输入 img = io.imread(args.image_path) img = np.float32(cv2.resize(img, (224, 224))) / 255 inputs = prepare_input(img) # 输出图像 image_dict = {} # 网络 net = get_net(args.network, args.weight_path) # Grad-CAM layer_name = get_last_conv_name( net) if args.layer_name is None else args.layer_name grad_cam = GradCAM(net, layer_name) mask = grad_cam(inputs, args.class_id) # cam mask image_dict['cam'], image_dict['heatmap'] = gen_cam(img, mask) grad_cam.remove_handlers() # Grad-CAM++ grad_cam_plus_plus = GradCamPlusPlus(net, layer_name) mask_plus_plus = grad_cam_plus_plus(inputs, args.class_id) # cam mask image_dict['cam++'], image_dict['heatmap++'] = gen_cam(img, mask_plus_plus) grad_cam_plus_plus.remove_handlers() # GuidedBackPropagation gbp = GuidedBackPropagation(net) inputs.grad.zero_() # 梯度置零 grad = gbp(inputs) gb = gen_gb(grad) image_dict['gb'] = gb # 生成Guided Grad-CAM cam_gb = gb * mask[..., np.newaxis] image_dict['cam_gb'] = norm_image(cam_gb) save_image(image_dict, os.path.basename(args.image_path), args.network, args.output_dir)
def grad_cam(fid, cam_model, net, im, im_size, class_idx=None, cuda=False): im_shape = im.shape #logger.info(f'grad_cam im_shape:{im_shape}') #img = np.float32(cv2.resize(im, (im_size, im_size))) / 255 img = np.float32(im) / 255 inputs = prepare_input(img) if cuda: inputs = inputs.cuda() #logger.info(f'grad_cam inputs:{type(inputs)}') # 输出图像 image_dict = {} layer_name = get_last_conv_name(net) #logger.info(f'grad_cam layer_name:{layer_name}') # Grad-CAM if cam_model == 'GradCAM': grad_cam = GradCAM(net, layer_name) mask = grad_cam(inputs, class_idx) # cam mask # mask = cv2.resize(mask, (im.shape[1], im.shape[0]), interpolation=cv2.INTER_CUBIC) image_dict['GradCAM'], image_dict['heatmap'] = gen_cam(img, mask) grad_cam.remove_handlers() # Grad-CAM++ if cam_model == 'GradCAMpp': grad_cam_plus_plus = GradCamPlusPlus(net, layer_name) mask_plus_plus = grad_cam_plus_plus(inputs, class_idx) # cam mask image_dict['GradCAMpp'], image_dict['heatmap++'] = gen_cam( img, mask_plus_plus) # cv2.imwrite(f'./output/GradCAMpp:{fid}.jpg', image_dict['GradCAMpp']) # cv2.imwrite(f'./output/heatmappp:{fid}.jpg', image_dict['heatmap++']) grad_cam_plus_plus.remove_handlers() return image_dict[cam_model]
def heat_map(image, tensors, model, class_id=None, layer_name=None, save_path='./heatmap/'): """ 生成热值图 :param image: 图片原始numpy对象 :param tensors: 图像tensor对象(之所以单独读取,是因为数据增强方式会变化) :param model: 模型对象 :param class_id: 识别类别索引,为None时去概率最大的类别 :param layer_name: 可视化的卷积层名称,请参考get_conv_name读取,默认最后一层 :param save_path: 结果保存路径,默认'./heatmap/' :return: """ image_dict = {} if layer_name is None: layer_name = get_last_conv_name(model) grad_cam = GradCAM(model, layer_name) mask = grad_cam(tensors, class_id) # cam mask image_dict['cam'], image_dict['heatmap'] = gen_cam(image, mask) grad_cam.remove_handlers() # Grad-CAM++ grad_cam_plus_plus = GradCamPlusPlus(model, layer_name) mask_plus_plus = grad_cam_plus_plus(tensors, class_id) # cam mask image_dict['cam++'], image_dict['heatmap++'] = gen_cam( image, mask_plus_plus) grad_cam_plus_plus.remove_handlers() # GuidedBackPropagation gbp = GuidedBackPropagation(model) # image_wakan.zero_grad() # 梯度置零 grad = gbp(tensors) gb = gen_gb(grad) image_dict['gb'] = norm_image(gb) # 生成Guided Grad-CAM cam_gb = gb * mask[..., np.newaxis] image_dict['cam_gb'] = norm_image(cam_gb) if not os.path.exists(save_path): os.mkdir(save_path) save_image(image_dict, 'heatmap', save_path)
def get_attribution_maps_methods(net, layer_name, method_name): ''' Get_attribution_maps_methods method_name: include GradCAM, GradCAM++ ''' if method_name in ["GradCAM"]: attr_maps = GradCAM(net, layer_name) elif method_name in ["GradCAM++"]: attr_maps = GradCamPlusPlus(net, layer_name) return attr_maps
def CAM(net, img_list, date, input_type): # img_list = glob.glob("./../eye_data/dataset/test/*") correct = 0 for img_path in img_list: file_name = img_path.split("/")[-1] class_id = 1 if file_name[0] == 'n' else 2 class_id -= 1 img = Image.open(img_path) transform_test = transforms.Compose([ transforms.Resize(size=(224, 224), interpolation=2), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) # img = transform_test(img) # img = img[np.newaxis, ...] # 增加batch维 # img = Variable(img).cuda() # output = net(img) # size(1, 2) inputs = transform_test(img) inputs = inputs[np.newaxis, ...] # 增加batch维 inputs = torch.tensor(inputs, requires_grad=True) inputs = Variable(inputs, requires_grad=True).cuda() inputs.retain_grad() output = net(inputs) img = io.imread(img_path) img = np.float32(cv2.resize(img, (224, 224))) / 255 # print(output.data, class_id-1) _, predicted = output.max(1) # print(predicted[0].item()) if (predicted[0].item() == class_id - 1): correct += 1 image_dict = {} # Grad-CAM layer_name = get_last_conv_name(net) grad_cam = GradCAM(net, layer_name) mask = grad_cam(inputs, class_id) # cam mask image_dict['cam'], image_dict['heatmap'] = gen_cam(img, mask) grad_cam.remove_handlers() # Grad-CAM++ grad_cam_plus_plus = GradCamPlusPlus(net, layer_name) mask_plus_plus = grad_cam_plus_plus(inputs, class_id) # cam mask image_dict['cam++'], image_dict['heatmap++'] = gen_cam( img, mask_plus_plus) grad_cam_plus_plus.remove_handlers() # GuidedBackPropagation gbp = GuidedBackPropagation(net) inputs.grad.zero_() # 梯度置零 grad = gbp(inputs) gb = gen_gb(grad) image_dict['gb'] = norm_image(gb) # 生成Guided Grad-CAM cam_gb = gb * mask[..., np.newaxis] image_dict['cam_gb'] = norm_image(cam_gb) save_image(image_dict, file_name, "EfficientNet-B0", f"./grad_cam_result/{input_type}_{date}") print("Test the accuracy on Grad-CAM:", correct / len(img_list))