机器学习的本质是模拟人的神经元对信息的处理方法。可以将神经元看成是一个简单的带有二进制输出功能的逻辑电路门,多种电信号可以从神经元的树突部分传入,然后对多个传入的电信号进行结合,统一地运算,得到的唯一的电信号会通过神经元的轴突–>神经末梢传递给其他神经元的树突。
在机器学习中对数据的分类算法有两种:
- 感知器
- 适应性线性神经元
1、神经元的数学表示
设: x = [ x 1 ⋮ x m ] x = \left[ \begin{matrix} x_1 \\ \vdots \\ x_m \end{matrix} \right] x=⎣⎢⎡x1⋮xm⎦⎥⎤ 为树突接受的多种电信号, w = [ w 1 ⋮ w m ] w = \left[ \begin{matrix} w_1 \\ \vdots \\ w_m \end{matrix} \right] w=⎣⎢⎡w1⋮wm⎦⎥⎤为 x x x 的运算系数。
则神经元会进行以下算法步骤:
第一步,将神经元将接收到的信号
x
x
x 进行整合处理:
z = w 1 x 1 + ⋯ + w m x m z = w_1x_1+\cdots+w_mx_m z=w1x1+⋯+wmxm
第二步,用激活函数对 z z z 进行处理,例如下面的步调函数:
ϕ ( z ) = { 1 if z ≥ θ − 1 if o t h e r w i s e \phi(z)= \begin{cases} 1 &\text{if $z≥\theta$}\\ -1 &\text{if $otherwise$} \end{cases} ϕ(z)={1−1if z≥θif otherwise
step function就是一个激活函数。
激活函数(Activation functions)对于人工神经网络模型去学习、理解非常复杂和非线性的函数来说具有十分重要的作用。它们将非线性特性引入到我们的网络中。如上图在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数。引入激活函数是为了增加神经网络模型的非线性。没有激活函数的每层都相当于矩阵相乘。就算你叠加了若干层之后,无非还是个矩阵相乘罢了。
我们把 w w w 称为权重向量, x x x 称为训练样本。
感知器数据分类的算法步骤如下:
- 把 w w w 初始化为 0,或者把 w w w 的每个分量初始化为[0, 1]之间的任意小数;
- 把训练样本 x x x 输入感知器,得到分类结果 ϕ ( z ) \phi(z) ϕ(z) (-1或1);
- 根据分类结果更新权重向量。
接下来我们对每个步骤进行详细的解说。
步调函数和阈值的概念:
感知器中的算法如下:
z = w 0 x 0 + w 1 x 1 + ⋯ + w m x m z = w_0x_0+w_1x_1+\cdots+w_mx_m z=w0x0+w1x1+⋯+wmxm and
ϕ ( z ) = { 1 if z ≥ θ − 1 if o t h e r w i s e \phi(z)= \begin{cases} 1 &\text{if $z≥\theta$}\\ -1 &\text{if $otherwise$} \end{cases} ϕ(z)={1−1if z≥θif otherwise
其中 ϕ ( z ) \phi(z) ϕ(z) 是一个步调函数,在感知器中作为激活函数使用; θ \theta θ 为阈值。
这时,我们令 w 0 = − θ w_0 = -\theta w0=−θ and x 0 = 1 x_0 = 1 x0=1,即对阈值的初始化。
权重更新算法:
w j = w j + ∇ w j w_j=w_j+\nabla w_j wj=wj+∇wj ∇ w j = η ∗ ( y − y ′ ) ∗ x j \nabla w_j=\eta * (y-y')*x_j ∇wj=η∗(y−y′)∗xj
- η \eta η 表示学习率,是一个 [0, 1] 之间的小数;
- y 是输入样本的正确分类,y’ 是感知器计算出来的分类。
下面我们通过一个例子来更清楚的了解权重更新算法以及感知器的运行机理:
设:
w
=
[
0
,
0
,
0
]
w = [0, 0, 0]
w=[0,0,0],
x
=
[
1
,
2
,
3
]
x = [1, 2, 3]
x=[1,2,3],
η
=
0.3
\eta = 0.3
η=0.3,
y
=
1
y = 1
y=1,
y
′
=
−
1
y' = -1
y′=−1
则根据上面的算法:
∇
w
0
=
0.3
∗
(
1
−
(
−
1
)
)
∗
x
0
=
0.3
∗
2
∗
1
=
0.6
\nabla w_0 = 0.3*(1-(-1))*x_0 = 0.3*2*1 = 0.6
∇w0=0.3∗(1−(−1))∗x0=0.3∗2∗1=0.6;
w
0
=
w
0
+
∇
w
0
=
0.6
w_0 = w_0+\nabla w_0 = 0.6
w0=w0+∇w0=0.6;
同理,计算其他分量:
∇
w
1
=
0.3
∗
(
1
−
(
−
1
)
)
∗
x
1
=
0.3
∗
2
∗
2
=
1.2
\nabla w_1 = 0.3*(1-(-1))*x_1 = 0.3*2*2 = 1.2
∇w1=0.3∗(1−(−1))∗x1=0.3∗2∗2=1.2;
w
1
=
w
1
+
∇
w
1
=
1.2
w_1 = w_1+\nabla w_1 = 1.2
w1=w1+∇w1=1.2;
∇
w
2
=
0.3
∗
(
1
−
(
−
1
)
)
∗
x
2
=
0.3
∗
2
∗
3
=
1.8
\nabla w_2 = 0.3*(1-(-1))*x_2 = 0.3*2*3 = 1.8
∇w2=0.3∗(1−(−1))∗x2=0.3∗2∗3=1.8;
w
2
=
w
2
+
∇
w
2
=
1.8
w_2 = w_2+\nabla w_2 = 1.8
w2=w2+∇w2=1.8;
最后,更新后的权重向量为 w = [ 0.6 , 1.2 , 1.8 ] w = [0.6, 1.2, 1.8] w=[0.6,1.2,1.8]
阈值的更新:
阈值并不是一成不变的,初次的阈值可以人为制定,以后会不断的自动更新。
阈值更新如下:
w 0 = 0 w_0 = 0 w0=0, ∇ w 0 = η ∗ ( y − y ′ ) \nabla w_0=\eta * (y-y') ∇w0=η∗(y−y′)
y = 1 y = 1 y=1, y ′ = − 1 y' = -1 y′=−1
w 0 = w 0 + ∇ w 0 = 0 + 0.3 ∗ ( 1 − ( − 1 ) ) = 0.6 w_0=w_0+\nabla w_0=0+0.3*(1-(-1))=0.6 w0=w0+∇w0=0+0.3∗(1−(−1))=0.6
最后,我们对感知器的算法做一下总结,如下图:
3、适应性线性神经元
如图,适应性线性神经元与感知器的区别有二:
-
适应性线性神经元会将计算结果与给定的标准结果进行比较,如果出现Error,则会根据两者的差距进行动态的调整神经元的参数 w i w_i wi,使得与给定的标准结果的差距越来越小。
-
两者的激活函数(Activation function)不一样;感知器的激活函数是一个步调函数,而自适应性先行神经元使用的激活函数是将 x x x 与 w w w 的点积 z z z 直接当作最终结果,即: ϕ ( z ) = z \phi(z)=z ϕ(z)=z 。
那么适应线性神经元是如何动态的调整神经元的参数
w
i
w_i
wi 的呢?
适应线性神经元会使用一种渐进下降的算法来不断的缩短计算结果与标准结果之间的距离。
这里我们要引进一下“距离”的定义:
J ( w ) = 1 2 ∑ i ( y ( i ) − ϕ ( z ( i ) ) ) 2 J(w) = { \frac{1}{2} }\sum _i{(y^{(i)}-\phi(z^{(i)}))^2} J(w)=21i∑(y(i)−ϕ(z(i)))2
其中
z
=
w
0
x
0
+
w
1
x
1
+
⋯
+
w
m
x
m
=
w
T
x
z =w_0x_0+w_1x_1+\cdots+w_mx_m = w^Tx
z=w0x0+w1x1+⋯+wmxm=wTx
ϕ
(
z
)
=
z
\phi(z)=z
ϕ(z)=z
(
w
T
w^T
wT 是矩阵的转置,即行列互换)
上面是一个和方差公式,和方差的数学函数图像如下:
根据上图,我们目的是求当距离最小时的状态,即
J
(
w
)
J(w)
J(w) 的最小值,我们可以对上图的函数进行求偏导数,当导数为0时即距离的最小值时的状态。所以自适应线性神经元在进行动态调整参数时,当导数小于零时,可以动态的增大
w
j
w_j
wj 的值,反之当导数大于零的时,就会动态的减小
w
j
w_j
wj 的值。
和方差求导如下:
∂ J ∂ w j = ∂ ∂ w j 1 2 ∑ i ( y ( i ) − ϕ ( z ( i ) ) ) 2 \frac{\partial J}{\partial w_j}= \frac{\partial }{\partial w_j}{ \frac{1}{2} }\sum _i{(y^{(i)}-\phi(z^{(i)}))^2} ∂wj∂J=∂wj∂21∑i(y(i)−ϕ(z(i)))2
= 1 2 ∂ ∂ w j ∑ i ( y ( i ) − ϕ ( z ( i ) ) ) 2 ={ \frac{1}{2} }\frac{\partial }{\partial w_j}\sum _i{(y^{(i)}-\phi(z^{(i)}))^2} =21∂wj∂∑i(y(i)−ϕ(z(i)))2
= 1 2 ∑ i 2 ( y ( i ) − ϕ ( z ( i ) ) ) ∂ ∂ w j ( y ( i ) − ϕ ( z ( i ) ) = \frac{1}{2}{\sum _i 2{(y^{(i)}-\phi(z^{(i)})) }\frac{\partial }{\partial w_j}}{(y^{(i)}-\phi(z^{(i)})} =21∑i2(y(i)−ϕ(z(i)))∂wj∂(y(i)−ϕ(z(i))
= ∑ i ( y ( i ) − ϕ ( z ( i ) ) ) ∂ ∂ w j [ ( y ( i ) − ∑ i w j ( i ) x j ( i ) ] ={\sum _i {(y^{(i)}-\phi(z^{(i)}))}} \frac{\partial }{\partial w_j}[{(y^{(i)}-\sum _i w_j^{(i)}x_j^{(i)}}] =∑i(y(i)−ϕ(z(i)))∂wj∂[(y(i)−∑iwj(i)xj(i)]
= ∑ i ( y ( i ) − ϕ ( z ( i ) ) ) ( − x j ( i ) ) ={\sum _i {(y^{(i)}-\phi(z^{(i)}))}} (-x_j^{(i)}) =∑i(y(i)−ϕ(z(i)))(−xj(i))
= − ∑ i ( y ( i ) − ϕ ( z ( i ) ) ) x j ( i ) =-{\sum _i {(y^{(i)}-\phi(z^{(i)}))}} x_j^{(i)} =−∑i(y(i)−ϕ(z(i)))xj(i)
有了导数之后,我们就要对神经元的参数 w j w_j wj 进行更新:
w : = w + Δ w w:=w+\Delta w w:=w+Δw
其中
Δ w j = − η ∂ J ∂ w j = μ ∑ i ( y ( i ) − ϕ ( z ( i ) ) ) x j ( i ) \Delta w_j = - \eta \frac{\partial J}{\partial w_j} = \mu {\sum _i {(y^{(i)}-\phi(z^{(i)}))}} x_j^{(i)} Δwj=−η∂wj∂J=μi∑(y(i)−ϕ(z(i)))xj(i)
我们通过这种方式不断的调整神经元的每一个参数,这样会使得整体神元上的和方差的值不断地趋于最小,这样一来,神经网络的计算误差就会越来越小,计算结果就会越来越精确,神经网络对数据的预测的准确率就会越来越高。
学习课程来自:慕课网【机器学习-实现简单神经网络】