y
=
1
1
+
e
−
x
=
tanh
(
x
2
)
+
1
2
y = \frac{1}{1 + e^{-x}} = \frac{\text{tanh}(\frac{x}{2}) + 1}{2}
y=1+e−x1=2tanh(2x)+1
tanh
(
x
)
=
sinh
(
x
)
cosh
(
x
)
=
e
x
−
e
−
x
e
x
+
e
−
x
=
2
×
sigmoid
(
2
×
x
)
−
1
\text{tanh}(x) = \frac{\text{sinh}(x)}{\text{cosh}(x)} = \frac{e^x - e^{-x}}{e^x + e^{-x}} = 2 \times \text{sigmoid}(2 \times x) - 1
tanh(x)=cosh(x)sinh(x)=ex+e−xex−e−x=2×sigmoid(2×x)−1
defrelu(x):"""
rele函数:y = max(x, 0)
:param x:
:return:
"""return np.array([0if num <0else num for num in x])defrelu_derivative(x):"""
relu函数求导
"""
x = tf.cast(x, dtype=tf.float32)
zeros = tf.fill(dims=x.shape, value=0.0)with tf.GradientTape()as tape:
tape.watch(x)
y = tf.math.maximum(x, zeros)
dy_dx = tape.gradient(y, x)return dy_dx.numpy()
Leaky ReLU(渗漏型修正线性单元)
API:tf.nn.leaky_relu
y
=
m
a
x
(
α
×
x
,
x
)
y = max(\alpha \times x, x)
y=max(α×x,x),一般情况下
0.1
≤
α
≤
0.3
0.1 \le \alpha \le 0.3
0.1≤α≤0.3
缺点
输出值y不以0为中心
结果不连贯
无法避免梯度爆炸问题;
两部分均为线性(求导结果为常值:
α
\alpha
α和1)
优点
能避免死亡 ReLU 问题,因为其在计算导数时允许较小的梯度
由于不包含指数运算,所以计算速度比 ELU 快
函数、函数导数形状及代码
ELU(指数线性单元)
API:tf.nn.elu
y
=
x
i
f
x
>
0
e
l
e
s
α
×
(
e
x
−
1
)
y = x \quad if \quad x \gt 0 \quad eles \quad \alpha \times (e^{x} -1)
y=xifx>0elesα×(ex−1),一般情况下
0.1
≤
α
≤
0.3
0.1 \le \alpha \le 0.3
0.1≤α≤0.3
缺点
输出值y不以0为中心
由于包含指数运算,所以计算时间更长
无法避免梯度爆炸问题;
两部分均为线性(求导结果为常值:
α
\alpha
α和1)
优点
能避免死亡 ReLU 问题
能得到负值输出,这能帮助网络向正确的方向推动权重和偏置变化
在计算梯度时能得到激活,而不是让它们等于 0。
函数、函数导数形状及代码
def elu(x, a=0.2):
"""
elu函数:y = x if x > 0 else a * (e^x - 1)
:param x:
:return:
"""
return np.array([num if num > 0 else a * (np.exp(num) - 1) for num in x])
SELU(扩展型指数线性单元)
API:tf.nn.selu
y
=
λ
×
x
i
f
x
>
0
e
l
e
s
λ
×
α
×
(
e
x
−
1
)
y = \lambda \times x \quad if \quad x \gt 0 \quad eles \quad \lambda \times \alpha \times (e^{x} -1)
y=λ×xifx>0elesλ×α×(ex−1)
说明
SELU 函数也需要 lecun_normal 进行权重初始化(网络参数会被初始化一个正态分布)
如果你想使用 dropout,你也必须使用名为 Alpha Dropout 的特殊版本
缺点
输出值y不以0为中心
新激活函数
优点
内部归一化的速度比外部归一化快,这意味着网络能更快收敛
不可能出现梯度消失或爆炸问题
函数、函数导数形状及代码
def selu(x, a=1.673263, lam=1.0507):
"""
rele函数:y = lam * x if x > 0 else lam * a * (e^x - 1)
:param x:
:return:
"""
y = np.array([num if num > 0 else a * (np.exp(num) - 1) for num in x])
return lam * y
GELU
y
=
0.5
×
x
×
(
1
+
tanh
(
2
π
×
(
x
+
0.044715
×
x
3
)
)
)
y = 0.5 \times x \times (1 + \tanh(\sqrt{\frac{2}{\pi}} \times (x + 0.044715 \times x ^ 3)))
y=0.5×x×(1+tanh(π2×(x+0.044715×x3)))