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

运行《Python深度学习》配套代码生成异常热力图:问题源于Google Colab还是代码错误?

问题排查:不是Colab的问题,是模型结构不匹配导致的

我帮你仔细梳理了代码,发现问题完全不是Google Colab平台的问题,而是你选用的模型和原书《Python深度学习》里的示例模型结构差异极大,导致热力图生成逻辑失效。具体来说:

核心问题:Keras Hub封装模型 vs 原书原生模型

原书第十章用的是Keras内置的keras.applications.xception.Xception模型,但你用的是keras_hub.models.ImageClassifier.from_preset("xception_41_imagenet")——这是Keras Hub封装好的高级分类器,它的内部层命名、分类器结构和原生Xception完全不一样:

  • 你指定的block14_sepconv2_act是原生Xception的最后卷积层名称,但Keras Hub的Xception backbone里的层名可能是其他命名(比如block14_sepconv2_activation),直接调用会导致逻辑错误
  • 代码里遍历的pooler、predictions层是Keras Hub封装的组件,和原书里原生Xception的avg_pool+全连接层的分类逻辑完全不同,梯度计算自然会出错

另外还有一个小问题:你没有对输入图片做Xception要求的预处理(归一化、尺寸调整),这也会干扰模型的预测和梯度计算结果。

修正后的代码(和原书逻辑完全对齐)

把模型替换成原书用的原生Xception,加上正确的预处理,就能生成符合预期的热力图:

import keras
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras import ops

# 加载图片并做Xception要求的预处理
img_path = keras.utils.get_file(
    fname="elephant.jpg",
    origin="https://img-datasets.s3.amazonaws.com/elephant.jpg",
)
# Xception要求输入尺寸为299x299
img = keras.utils.load_img(img_path, target_size=(299, 299))
img_array = keras.utils.img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
# 应用Xception专属的预处理
img_array = keras.applications.xception.preprocess_input(img_array)

# 使用原书的原生Xception模型(带ImageNet权重)
model = keras.applications.xception.Xception(weights="imagenet")

# 查看预测结果(验证模型正常工作)
preds = model.predict(img_array)
print("Top 3预测结果:", keras.applications.xception.decode_predictions(preds, top=3)[0])

# 原书的最后卷积层名称,原生Xception确实是block14_sepconv2_act
last_conv_layer_name = "block14_sepconv2_act"
last_conv_layer = model.get_layer(last_conv_layer_name)
last_conv_layer_model = keras.Model(model.inputs, last_conv_layer.output)

# 重构分类器部分,匹配原生Xception的结构
classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])
x = model.get_layer("avg_pool")(classifier_input)  # 原生Xception的全局平均池化层
x = model.get_layer("predictions")(x)  # 原生Xception的全连接预测层
classifier_model = keras.Model(classifier_input, x)

def get_top_class_gradients(img_array):
    last_conv_layer_output = last_conv_layer_model(img_array)
    with tf.GradientTape() as tape:
        tape.watch(last_conv_layer_output)
        preds = classifier_model(last_conv_layer_output)
        top_pred_index = ops.argmax(preds[0])
        top_class_channel = preds[:, top_pred_index]
    grads = tape.gradient(top_class_channel, last_conv_layer_output)
    return grads, last_conv_layer_output

grads, last_conv_layer_output = get_top_class_gradients(img_array)
grads = ops.convert_to_numpy(grads)
last_conv_layer_output = ops.convert_to_numpy(last_conv_layer_output)

# 计算权重并生成热力图
pooled_grads = np.mean(grads, axis=(0, 1, 2))
last_conv_layer_output = last_conv_layer_output[0].copy()
for i in range(pooled_grads.shape[-1]):
    last_conv_layer_output[:, :, i] *= pooled_grads[i]

heatmap = np.mean(last_conv_layer_output, axis=-1)
heatmap = np.maximum(heatmap, 0)
heatmap /= np.max(heatmap)

# 显示热力图
plt.matshow(heatmap)
plt.show()

修正点说明

  • 替换成keras.applications.xception.Xception,和原书模型结构完全一致
  • 添加了Xception要求的输入尺寸调整(299x299)和专属预处理
  • 重构了分类器部分,匹配原生Xception的avg_pool和predictions层
  • 运行这段代码后,生成的热力图会聚焦在大象的身体区域,和原书预期结果一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 09:37:31