[Daily]torch里的一些初始化

虽然少壮不努力但是老大还是要亡(精)羊(卫)补(填)牢(海)

torch.nn.init里的一些对tensor的初始化

均匀分布

nn.init.uniform_(tensor, a=0, b=1)

X\sim U[a, b]

用均匀分布生成值来填充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.)

X\sim N(mean, std)

用给定均值(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)

X\sim\psi (mean, std,a ,b)

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函数来举例,并不能让我愚蠢的大脑大彻大悟。)

所以各种公式推导以后,就可以从输入的神经元的个数来得到初始化权重的方差。具体公式如下

std = gain *\sqrt{\frac{2}{in + out}}

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')

具体方差计算公式如下

std=\frac{gain * \sqrt{3}}{\sqrt{in / out}}

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]])

你可能感兴趣的:(Daliy,pytorch,深度学习)