0607-引數初始化策略
pytorch完整教程目錄:https://www.cnblogs.com/nickchen121/p/14662511.html
一、引數初始化策略概述
深度學習中,一個好的引數初始化策略可以讓模型更快地收斂,而一個差的引數初始化策略可能會讓模型很難進行收斂,反覆震盪甚至崩潰。
nn.Module
中的引數一般都採取了比較合適的初始化策略,因此一般我們不需要考慮。不過我們也可以自定義一個引數初始化策略代替系統預設的,比如當我們使用 Parameter 時,由於 t.Tensor()
返回的是記憶體中的隨機數,很可能會有極大值,這會時訓練網路時造成溢位或者梯度小時,因此此時自定義一個引數的初始化策略尤為重要。
torch 中的 nn.init
模組專門為初始化設計,實現了一些常用的初始化側路了,而且就算如果某種初始化策略 nn.init
不提供,使用者也可以自己直接初始化。
二、利用 nn.init 初始化
Glorot 正態分佈初始化方法,也稱作 Xavier 正態分佈初始化,引數由 0 均值,標準差為 \(\sqrt{\frac{2}{(fan_{in} + fan_{out}})}\) 的正態分佈產生,其中\(fan_{in}\) 和 \(fan_{out}\) 是分別權值張量的輸入和輸出元素數目。這種初始化同樣是為了保證輸入輸出的方差不變,但是原論文中 [1]
是基於線性函式推導的,同時在 tanh 啟用函式上有很好的效果,但不適用於ReLU啟用函式。
\[std=gain×\sqrt{\frac{2}{fan_{in}+fan_{out}}}
\]
看不懂就別看了,我都沒仔細看,百度 copy 來的。
參考:[1] Understanding the difficulty of training deep feedforward neural networks — Glorot, X. & Bengio, Y. (2010)
import torch as t
from torch import nn
from torch.nn import init
linear = nn.Linear(3, 4)
t.manual_seed(1)
# 等價於 linear.weight.data.normal_(0, std)
init.xavier_normal_(linear.weight) #
Parameter containing:
tensor([[ 0.3535, 0.1427, 0.0330],
[ 0.3321, -0.2416, -0.0888],
[-0.8140, 0.2040, -0.5493],
[-0.3010, -0.4769, -0.0311]], requires_grad=True)
三、直接初始化
import math
t.manual_seed(1)
# xavier初始化的計算公式
std = math.sqrt(2) / math.sqrt(7.)
linear.weight.data.normal_(0, std)
tensor([[ 0.3535, 0.1427, 0.0330],
[ 0.3321, -0.2416, -0.0888],
[-0.8140, 0.2040, -0.5493],
[-0.3010, -0.4769, -0.0311]])
# 對模型的所有引數進行初始化
for name, params in net.named_parameters():
if name.find('linear') != -1: # 對所有全連線層的引數進行初始化
# init linear
params[0] # weight
params[1] # bias
elif name.find('conv') != -1:
pass
elif name.find('norm') != -1:
pass
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-3-78d2673ab1d6> in <module>
1 # 對模型的所有引數進行初始化
----> 2 for name, params in net.named_parameters():
3 if name.find('linear') != -1: # 對所有全連線層的引數進行初始化
4 # init linear
5 params[0] # weight
NameError: name 'net' is not defined