多层感知机:MLP
多层感知机由感知机推广而来,最主要的特点是有多个神经元层,因此也叫深度神经网络(DNN: Deep Neural Networks)。
感知机:PLA
为了理解神经网络,我们应该先理解神经网络的组成单元——神经元,神经元也叫做感知机。感知器算法在上个世纪50-70年代很流行,也成功解决了很多问题,并且感知机算法也是非常简单的
感知机有如下组成部分:
- 输入权值:一个感知器可以接受多个输入 ( x 1 , x 2 , . . . x n ) (x_1,x_2,...x_n) (x1,x2,...xn),每个输入有一个权值 w i w_i wi,此外还有一个偏置项 x 0 x_0 x0(不妨思考一下为什么要加一个 x 0 x_0 x0?)
- 激活函数:感知机的激活函数可以有很多选择,比如我们可以选择下面这个阶跃函数f来作为激活函数:(其中0为threshold,我们可以自定义,不一定是0)
o ( x 1 , . . . , x n ) = { 1 w 0 + w 1 × x 1 + . . . + w n × x n > 0 0 o t h e r w i s e o(x_1,...,x_n) = \begin{cases} 1 & w_0+w_1×x_1+...+w_n×x_n >0 \\ 0 & otherwise \end{cases} o(x1,...,xn)={10w0+w1×x1+...+wn×xn>0otherwise - 输出:感知机的输出由下面这个公式来计算
y = f ( w ∗ x + b ) y = f(w*x+b) y=f(w∗x+b)
从上述内容更可以看出,PLA是一个线性的二分类器,但不能对非线性的数据并不能进行有效的分类。因此便有了对网络层次的加深,理论上,多层网络可以模拟任何复杂的函数。
问题引起
看上图,如果我们还是还是使用一个感知机进行线性分类,显然是无法将1和0全部分开的,即异或操作是无法完成的。此时就要用到多层感知机。
多层感知机:MLP
多层感知机的一个重要特点就是多层,我们将第一层称之为输入层,最后一层称之有输出层,中间的层称之为隐层。MLP并没有规定隐层的数量,因此可以根据各自的需求选择合适的隐层层数。且对于输出层神经元的个数也没有限制。
MLP神经网络结构模型如下,本文中只涉及了一个隐层,输入只有三个变量 [ x 1 , x 2 , x 3 ] [x_1,x_2,x_3] [x1,x2,x3]和一个偏置量b,输出层有三个神经元。相比于感知机算法中的神经元模型对其进行了集成。
问题解决
现在我们就用多层感知机来处理一下上面我们提出的那个问题。
我们先对异或进行一次转换
不难看出异或是由一个或门和一个与非门再进行一个与操作形成的。此时构造我们的神经网络。
在隐藏层,就相当于此时我们拥有了两个线性的分类器,进行分类:
进一步,隐藏层的输出此时要作为输出层的输入进行运算,即我们聚焦于这一步:
我们先看一张图:
该图表示了各个神经元的一个输出情况,根据or和and的输出情况,我们可以构造一张图表看一下最终的输出情况,并用一个线性分类器就能很简单的进行分类了。
看,经过两步的运算,我们是不是就完成了我们的异或需求。
激活函数
使用多层感知机,我们的隐藏层感知器激活函数选用Sigmoid:
s
i
g
m
o
i
d
(
x
)
=
1
1
+
e
−
x
sigmoid(x) = \frac{1}{1+e^{-x}}
sigmoid(x)=1+e−x1
对应的图像如下:
我们在多层感知机中的使用
这里我们对Sigmoid进行一个求导,下方会用到:
方向传播算法(Backpropagation)
反向传播算法是神经网络的基础之一,该算法主要用于根据损失函数来对网络参数进行优化。
根据下面这幅图,给出下文要用到的一些定义:
-
x j i x_{ji} xji = the i t h i^{th} ith input to unit j
-
w j i w_{ji} wji = the weight associated with the i t h i^{th} ith input to unit j
-
n e t j net_j netj = ∑ w j i x j i \sum w_{ji}x_{ji} ∑wjixji (the weighted sum of inputs for unit j )
-
o j o_j oj= the output of unit j
-
t j t_j tj= the target output of unit j
-
σ = the sigmoid function
-
outputs = the set of units in the final layer
-
Downstream (j ) = the set of units directly taking the output of unit j as inputs
首先,根据目标值和实际值(即最终输出)来计算我们的误差情况:
根据偏导和学习率可以算出我们的权重修改值:
可以看出,权重的修改值就是要计算我们的偏导,但显然,我们的这个偏导并不能仅仅的使用我们在单个神经元中使用的求导方式,因为我们的输出和输入并不在同一个神经元上进行的。我们先来进行一个转换:
这时我们只需要求出
∂
E
d
∂
n
e
t
j
\frac{\partial E_d}{\partial net_j}
∂netj∂Ed即可,当然我们这里对输出层和隐藏层的求法是不一样的。因为隐藏层的输出我们并不知道,那应该怎么解决呢?别急,我们先来看一下输出层的反向传播公式。
输出层的反向传播公式
隐藏层的反向传播公式
隐藏层咋办?依然是简单粗暴的解决办法——拿输出层输出的误差函数E对该层权值求梯度,只不过要更纠结一些。
先设这隐藏层后边就是输出层。此时输出层是第k层,隐藏层是第j层。
其中, δ k δ_k δk是k神经元的局部梯度, δ j δ_j δj是j神经元的局部梯度
从而可以推导出,每一层隐藏层神经元的局域梯度,等于其 后一层所有神经元的局域梯度 与其 对本层神经元连接边的权值的乘积 之和,乘上本层神经元激活函数对局部诱导域的导数。
如此一来,无论隐藏层有多深,每层隐藏层的权值修改都可以通过前一层的信息推导而得,而这一信息最终来源于输出层,输出层的信息又来源于误差信号。这就好像误差信号在从输出层开始,沿着各层间的连接边往后传播一样。
反向传播(Back Propagation)的说法就是这么来的。
这张图用来可视化误差的反向传播。
总结
神经元的调权公式的形式均为:
Δ
w
j
i
=
η
δ
j
x
j
i
Δw_{ji}=ηδ_jx_{ji}
Δwji=ηδjxji
即 学习率参数 乘 局域梯度 乘 该权值对应的输入值。
对于输出层,局域梯度
δ
k
δ_k
δk计算公式为:
δ
k
=
(
t
k
−
o
k
)
o
k
(
1
−
o
k
)
δ_k = (t_k-o_k)o_k(1 -o_k)
δk=(tk−ok)ok(1−ok)
即 误差信号 乘 激活函数对局部诱导域的导数;
对于隐藏层则为:
δ h = o h ( 1 − o h ) ∑ k ∈ o u t p u t s w k h δ k δ_h = o_h(1-o_h)\sum_{k∈outputs}w_{kh}δ_k δh=oh(1−oh)k∈outputs∑wkhδk
即 后一层所有神经元的 局域梯度以及 其与本层神经元各对应连接边的权值 乘积 之和,乘上 激活函数对本隐藏层神经元局部诱导域的导数。
对每一项权值的更新:
w j i ← w j i + △ w j i = w j i + η δ i x j i w_{ji} \leftarrow \ \ w_{ji} + △w_{ji} = w_{ji} + \eta \delta_ix_{ji} wji← wji+△wji=wji+ηδixji