在Pytorch中初始化嵌入层权重的不同方法

时间:2019-03-21 08:40:50

标签: python pytorch

在Pytorch 1.0中,似乎有两种方法可以使用均匀分布来初始化嵌入层。

例如,您有一个嵌入层:

self.in_embed = nn.Embedding(n_vocab, n_embed)

您想要使用均匀分布来初始化其权重。完成此任务的第一种方法是:

self.in_embed.weight.data.uniform_(-1, 1)

另一个是:

nn.init.uniform_(self.in_embed.weight, -1.0, 1.0)

我的问题是:第一种和第二种初始化形式之间有什么区别。两种方法都做同一件事吗?

2 个答案:

答案 0 :(得分:1)

都是一样的

torch.manual_seed(3)
emb1 = nn.Embedding(5,5)
emb1.weight.data.uniform_(-1, 1)

torch.manual_seed(3)
emb2 = nn.Embedding(5,5)
nn.init.uniform_(emb2.weight, -1.0, 1.0)

assert torch.sum(torch.abs(emb1.weight.data - emb2.weight.data)).numpy() == 0

每个张量都有一个uniform_方法,该方法使用均匀分布中的值对其进行初始化。同样,nn.init模块具有方法uniform_,该方法采用张量并使用来自均匀分布的值对其进行初始化。两者都相同,期望第一个使用成员函数,第二个使用通用工具函数。

答案 1 :(得分:1)

据我所知,这两种形式实际上与@mujjiga答案相同。

通常,我倾向于第二种选择,因为:

  1. 在手动情况下,您必须访问.data属性。

  2. 使用torch.nn.init更明确,更易读(有点主观)

  3. 允许其他人更轻松地修改您的源代码(如果他们将初始化方案更改为xavier_uniform,则只需更改名称)。

有点题外话: TBH,我认为torch.nn.init应该在层本身上是可调用的,因为它将有助于使用简单的torch.nn.Sequential初始化model.apply(torch.nn.init.xavier_uniform_)模型。此外,它也可以为其初始化bias张量(或使用适当的参数),但这可能是有益的。