Sigmoid及tanh
sigmoid及tanh的函数图像较为相似,它们的公式如下
Sigmoid公式
tanh公式
Sigmoid及tanh性质解析
Sigmoid和tanh作为激活函数都可以有效完成非线性映射的功效,其中Sigmoid经常作为2分类的神经网络的输出层的激活函数,由于其非线性映射会将输出值转换到0-1的区间内.
但是Sigmoid和tanh也有一定的缺陷,在值偏离0较多的时候,这两者的导数会越发近似于0,也就会造成梯度连乘后梯度消失的现象
Sigmoid及tanh函数图像及导数绘制
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import torch
import torch.nn.functional as F
if __name__ == '__main__':
device = torch.device('mps' if torch.backends.mps.is_available() else 'cpu')
x = torch.linspace(-20,20,200, requires_grad=True,device=device)
x1 = torch.linspace(-20,20,200, requires_grad=True,device=device)
y = F.sigmoid(x)
y1 = F.tanh(x1)
fig = plt.figure()
axes1 = plt.subplot(221)
axes2 = plt.subplot(223)
axes3 = plt.subplot(222)
axes4 = plt.subplot(224)
axes1.plot(x.cpu().detach(),y.cpu().detach())
axes2.plot(x.cpu().detach(),y1.cpu().detach())
axes1.set_title('sigmoid')
axes2.set_title('tanh')
axes1.set_xlabel('x')
axes1.set_ylabel('y')
axes2.set_xlabel('x')
axes2.set_ylabel('y')
axes1.grid()
axes2.grid()
y.sum().backward()
y1.sum().backward()
axes3.plot(x.cpu().detach(),x.grad.cpu().detach())
axes4.plot(x1.cpu().detach(),x1.grad.cpu().detach())
print(x.grad)
print(x1.grad)
fig.savefig('sig_tanh.png')
plt.show()
可以看到使用matplotlib绘制的时候,由于需要使用张量绘制,有两个注意点
1.可以注意到这里的张量是存储在gpu上的,但是gpu上的张量不支持直接转换为ndarray形式绘制(由于matplotlib底层会默认将参数转换为ndarray进行绘制),所以需要使用.cpu()将张量转换到cpu上
2.在使用plot绘图的时候,需要注意要使用detach()将这里的张量从计算图上切割下来,确保会吐函数不会干扰计算图
ReLU
ReLU公式
ReLU性质解析
可以看到ReLU只是一个简单的max()求最大值函数,效益主要有两个
1.首先,当值大于0的时候,输出值不变,也就是导数为1,由此可加速梯度计算
2.当值小于等于0的时候,输出值会变为0,也就是神经元会失效,一定程度上可以完成类似正则化的效果
ReLU的由来
ReLU 激活函数在 2012 年的 ImageNet Large Scale Visual Recognition Challenge (ILSVRC) 上被 AlexNet 模型成功应用,大幅提高了图像分类的准确率,也标志着卷积神经网络的进步
ReLU函数图像及导数绘制
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import torch
import torch.nn.functional as F
if __name__ == '__main__':
device = torch.device('mps' if torch.backends.mps.is_available() else 'cpu')
x = torch.linspace(-20,20,200, requires_grad=True,device=device)
y = F.relu(x)
y.sum().backward()
fig = plt.figure()
axes1 = plt.subplot(121)
axes2 = plt.subplot(122)
axes1.plot(x.cpu().detach(),y.cpu().detach())
axes1.grid()
axes1.set_title('ReLU')
axes1.set_xlabel('x')
axes1.set_ylabel('y')
axes2.plot(x.cpu().detach(),x.grad.cpu().detach())
axes2.grid()
axes2.set_title('Gradient')
axes2.set_xlabel('x')
axes2.set_ylabel('y')
fig.savefig('relu.png')
plt.show()
Softmax
Softmax公式
Softmax性质分析
Softmax常用于多分类问题的输出层的激活,Softmax的输出结果一般将神经网络最后输出的logits分数,根据Softmax激活后,会转化为和为1的序列,根据为底数为e的指数运算,e^x会将logits值较小的继续缩小,logits较大的继续放大,(由于e^x的性质)
样例
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import torch
import torch.nn.functional as F
if __name__ == '__main__':
device = torch.device('mps' if torch.backends.mps.is_available() else 'cpu')
x = torch.linspace(-20,20,30, requires_grad=True,device=device)
y = F.softmax(x,dim=0)
print(x.detach())
print(y.detach())
print(y.detach().sum())
# tensor([-20.0000, -18.6207, -17.2414, -15.8621, -14.4828, -13.1034, -11.7241,
# -10.3448, -8.9655, -7.5862, -6.2069, -4.8276, -3.4483, -2.0690,
# -0.6897, 0.6897, 2.0690, 3.4483, 4.8276, 6.2069, 7.5862,
# 8.9655, 10.3448, 11.7241, 13.1034, 14.4828, 15.8621, 17.2414,
# 18.6207, 20.0000], device='mps:0')
# tensor([3.1788e-18, 1.2627e-17, 5.0156e-17, 1.9923e-16, 7.9136e-16, 3.1434e-15,
# 1.2486e-14, 4.9597e-14, 1.9701e-13, 7.8254e-13, 3.1084e-12, 1.2347e-11,
# 4.9044e-11, 1.9481e-10, 7.7382e-10, 3.0738e-09, 1.2209e-08, 4.8498e-08,
# 1.9264e-07, 7.6520e-07, 3.0395e-06, 1.2073e-05, 4.7958e-05, 1.9050e-04,
# 7.5668e-04, 3.0056e-03, 1.1939e-02, 4.7423e-02, 1.8837e-01, 7.4825e-01],
# device='mps:0')
# tensor(1., device='mps:0')
可以最后使用经过Softmax激活后的y进行sum()聚合,得到的结果为一,可见非常适用于多分类的概率预测,常配合负对数损失函数进行损失计算.