python - 使用 Pytorch LSTM 模块时尺寸不匹配
问题描述
我有一个 pytorch 预训练模型,我从中为一些输入句子生成特征/嵌入。特征本质上是torch
对象。例如input_embedding
,一个句子的示例(火炬对象列表)如下所示
[tensor([-0.8264, 0.2524], device='cuda:0', grad_fn=<SelectBackward>)]
现在,我想通过一个自定义模型传递这个嵌入,该模型基本上是一个双向 LSTM:
def custom_model(input_embedding):
#initialize BiLSTM
bilstm = torch.nn.LSTM(input_size=1, hidden_size=1, num_layers=1, batch_first=False, bidirectional=True)
#feed input to bilstm object
bi_output, bi_hidden = bilstm(input_embedding)
# more code ....
return F.softmax(x)
我想将我的传递input_embedding
给这个自定义模型以获得如下预测输出:
for item in input_embedding:
y_pred = biLSTM_single_sentence_student_model(item)
但它bi_output, bi_hidden = bilstm(input_embedding)
在线上抛出错误说:
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
由于我对Pytorch nn.LSTM inputbilstm
缺乏了解,很可能我没有正确定义对象。
请建议。
解决方案
LSTM 基础知识
注意:下面的解释是针对 pytorch 时的batch_first=True
让我们先看看展开的 LSTM 的样子
上图是一个堆叠的单向 LSTM。
- 堆叠的 LSTM 有多个 LSTM 单元相互堆叠。堆叠 LSTM 的数量由层数 (
no:of_layers
) 定义。 - LSTM 单元在输入上随时间展开。展开次数由输入序列的长度决定 (
seq_len
) - 展开的 LSTM 的每个输入都是一定大小的向量(由 定义
input_size
) - 展开的 LSTM 的输出是一个特定大小的向量(由 定义
hidden_size
)。这是使用对输入、最后隐藏状态和当前单元状态的一系列操作来计算的。 - 通常,训练发生在一批数据(前向道具和后向道具)上,而不是一次针对单个输入样本。
定义
所以要使用\定义一个 LSTM,我们需要定义以下信息
- 输入:大小
batch_size x seq_len x input_size
- 输出:大小
batch_size x seq_len x hidden_size
LSTM 定义为提供给展开的 LSTM 单元的向量大小和从展开的 LSTM 单元返回的输出向量大小
lstm = nn.LSTM(2, 5, batch_first=True)
定义一个 LSTM,它接受一个向量或大小为 2(每次展开)并返回一个大小为 5(每次展开)的向量
展开
我们通过给 LSTM 提供一批数据并提供可选的初始隐藏状态和单元状态来计算 LSTM 的输出。
初始隐藏状态:在双向 LSTM 中,一个 LSTM 角色从左到右,另一个从右到左。所以初始隐藏状态的大小为no:of_layers X no:of_directions X hidden_size
。这对于单元状态也是完全相同的。
现在让我们为 a 创建数据,batch_size=32
其中每个输入的序列为 10,向量为 2。
X = torch.randn(32,10,2)
可选的隐藏状态和单元状态
h = torch.randn(1*1, 32, 5)
c = torch.randn(1*1, 32, 5)
最后让我们展开并计算输出
out, hidden = lstm(X, (h,c))
你的问题
在您的情况下,您有一个张量列表,每个张量对应于样本的特征。我们需要将其转换为形状张量,batch_size x seq_len x input_size
其中张量的batch_size
数量seq_len=2
和input_size=1
工作代码
class CustomModel(nn.Module):
def __init__(self):
super(CustomModel, self).__init__()
input_size = 1
hidden_size = 6
target_size = 2
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
self.linear = nn.Linear(hidden_size, target_size)
def forward(self, X):
out, hidden = self.lstm(X)
y_hat = self.linear(hidden[0][0])
y_hat = F.log_softmax(y_hat, dim=1)
return y_hat
data = [torch.randn(2) for i in range(100)]
X = torch.stack(data)
X = X.unsqueeze(-1)
model = CustomModel()
for epoch in range(1):
tag_scores = model(X)
print (tag_scores)
推荐阅读
- r - R/闪亮钻取报告
- javascript - React Admin - 从数组创建表
- angular - Angular中标题案例字段的指令
- javascript - 在sails 中,如何处理数据库中JSON 字段中的“空值”?
- python-3.x - 从 1 到 n 数 9
- java - 错误:java.lang.NumberFormatException:对于输入字符串:servlet 中的“名称”
- ios - SceneKit 覆盖SKScene,某些帧的纹理错误(iOS,Swift)
- javascript - ReactNative Fusioncharts 事件未在 iOS 中触发
- python - 在 groupby 和聚合之后获取最后一个非 NaN 值
- sql - SQL:统计并显示一个scheme下所有表的所有行和列