LSTM+VNN实现主动转被动文本训练时维度不匹配错误求助
问题描述
我用LSTM和VNN实现主动语态到被动语态的文本转换。将分词后的数据输入LSTM,得到形状为(68,1)的特征向量feature_vec,把它作为Vanilla神经网络(VNN)的输入,对应的输出概率矩阵output_prob_matrix形状是(68,10,10)。调用model.fit()时出现以下错误:
Epoch 1/100 Traceback (most recent call last): File "/Users/pranavpallavalli/PycharmProjects/pythonProject3/LstmSeq2Seq/ActivePassiveLSTM.py", line 77, in <module> vnn.fit(feature_vec,output_prob_matrix,32,100) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/utils/traceback_utils.py", line 67, in error_handler raise e.with_traceback(filtered_tb) from None File "/var/folders/6q/v9z_sbmd25q2ntjw2pn6hfk80000gn/T/__autograph_generated_fileg6buiumj.py", line 15, in tf__train_function retval_ = ag__.converted_call(ag__.ld(step_function), (ag__.ld(self), ag__.ld(iterator)), None, fscope) ValueError: in user code: File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/engine/training.py", line 1051, in train_function * return step_function(self, iterator) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/engine/training.py", line 1040, in step_function ** outputs = model.distribute_strategy.run(run_step, args=(data,)) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/engine/training.py", line 1030, in run_step ** outputs = model.train_step(data) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/engine/training.py", line 890, in train_step loss = self.compute_loss(x, y, y_pred, sample_weight) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/engine/training.py", line 948, in compute_loss return self.compiled_loss( File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/engine/compile_utils.py", line 201, in __call__ loss_value = loss_obj(y_t, y_p, sample_weight=sw) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/losses.py", line 139, in __call__ losses = call_fn(y_true, y_pred) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/losses.py", line 243, in call ** return ag_fn(y_true, y_pred, **self._fn_kwargs) File "/Users/pranavpallavalli/miniforge3/envs/env_tensorflow/lib/python3.9/site-packages/keras/losses.py", line 1327, in mean_squared_error return backend.mean(tf.math.squared_difference(y_pred, y_true), axis=-1) ValueError: Dimensions must be equal, but are 68 and 10 for '{{node mean_squared_error/SquaredDifference}} = SquaredDifference[T=DT_FLOAT](sequential_1/dense_1/Sigmoid, IteratorGetNext:1)' with input shapes: [68,10], [?,10,10].
模型搭建代码如下:
lstm = Sequential() lstm.add(LSTM(10,input_shape=(1,10))) lstm.add(Dense(1)) feature_vec = lstm(lstm_input_sequences) feature_vec = np.array(feature_vec) # np.reshape(feature_vec,(68,10,10)) vnn = Sequential() vnn.add(Input(1,68)) vnn.add(Dense(units=10,activation='sigmoid')) loss_fn = keras.losses.MeanSquaredError() vnn.compile(loss='mse',optimizer='adam',metrics=['accuracy']) print(vnn.summary()) vnn.fit(feature_vec,output_prob_matrix,32,100)
问题原因与解决方案
核心问题:输入输出维度不匹配
错误日志明确显示,VNN的输出形状是[68,10],但标签output_prob_matrix的形状是[?,10,10],两者维度无法对齐,导致MSE损失计算失败。同时VNN的输入层定义也存在错误。
1. 修正VNN输入层
原代码中vnn.add(Input(1,68))的写法错误,Keras的Input层需要传入shape参数定义单个样本的特征形状。因为feature_vec是(68,1),即每个样本有1个特征,所以输入层应改为:
vnn.add(Input(shape=(1,)))
2. 调整VNN输出层,匹配标签形状
标签output_prob_matrix是(68,10,10),意味着每个样本要输出10×10=100个值。需要修改VNN的输出结构,让最终输出形状与标签一致:
vnn = Sequential() vnn.add(Input(shape=(1,))) # 可添加中间隐藏层提升模型能力(可选) vnn.add(Dense(units=128, activation='relu')) # 先输出100个神经元对应10×10的维度 vnn.add(Dense(units=100, activation='sigmoid')) # 用Reshape层把输出转换成(10,10) vnn.add(Reshape((10,10)))
3. 规范fit函数参数
原代码中vnn.fit(feature_vec,output_prob_matrix,32,100)的参数顺序容易混淆,建议显式指定参数名:
vnn.fit(feature_vec, output_prob_matrix, batch_size=32, epochs=100)
可选优化:提升LSTM特征表达能力
当前LSTM最后只输出1维特征,可能不足以支撑复杂的文本转换任务。可以考虑去掉LSTM后的Dense(1),直接用LSTM的输出作为VNN输入,比如:
lstm = Sequential() lstm.add(LSTM(10, input_shape=(1,10))) # 去掉Dense(1),得到(68,10)的特征向量 feature_vec = lstm(lstm_input_sequences) feature_vec = np.array(feature_vec) # 对应修改VNN输入层为shape=(10,) vnn.add(Input(shape=(10,)))
这样能保留更多LSTM学到的序列特征,提升模型性能。
内容的提问来源于stack exchange,提问作者abzd
相关产品推荐
相关产品推荐

