Seq2Seq英西翻译模型LSTM解码层RuntimeError问题求助
嘿,我来帮你拆解下这个问题~你遇到的RuntimeError核心是解码层的输入维度不匹配,还有几个细节没处理到位,咱们一步步来解决:
1. 解码层输入维度错误(最关键)
从你的训练日志能看到,y shape: torch.Size([32, 68])是个2D张量,但PyTorch的LSTM(开启batch_first=True时)要求输入必须是3D张量,格式为[batch_size, seq_len, input_size]。
你提到西班牙语单词用单个数字表示,那每个词的特征维度是1,所以需要给y扩展一个维度:
y = y.unsqueeze(-1) # 形状从[32,68]变为[32,68,1]
这样LSTM就能正确识别这是批量输入,不会把它当成“无批量的2D输入”,也就不会触发隐藏状态维度不匹配的错误了。
2. Decoder的input_size参数设置错误
你现在把decoder的input_size设成了68,但68是西班牙语序列的最大长度,不是单个输入词的特征维度!因为西班牙语词是单个数字,所以input_size应该是1,初始化模型时要修正:
# 注意:output_size也错了!它应该是西班牙语的词汇总数,不是序列长度68 model = Seq2SeqModel(input_size=100, hidden_size=256, output_size=西班牙语词汇表大小, num_layers=1)
举个例子,如果你的西班牙语词汇表有1500个词,output_size就设成1500,这样全连接层才能输出对应每个词的概率。
3. 代码里的语法小bug
看你forward函数里的decoder调用行:
decoder_output, _ = self.decoder(y, (hidden, cell)), #self.decoder(y, (hidden.view(1, 32, 256), cell.view(1, 32, 256)))
末尾多了个逗号,这会导致右边变成一个元组,decoder_output会拿到LSTM的完整返回结果(也是元组),后续调用decoder_output.shape肯定会报错,把这个逗号删掉就行。
4. 隐藏状态维度的小优化(可选但规范)
你的encoder输出的hidden和cell形状是[1,32,256],这个是对的(对应num_layers=1, batch_size=32, hidden_size=256)。不过建议把num_layers和hidden_size存成模型属性,避免依赖全局变量:
def __init__(self, input_size, hidden_size, output_size, num_layers): super(Seq2SeqModel, self).__init__() self.num_layers = num_layers self.hidden_size = hidden_size self.encoder = nn.LSTM(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, batch_first=True) self.decoder = nn.LSTM(input_size=1, hidden_size=hidden_size, num_layers=num_layers, batch_first=True) # input_size改为1 self.fc = nn.Linear(in_features=hidden_size, out_features=output_size)
然后在forward里初始化隐藏状态时用self.num_layers和self.hidden_size,这样代码更健壮。
修正后的forward关键部分示例
def forward(self, x, y): print(f"x shape: {x.shape}") # 扩展y的维度 y = y.unsqueeze(-1) print(f"y shape after unsqueeze: {y.shape}") # 应为[32,68,1] print("Set Memories") h_0 = torch.autograd.Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size)) c_0 = torch.autograd.Variable(torch.zeros(self.num_layers, x.size(0), self.hidden_size)) print(f"h: {h_0.shape}") print(f"c: {c_0.shape}") print("Encoder...") _, (hidden, cell) = self.encoder(x, (h_0, c_0)) print("Results:") print(hidden.shape, cell.shape) print("Decoder:") decoder_output, _ = self.decoder(y, (hidden, cell)) # 删掉多余逗号 print("Results: ", decoder_output.shape) # 应为[32,68,256] output = self.fc(decoder_output) return output
这样改完之后,应该就能解决那个RuntimeError,同时也修正了模型初始化的几个关键参数错误~
备注:内容来源于stack exchange,提问作者soosmann

