一、nn.Embedding.weight初始化分布
nn.Embedding.weight隨機初始化方式是標准正態分布
,即均值$\mu=0$,方差$\sigma=1$的正態分布。
論據1——查看源代碼
## class Embedding具體實現(在此只展示部分代碼) import torch from torch.nn.parameter import Parameter from .module import Module from .. import functional as F class Embedding(Module): def __init__(self, num_embeddings, embedding_dim, padding_idx=None, max_norm=None, norm_type=2, scale_grad_by_freq=False, sparse=False, _weight=None): if _weight is None: self.weight = Parameter(torch.Tensor(num_embeddings, embedding_dim)) self.reset_parameters() else: assert list(_weight.shape) == [num_embeddings, embedding_dim], \ 'Shape of weight does not match num_embeddings and embedding_dim' self.weight = Parameter(_weight) def reset_parameters(self): self.weight.data.normal_(0, 1) if self.padding_idx is not None: self.weight.data[self.padding_idx].fill_(0)
Embedding這個類有個屬性weight,它是torch.nn.parameter.Parameter類型的,作用就是存儲真正的word embeddings。如果不給weight賦值,Embedding類會自動給他初始化,看上述代碼第6~8行,如果屬性weight沒有手動賦值,則會定義一個torch.nn.parameter.Parameter對象,然后對該對象進行reset_parameters(),看第21行,對self.weight先轉為Tensor在對其進行normal_(0, 1)(調整為$N(0, 1)$正態分布)。所以nn.Embeddig.weight默認初始化方式就是N(0, 1)分布,即均值$\mu=0$,方差$\sigma=1$的標准正態分布。
論據2——簡單驗證nn.Embeddig.weight的分布
下面將做的是驗證nn.Embeddig.weight某一行詞向量的均值和方差,以便驗證是否為標准正態分布。
注意:驗證一行數字的均值為0,方差為1,顯然不能說明該分布就是標准正態分布,只能是其必要條件,而不是充分條件,要想真正檢測這行數字是不是正態分布,在概率論上有專門的較為復雜的方法,請查看概率論之假設檢驗。
import torch.nn as nn # dim越大,均值、方差越接近0和1 dim = 800000 # 定義了一個(5, dim)的二維embdding # 對於NLP來說,相當於是5個詞,每個詞的詞向量維數是dim # 每個詞向量初始化為正態分布 N(0,1)(待驗證) embd = nn.Embedding(5, dim) # type(embd.weight) is Parameter # type(embd.weight.data) is Tensor # embd.weight.data[0]是指(5, dim)的word embeddings中取第1個詞的詞向量,是dim維行向量 weight = embd.weight.data[0].numpy() print("weight: {}".format(weight)) weight_sum = 0 for w in weight: weight_sum += w mean = weight_sum / dim print("均值: {}".format(mean)) square_sum = 0 for w in weight: square_sum += (mean - w) ** 2 print("方差: {}".format(square_sum / dim))
代碼輸出:
weight: [-0.65507996 0.11627434 -1.6705967 ... 0.78397447 ... -0.13477565]
均值: 0.0006973597864689242
方差: 1.0019535550544454
可見,均值接近0,方差接近1,從這里也可以反映出nn.Embeddig.weight是標准正態分布$N(0, 1)$。
二、torch.Tensor、torch.tensor、torch.randn初始化分布
1、torch.rand
返回$[0,1)$上的均勻分布(uniform distribution)。
2、torch.randn
返回$N(0, 1)$,即標准正態分布(standard normal distribution)。
3、torch.Tensor
torch.Tensor是Tensor class,torch.Tensor(2, 3)是調用Tensor的構造函數,構造了$2\times3$矩陣,但是沒有分配空間,未初始化。
不推薦使用torch.Tensor創建Tensor,應使用torch.tenstor、torch.ones、torch.zeros、torch.rand、torch.randn等,原因:
t = torch.Tensor(2,3)
# 容易出現下述錯誤,因為t中的值取決當前內存中的隨機值
# 如果當前內存中隨機值特別大會溢出
RuntimeError: Overflow when unpacking long
