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

基于ResNet的visible与thermal图像融合分类代码修改咨询

双输入ResNet实现热成像与可见光图像融合方案

我来帮你搞定这个双输入ResNet的融合问题!你的思路完全没问题——分别用热成像(thermal)和可见光(visible)图像训练ResNet的卷积块,拼接输出后再送入全连接层。下面我一步步给你讲怎么修改现有代码:

一、核心修改思路

  1. 定义两个独立的输入层,分别对应可见光和热成像图像
  2. 为两个输入分别构建ResNet的卷积特征提取分支
  3. 把两个分支的卷积输出做拼接操作
  4. 将拼接后的特征送入全连接层完成分类

二、具体代码修改步骤

1. 导入必要的层

首先需要导入Concatenate层,用于拼接两个分支的输出:

from keras.layers import Concatenate  # 新增这一行

2. 封装ResNet卷积块为可复用函数

把原来的ResNet卷积部分(到你指定的convolution blocks为止)封装成一个函数,这样两个分支可以复用相同的结构:

def build_resnet_conv_branch(input_tensor):
    eps = 1.1e-5
    
    # 这里替换成你原来ResNet的卷积块代码,从输入到目标卷积层结束
    # 以下是ResNet50前半段示例,你可以根据自己的实际结构调整
    x = ZeroPadding2D((3, 3))(input_tensor)
    x = Conv2D(64, (7, 7), strides=(2, 2), name='conv1', use_bias=False)(x)
    x = BatchNormalization(epsilon=eps, axis=bn_axis, name='bn_conv1')(x)
    x = Scale(axis=bn_axis, name='scale_conv1')(x)
    x = Activation('relu')(x)
    x = MaxPooling2D((3, 3), strides=(2, 2))(x)

    x = conv_block(x, 3, [64, 64, 256], stage=2, block='a', strides=(1, 1))
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='b')
    x = identity_block(x, 3, [64, 64, 256], stage=2, block='c')

    x = conv_block(x, 3, [128, 128, 512], stage=3, block='a')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='b')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='c')
    x = identity_block(x, 3, [128, 128, 512], stage=3, block='d')

    # 继续添加你需要的卷积块,直到目标convolution blocks结束位置
    return x

提示:如果你的代码里没有conv_block函数,需要补充ResNet的卷积块实现(和identity_block对应)

3. 构建双输入模型

现在定义两个输入层,分别构建分支,然后拼接特征:

# 根据你的图像尺寸调整输入形状,示例为(224,224,3)
img_rows, img_cols, img_channels = 224, 224, 3
bn_axis = 3  # TensorFlow通道维度在最后

# 定义双输入层
visible_input = Input(shape=(img_rows, img_cols, img_channels), name='visible_input')
thermal_input = Input(shape=(img_rows, img_cols, img_channels), name='thermal_input')

# 分别构建两个卷积特征分支
visible_conv_out = build_resnet_conv_branch(visible_input)
thermal_conv_out = build_resnet_conv_branch(thermal_input)

# 在通道维度拼接两个分支的特征
merged_features = Concatenate(axis=bn_axis)([visible_conv_out, thermal_conv_out])

# 接入全连接层完成分类
x = AveragePooling2D((7, 7), name='avg_pool')(merged_features)
x = Flatten()(x)
x = Dense(num_classes, activation='softmax', name='fc_final')(x)

# 定义完整的双输入模型
model = Model(inputs=[visible_input, thermal_input], outputs=x)

4. 数据加载与训练调整

原来的单数据集加载要改成同时加载双数据集,训练时传入两个输入数组:

# 加载双数据集
visible_train, labels_train = visible_load_train_data()
thermal_train, _ = lwir_load_train_data()  # 标签与可见光数据集一致,无需重复加载
visible_test, labels_test = visible_load_test_data()
thermal_test, _ = lwir_load_test_data()

# 标签one-hot编码
num_classes = len(np.unique(labels_train))
labels_train = np_utils.to_categorical(labels_train, num_classes)
labels_test = np_utils.to_categorical(labels_test, num_classes)

# 编译模型
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])

# 训练模型:输入是两个数组的列表
model.fit(
    x=[visible_train, thermal_train],
    y=labels_train,
    batch_size=32,
    epochs=50,
    validation_data=([visible_test, thermal_test], labels_test)
)

三、关键细节说明

  • 权重共享选项:如果希望两个分支共享卷积核权重(热成像和可见光用相同特征提取逻辑),可以只构建一次卷积分支,将两个输入都传入该分支;如果需要独立训练权重,就像上面代码那样分别构建两个分支即可。
  • 拼接维度:Concatenate(axis=bn_axis)是在通道维度拼接,拼接后特征图的通道数为两个分支通道数之和。
  • 输入一致性:要确保可见光和热成像图像的尺寸、通道数一致,若不一致需先做resize或通道转换处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:23:51