深度学习初始化
torch.nn.init
作者:elfin
初始化在深度学习模型训练中占有非常重要的位置,好的初始化可以对模型性能有不小的提升。下面将介绍pytorch的一些初始化方法。
1、calculate_gain
torch.nn.init.calculate_gain(nonlinearity, param=None)
见名知意,这个接口是计算增益的!计算什么的增益呢?它计算的是非线性函数的增益。
nonlinearity | gain |
---|---|
Linear / Identity | 1 |
Conv{1,2,3}D | 1 |
Sigmoid | 1 |
Tanh | \(\frac{5}{3}\) |
ReLU | \(\sqrt{2}\) |
Leaky Relu | \(\sqrt{\frac{2}{1 + negative\_slope^2}}\) |
SELU | \(\frac{3}{4}\) |
参数:
- nonlinearity:非线性函数(nn.functional name);
- param:非线性函数的可选参数
案例:
# leaky_relu with negative_slope=0.2
>>> gain = nn.init.calculate_gain('leaky_relu', 0.2)
>>> gain
2、uniform_
torch.nn.init.uniform_(tensor, a=0.0, b=1.0)
均匀分布初始化。需要指定张量对象,均匀分布的起始与终点值。
参数:
- tensor:一个张量实例;
- a:均匀分布的下确界;
- b:均匀分布的上确界。
案例:
>>> w = torch.empty(3, 5)
>>> nn.init.uniform_(w)
3、normal_
torch.nn.init.normal_(tensor, mean=0.0, std=1.0)
默认标准正态分布初始化。
……
4、constant_
torch.nn.init.constant_(tensor, val)
使用val填充tensor.
……
5、ones_
torch.nn.init.ones_(tensor)
使用1填充张量tensor.
……
6、zeros_
torch.nn.init.zeros_(tensor)
使用0填充张量tensor.
……
7、eye_
torch.nn.init.eye_(tensor)
用单位矩阵填充二维输入张量。在线性层中保留输入的标识,在线性层中保留尽可能多的输入。
案例:
>>> w = torch.empty(3, 5)
>>> nn.init.eye_(w)
8、dirac_
torch.nn.init.dirac_(tensor, groups=1)
用狄拉克三角函数填充{3,4,5}维输入张量。在卷积层中保留输入的标识,在卷积层中保留尽可能多的输入通道。在groups>1的情况下,每组通道保持同一性。
参数:
- tensor:一个{3,4,5}维的输入张量;
- groups:卷积层的分组。
案例:
>>> w = torch.empty(3, 16, 5, 5)
>>> nn.init.dirac_(w)
>>> w = torch.empty(3, 24, 5, 5)
>>> nn.init.dirac_(w, 3)
9、xavier_uniform_
torch.nn.init.xavier_uniform_(tensor, gain=1.0)
从xavier均匀分布\(\mathcal{U}(-a, a)\)采样填充张量tensor实现张量的初始化。
其中:
- \(fan\_in\) 为 \(tensor.size(1) \times tensor[0][0].numel()\)
- \(fan\_out\) 为 \(tensor.size(0) \times tensor[0][0].numel()\)
参数:
- tensor:一个torch张量
- gain:可选的缩放因子
案例:
>>> w = torch.empty(3, 5)
>>> nn.init.xavier_uniform_(w, gain=nn.init.calculate_gain('relu'))
10、xavier_normal_
torch.nn.init.xavier_normal_(tensor, gain=1.0)
从xavier正态分布\(\mathcal{N}(0, \text{std}^2)\)采样填充张量tensor实现张量的初始化。
\(fan\_in\) 、\(fan\_out\)同上。参数同上。
案例:
>>> w = torch.empty(3, 5)
>>> nn.init.xavier_normal_(w)
11、kaiming_uniform_🌟
何凯明初始化是xavier初始化的变种,他的初始化方法是非常重要的方法!
torch.nn.init.kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
从kaiming_uniform_均匀分布\(\mathcal{U}(-\text{bound}, \text{bound})\)采样填充张量tensor实现张量的初始化。
参数:
- tensor:一个torch张量
- a:此层之后使用的整流器的负斜率(仅与“leaky_relu”一起使用)
- mode:可选 “fan_in”(默认) 和 “fan_out”。前者保持forward的权值方差一致;后者保持backwards的权值方差一致。
- nonlinearity:非线性函数(nn.functional name),建议仅与“relu”或“leaky_relu”一起使用(默认)。
案例:
>>> w = torch.empty(3, 5)
>>> nn.init.kaiming_uniform_(w, mode='fan_in', nonlinearity='relu')
12、kaiming_normal_🌟
torch.nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
从kaiming_normal_正态分布\(\mathcal{N}(0, \text{std}^2)\)采样填充张量tensor实现张量的初始化。
参数同上。
案例:
>>> w = torch.empty(3, 5)
>>> nn.init.kaiming_normal_(w, mode='fan_out', nonlinearity='relu')
13、orthogonal_
torch.nn.init.orthogonal_(tensor, gain=1)
用一个(半)正交矩阵填充输入张量,如《深层线性神经网络学习非线性动力学精确解》中所述。输入张量必须至少有2个维度,对于超过2个维度的张量,尾部维度将被平铺。
参数:
- tensor:一个大于等于2维的张量
- gain:可选的缩放因子
案例:
>>> w = torch.empty(3, 5)
>>> a = nn.init.orthogonal_(w)
>>> a
tensor([[ 0.8019, -0.0586, -0.3235, -0.3922, 0.3082],
[ 0.1892, 0.0526, 0.0613, 0.7863, 0.5826],
[-0.5395, -0.3481, -0.4893, -0.2158, 0.5493]])
>>> b = a[1,:]*a[2,:]
>>> b.numpy().sum()
8.940697e-08
>>> c = a[:,0]*a[:,1]
>>> c.numpy().sum()
0.1507516
通过上面的操作我们可以发现行向量两两正交!
14、sparse_
torch.nn.init.sparse_(tensor, sparsity, std=0.01)
将2D 输入张量作为稀疏矩阵进行填充,其中非零元素将从正态分布\(\mathcal{N}(0, 0.01)\)中抽取。实际是先使用正态分布初始化,在按照sparsity乘以行数获取零元素的个数,在到初始化的张量中随机采样索引将张量对应位置置零。
参数:
- tensor:2D torch张量
- sparsity:每列中要设置为零的元素的分数
- std:用于产生非零值的正态分布的标准差
案例:
>>> w = torch.empty(3, 5)
>>> nn.init.sparse_(w, sparsity=0.1)
tensor([[ 0.0000, -0.0045, 0.0000, 0.0098, 0.0000],
[-0.0174, 0.0000, -0.0116, 0.0118, -0.0096],
[ 0.0005, 0.0060, -0.0041, 0.0000, -0.0107]])
完!