1. 激活函数的多种形式
- 在pytorch中,每个激活函数都有两种形式,类形式和函数形式。
- 类形式在torch.nn模块中定义。在使用时,需要先对其实例化才能应用。
- 函数形式在torch.nn.functional模块中定义。在使用时,可以直接以函数调用的方式进行。
- 以激活函数tanh为例,定义激活函数:
- 以类形式使用,在模型类的init()方法中,定义激活函数
# 对tanh类进行实例化
self.tanh = torch.nn.tanh()
接着便可以在模型类的forward()方法中,添加激活函数的应用
# 应用tanh类的实例化对象
output = self.tanh(input)
- 以类的形式直接使用:还可以将1中的操作统一在模型类中的forward()方法中完成。
output = torch.nn.tanh()(input)
- 以函数的形式使用
在模型类的forward()方法中,直接调用激活函数的方式。
output = torch.nn.functional.tanh(input)
在以函数的形式使用激活函数时,该激活函数不会驻留在模型类的内存里,会与其他的pytorch库函数一样,在全局内存中被调用。
在torch.nn.functional中激活函数的命名都是小写形式。
2. Swish函数
- 好的激活函数可以对特征数据的激活更加精准,能够提高模型的精度。
- 目前,业界公认好的激活函数为Swish和Mish。
- 在保持结构不变的基础上,直接将模型中的其他激活函数换成Swish或Mish激活函数,都会使模型的精度有所提升。
import numpy as np
import matplotlib.pyplot as plt
# 定义Swish函数
def swish(x, beta=1.0):
return x * (1.0 / (1.0 + np.exp(-beta*x)))
# 定义Mish函数
def mish(x):
return x * np.tanh(np.log(1 + np.exp(x)))
x = np.linspace(-5, 5, 100)
y_swish = swish(x)
y_mish = mish(x)
plt.plot(x, y_swish, label='Swish')
plt.plot(x, y_mish, label='Mish')
plt.title('Swish VS Mish Activation Functions')
plt.xlabel('x')
plt.ylabel('Activation Function Output')
plt.legend()
plt.grid(True)
plt.show()
运行结果:
- 二者的曲线非常的相似,如上所示Mish比Swish更胜一筹。
- Swish是谷歌公司发现一个效果更优于ReLU的激活函数。
- 在测试中,保持所有的模型参数参数不变,只是把原来模型中的ReLU激活函数修改为Swish激活函数,模型的准确率均由提升。公式如下所示:
f(x) = xSigmoid(βx)
- 其中β为x的缩放参数,一般情况下默认值1即可。
- 在使用了批量归一化算法的情况下,还需要对x的缩放值β进行调节。
- 在实际应用中,β参数可以是常数,由手动调节,也可以是可训练的参数,由神经网络自己学习。
3. Mish激活函数
- Mish激活函数从Swish中获得"灵感",也是用输入变量与其非线性变化后的激活函数相乘。
- 其中,将非线性变化部分的缩放参数β用Softplus激活函数来代替,使其无须输入任何标量就可以更改网络参数,其公式为:
f(x) = x tanh(Softplus(x))
- 将Softplus的公式代入,也可以把上式写为
f(x) = x tanh(In(1+ex))
- 相比Swish,Mish激活函数没有了参数,使用起来更方便。
import torch
import torch.nn as nn
import torch.nn.functional as F
# Swish激活函数
def swish(x, beta=1):
return x * torch.nn.Sigmoid()(x*beta)
# Mish激活函数
def mish(x):
return x * (torch.tanh(F.softplus))
class Mish(nn.Module):
def __init__(self):
super().__init__()
def forward(self, x):
return x * (torch.tanh(F.softplus))
4.激活函数的总结
- 在神经网络中,运算特征不断进行循环计算,因此,在每次循环过程中,每个神经元的值也是在不断变化的,特征间的差距会再循环过程中被不断地方法,当输入数据本身差别较大时,用tanh会好一点。
- 当输入数据本身差别不大时,用Sigmoid效果就会更好一些。
- 而后来出现的ReLU激活函数,主要优势是能够生成稀疏性更好的特征数据,即将数据转化为只有最大数值,其他都为0的特征。
- 这种变换可以更好地突出输入特征,用大多数元素为0的稀疏矩阵来实现。
- Swish激活函数和Mish激活函数是ReLU基础上进一步优化产生的,在深层神经网络中效果更加明显。
- Mish激活函数会比Swish激活函数还要好一些。
5. 训练模型的步骤与方法
- 将样本数据输入模型算出正向的结果。
- 计算模型结果与样本的目标标签之间的差距(也称为损失值,即loss)
- 根据损失值,使用链式反向求导,依次计算模型中每个参数(即权重)的梯度。
- 使用优化器中的策略对模型中的参数进行更新。