训练LSTM编解码器德英翻译模型时提示无法将y转为张量如何排查
错误原因分析
- 核心触发逻辑:你使用了
@tf.function装饰器将损失函数转为静态图计算,静态图要求所有计算节点的输入输出都必须是合法张量,不能出现None值,而你的代码存在多处未定义/非法变量,导致计算链路中生成了None值,触发转换失败报错。 - 具体错误点:
loss_fn中梯度计算的参数variables未定义,直接导致tape.gradient返回None,后续要把这个返回值转为张量时直接报错。- Encoder定义中存在未定义的
layer变量,h= layer(input_layer)这行代码的输出为None,后续Encoder的输出均为非法值。 - 测试循环中调用Encoder时使用了未定义的
en变量,正确的输入应该是当前循环的english2,导致Encoder输出为None。 - 测试循环中调用
loss_fn时只传入了3个参数,而函数定义要求4个参数(缺少loss参数),返回值非法。 - 存在多处拼写错误:训练环节的
avg_loss1未定义、ave_loss3拼写错误;测试环节batch_num2没有累加、ave_loss4拼写错误,这些都会导致计算过程中出现非法值。
解决方案
你可以按照以下顺序依次修复代码:
- 修复Encoder定义:删除未定义的layer调用行,调整后Encoder代码如下:
def encoder(): input_layer = Input(batch_shape=(None, 13, 128)) h= Masking(mask_value=0.0)(input_layer) h, hidden_layer, cell_layer = LSTM(512, return_state=True)(h) model = Model(inputs = input_layer, outputs = [hidden_layer, cell_layer]) return model
- 修复loss_fn的梯度参数:把梯度计算的参数替换为已定义的可训练变量集合:
@tf.function def loss_fn(en_input, germ_input, germ_output, loss): with tf.GradientTape() as tape: enc_hidden_s, enc_cell_s = model(en_input) dec_output, dec_hidden_s, dec_cell_s = decoder(germ_input, enc_hidden_s,enc_cell_s) loss_value = loss(germ_output, dec_output) # 把未定义的variables替换为实际的可训练参数 grads = tape.gradient(loss_value, model.trainable_variables + decoder.trainable_variables) return loss_value, grads
- 修复测试循环的逻辑错误:
for english2,germany2 in test: germany_in2,germany_out2=fit_german_shape(germany2) # 替换未定义的en为当前循环的english2 hidden_state,cell_state=model(english2) pred,temp1,temp2=decoder(germany_in2,hidden_state,cell_state) # 补全loss_fn的第四个参数 loss_val, temp3 = loss_fn(english2, germany_in2, germany_out2, loss) epoch_loss2=loss_val+epoch_loss2 # 累加测试集的batch计数 batch_num2=batch_num2+1 avg_loss2=epoch_loss2/batch_num2 # 张量先转numpy再转字符串,修正拼写错误 avg_loss4=str(avg_loss2.numpy()) print("In this test epoch, the loss is"+avg_loss4)
- 修复训练循环的拼写错误:
for english,germany in train: germany_in,germany_out=fit_german_shape(germany) loss2, grad= loss_fn(english, germany_in, germany_out, loss) optimizer.apply_gradients(zip(grad,model.trainable_variables + decoder.trainable_variables)) epoch_loss=epoch_loss+loss2 batch_num=batch_num+1 avg_loss=epoch_loss/batch_num # 替换未定义的avg_loss1,修正拼写和类型转换逻辑 avg_loss3=str(avg_loss.numpy()) print("In this train epoch, the loss is"+avg_loss3)
内容的提问来源于stack exchange,提问作者jqqqq
相关产品推荐
相关产品推荐

