TensorFlow LSTM音乐生成model.fit()报错:形状不兼容求助
TensorFlow LSTM音乐生成模型:shape不兼容错误修复
问题背景
使用TensorFlow构建LSTM音乐生成模型时,调用model.fit()出现形状不兼容错误,相关信息如下:
训练代码
# Compile the model lstm.compile(loss='categorical_crossentropy', optimizer='rmsprop') tf.keras.utils.plot_model(lstm, show_shapes=True) # Train the model lstm.fit([trainChords, trainDurations], [targetChords, targetDurations], epochs=500)
模型结构
Model: "model_6" __________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_19 (InputLayer) [(None, 32)] 0 [] input_20 (InputLayer) [(None, 32)] 0 [] embedding_18 (Embedding) (None, 32, 64) 2048 ['input_19[0][0]'] embedding_19 (Embedding) (None, 32, 64) 2048 ['input_20[0][0]'] concatenate_9 (Concatenate) (None, 64, 64) 0 ['embedding_18[0][0]', 'embedding_19[0][0]'] lstm_8 (LSTM) (None, 64, 512) 1181696 ['concatenate_9[0][0]'] dense_18 (Dense) (None, 64, 256) 131328 ['lstm_8[0][0]'] dense_19 (Dense) (None, 64, 32) 8224 ['dense_18[0][0]'] dense_20 (Dense) (None, 64, 32) 8224 ['dense_18[0][0]'] ================================================================================================== Total params: 1,333,568 Trainable params: 1,333,568 Non-trainable params: 0
报错信息
ValueError Traceback (most recent call last) <ipython-input-63-8785c106bc4b> in <module> 5 6 # Train the model ----> 7 lstm.fit([trainChords, trainDurations], [targetChords, targetDurations], epochs=500) ValueError: Shapes (None,) and (None, 64, 32) are incompatible
模型构建代码
# Define input layers chordInput = tf.keras.layers.Input(shape = (nChords)) durationInput = tf.keras.layers.Input(shape = (nDurations)) # Define embedding layers chordEmbedding = tf.keras.layers.Embedding(nChords, embedDim, input_length = sequenceLength)(chordInput) durationEmbedding = tf.keras.layers.Embedding(nDurations, embedDim, input_length = sequenceLength)(durationInput) # Merge embedding layers using a concatenation layer mergeLayer = tf.keras.layers.Concatenate(axis=1)([chordEmbedding, durationEmbedding]) # Define LSTM layer lstmLayer = tf.keras.layers.LSTM(512, return_sequences=True)(mergeLayer) # Define dense layer denseLayer = tf.keras.layers.Dense(256)(lstmLayer) # Define output layers chordOutput = tf.keras.layers.Dense(nChords, activation = 'softmax')(denseLayer) durationOutput = tf.keras.layers.Dense(nDurations, activation = 'softmax')(denseLayer) # nChords and nDurations are both 32 # Define model lstm = tf.keras.Model(inputs = [chordInput, durationInput], outputs = [chordOutput, durationOutput])
错误原因
模型输出层的形状是(None, 64, 32)(3D:批量大小、时间步数、类别数),但你传入的targetChords/targetDurations是1D或2D形状(比如(None,)或(None,32)),两者维度不匹配。
核心问题是LSTM层设置了return_sequences=True,会返回每个时间步的输出,而非仅最后一个时间步的输出,对应的目标数据需要和输出维度完全对齐。
修复方案
根据你的任务需求,选择以下两种方案之一:
方案1:序列到单输出(输入序列,输出最终的和弦/时长)
如果只需模型根据输入序列生成最终的一个和弦和时长,修改LSTM层的return_sequences参数为False,让模型仅返回最后一个时间步的输出:
# 修改LSTM层,移除return_sequences=True(默认值为False) lstmLayer = tf.keras.layers.LSTM(512)(mergeLayer) # 后续层自动调整为2D输出:(None, 256) → (None, 32) denseLayer = tf.keras.layers.Dense(256)(lstmLayer) chordOutput = tf.keras.layers.Dense(nChords, activation='softmax')(denseLayer) durationOutput = tf.keras.layers.Dense(nDurations, activation='softmax')(denseLayer)
此时模型输出形状为(None,32),只需确保targetChords/targetDurations是one-hot编码后的2D数组(形状(样本数, 32))即可匹配。
方案2:序列到序列输出(输入序列,生成每个时间步的和弦/时长)
如果需要模型生成序列形式的输出(每个时间步对应一个和弦/时长),需要调整目标数据的形状,使其与模型输出对齐:
- 确认
targetChords和targetDurations的形状为(样本数, 64, 32),其中64是合并后的时间步数,32是one-hot编码的类别维度。 - 如果当前目标是单标签(比如
(样本数,)或(样本数,32)),需要重新预处理数据,生成每个样本对应的64步序列标签。例如,将输入序列的每个时间步对应下一个时间步的标签,构建序列式目标。
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

