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

基于迁移学习ResNet50实现类激活图及计算图断开问题求解

访问ResNet50内部层的方法

你可以直接通过model.layers[0]获取封装在Sequential内的ResNet50 functional对象,之后通过两种方式访问内部层:

  • 按索引访问:model.layers[0].layers[index]
  • 更稳定的按名称访问:model.layers[0].get_layer('层名'),ResNet50内置的全局平均池化层名称为avg_pool,最后一个卷积层的名称为conv5_block3_out,不会随TensorFlow版本变化出现索引偏移问题。

计算图断开问题的解决方案

你报错的核心原因是直接引用了ResNet50内部的输入层作为CAM模型的输入,该输入节点和你外层Sequential模型的输入节点是相互独立的,没有建立张量连接,因此计算图判定为链路断开。
正确的构建方式是直接复用你训练好的整个模型的输入作为CAM模型的输入,代码如下:

import tensorflow as tf
import numpy as np

# 提取目标层
last_conv_layer = model.layers[0].get_layer('conv5_block3_out')
final_dense_layer = model.layers[1]

# 构建CAM模型,输入直接用外层模型的输入
cam_model = tf.keras.Model(
    inputs=model.input,
    outputs=[last_conv_layer.output, final_dense_layer.output]
)

类激活图计算示例

你可以用以下代码生成对应类别的激活图:

def generate_cam(preprocessed_img, target_class_idx):
    # preprocessed_img为预处理后的输入,shape为(1, 180, 180, 3)
    conv_feature_map, pred = cam_model.predict(preprocessed_img, verbose=0)
    conv_feature_map = conv_feature_map[0]
    # 获取对应类别的全连接层权重
    dense_weights = final_dense_layer.get_weights()[0]
    class_weights = dense_weights[:, target_class_idx]
    # 加权求和生成CAM
    cam = np.zeros(conv_feature_map.shape[:2], dtype=np.float32)
    for channel_idx, weight in enumerate(class_weights):
        cam += weight * conv_feature_map[:, :, channel_idx]
    # 归一化到0-1区间
    cam = (cam - cam.min()) / (cam.max() - cam.min())
    return cam

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 06:15:01