梯度消失和爆炸:
三层的全连接网络,第二个隐藏层的权值梯度是怎么求取的
loss是不是每层都产生一个loss?然后前后都会有一个传播。会指导前面后面的值。
W2的梯度依赖于上一层的输出。
Class MLP(nn.Module):
def__init__(self , neural_num,layers):
super(MLP, self).__init__()
self.liner = nn.ModuleList([nn.Linear(neural_num, neural_num, bias = False) for i in range(layers)])
self.neural_num = neural_num
init里面用ModuleList和列表生成式和一个for循环来循环构建网络层。
每层的特征的方差(标准差)尽可能相等,否则就尽可能梯度爆炸和消失
每个网络输出层的标准差逐渐变大,超出了计算机的计算能力,所以计算机不能进行下一步处理。
为什么输入输出跟方差相关:
下层的输入是上一层的输出乘该层的权重。举例这句:
H11的值就是x1*w11+x2*w12等等,算方差的时候就是:D(xi)=(x1-x0)+()
输入都是0均值,1标准差。
n*1*1:n是神经元的个数,1是输入的方差,1是权值的方差。如果想要网络层方差保持尺度不变,那就要让这个层的方差等于1。所以每个网络层输出的标准差都是1,权值设置为根号(1/n)
前面这种加完之后,没有考虑到激活函数,加入激活函数之后,标准差会越来越小,这种情况也是不希望看到的。
针对有激活函数进行的权值初始化:
Xavier初始化:
文献:Understanding the difficulty of training deep feedforward neural networks
激活函数:sigmoid和tanh
公式:
Kaiming初始化:
激活函数:ReLU及其变种
公式:
试一个代码:
补充知识:
在初始化当中设置标准差,isinstance函数的用法:isinstance(object, classinfo),检查object是否是classinfo。
if flag:
layer_nums = 100
neural_nums = 256
batch_size = 16
net = MLP(neural_nums, layer_nums)
net.initialize()
def initialize(self):
for m in self.modules():
if isinstance(m, nn.Linear):
nn.init.normal_(m.weight.data, std=)