我最近开始在 PyTorch 中探索 LSTM,但在尝试定义 LSTM 的输出大小时,我不太明白使用
hidden_size
和 proj_size
之间的区别?
对于上下文,我的输入大小为 5,序列长度为 30,并且希望输出大小为 2,两个输出的序列长度均为 30。我应该将
hidden_size
设置为 2 还是使用 proj_size=2
更好,以便我可以调整 hidden_size
超参数?
来自文档
单向 LSTM 模型提供三个输出:
output
,主要输出,尺寸(L, N, H_out)
h_n
,隐藏状态,大小(num_layers, N, H_out)
c_n
,细胞状态,大小(num_layers, N, H_cell)
proj_size
参数会更改模型的 H_out
。如果proj_size>0
,则H_out=proj_size
,否则H_out=hidden_size
。 proj_size
还会改变隐藏状态权重的维度,W_hi
。
此功能是由文档中链接的paper激发的。
论文发现,使用较小的隐藏尺寸和投影来匹配单元尺寸可以提供更好的参数调整性能。
显示差异:
# without projection
lstm_kwargs = {
'input_size' : 64,
'hidden_size' : 512,
'num_layers' : 3,
'batch_first' : True
}
lstm1 = nn.LSTM(**lstm_kwargs)
[(k, v.shape) for k,v in lstm1.state_dict().items()]
> [('weight_ih_l0', torch.Size([2048, 64])),
('weight_hh_l0', torch.Size([2048, 512])),
('bias_ih_l0', torch.Size([2048])),
('bias_hh_l0', torch.Size([2048])),
('weight_ih_l1', torch.Size([2048, 512])),
('weight_hh_l1', torch.Size([2048, 512])),
('bias_ih_l1', torch.Size([2048])),
('bias_hh_l1', torch.Size([2048])),
('weight_ih_l2', torch.Size([2048, 512])),
('weight_hh_l2', torch.Size([2048, 512])),
('bias_ih_l2', torch.Size([2048])),
('bias_hh_l2', torch.Size([2048]))]
x = torch.randn(8, 12, 64)
x1, (h1, c1) = lstm1(x)
x1.shape
> torch.Size([8, 12, 512])
h1.shape
> torch.Size([3, 8, 512])
c1.shape
> torch.Size([3, 8, 512])
# with projection
lstm_kwargs = {
'input_size' : 64,
'hidden_size' : 512,
'num_layers' : 3,
'batch_first' : True
}
lstm2 = nn.LSTM(proj_size=256, **lstm_kwargs)
[(k, v.shape) for k,v in lstm2.state_dict().items()]
> [('weight_ih_l0', torch.Size([2048, 64])),
('weight_hh_l0', torch.Size([2048, 256])),
('bias_ih_l0', torch.Size([2048])),
('bias_hh_l0', torch.Size([2048])),
('weight_hr_l0', torch.Size([256, 512])),
('weight_ih_l1', torch.Size([2048, 256])),
('weight_hh_l1', torch.Size([2048, 256])),
('bias_ih_l1', torch.Size([2048])),
('bias_hh_l1', torch.Size([2048])),
('weight_hr_l1', torch.Size([256, 512])),
('weight_ih_l2', torch.Size([2048, 256])),
('weight_hh_l2', torch.Size([2048, 256])),
('bias_ih_l2', torch.Size([2048])),
('bias_hh_l2', torch.Size([2048])),
('weight_hr_l2', torch.Size([256, 512]))]
x = torch.randn(8, 12, 64)
x1, (h1, c1) = lstm1(x)
x1.shape
> torch.Size([8, 12, 256])
h1.shape
> torch.Size([3, 8, 256])
c1.shape
> torch.Size([3, 8, 512])
请注意,通过投影,我们为投影提供了额外的权重矩阵,并且输出/隐藏大小发生了变化。细胞大小不是。
对于关于输出大小的问题,通常您会在 LSTM 之上使用另一层来预测确切的输出。