w_times_x = torch.bmm(batch_w_ih, x.unsqueeze(-1)) # [bs, 4*h_size, 1] RuntimeError: Expected batch2_sizes[0] == bs && batch2_sizes[1] == contraction_size to be true, but got false. (Could this error message be improved? If so, please report an enhancement request to PyTorch.)
时间: 2024-03-03 22:52:04 浏览: 22
这个错误通常是因为batch_w_ih和x的形状不兼容导致的。在这种情况下,batch_w_ih和x的维度应该分别为[bs, 4*h_size, h_size]和[bs, h_size],其中bs是批量大小,h_size是隐藏状态的大小。
请确保您的输入张量具有正确的形状。如果batch_w_ih或x的形状不正确,您可以使用以下代码更改它们的形状:
```
batch_w_ih = batch_w_ih.view(bs, 4*h_size, h_size)
x = x.view(bs, h_size)
```
如果您的输入张量已经具有正确的形状,则可能是由于其他代码中的错误导致的。您可以尝试打印batch_w_ih和x的形状,以确定它们是否正确,并查看其他代码是否有问题。
相关问题
以下代码存在无法求导反向传播的bug,请你修改:# 反向LSTM input_backward = torch.flip(input, [0]) outputs_backward = [] for t in range(input_backward.size(0)): x = input_backward[t] i = torch.sigmoid(torch.matmul(x, self.W_i_backward) + torch.matmul(h_backward[-1], self.U_i_backward) + self.b_i_backward) f = torch.sigmoid(torch.matmul(x, self.W_f_backward) + torch.matmul(h_backward[-1], self.U_f_backward) + self.b_f_backward) c_tilde = torch.tanh(torch.matmul(x, self.W_c_backward) + torch.matmul(h_backward[-1], self.U_c_backward) + self.b_c_backward) c_backward[-1] = f * c_backward[-1] + i * c_tilde o = torch.matmul(x, self.W_o_backward) + torch.matmul(h_backward[-1], self.U_o_backward) + self.b_o_backward o = torch.sigmoid(o) h_backward[-1] = o * torch.tanh(c_backward[-1]) outputs_backward.append(h_backward[-1]) outputs_backward = torch.flip(torch.stack(outputs_backward), [0])
这段代码看起来没有明显的无法求导反向传播的 bug,但是如果存在问题的话可能是因为某些操作的输入没有进行 requires_grad=True 的设置。可以尝试添加以下代码,保证所有涉及到反向传播的张量都设置了 requires_grad=True:
```
input_backward.requires_grad_()
self.W_i_backward.requires_grad_()
self.U_i_backward.requires_grad_()
self.b_i_backward.requires_grad_()
self.W_f_backward.requires_grad_()
self.U_f_backward.requires_grad_()
self.b_f_backward.requires_grad_()
self.W_c_backward.requires_grad_()
self.U_c_backward.requires_grad_()
self.b_c_backward.requires_grad_()
self.W_o_backward.requires_grad_()
self.U_o_backward.requires_grad_()
self.b_o_backward.requires_grad_()
```
另外,如果在模型训练时发现该部分无法进行反向传播,可以尝试将该部分的代码放到 `torch.no_grad()` 中,避免该部分的梯度被累加。
```
with torch.no_grad():
input_backward = torch.flip(input, [0])
outputs_backward = []
for t in range(input_backward.size(0)):
x = input_backward[t]
i = torch.sigmoid(torch.matmul(x, self.W_i_backward) + torch.matmul(h_backward[-1], self.U_i_backward) + self.b_i_backward)
f = torch.sigmoid(torch.matmul(x, self.W_f_backward) + torch.matmul(h_backward[-1], self.U_f_backward) + self.b_f_backward)
c_tilde = torch.tanh(torch.matmul(x, self.W_c_backward) + torch.matmul(h_backward[-1], self.U_c_backward) + self.b_c_backward)
c_backward[-1] = f * c_backward[-1] + i * c_tilde
o = torch.matmul(x, self.W_o_backward) + torch.matmul(h_backward[-1], self.U_o_backward) + self.b_o_backward
o = torch.sigmoid(o)
h_backward[-1] = o * torch.tanh(c_backward[-1])
outputs_backward.append(h_backward[-1])
outputs_backward = torch.flip(torch.stack(outputs_backward), [0])
```
以下代码存在不可以自动反向传播的bug,为什么: # 前向LSTM outputs_forward = [] for t in range(input.size(0)): x = input[t] i = torch.sigmoid(torch.matmul(x, self.W_i_forward) + torch.matmul(h_forward[-1], self.U_i_forward) + self.b_i_forward) f = torch.sigmoid(torch.matmul(x, self.W_f_forward) + torch.matmul(h_forward[-1], self.U_f_forward) + self.b_f_forward) c_tilde = torch.tanh(torch.matmul(x, self.W_c_forward) + torch.matmul(h_forward[-1], self.U_c_forward) + self.b_c_forward) c_forward[-1] = f * c_forward[-1] + i * c_tilde o = torch.matmul(x, self.W_o_forward) + torch.matmul(h_forward[-1], self.U_o_forward) + self.b_o_forward o = torch.sigmoid(o) h_forward[-1] = o * torch.tanh(c_forward[-1]) outputs_forward.append(h_forward[-1])
这段代码存在一个不能自动反向传播的bug,原因是在循环中对h_forward和c_forward的值进行了修改。在PyTorch中,只有被标记为requires_grad=True的张量才能够自动求梯度,而对张量进行in-place操作会导致梯度信息丢失,从而无法进行自动求梯度。
具体来说,在这段代码中,对h_forward和c_forward的修改会导致后续的梯度计算出现问题,从而无法进行自动反向传播。解决这个问题的方法是创建一个新的变量来保存h_forward和c_forward的值,而不是直接修改它们的值。修改后的代码如下:
```python
# 前向LSTM
outputs_forward = []
h_forward_new = h_forward.clone()
c_forward_new = c_forward.clone()
for t in range(input.size(0)):
x = input[t]
i = torch.sigmoid(torch.matmul(x, self.W_i_forward) + torch.matmul(h_forward_new[-1], self.U_i_forward) + self.b_i_forward)
f = torch.sigmoid(torch.matmul(x, self.W_f_forward) + torch.matmul(h_forward_new[-1], self.U_f_forward) + self.b_f_forward)
c_tilde = torch.tanh(torch.matmul(x, self.W_c_forward) + torch.matmul(h_forward_new[-1], self.U_c_forward) + self.b_c_forward)
c_forward_new[-1] = f * c_forward_new[-1] + i * c_tilde
o = torch.matmul(x, self.W_o_forward) + torch.matmul(h_forward_new[-1], self.U_o_forward) + self.b_o_forward
o = torch.sigmoid(o)
h_forward_new[-1] = o * torch.tanh(c_forward_new[-1])
outputs_forward.append(h_forward_new[-1])
h_forward_new = torch.cat([h_forward_new[1:], h_forward_new[-1].unsqueeze(0)])
c_forward_new = torch.cat([c_forward_new[1:], c_forward_new[-1].unsqueeze(0)])
h_forward = h_forward_new
c_forward = c_forward_new
```
在修改后的代码中,我们先创建了新的变量h_forward_new和c_forward_new来保存h_forward和c_forward的值,并使用clone()方法复制张量的值。然后,在循环中,我们使用h_forward_new和c_forward_new来进行前向计算,并将计算得到的输出保存到outputs_forward中。最后,我们使用torch.cat()方法来更新h_forward_new和c_forward_new的值,并将其赋值给h_forward和c_forward。这样就可以避免in-place操作导致的梯度丢失问题。