我想在PyTorch中创建nn.Module
。我使用了以下代码来处理文本相关问题(实际上,我使用了Glove
300维预训练嵌入,并使用句子中单词的加权平均值进行分类)。
class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv1d(300, 128, kernel_size=5) self.conv2 = nn.Conv1d(128, 64, kernel_size=2) self.conv2_drop = nn.Dropout() self.fc1 = nn.Linear(64, 20) self.fc2 = nn.Linear(20, 2) def forward(self, x): x = F.relu(F.avg_pool1d(self.conv1(x), 2)) x = F.relu(F.avg_pool1d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(-1, 1) x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) return self.fc2(x)
但这会给我以下错误:
Traceback (most recent call last): x = F.relu(F.avg_pool1d(self.conv1(x), 2)) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/torch/nn/modules/module.py", line 224, in __call__ result = self.forward(*input, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/torch/nn/modules/conv.py", line 154, in forward self.padding, self.dilation, self.groups) File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/torch/nn/functional.py", line 83, in conv1d return f(input, weight, bias)RuntimeError: expected Double tensor (got Float tensor)
我对Conv1d
还不是很熟悉,大多数教程都是用Conv1d
来处理图像问题。有人能给我一些关于问题出在哪里的建议吗?
我还在forward
方法中添加了model.double()
,但这又引发了另一个错误:
RuntimeError: Given input size: (300 x 1 x 1). Calculated output size: (128 x 1 x -3). Output size is too small
回答:
错误1
RuntimeError: expected Double tensor (got Float tensor)
当你将一个双精度张量传递给第一个conv1d
函数时,就会发生这种情况。Conv1d
只能处理浮点张量。你可以做以下两种操作之一:
conv1.double()
,或者model.double()
。
你已经做了这些操作,这是正确的。
错误2
RuntimeError: Given input size: (300 x 1 x 1). Calculated output size: (128 x 1 x -3). Output size is too small
这是因为你传递的输入对于窗口大小为5的卷积来说是无效的。你需要为Conv1d
添加填充来解决这个问题,像这样:
self.conv1 = nn.Conv1d(300, 128, kernel_size=5, padding=2)
如果你不想添加填充,那么给定输入张量的大小为(batch_size, in_channels, inp_size),你必须确保你的inp_size大于5。
所有修复方法的结合
确保你网络的其余部分的大小是正确的,像这样:
class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv1d(300, 128, kernel_size=5, padding=2) self.conv2 = nn.Conv1d(128, 64, kernel_size=2, padding=1) self.conv2_drop = nn.Dropout() self.fc1 = nn.Linear(64, 20) self.fc2 = nn.Linear(20, 2) def forward(self, x): x = F.relu(F.avg_pool1d(self.conv1(x), 2, padding=1)) x = F.relu(F.avg_pool1d(self.conv2_drop(self.conv2(x)), 2)) x = x.view(1, -1) # 额外修复,Linear需要(batch_size, in_features)而不是(in_features, batch_size)作为输入。 x = F.relu(self.fc1(x)) x = F.dropout(x, training=self.training) return self.fc2(x)if __name__ == '__main__': t = Variable(torch.randn((1, 300, 1))).double() # t是一个双精度张量 model = Net() model.double() # 这将确保conv1d能够处理双精度张量 out = model(t)