1. 神经网络的代价函数
假设我们有下图所示的神经网络:
我们记其层数为
L
=
4
L=4
L=4,记其第
l
l
l 层神经元的个数(不包含偏置项)为
s
l
s_l
sl,如
s
1
=
3
,
s
2
=
5
,
⋯
s_1=3,s_2=5,\cdots
s1=3,s2=5,⋯。
为了对不同的分类问题进行描述,我们定义两种分类:
-
二分类
对于二分类问题,我们只需要在输出层设置 K = 1 K=1 K=1 个输出神经元,即 s L = 1 s_L=1 sL=1。下图就表示是一个进行二分类的神经网络,其 s 4 = 1 s_4=1 s4=1:
-
多分类
多分类是在输出层有 K ( K ≥ 3 ) K(K\geq3) K(K≥3) 个输出单元的神经网络,即假设函数 h θ ( x ) ∈ R K h_\theta(x)\in \mathbb{R}^K hθ(x)∈RK 是一个 K K K 维的向量,下面的四个向量就表示四分类问题可能输出的结果。
y ( i ) = [ 1 0 0 0 ] 或 [ 0 1 0 0 ] 或 [ 0 0 1 0 ] 或 [ 0 0 0 1 ] y^{(i)}= \left [ \begin{matrix} 1 \\ 0 \\ 0 \\ 0 \end{matrix} \right] 或 \left [ \begin{matrix} 0 \\ 1 \\ 0 \\ 0 \end{matrix} \right] 或 \left [ \begin{matrix} 0 \\ 0 \\ 1 \\ 0 \end{matrix} \right] 或 \left [ \begin{matrix} 0 \\ 0 \\ 0 \\ 1 \end{matrix} \right] y(i)=⎣⎢⎢⎡1000⎦⎥⎥⎤或⎣⎢⎢⎡0100⎦⎥⎥⎤或⎣⎢⎢⎡0010⎦⎥⎥⎤或⎣⎢⎢⎡0001⎦⎥⎥⎤因为我们使用一个输出单元就能表示二分类,所以多分类中的 K ≥ 3 K\geq3 K≥3。
定义了不同的分类后,我们就可以为其定义代价函数。在神经网络中,我们使用和逻辑回归相同的代价函数,下式表示逻辑回归的代价函数:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
[
y
(
i
)
log
h
θ
(
x
(
i
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
h
θ
(
x
(
i
)
)
)
]
+
λ
2
m
∑
j
=
1
n
θ
j
2
J(\theta) = - \frac{1}{m} \sum_{i=1}^{m} \left[ y^{(i)} \log h_\theta(x^{(i)}) + (1-y^{(i)})\log(1-h_\theta(x^{(i)}) )\right] +\frac{\lambda}{2m}\sum_{j=1}^n\theta_j^2
J(θ)=−m1i=1∑m[y(i)loghθ(x(i))+(1−y(i))log(1−hθ(x(i)))]+2mλj=1∑nθj2
神经网络和逻辑回归不同的一点在于,输出结果
h
θ
(
x
)
∈
R
K
h_\theta(x) \in \mathbb{R}^K
hθ(x)∈RK 与真实标签
y
y
y 都是一个
K
K
K 维的向量,如果我们用
(
h
θ
(
x
)
)
i
\left(h_\theta(x)\right)_i
(hθ(x))i 表示
K
K
K 维向量中的第
i
i
i 个元素,
y
i
y_i
yi 表示真实标签中的第
i
i
i 个元素,那么我们就可以将神经网络的代价函数表示为:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
∑
k
=
1
K
[
y
k
(
i
)
log
(
h
θ
(
x
(
i
)
)
)
k
+
(
1
−
y
k
(
i
)
)
log
(
1
−
(
h
θ
(
x
(
i
)
)
)
k
)
]
+
λ
2
m
∑
l
=
1
L
−
1
∑
i
=
1
s
l
∑
j
=
1
s
l
+
1
(
θ
j
i
(
l
)
)
2
\begin{aligned} J(\theta) = & -\frac{1}{m} \sum_{i=1}^{m} \sum_{k=1}^{K} \left[ y^{(i)}_k \log \left(h_\theta(x^{(i)})\right)_k + (1-y^{(i)}_k)\log\left(1- \left(h_\theta(x^{(i)})\right)_k \right) \right] \\ &+\frac{\lambda}{2m} \sum_{l=1}^{L-1} \sum_{i=1}^{s_l}\sum_{j=1}^{s_{l+1}} (\theta_{ji}^{(l)})^2 \end{aligned}
J(θ)=−m1i=1∑mk=1∑K[yk(i)log(hθ(x(i)))k+(1−yk(i))log(1−(hθ(x(i)))k)]+2mλl=1∑L−1i=1∑slj=1∑sl+1(θji(l))2
上面的代价函数我们可以分为两部分进行理解:
- 前面的误差项其实就是在逻辑回归误差项的基础上,加入对 K K K 维向量中每个元素之间的误差,对于预测结果只有一个值的情况,我们就不需要考虑 K K K ,上式就退变为逻辑回归的代价函数。预测结果有多个值时,我们对这多个值分别求代价,进行累加,就是上式中对 K K K 的求和项。
- 后面的正则项就是对神经网络中每个 θ \theta θ 进行正则化。首先思考,对于有多个 θ \theta θ 的线性回归和逻辑回归,我们都是对其中的每个 θ \theta θ 都正则化。类比到神经网络,我们这里使用 θ ( l ) \theta^{(l)} θ(l) 表示第 l l l 层的参数,用 θ j i \theta_{ji} θji 表示从 s l s_l sl 层的第 i i i 个神经元到 s l + 1 s_{l+1} sl+1 层第 j j j 个神经元的参数 θ \theta θ。所以整个正则项就表示对所有 θ \theta θ 进行正则化。这里同样按照惯例没有考虑偏置的正则项,即 θ 0 \theta_0 θ0。
2. 反向传播算法
上面我们给出了神经网络的代价函数,有了代价函数,我们的目的就是使得代价函数最小,即
min
θ
J
(
θ
)
\min_\theta J(\theta)
θminJ(θ)
为了使用梯度下降算法最小化代价函数,我们还需要求得代价函数相对于每个
θ
\theta
θ 参数的偏导数:
∂
∂
θ
i
j
(
l
)
J
(
θ
)
\frac{\partial}{\partial\theta_{ij}^{(l)}}J(\theta)
∂θij(l)∂J(θ)
为了求解偏导数,我们从最简单的情况开始看,首先我们梳理前向传播的过程,对于只有一个样本的训练集
(
x
,
y
)
(x,y)
(x,y),通过如下所示的神经网络,其前向传播的过程为:
a
(
1
)
=
x
→
z
(
2
)
=
θ
(
1
)
a
(
1
)
a
(
2
)
=
g
(
z
(
2
)
)
→
z
(
3
)
=
θ
(
2
)
a
(
2
)
a
(
3
)
=
g
(
z
(
3
)
)
→
z
(
4
)
=
θ
(
3
)
a
(
3
)
a
(
4
)
=
h
θ
(
x
)
=
g
(
z
(
4
)
)
\begin{matrix} a^{(1)} =x & \rightarrow & \begin{aligned} z^{(2)} &=\theta^{(1)}a^{(1)} \\ a^{(2)} &=g(z^{(2)}) \\ \end{aligned} & \rightarrow & \begin{aligned} z^{(3)} &=\theta^{(2)}a^{(2)} \\ a^{(3)} &=g(z^{(3)}) \\ \end{aligned} & \rightarrow & \begin{aligned} z^{(4)} &=\theta^{(3)}a^{(3)} \\ a^{(4)} &=h_{\theta}(x)=g(z^{(4)}) \\ \end{aligned} \end{matrix}
a(1)=x→z(2)a(2)=θ(1)a(1)=g(z(2))→z(3)a(3)=θ(2)a(2)=g(z(3))→z(4)a(4)=θ(3)a(3)=hθ(x)=g(z(4))
反向传播中需要计算每个结点和真实标签之间的误差 δ j ( l ) \delta_j^{(l)} δj(l),其表示 l l l 层的第 j j j 个结点的 a j ( l ) a_j^{(l)} aj(l) 的误差。
具体来看,对于上图表示的神经网络,我们首先可以根据真实标签
y
y
y 计算最后一层结点和真实标签之间的误差 :
δ
j
(
4
)
=
a
j
(
4
)
−
y
j
\delta_j^{(4)}=a_j^{(4)}-y_j
δj(4)=aj(4)−yj
如果我们用向量表示真实标签和预测结果,就可以省略下标
j
j
j,从而第
4
4
4 层的误差就可以表示为:
δ
(
4
)
=
a
(
4
)
−
y
\delta^{(4)}=a^{(4)}-y
δ(4)=a(4)−y
有了第四层的误差后,我们就可以根据
δ
(
4
)
\delta^{(4)}
δ(4) 来计算
δ
(
3
)
\delta^{(3)}
δ(3) ,再根据
δ
(
3
)
\delta^{(3)}
δ(3) 计算
δ
(
2
)
\delta^{(2)}
δ(2) 1 :
δ
(
3
)
=
(
θ
(
3
)
)
T
δ
(
4
)
.
∗
g
′
(
z
(
3
)
)
δ
(
2
)
=
(
θ
(
2
)
)
T
δ
(
3
)
.
∗
g
′
(
z
(
2
)
)
\begin{aligned} \delta^{(3)} & =(\theta^{(3)})^T\delta^{(4)} .* g' (z^{(3)})\\ \delta^{(2)} & =(\theta^{(2)})^T\delta^{(3)} .* g' (z^{(2)})\\ \end{aligned}
δ(3)δ(2)=(θ(3))Tδ(4).∗g′(z(3))=(θ(2))Tδ(3).∗g′(z(2))
从上面误差的计算过程我们可以看出,我们首先计算出最后一层的误差,之后将最后一层的误差向前传播,不断地计算更前面一层的误差,最后传到第二层,反向传播的名字也因此而来。
通过上面的过程和一些数学证明,我们可以得到,在不考虑正则项时,代价函数相对于每个参数
θ
\theta
θ 的偏导数可以表示为:
∂
∂
θ
i
j
(
l
)
J
(
θ
)
=
a
j
(
l
)
δ
j
(
l
+
1
)
\frac{\partial}{\partial\theta_{ij}^{(l)}}J(\theta) = a_j^{(l)}\delta_j^{(l+1)}
∂θij(l)∂J(θ)=aj(l)δj(l+1)
当我们有更多的数据集时,如 { ( x ( 1 ) , y ( 1 ) ) , ⋯ , ( x ( m ) , y ( m ) ) } \{(x^{(1)},y^{(1)}), \cdots, (x^{(m)},y^{(m)})\} {(x(1),y(1)),⋯,(x(m),y(m))},计算偏导数的过程如下:
设置误差 Δ i j ( l ) = 0 \Delta_{ij}^{(l)}=0 Δij(l)=0
f o r k = 1 t o m for \quad k=1 \quad to \quad m fork=1tom
a ( 1 ) = x ( k ) \quad\quad a^{(1)}=x^{(k)} a(1)=x(k)
c o m p u t e a ( l ) , f o r l = 2 , 3 , ⋯ , L \quad\quad compute \ \ a^{(l)},\ for \ \ l=2,3,\cdots,L compute a(l), for l=2,3,⋯,L
u s i n g y ( i ) , c o m p u t e δ ( L ) = a ( L ) − y ( k ) \quad\quad using \ \ y^{(i)}, compute \ \ \delta^{(L)}=a^{(L)}-y^{(k)} using y(i),compute δ(L)=a(L)−y(k)
c o m p u t e δ ( L − 1 ) , δ ( L − 2 ) , ⋯ , δ ( 2 ) \quad\quad compute \ \ \delta^{(L-1)},\delta^{(L-2)},\cdots,\delta^{(2)} compute δ(L−1),δ(L−2),⋯,δ(2)
Δ i j ( l ) = Δ i j ( l ) + a j ( l ) δ i ( l + 1 ) \quad\quad \Delta_{ij}^{(l)} = \Delta_{ij}^{(l)} + a_j^{(l)}\delta_i^{(l+1)} Δij(l)=Δij(l)+aj(l)δi(l+1)
D i j ( l ) = 1 m Δ i j ( l ) + λ θ i j ( l ) , j ≠ 0 D_{ij}^{(l)} = \frac{1}{m}\Delta_{ij}^{(l)}+\lambda\theta_{ij}^{(l)}, \quad j\neq 0 Dij(l)=m1Δij(l)+λθij(l),j=0
D i j ( l ) = 1 m Δ i j ( l ) , j = 0 D_{ij}^{(l)} = \frac{1}{m}\Delta_{ij}^{(l)}, \quad j= 0 Dij(l)=m1Δij(l),j=0
其中, Δ i j ( l ) \Delta_{ij}^{(l)} Δij(l) 表示所有样本对应位置误差的累加值。对于下面的赋值操作,当 j = 0 j=0 j=0 时表示是偏置项, j ≠ 0 j\neq 0 j=0 时,表示不是偏置项,需要加上正则项。
当我们计算出
D
i
j
(
l
)
D_{ij}^{(l)}
Dij(l) 后,代价函数相对于每个
θ
\theta
θ 的偏导数就是:
∂
∂
θ
i
j
(
l
)
J
(
θ
)
=
D
i
j
(
l
)
\frac{\partial}{\partial \theta_{ij}^{(l)}}J(\theta) =D_{ij}^{(l)}
∂θij(l)∂J(θ)=Dij(l)
为了更好的理解反向传播,我们对
δ
\delta
δ 进行更加深入的理解。首先我们简化代价函数,省略代价函数中的正则项,那么代价函数变为:
J
(
θ
)
=
−
1
m
∑
i
=
1
m
[
y
(
i
)
log
h
θ
(
x
(
i
)
)
+
(
1
−
y
(
i
)
)
log
(
1
−
h
θ
(
x
(
i
)
)
)
]
J(\theta) = - \frac{1}{m} \sum_{i=1}^{m} \left[ y^{(i)} \log h_\theta(x^{(i)}) + (1-y^{(i)})\log(1-h_\theta(x^{(i)}) )\right]
J(θ)=−m1i=1∑m[y(i)loghθ(x(i))+(1−y(i))log(1−hθ(x(i)))]
为了更加简化代价函数,我们只考虑某个样本
(
x
(
i
)
,
y
(
i
)
)
(x^{(i)},y^{(i)})
(x(i),y(i)),且假设神经网络的输出只有一个单元,那么我们就可以将该样本的代价函数可以写为:
c
o
s
t
(
i
)
=
y
(
i
)
log
h
θ
(
x
(
i
)
)
+
(
1
−
y
(
i
)
)
log
[
1
−
h
θ
(
x
(
i
)
)
]
cost(i) = y^{(i)}\log h_\theta(x^{(i)}) + (1-y^{(i)})\log [1- h_\theta(x^{(i)})]
cost(i)=y(i)loghθ(x(i))+(1−y(i))log[1−hθ(x(i))]
我们可以将代价函数
c
o
s
t
(
i
)
cost(i)
cost(i) 看作是预测值
h
θ
(
x
(
i
)
)
h_\theta(x^{(i)})
hθ(x(i)) 和真实值
y
(
i
)
y^{(i)}
y(i) 之间的接近程度。
δ
j
(
l
)
\delta_j^{(l)}
δj(l) 可以看作第
l
l
l 层第
j
j
j 个单元激活项
a
j
(
l
)
a_j^{(l)}
aj(l) 的误差,用公式可以表示为:
δ
j
(
l
)
=
∂
∂
z
j
(
l
)
c
o
s
t
(
i
)
\delta_j^{(l)} = \frac{\partial}{\partial z_j^{(l)}}cost(i)
δj(l)=∂zj(l)∂cost(i)
也就是代价函数相对于网络中的中间项 z j ( l ) z_j^{(l)} zj(l) 的偏导数,这些中间项是通过权重 θ \theta θ 计算出来的,所以我们对这些中间项求偏导就表示我们要以多大的程度改变 θ \theta θ 才能通过 z j ( l ) z_j^{(l)} zj(l) 计算得到和真实标签相近的 h θ ( x ) h_\theta(x) hθ(x)。
如下图所示,我们将所有
z
,
a
,
δ
z,a,\delta
z,a,δ 都标注在结点中,类比于前向传播,
δ
(
l
)
\delta^{(l)}
δ(l) 的计算可以通过
δ
(
l
+
1
)
\delta^{(l+1)}
δ(l+1)得到,例如:
δ
1
(
4
)
=
a
1
(
4
)
−
y
(
i
)
δ
2
(
2
)
=
θ
12
(
1
)
δ
1
(
3
)
+
θ
22
(
2
)
δ
2
(
3
)
\begin{aligned} \delta_1^{(4)} & = a_1^{(4)} - y^{(i)} \\ \delta_2^{(2)} & = \theta_{12}^{(1)}\delta_1^{(3)} + \theta_{22}^{(2)}\delta_2^{(3)} \end{aligned}
δ1(4)δ2(2)=a1(4)−y(i)=θ12(1)δ1(3)+θ22(2)δ2(3)
3. 参数随机初始化
在线性回归和逻辑回归中,其参数 θ \theta θ 都是可以直接初始化为 0 0 0,但是在神经网络中将所有参数 θ i j ( l ) = 0 \theta_{ij}^{(l)}=0 θij(l)=0 会造成错误的结果。如下所示
如果所有的权重 θ i j ( l ) = 0 \theta_{ij}^{(l)}=0 θij(l)=0 那么经过前向传播, a 1 ( 2 ) = a 2 ( 2 ) a_1^{(2)}=a_2^{(2)} a1(2)=a2(2),通过反向传播, δ 1 ( 2 ) = δ 2 ( 2 ) \delta_1^{(2)}=\delta_2^{(2)} δ1(2)=δ2(2),因此 ∂ ∂ θ 01 ( 1 ) J ( θ ) = ∂ ∂ θ 02 ( 1 ) J ( θ ) \frac{\partial}{\partial \theta_{01}^{(1)}}J(\theta)=\frac{\partial}{\partial \theta_{02}^{(1)}}J(\theta) ∂θ01(1)∂J(θ)=∂θ02(1)∂J(θ),这意味着每次更新,图中相同颜色的参数都相同,如 θ 01 ( l ) = θ 02 ( l ) \theta_{01}^{(l)}=\theta_{02}^{(l)} θ01(l)=θ02(l)。如果存在很多层隐藏层,那么每个隐藏层的参数都相同,它们都在学习相同的特征,这会导致神经网络不能有效的工作。
为了解决这个问题,我们在对神经网络初始化时,将所有 θ i j ( l ) \boldsymbol{\theta_{ij}^{(l)}} θij(l) 都初始化为一个 [ − ϵ , ϵ ] \boldsymbol{[-\epsilon,\epsilon]} [−ϵ,ϵ] 之间的随机值,这样就能保证得到我们想要的结果。
4. 总结
4.1 神经网络结构的选择
-
输入输出单元的个数
构建神经网络时,输入神经元的个数就是每个样本 x ( i ) x^{(i)} x(i) 的特征维度。而输出神经元的个数就是需要分类的类别数。 -
神经元的层数
一般情况下,选择一层的隐藏层,如果要构建多层的隐藏层,通常可以使每层的神经元个数相同,并且可以使隐藏层神经元的个数是输入神经元的 n n n 倍。
4.2 神经网络的训练过程
- 构建神经网络,将每个参数 θ \theta θ 初始化为一个较小的值
- 循环执行前向传播,对每个训练样本 x ( i ) x^{(i)} x(i) 计算 h θ ( x ( i ) ) h_\theta(x^{(i)}) hθ(x(i))
- 计算代价函数 J ( θ ) J(\theta) J(θ)
- 通过反向传播计算偏导数 ∂ ∂ θ j k ( l ) J ( θ ) \frac{\partial}{\partial \theta_{jk}^{(l)}}J(\theta) ∂θjk(l)∂J(θ)
- 通过梯度检查比较得到的偏导数是否在正确的范围内。
- 使用梯度下降等高级优化算法使用反向传播优化参数 θ \theta θ 使得损失函数 J ( θ ) J(\theta) J(θ) 最小。