引數初始化
阿新 • • 發佈:2021-08-02
一、前言
1、深度學習框架提供預設隨機初始化
2、深度學習框架提供了最常用的規則,也允許建立自定義初始化方法
3、預設情況下,Pytorch會根據一個範圍均勻地初始化權重和偏置矩陣,這個範圍是根據輸入和輸出維度計算出來的
二、內建初始化
1、下面程式碼將所有權重引數初始化為標準差為0.01的正態分佈,且將偏置引數設定為0
# 內建的初始化器 # m就是一個module def init_normal(m): if type(m) == nn.Linear: # 給權重賦值-將所有權重引數初始化為標準差為0.01的正態分佈 nn.init.normal_(m.weight, mean=0, std=0.01) # 給偏置賦值-將偏置設為0 nn.init.zeros_(m.bias) # 將net裡面所以層遍歷一遍 net.apply(init_normal) net[0].weight.data[0], net[0].bias.data[0] # 輸出結果 (tensor([-0.0210, -0.0141, -0.0058, 0.0037]), tensor(0.))
2、將所有引數初始化為給定的常數
# 將引數初始化為給定的常數 def init_constant(m): if type(m) == nn.Linear: ''' torch.nn.init.constant_(tensor, val)[source] 用值val填充向量tensor ''' nn.init.constant_(m.weight, 1) nn.init.zeros_(m.bias) net.apply(init_constant) net[0].weight.data[0], net[0].bias.data[0] #輸出結果 (tensor([1., 1., 1., 1.]), tensor(0.))
3、對不同的塊應用不同的初始化方法
# 對不同的塊用不同的初始化方法 def xavier(m): if type(m) == nn.Linear: # 均勻分佈 nn.init.xavier_uniform_(m.weight) def init_42(m): if type(m) == nn.Linear: # 常數賦值 nn.init.constant_(m.weight, 42) net[0].apply(xavier) net[2].apply(init_42) print(net[0].weight.data[0]) print(net[2].weight.data) #輸出結果 tensor([ 0.1352, -0.2794, 0.1592, 0.3462]) tensor([[42., 42., 42., 42., 42., 42., 42., 42.]])
三、自定義初始化
def my_init(m): if type(m) == nn.Linear: print( "Init", *[(name, param.shape) for name, param in m.named_parameters()][0]) # 對權重使用均勻分佈 nn.init.uniform_(m.weight, -10, 10) m.weight.data *= m.weight.data.abs() >= 5 net.apply(my_init) net[0].weight[:2] #輸出結果 Init weight torch.Size([8, 4]) Init weight torch.Size([1, 8]) tensor([[ 0.0000, 5.1760, 0.0000, -7.1530], [ 0.0000, 0.0000, 0.0000, -0.0000]], grad_fn=<SliceBackward>)
我們可以直接設定引數,先直接定位到引數再給其賦值
net[0].weight.data[:] += 1 net[0].weight.data[0, 0] = 42 net[0].weight.data[0] #輸出結果 tensor([42.0000, 6.1760, 1.0000, -6.1530])
四、引數繫結
1、在多個層間共享引數。我們可以定義一個稠密層,然後使用他的引數來設定另一個層的引數
2、列子表明,第二層和第三層是繫結的。他們不僅值相等,而且由相同的張量表示。因此,如果改變其中一個引數,另一個引數也會相應改變
# 在多個層間共享引數 # 我們需要給共享層一個名稱,以便可以引用它的引數。 shared = nn.Linear(8, 8) net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), shared, nn.ReLU(), shared, nn.ReLU(), nn.Linear(8, 1)) net(X) # 檢查引數是否相同 print(net[2].weight.data[0] == net[4].weight.data[0]) # 改變net[2]中的值,net[4]也會改變。說明使用的其實是一個物件 net[2].weight.data[0, 0] = 100 print(net[2].weight.data[0,0]) print(net[4].weight.data[0,0]) # 確保它們實際上是同一個物件,而不只是有相同的值。 print(net[2].weight.data[0] == net[4].weight.data[0]) # 輸出結果 tensor([True, True, True, True, True, True, True, True]) tensor(100.) tensor(100.) tensor([True, True, True, True, True, True, True, True])