我有一个自定义的双向LSTM模型,其中自定义的部分是
- 提取前向和后向的最后隐藏状态- 连接这些状态- 创建一个全连接层并通过softmax层处理。
代码如下所示:
class customModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers, num_classes): super(customModel, self).__init__() self.hidden_size = hidden_size self.num_layers = num_layers self.bilstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=False, bidirectional=True) self.fcl = nn.Linear(hidden_size, num_classes) def forward(self, x): # 设置初始隐藏状态和细胞状态 h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device) c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device) # 前向传播LSTM out, hidden = self.bilstm(x, (h0, c0)) # out: 张量的形状为 (batch_size, seq_length, hidden_size) # 连接前向和后向的隐藏状态 fw_bilstm = out[-1, :, :self.hidden_size] bk_bilstm = out[0, :, :self.hidden_size] concat_fw_bw = torch.cat((fw_bilstm, bk_bilstm), dim = 1) fc = nn.Linear(concat_fw_bw, num_classes) x = F.relu(fc(x)) return F.softmax(x)
我使用以下参数和输入
input_size = 2hidden_size = 32 num_layers = 1num_classes = 2input_embedding = [ torch.FloatTensor([[-0.8264], [0.2524]]), torch.FloatTensor([[-0.3259], [0.3564]])]
然后我创建一个模型对象
model = customModel(input_size, hidden_size, num_layers, num_classes)
然后我像下面这样使用它:
for item in input_embedding: print(item.size()) for epoch in range(1): pred = model(item) print (pred)
当我运行它时,我看到这一行 out, hidden = self.bilstm(x, (h0, c0))
显示错误
RuntimeError: input must have 3 dimensions, got 2
我不确定为什么模型认为输入必须有3个维度,当我明确指定 input_size=2
我错过了什么?
回答:
你的输入似乎缺少(批次或序列)维度。
nn.LSTM
和 nn.LSTMCell
之间存在差异。你使用的是前者,它接受整个序列作为输入。因此,它需要形状为 (seq_len, batch, input_size) 的3维输入。
假设你想以批次形式输入4个字母序列(你编码为独热向量):
x0 = [a,b,c]x1 = [c,d,e]x2 = [e,f,g]x3 = [h,i,j]### input.size() 应该给你以下结果:(3,4,8)
seq_len
参数是序列的大小:这里是3,input_size
参数是每个输入向量的大小:这里,输入将是大小为8的独热向量,batch
是你放一起的序列数量:这里有4个序列。
注意:通过将批次序列放在第一位并将 batch_first
设置为 True,可能会更容易理解
另外:如果未提供 (h_0, c_0),则 h_0 和 c_0 默认为零,因此创建它们没有用处。