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

gil*_*des 9 python pytorch

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

例如,您有一个嵌入层:

self.in_embed = nn.Embedding(n_vocab, n_embed)
Run Code Online (Sandbox Code Playgroud)

并且您想用均匀分布初始化其权重。您可以完成此操作的第一种方法是:

self.in_embed.weight.data.uniform_(-1, 1)
Run Code Online (Sandbox Code Playgroud)

另一个是:

nn.init.uniform_(self.in_embed.weight, -1.0, 1.0)
Run Code Online (Sandbox Code Playgroud)

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

muj*_*iga 9

两者都一样

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
Run Code Online (Sandbox Code Playgroud)

每个张量都有一个uniform_方法,可以使用均匀分布中的值对其进行初始化。此外,该nn.init模块有一个方法uniform_,它接受一个张量并使用均匀分布的值对其进行初始化。两者都是一样的,第一个是使用成员函数,第二个是使用通用实用程序。


Szy*_*zke 5

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

一般来说,我更倾向于第二种选择,因为:

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

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

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

小题外话:说实话,我认为torch.nn.init应该可以在层本身上调用,因为它将有助于torch.nn.Sequential使用简单的model.apply(torch.nn.init.xavier_uniform_). 此外,为其初始化biasTensor(或使用适当的参数)可能也是有益的,但事实就是如此。