我在Pytorch中寻找一个可以扩展的LSTM单元的实现,我在接受的答案here中找到了它的实现。我会把它贴在这里,因为我想参考一下。有相当多的实施细节,我不明白,我想知道是否有人可以澄清
import math
import torch as th
import torch.nn as nn
class LSTM(nn.Module):
def __init__(self, input_size, hidden_size, bias=True):
super(LSTM, self).__init__()
self.input_size = input_size
self.hidden_size = hidden_size
self.bias = bias
self.i2h = nn.Linear(input_size, 4 * hidden_size, bias=bias)
self.h2h = nn.Linear(hidden_size, 4 * hidden_size, bias=bias)
self.reset_parameters()
def reset_parameters(self):
std = 1.0 / math.sqrt(self.hidden_size)
for w in self.parameters():
w.data.uniform_(-std, std)
def forward(self, x, hidden):
h, c = hidden
h = h.view(h.size(1), -1)
c = c.view(c.size(1), -1)
x = x.view(x.size(1), -1)
# Linear mappings
preact = self.i2h(x) + self.h2h(h)
# activations
gates = preact[:, :3 * self.hidden_size].sigmoid()
g_t = preact[:, 3 * self.hidden_size:].tanh()
i_t = gates[:, :self.hidden_size]
f_t = gates[:, self.hidden_size:2 * self.hidden_size]
o_t = gates[:, -self.hidden_size:]
c_t = th.mul(c, f_t) + th.mul(i_t, g_t)
h_t = th.mul(o_t, c_t.tanh())
h_t = h_t.view(1, h_t.size(0), -1)
c_t = c_t.view(1, c_t.size(0), -1)
return h_t, (h_t, c_t)
1-为什么将self.i2h和self.h2h的隐藏大小都乘以4(在init
方法中)
2-我不了解参数的重置方法。特别是,为什么我们要以这种方式重置参数
3-为什么在正向方法中对h、c和x使用view
4-我还对forward方法的activations
部分中的列边界感到困惑。例如,为什么我们要用3*self.hidden_大小作为gates
的上界
在您包含的方程式中,输入x和隐藏状态h用于四个计算,其中每个计算都是矩阵与权重的乘积。无论您是执行四次矩阵乘法,还是将权重串联,然后执行一次更大的矩阵乘法,然后分离结果,都会得到相同的结果
通过将线性层的输出大小设置为4*隐藏大小,有四个大小隐藏大小的权重,因此只需要一个层而不是四个层。这样做并没有什么好处,除了可能会有轻微的性能改进,主要是针对较小的输入,如果单独进行,则不会完全耗尽并行功能
在这里,输出被分离,以对应于四个单独计算的输出。输出是
[i_t; f_t; o_t; g_t]
的串联(分别不包括tanh和sigmoid)通过使用^{} 将输出分成四个块,可以获得相同的分隔:
但是在分离之后,您必须将
torch.sigmoid
应用于i_t
,f_t
和o_t
,以及torch.tanh
应用于g_t
参数W是线性层
self.i2h
中的权重和线性层self.h2h
中的U中的权重,但是是串联的根据最后的} 实现
h_t = h_t.view(1, h_t.size(0), -1)
,隐藏状态的大小为[1,批处理大小,隐藏大小]。用h = h.view(h.size(1), -1)
去掉第一个单数维,得到size[batch\u size,hidden\u size]。同样可以通过^{参数初始化会对模型的学习能力产生很大影响。初始化的一般规则是使值接近零而不太小。常用的初始化方法是从均值为0且方差为1/n的正态分布中提取,其中n是神经元的数量,这反过来意味着1/sqrt(n)的标准偏差
在这种情况下,它使用均匀分布而不是正态分布,但总体思路类似。根据神经元数量确定最小/最大值,但避免使其太小。如果最小/最大值为1/n,则值会变得非常小,因此使用1/sqrt(n)更合适,例如256个神经元:1/256=0.0039,而1/sqrt(256)=0.0625
Initializing neural networks通过交互式可视化提供了不同初始化的一些解释
相关问题 更多 >
编程相关推荐