Relu
ReLU(rectified linear unit)函数提供了一个很简单的非线性变换。给定元素xx,该函数定义为:
R
e
L
U
(
x
)
=
m
a
x
(
x
,
0
)
ReLU(x)=max(x,0)
ReLU(x)=max(x,0)
实现:
import torch
import numpy as np
import matplotlib.pylab as plt
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l
def xyplot(x_vals, y_vals, name):
d2l.set_figsize(figsize=(5, 2.5))
d2l.plt.plot(x_vals.detach().numpy(), y_vals.detach().numpy())
d2l.plt.xlabel('x')
d2l.plt.ylabel(name + '(x)')
x = torch.arange(-8.0, 8.0, 0.1, requires_grad=True)
y = x.relu()
xyplot(x, y, 'relu')
plt.show()
显然,当输入为负数时,ReLU函数的导数为0;当输入为正数时,ReLU函数的导数为1。尽管输入为0时ReLU函数不可导,但是我们可以取此处的导数为0。下面绘制ReLU函数的导数。
y.sum().backward()
xyplot(x, x.grad, 'grad of relu')
Sigmoid函数
sigmoid函数可以将元素的值变换到0和1之间:
s
i
g
m
o
i
d
(
x
)
=
1
1
+
e
x
p
(
−
x
)
sigmoid(x)=\frac{1}{1+exp(-x)}
sigmoid(x)=1+exp(−x)1
sigmoid函数在早期的神经网络中较为普遍,但它目前逐渐被更简单的ReLU函数取代,下面绘制了sigmoid函数。当输入接近0时,sigmoid函数接近线性变换。
依据链式法则,sigmoid函数的导数:
s
i
g
m
o
i
d
′
(
x
)
=
s
i
g
m
o
i
d
(
x
)
(
1
−
s
i
g
m
o
i
d
(
x
)
)
sigmoid^{'}(x)=sigmoid(x)(1-sigmoid(x))
sigmoid′(x)=sigmoid(x)(1−sigmoid(x)).
下面绘制了sigmoid函数的导数。当输入为0时,sigmoid函数的导数达到最大值0.25;当输入越偏离0时,sigmoid函数的导数越接近0。
x.grad.zero_()
y.sum().backward()
xyplot(x, x.grad, 'grad of sigmoid')
tanh函数
tanh(双曲正切)函数可以将元素的值变换到-1和1之间:
t
a
n
h
(
x
)
=
1
−
e
x
p
(
−
2
x
)
1
+
e
x
p
(
−
2
x
)
tanh(x)=\frac{1-exp(-2x)}{1+exp(-2x)}
tanh(x)=1+exp(−2x)1−exp(−2x).
我们接着绘制tanh函数。当输入接近0时,tanh函数接近线性变换。虽然该函数的形状和sigmoid函数的形状很像,但tanh函数在坐标系的原点上对称。
y = x.tanh()
xyplot(x, y, 'tanh')
依据链式法则,tanh函数的导数:
t
a
n
h
′
(
x
)
=
1
−
t
a
n
h
2
(
x
)
tanh^{'}(x)=1-tanh^2(x)
tanh′(x)=1−tanh2(x).
下面绘制了tanh函数的导数。当输入为0时,tanh函数的导数达到最大值1;当输入越偏离0时,tanh函数的导数越接近0。
y.sum().backward()
xyplot(x, x.grad, 'grad of tanh')
多层感知机
多层感知机就是含有至少一个隐藏层的由全连接层组成的神经网络,且每个隐藏层的输出通过激活函数进行变换。多层感知机的层数和各隐藏层中隐藏单元个数都是超参数。以单隐藏层为例并沿用本节之前定义的符号,多层感知机按以下方式计算输出:
H
=
ϕ
(
X
W
h
+
b
h
)
H=ϕ(XW_h+b_h)
H=ϕ(XWh+bh)
O
=
H
W
o
+
B
o
O=HW_o+B_o
O=HWo+Bo
其中ϕ表示激活函数。在分类问题中,我们可以对输出O做softmax运算,并使用softmax回归中的交叉熵损失函数。 在回归问题中,我们将输出层的输出个数设为1,并将输出O直接提供给线性回归中使用的平方损失函数
小结
- 多层感知机在输出层与输入层之间加入了一个或多个全连接隐藏层,并通过激活函数对隐藏层输出进行变换。
- 常用的激活函数包括ReLU函数、sigmoid函数和tanh函数。