虽然少壮不努力但是老大还是要亡(精)羊(卫)补(填)牢(海)
torch.nn.init里的一些对tensor的初始化
均匀分布
nn.init.uniform_(tensor, a=0, b=1)
用均匀分布生成值来填充tensor
t1 = torch.zeros(2, 2)
print(t1)
t2 = nn.init.uniform_(t1)
print(t2)
>>> tensor([[0., 0.],
>>> [0., 0.]])
>>> tensor([[0.0174, 0.9981],
>>> [0.7287, 0.9384]])
正态分布
nn.init.normal_(tensor, mean=0., std=1.)
用给定均值(mean)和标准差(std)的正态分布中的值来填充tensor
t1 = torch.zeros(2, 2)
print(t1)
t2 = nn.init.normal_(t1)
print(t2)
>>> tensor([[0., 0.],
>>> [0., 0.]])
>>> tensor([[-0.0445, -0.9591],
>>> [ 0.9115, 0.7865]])
截断正态分布(详情点击链接自行了解
nn.init.trunc_normal_(tensor, mean=0.0, std=1.0, a=-2.0, b=2.0)
t1 = torch.zeros(2, 2)
print(t1)
t2 = nn.init.trunc_normal_(t1, 0, 2, -1, 1)
print(t2)
>>> tensor([[0., 0.],
>>> [0., 0.]])
>>> tensor([[ 0.2673, 0.2764],
>>> [ 0.4828, -0.0619]])
常数
nn.init.constant_(tensor, val)
初始化成常数
t1 = torch.zeros(2, 2)
print(t1)
t2 = nn.init.constant_(t1, 233)
print(t2)
>>> tensor([[0., 0.],
>>> [0., 0.]])
>>> tensor([[233., 233.],
>>> [233., 233.]])
1 / 0
nn.init.ones_(tensor)
nn.init.zeros_(tensor)
初始化成常数1 / 0(float)
太简单了不示例了
单位矩阵
nn.init.eye_(tensor)
填充二维tensor为单位矩阵
t1 = torch.zeros(2, 3)
print(t1)
t2 = nn.init.eye_(t1,)
print(t2)
>>> tensor([[0., 0., 0.],
>>> [0., 0., 0.]])
>>> tensor([[1., 0., 0.],
>>> [0., 1., 0.]])
狄拉克函数
nn.init.dirac_(tensor, groups=1)
用 dirac delat function (详情点击链接自行了解)概率密度函数初始化tensor仅限 3,4,5维
t1 = torch.zeros(2, 3, 4)
print(t1)
t2 = nn.init.dirac_(t1)
print(t2)
>>> tensor([[[0., 0., 0., 0.],
>>> [0., 0., 0., 0.],
>>> [0., 0., 0., 0.]],
>>>
>>> [[0., 0., 0., 0.],
>>> [0., 0., 0., 0.],
>>> [0., 0., 0., 0.]]])
>>> tensor([[[0., 0., 1., 0.],
>>> [0., 0., 0., 0.],
>>> [0., 0., 0., 0.]],
>>>
>>> [[0., 0., 0., 0.],
>>> [0., 0., 1., 0.],
>>> [0., 0., 0., 0.]]])
在开始下一part之前
Understanding Xavier Initialization In Deep Neural Networks
看这个的时候甚至花了很久很久去想方差的公式。。
大概就是为什么要使用这种方法,因为初始化权重的太小,那么在每一层的传播过程中输入的方差就会越来越小,输入最终就会变成非常小的值。如果初始化权重过大,每一层传播过程中,方差就会增加的很快,最终他就会变得很大,就变得没什么用。(至于具体为什么我也不李姐,虽然很想李姐,但是找不到资料,找的资料只从一个sigmoid函数来举例,并不能让我愚蠢的大脑大彻大悟。)
所以各种公式推导以后,就可以从输入的神经元的个数来得到初始化权重的方差。具体公式如下
nn.init.xavier_uniform_(tensor, gain=1.)
用xavier计算方法来标准化tensor
t1 = torch.zeros(2, 3)
print(t1)
t2 = nn.init.xavier_normal_(t1)
print(t2)
>>> tensor([[0., 0., 0.],
>>> [0., 0., 0.]])
>>> tensor([[-0.6681, -0.3622, 0.3332],
>>> [ 0.1421, 0.4628, -0.4276]])
再下一part也是。。
需要先看。何凯明发明的初始化方法详解
主要是xavier方法对于tanh表现很好,但对于ReLU表现很差,所以有了hekaiming发明的初始化方法,方法具体原理可以看链接,推导数学公式还是很爽的。pytorch默认的初始化方法就是这个。
nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
具体方差计算公式如下
t1 = torch.zeros(2, 3)
print(t1)
t2 = nn.init.kaiming_normal_(t1)
print(t2)
>>> tensor([[0., 0., 0.],
>>> [0., 0., 0.]])
>>> tensor([[-1.0138, -0.5110, 0.3337],
>>> [-0.1629, 0.5683, 2.1465]])
正交矩阵
nn.init.orthogonal_(tensor, gain=1)
初始化成正交矩阵
t1 = torch.zeros(2, 3)
print(t1)
t2 = nn.init.orthogonal_(t1)
print(t2)
>>> tensor([[0., 0., 0.],
>>> [0., 0., 0.]])
>>> tensor([[ 0.5269, 0.5248, -0.6686],
>>> [ 0.8418, -0.2135, 0.4958]])
稀疏矩阵
(只接受二维tensor)
nn.init.sparse_(tensor, sparsity, std=0.01)
sparsity是每列要设置成零元素的比例
std是生成非零值的正态分布的标准差
t1 = torch.zeros(2, 4)
print(t1)
t2 = nn.init.sparse_(t1, 0.5)
print(t2)
>>> tensor([[0., 0., 0., 0.],
>>> [0., 0., 0., 0.]])
>>> tensor([[-0.0095, 0.0129, 0.0000, 0.0000],
>>> [ 0.0000, 0.0000, -0.0069, -0.0050]])