我们在之前介绍了sigmoid激活函数,但是它现在不常用了,因为他就是导致梯度消失的一个常见的情况。现在我们来看看sigmoid的梯度情况
%matplotlib inline
import torch
import matplotlib.pyplot as plt
from torch import nn
x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
y = torch.sigmoid(x)
y.backward(torch.ones_like(x))
plt.plot(x.detach().numpy(), y.detach().numpy(),'--',label='sigmoid')
plt.plot(x.detach().numpy(), x.grad.numpy(),'r--',label='gradient')
plt.legend(loc = 'best')
plt.grid(True)
可以看出,当sigmoid函数的输入很大或是很小时,它的梯度都会消失。 此外,当反向传播通过许多层时, 这些地方sigmoid函数的输入接近于零,可能导致整个乘积的梯度可能会消失。因此,ReLU激活函数成为了大家默认的选择
同样的,梯度爆炸也是一个非常严重的问题,它会让导致梯度下降很难收敛。下面我们举一个简单的例子,来看看梯度爆炸的情况,我们定义一个4×4的随机矩阵,满足标准正态分布,观察乘以50次之后的结果
M = torch.normal(0, 1, size=(4,4))
print('一个矩阵 \n',M)
for i in range(50):
M = torch.mm(M,torch.normal(0, 1, size=(4, 4)))
print('乘以50个矩阵后\n', M)
一个矩阵
tensor([[ 1.2106, -1.2478, 0.9032, 0.1750],
[-0.4060, 0.7475, -2.2134, -2.1323],
[-1.0121, 0.1883, 1.7743, -0.6649],
[ 0.1302, 0.2794, 0.0039, -0.2880]])
乘以50个矩阵后
tensor([[-6.4536e+12, 2.9500e+11, -3.1643e+12, 3.2686e+12],
[ 4.9242e+12, -2.2509e+11, 2.4144e+12, -2.4940e+12],
[-1.8533e+12, 8.4715e+10, -9.0872e+11, 9.3866e+11],
[-6.2537e+11, 2.8586e+10, -3.0663e+11, 3.1674e+11]])
"""定义一个神经网络"""
net = nn.Sequential(nn.Linear(4, 8), nn.ReLU(), nn.Linear(8, 1))
"""正态分布初始化"""
def norm(m):
if type(m) == nn.Linear:#对线性层进行初始化权重
nn.init.normal_(m.weight, mean=0, std=0.01)#正态分布初始化
"""Xavier初始化"""
def Xavier(m):
if type(m) == nn.Linear:
nn.init.xavier_uniform_(n.weight)#Xavier初始化
net[0].apply(norm)#对第一个线性层进行正态初始化
print(net[0].weight)
net[2].apply(Xavier)#对第二个线性层进行Xavier初始化
print(net[2].weight)
Parameter containing:
tensor([[ 2.6455e-03, -9.4835e-03, -2.3148e-03, 7.3588e-03],
[ 8.4367e-03, -6.8525e-03, 4.5711e-03, 6.6946e-04],
[-1.7318e-03, -2.4081e-03, -5.8394e-03, 4.2219e-03],
[-8.6585e-03, 1.5090e-02, 1.2062e-02, 4.7167e-03],
[ 8.8256e-03, -7.8020e-05, -1.7378e-03, -2.5176e-02],
[-1.1565e-02, 1.7698e-03, -1.8693e-02, 8.1501e-05],
[-1.3891e-02, -6.1892e-03, -4.7369e-03, 9.8099e-03],
[ 3.5225e-04, 4.4494e-03, -2.1365e-03, 4.0189e-03]],
requires_grad=True)
Parameter containing:
tensor([[ 0.1272, 0.1947, -0.1398, -0.0676, 0.1016, -0.2671, -0.1270, -0.3072]],
requires_grad=True)
阅读量:918
点赞量:0
收藏量:0