コード例 #1
0
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]
コード例 #2
0
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)
コード例 #3
0
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)
コード例 #4
0
def main(args):

    # 输入图像预处理
    img = io.imread(args.image_path)
    img = np.float32(cv2.resize(img, (224, 224))) / 255
    inputs = preprocess_image(img)

    image_dict = {}  # 将输出CAM图像存为字典
    net = get_net(args.network, args.weight_path)  # 获取网络
    layer_name = get_last_conv_name(net) if args.layer_name is None else args.layer_name

    # Grad-CAM
    grad_cam = GradCAM(net, layer_name)  # 类实例化
    mask = grad_cam(inputs, args.class_id)  # 调用该对象得到 mask
    image_dict['cam'], image_dict['heatmap'] = show_cam_on_image(img, mask)
    # cam, heatmap = show_cam_on_image(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++'] = show_cam_on_image(img, mask_plus_plus)
    # grad_cam_plus_plus.remove_handlers()

    # Guided BP
    gbp = GuidedBackPropagation(net)
    inputs.grad.zero_()  # 梯度置零
    grad = gbp(inputs)
    gb = get_gb(grad)
    image_dict['gb'] = gb

    # 生成Guided Grad-CAM
    cam_gb = gb * mask[..., np.newaxis]  # CAM
    # cam_gb = gb * mask_plus_plus[..., np.newaxis]  # CAM

    cam_gb = cam_gb.copy()
    cam_gb = cam_gb - np.max(np.min(cam_gb), 0)
    cam_gb = cam_gb / np.max(cam_gb)
    cam_gb = np.uint8(255 * cam_gb)
    image_dict['cam_gb'] = cam_gb
    # cv2.imwrite("./results/GBP_beat.jpg", cam_gb)

    save_image(image_dict, os.path.basename(args.image_path), args.network, args.output_dir)
コード例 #5
0
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
コード例 #6
0
def call_func(class_name_list, output_dir, net, network_name, inputs, img,
              image_path, true_label, want_correct):
    class_id = None
    print("network = {}".format(network_name))
    layer_name = get_last_conv_name(network_name)
    grad_cam = GradCAM(net, layer_name, class_name_list)
    mask, pseudo_label, predict_class_name, score = grad_cam(inputs, class_id)
    image_dict = {}
    if want_correct:  # get the attention map of correctly classified sample
        if pseudo_label == true_label:
            image_dict['cam'], _ = gen_cam(img, mask)
            grad_cam.remove_handlers()
            file_name = network_name + "_" + predict_class_name + "_" + "{:.3f}".format(
                score * 100.0)
            save_image(image_dict, os.path.basename(image_path), file_name,
                       output_dir)
            return 1
        else:
            return 0
    else:  # get the attention map of misclassified sample
        if pseudo_label != true_label:
            image_dict['cam'], _ = gen_cam(img, mask)  # 生成CAM图和heatmap
            grad_cam.remove_handlers()
            file_name = network_name + "_" + predict_class_name + "_" + "{:.3f}".format(
                score * 100.0)
            save_image(image_dict, os.path.basename(image_path), file_name,
                       output_dir)
            return 1
        else:
            return 0
コード例 #7
0
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))