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

Keras中VGG-19模型标签与输出形状不匹配问题咨询

问题分析与解决方法

核心结论

模型训练时标签(Ground Truth)与模型输出的形状必须完全匹配,这是监督学习的基本要求,你遇到的ValueError就是因为标签形状(1,128,128)和输出形状(1,2)不匹配导致的,这种情况下无法直接训练,必须调整标签或模型结构。

具体解决思路

1. 调整标签为运动向量(最直接方案)

既然你的目标是让模型输出V_x和V_y运动向量,训练时必须使用对应CT序列的真实运动向量作为标签(形状为(1,2)),而非完全重建的图像:

  • 若为模拟生成的CT数据,直接提取生成时设定的V_x、V_y值作为标签;
  • 若为真实临床数据,需先通过图像配准算法(如SimpleITK配准模块)计算序列中每张图像相对参考图像的运动向量,以此作为标签。

同时,当前模型用的categorical_crossentropy是分类任务损失,运动向量估计属于回归任务,需替换为回归损失,比如mse或mae:

model.compile(optimizer=opti, 
             loss='mse', metrics=['mae'])

2. 多任务模型:同时输出重建图像与运动向量

如果既要获取运动向量,又想用重建图像做监督信号,可将模型改为多输出结构,同时学习两个任务:

  • 分支1:输出重建图像(形状(1,128,128)),用重建图像做标签,MSE损失监督;
  • 分支2:输出运动向量(形状(1,2)),用真实运动向量做标签,回归损失监督。

示例代码(Keras Functional API实现):

from tensorflow.keras import Model, layers, optimizers

# 输入层
inputs = layers.Input(shape=(128,128,19))

# 共享特征提取(VGG-19前半部分)
x = layers.Conv2D(filters=3, kernel_size=(3,3), padding="same", activation="relu")(inputs)
x = layers.Conv2D(filters=3, kernel_size=(3,3), padding="same", activation="relu")(x)
x = layers.MaxPool2D(pool_size=(2,2), strides=(2,2))(x)

x = layers.Conv2D(filters=64, kernel_size=(3,3), padding="same", activation="relu")(x)
x = layers.Conv2D(filters=64, kernel_size=(3,3), padding="same", activation="relu")(x)
x = layers.MaxPool2D(pool_size=(2,2), strides=(2,2))(x)

# 继续堆叠剩余VGG-19卷积池化层(省略重复代码)
# ...
x = layers.MaxPool2D(pool_size=(2,2), strides=(2,2), name="vgg19")(x)

# 分支1:图像重建(转置卷积恢复尺寸)
recon_branch = layers.Conv2DTranspose(filters=512, kernel_size=(3,3), padding="same", activation="relu")(x)
recon_branch = layers.UpSampling2D(size=(2,2))(recon_branch)
# 重复转置卷积+上采样直到输出128x128尺寸
# ...
recon_output = layers.Conv2D(filters=1, kernel_size=(3,3), padding="same", activation="sigmoid", name="recon")(recon_branch)

# 分支2:运动向量估计
motion_branch = layers.Flatten()(x)
motion_branch = layers.Dense(512, activation="relu")(motion_branch)
motion_output = layers.Dense(2, name="motion")(motion_branch)

# 构建多输出模型
model = Model(inputs=inputs, outputs=[recon_output, motion_output])

# 编译:为不同分支指定损失和权重
model.compile(optimizer=optimizers.Adam(learning_rate=0.001),
             loss={"recon": "mse", "motion": "mse"},
             loss_weights={"recon": 1.0, "motion": 0.5},  # 可调整权重平衡任务
             metrics={"recon": "mae", "motion": "mae"})

训练时需传入两个标签:

model.fit(ct_sequences, [reconstructed_images, motion_vectors], epochs=50)

3. 修正当前模型的其他问题

  • 模型开头用filters=3,但输入通道是19,特征提取效率低,可直接用filters=64作为第一层通道数,无需先转3通道;
  • 最后一层Dense无激活函数,对于运动向量回归任务是合理的,无需额外激活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 05:10:55