我们使用相同的神经网络(NN)结构比较权重初始化的不同模式。
全零或全零
如果遵循Occam剃刀的原理,您可能会认为将所有权重设置为0或1是最佳解决方案。 不是这种情况。
在每个权重相同的情况下,每一层的所有神经元都产生相同的输出。 这使得很难决定要调整的权重。
# initialize two NN's with 0 and 1 constant weights
model_0 = Net(constant_weight=0)
model_1 = Net(constant_weight=1)
2个纪元后:
Validation Accuracy
9.625% -- All Zeros
10.050% -- All Ones
Training Loss
2.304 -- All Zeros
1552.281 -- All Ones
统一初始化
均匀分布具有从一组数字中选择任何数字的相等概率。
让我们看看神经网络使用统一权重初始化的训练效果如何,其中y=1/sqrt(n)和high=1.0。
在下面,我们将看到另一种方法(在Net类代码中)以初始化网络的权重。 要在模型定义之外定义权重,我们可以:
定义一个根据网络层类型分配权重的函数,然后
使用y=1/sqrt(n)将这些权重应用于初始化的模型,该模型将一个函数应用于每个模型层。
# takes in a module and applies the specified weight initialization
def weights_init_uniform(m):
classname = m.__class__.__name__
# for every Linear layer in a model..
if classname.find('Linear') != -1:
# apply a uniform distribution to the weights and a bias=0
m.weight.data.uniform_(0.0, 1.0)
m.bias.data.fill_(0)
model_uniform = Net()
model_uniform.apply(weights_init_uniform)
2个纪元后:
Validation Accuracy
36.667% -- Uniform Weights
Training Loss
3.208 -- Uniform Weights
设置权重的一般规则
在神经网络中设置权重的一般规则是将权重设置为接近零而又不会太小。
好的做法是在[-y,y]范围内开始权重,其中y=1/sqrt(n)
(n是给定神经元的输入数量)。
# takes in a module and applies the specified weight initialization
def weights_init_uniform_rule(m):
classname = m.__class__.__name__
# for every Linear layer in a model..
if classname.find('Linear') != -1:
# get the number of the inputs
n = m.in_features
y = 1.0/np.sqrt(n)
m.weight.data.uniform_(-y, y)
m.bias.data.fill_(0)
# create a new model with these weights
model_rule = Net()
model_rule.apply(weights_init_uniform_rule)
下面我们比较一下NN的性能,即使用均匀分布[-0.5,0.5)初始化的权重与使用一般规则初始化权重的权重
2个纪元后:
Validation Accuracy
75.817% -- Centered Weights [-0.5, 0.5)
85.208% -- General Rule [-y, y)
Training Loss
0.705 -- Centered Weights [-0.5, 0.5)
0.469 -- General Rule [-y, y)
正态分布以初始化权重
正态分布的平均值应为0,标准差应为y=1/sqrt(n),其中n是NN的输入数量
## takes in a module and applies the specified weight initialization
def weights_init_normal(m):
'''Takes in a module and initializes all linear layers with weight
values taken from a normal distribution.'''
classname = m.__class__.__name__
# for every Linear layer in a model
if classname.find('Linear') != -1:
y = m.in_features
# m.weight.data shoud be taken from a normal distribution
m.weight.data.normal_(0.0,1/np.sqrt(y))
# m.bias.data should be 0
m.bias.data.fill_(0)
下面我们展示了两个神经网络的性能,一个使用均匀分布初始化,另一个使用正态分布初始化
2个纪元后:
Validation Accuracy
85.775% -- Uniform Rule [-y, y)
84.717% -- Normal Distribution
Training Loss
0.329 -- Uniform Rule [-y, y)
0.443 -- Normal Distribution