Keras实现排序模型时输入输出形状不匹配问题求助
问题原因分析
错误核心是模型输出形状与目标标签形状不匹配:
- 目标标签
ytrue的形状为(2, 3)(batch_size=2,每个样本对应3个分类概率) - 模型最终输出形状为
(2, 1, 3),多了一个不必要的维度,导致交叉熵损失计算时维度校验失败。
形状不匹配的具体推导
- 输入
rinputs形状是(batch_size, 3, 2),通过tf.split(x, num_or_size_splits=3, axis=1)分割后,每个子张量的形状为(batch_size, 1, 2)(按第二个维度分割,保留长度为1的第二维)。 - 经过
Dense(1)层处理后,每个子张量的输出形状变为(batch_size, 1, 1)(Dense层默认作用在最后一维,保留前面的维度)。 - 使用默认
axis=-1拼接三个(batch_size,1,1)的张量后,concatLayer形状是(batch_size,1,3),再经过Dense(3, softmax)后,输出形状仍为(batch_size,1,3),与ytrue的(batch_size,3)无法匹配。
解决方案
以下两种修复方式任选其一即可:
方式1:分割后立即压缩多余维度
修改分割后的张量处理逻辑,去掉每个子张量中长度为1的第二维:
# 3 locations with 2 descriptions. rinputs = Input(shape=(3, 2), name='inputlayer') # take my 3 expected inputs, split them split = Lambda(lambda x: tf.split(x, num_or_size_splits=3, axis=1))(rinputs) # 压缩每个子张量的第1维(索引从0开始) input_one_tensor = tf.squeeze(split[0], axis=1) input_two_tensor = tf.squeeze(split[1], axis=1) input_three_tensor = tf.squeeze(split[2], axis=1) # combine each set of location elements into 1 "score" layer2 = Dense(1, name='Layer2', use_bias=True, activation='sigmoid') layer2a = layer2(input_one_tensor) # 形状变为(batch_size,1) layer2b = layer2(input_two_tensor) layer2c = layer2(input_three_tensor) concatLayer = Concatenate(name='ConcatLayer2')([layer2a, layer2b, layer2c]) # 形状变为(batch_size,3) # softmax my score to get "best selection" softmaxLayer = Dense(3, activation='softmax', name='softmax', use_bias=False) softmaxLayer = softmaxLayer(concatLayer) # 形状保持(batch_size,3) model = Model(inputs=rinputs, outputs=softmaxLayer) model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adam(), metrics=['accuracy'])
方式2:拼接后压缩多余维度
如果不想修改分割后的处理,可在拼接后添加Lambda层去掉多余维度:
# ... 前面代码保持不变 ... concatLayer = Concatenate(name='ConcatLayer2')([layer2a, layer2b, layer2c]) # 去掉第1维 concatLayer = Lambda(lambda x: tf.squeeze(x, axis=1))(concatLayer) # ... 后面代码保持不变 ...
修改后,模型输出形状会变为(batch_size,3),与ytrue形状完全匹配,即可正常训练。
内容的提问来源于stack exchange,提问作者user1639926
相关产品推荐
相关产品推荐

