You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Google Colab中使用Keras Vis(GradCAM、显著性图)的问题及替代方案

解决Keras Vis依赖旧版Scipy的问题及替代方案

一、不降级Scipy,修复Keras Vis的使用

Keras Vis报错的核心是scipy.misc.imresize被弃用,无需降级Scipy,通过以下两种方法即可修复:

1. 猴子补丁(Monkey Patch)替换imresize函数

直接在代码开头添加补丁,用PIL库的resize功能替代弃用的imresize,无需修改Keras Vis源码:

# 安装依赖(Colab默认已装PIL,若未装则执行)
!pip install pillow

import scipy.misc
from PIL import Image
import numpy as np

# 定义替代imresize的函数
def imresize(arr, size, interp='bilinear', mode=None):
    # 将numpy数组转换为PIL图像
    img = Image.fromarray(arr.astype(np.uint8) if mode == 'RGB' else arr)
    # 调整尺寸(注意PIL的size是(width, height),和scipy的(height, width)相反)
    resized_img = img.resize(
        size[::-1], 
        Image.Resampling.BILINEAR if interp == 'bilinear' else Image.Resampling.NEAREST
    )
    # 转回numpy数组
    return np.array(resized_img)

# 替换scipy.misc.imresize
scipy.misc.imresize = imresize

# 现在可以正常导入并使用Keras Vis
from vis.visualization import visualize_cam

2. 修改Keras Vis源码中的imresize调用

找到Keras Vis的工具类文件,替换其中的imresize依赖:

# 定位Keras Vis的utils.py文件路径
!find /usr/local/lib/python3.8/dist-packages -name "utils.py" | grep vis

# 假设输出路径为/usr/local/lib/python3.8/dist-packages/vis/utils/utils.py,编辑该文件
# 1. 替换导入语句:将from scipy.misc import imresize改为
from PIL import Image
import numpy as np

# 2. 找到调用imresize的代码(如resized = imresize(...)),替换为:
# resized = np.array(Image.fromarray(arr).resize(size[::-1], Image.Resampling.BILINEAR))
# 可以用sed命令批量替换(仅针对简单情况)
!sed -i 's/from scipy.misc import imresize/from PIL import Image\nimport numpy as np/' /usr/local/lib/python3.8/dist-packages/vis/utils/utils.py
!sed -i 's/imresize(\(.*\), \(.*\))/np.array(Image.fromarray(\1).resize(\2[::-1], Image.Resampling.BILINEAR))/' /usr/local/lib/python3.8/dist-packages/vis/utils/utils.py

二、替代Keras Vis的现代可视化库

由于Keras Vis已停止维护,推荐使用以下活跃维护的替代库:

1. tf-keras-vis

专为TensorFlow/Keras设计的可视化库,是Keras Vis的官方替代,支持TF 2.x,无需依赖旧版Scipy:

# 安装
!pip install tf-keras-vis

# 生成GradCAM示例
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from tf_keras_vis.gradcam import Gradcam
import matplotlib.pyplot as plt
import numpy as np

# 加载模型和图像
model = VGG16(weights='imagenet', include_top=True)
img = load_img('cat.jpg', target_size=(224, 224))
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

# 定义目标损失(取预测概率最高的类别)
def loss(output):
    return output[:, np.argmax(output[0])]

# 生成并可视化GradCAM热力图
gradcam = Gradcam(model, clone=True)
cam = gradcam(loss, x)

plt.imshow(img)
plt.imshow(cam[0], cmap='jet', alpha=0.5)
plt.axis('off')
plt.show()

2. Captum

PyTorch官方的可解释AI库,同时支持TensorFlow模型,提供多种归因方法(显著性图、GradCAM、Integrated Gradients等):

# 安装
!pip install captum

# TensorFlow模型使用GradCAM示例
import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
from tensorflow.keras.preprocessing.image import load_img, img_to_array
from captum.attr import LayerGradCam
import matplotlib.pyplot as plt

model = VGG16(weights='imagenet', include_top=True)
img = load_img('cat.jpg', target_size=(224, 224))
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

# 选择最后一层卷积层作为目标层
target_layer = model.get_layer('block5_conv3')
layer_gradcam = LayerGradCam(model, target_layer)

# 计算归因(指定目标类别,例如猫的类别ID为281)
attr = layer_gradcam.attribute(x, target=281)

# 调整热力图尺寸并可视化
attr = tf.image.resize(attr, (224, 224))
plt.imshow(img)
plt.imshow(attr[0].numpy(), cmap='jet', alpha=0.5)
plt.axis('off')
plt.show()

3. 手动实现GradCAM/显著性图

如果不想依赖第三方库,手动实现核心逻辑也很简单,以GradCAM为例:

import tensorflow as tf
from tensorflow.keras.applications.vgg16 import VGG16, preprocess_input
from tensorflow.keras.preprocessing.image import load_img, img_to_array
import matplotlib.pyplot as plt
import numpy as np

model = VGG16(weights='imagenet', include_top=True)
# 创建包含最后卷积层输出和模型预测的新模型
last_conv_layer = model.get_layer('block5_conv3')
heatmap_model = tf.keras.Model([model.inputs], [last_conv_layer.output, model.output])

# 加载并预处理图像
img = load_img('cat.jpg', target_size=(224, 224))
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

# 计算梯度
with tf.GradientTape() as tape:
    conv_outputs, predictions = heatmap_model(x)
    class_idx = tf.argmax(predictions[0])
    loss = predictions[:, class_idx]

grads = tape.gradient(loss, conv_outputs)
pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))

# 生成热力图
conv_outputs = conv_outputs[0]
heatmap = tf.matmul(conv_outputs, pooled_grads[..., tf.newaxis])
heatmap = tf.squeeze(heatmap)
heatmap = tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap)

# 调整尺寸并可视化
heatmap = tf.image.resize(tf.expand_dims(heatmap, axis=-1), (224, 224))
plt.imshow(img)
plt.imshow(heatmap.numpy()[..., 0], cmap='jet', alpha=0.5)
plt.axis('off')
plt.show()

内容的提问来源于stack exchange,提问作者Chira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:15:26