深度网络的一些常用激活函数,并通过matplot绘制出来:
python
import matplotlib.pyplot as plt
import numpy as np
def relu(x):
return np.maximum(0, x)
def leaky_relu(x, alpha=0.01):
return np.where(x > 0, x, alpha * x)
def gelu(x):
return 0.5 * x * (1 + np.tanh(np.sqrt(2 / np.pi) * (x + 0.044715 * x ** 3)))
def swish(x):
return x / (1 + np.exp(-x))
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_diff(x):
return np.exp(-x) / ((1 + np.exp(-x)) ** 2)
def plot_func():
x = np.linspace(-10, 10, 500)
plt.figure(figsize=(6, 4))
plt.plot(x, gelu(x), label='gelu')
plt.plot(x, relu(x), label='relu')
plt.plot(x, leaky_relu(x), label='leaky_relu', linestyle='--')
plt.plot(x, sigmoid(x), label='sigmoid')
plt.plot(x, swish(x), label='swish')
plt.plot(x, sigmoid_diff(x), label='sigmoid_diff')
plt.plot(x, np.tanh(x), label='tanh', linestyle='--')
plt.axhline(0, color='k', linewidth=0.5)
plt.axvline(0, color='k', linewidth=0.5)
plt.title('all trigger functions')
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.legend()
plt.show()
plot_func()
sigmoid和tanh的缺点是梯度饱和(梯度易消失)。relu则改进了这一点(正半区梯度为1),且很容易计算。leaky_relu和gelu则解决了relu负半区梯度消失的问题,它俩在负半区仍有微小梯度,确保训练可进行下去。gelu还解决了relu函数在原点处的硬转折,使得梯度更平滑,避免震荡,训练更稳定。