神经元模型
神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。
神经网络中最基本的成分是神经元模型,即上述定义中的“简单单元”,在生物神经网络中,每个神经元与其他神经元相连,当它“兴奋”时,就会向相连的神经元发送化学物质,从而改变这些神经元内的电位;如果某神经元的电位超过了一个“阈值”,那么它就会被激活,即“兴奋”起来,向其他神经元发送化学物质。
M-P神经元模型
M‑P神经元(一个用来模拟生物行为的数学模型):接收n个输入(通常是来自其他神经
元),并给各个输入赋予权重计算加权和,然后和自身特有的阈值
θ
\theta
θ进行比较(作减
法),最后经过激活函数(模拟“抑制”和“激活”)处理得到输出(通常是给下一个神经
元)
y = f ( ∑ i = 1 n w i x i − θ ) = f ( w T x + b ) y=f\left(\sum_{i=1}^{n} w_{i} x_{i}-\theta\right)=f\left(\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}+b\right) y=f(∑i=1nwixi−θ)=f(wTx+b)
单个M‑P神经元:感知机( sgn作激活函数)、对数几率回归(sigmoid作激活函数)
多个M‑P神经元:神经网络
感知机
感知机模型:激活函数为sgn(阶跃函数)的神经元
y = sgn ( w T x − θ ) = { 1 , w T x − θ ⩾ 0 0 , w T x − θ < 0 y=\operatorname{sgn}\left(\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}-\theta\right)=\left\{\begin{array}{ll} 1, & \boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}-\theta \geqslant 0 \\ 0, & \boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}-\theta<0 \end{array}\right. y=sgn(wTx−θ)={1,0,wTx−θ⩾0wTx−θ<0
其中, x ∈ R n x \in \mathbb{R^n} x∈Rn为样本的特征向量,是感知机模型的输入, w , θ w,\theta w,θ 是感知机模型的参数, w ∈ R n w \in \mathbb{R^n} w∈Rn为权重, θ \theta θ 为阈值。
再从几何角度来说,给定一个线性可分的数据集
T
T
T,感知机的学习目标是求得能对数据
集
T
T
T中的正负样本完全正确划分的超平面,其中
w
T
x
−
θ
w^Tx-\theta
wTx−θ 即为超平面方程。
n维空间的超平面(
w
T
x
+
b
=
0
w^Tx+b=0
wTx+b=0 ,其中
w
,
x
∈
R
n
w,x \in \mathbb{R^n}
w,x∈Rn):
超平面方程不唯一
法向量
w
w
w垂直于超平面
法向量
w
w
w和位移项确定一个唯一超平面
法向量
w
w
w指向的那一半空间为正空间,另一半为负空间
感知机学习策略:随机初始化
w
,
b
w,b
w,b,将全体训练样本代入模型找出误分类样本,假设此
时误分类样本集合为
M
⊆
T
M\subseteq T
M⊆T,对任意一个误分类样本来
(
x
,
y
)
∈
M
(x,y)\in M
(x,y)∈M说,当
w
T
−
θ
≥
0
w^T- \theta \ge 0
wT−θ≥0时,模型输出值为
y
^
=
1
\hat{y}=1
y^=1 ,样本真实标记为
y
=
0
y=0
y=0 ;反之,当
w
T
x
−
θ
<
0
w^Tx-\theta<0
wTx−θ<0时,模型输出值为
y
^
=
0
\hat{y}=0
y^=0,样本真实标记为
y
=
1
y=1
y=1。综合两种情形可知,以下公式恒成立
( y ^ − y ) ( w T x − θ ) ≥ 0 (\hat{y}-y)(w^Tx-\theta)\ge0 (y^−y)(wTx−θ)≥0
所以,给定数据集T,其损失函数可以定义为
L ( w , θ ) = ∑ x ∈ M ( y ^ − y ) ( w T x − θ ) L(\boldsymbol{w}, \theta)=\sum_{\boldsymbol{x} \in M}(\hat{y}-y)\left(\boldsymbol{w}^{\mathrm{T}} \boldsymbol{x}-\theta\right) L(w,θ)=∑x∈M(y^−y)(wTx−θ)
显然,此损失函数是非负的。如果没有误分类点,损失函数值是0。而且,误分类点越
少,误分类点离超平面越近,损失函数值就越小。
感知机学习算法:当误分类样本集合 M M M固定时,那么可以求得损失函数的梯度 L ( w ) L(w) L(w)为
∇ w L ( w ) = ∑ x i ∈ M ( y ^ i − y i ) x i \nabla_{\boldsymbol{w}} L(\boldsymbol{w})=\sum_{\boldsymbol{x}_{i} \in M}\left(\hat{y}_{i}-y_{i}\right) \boldsymbol{x}_{i} ∇wL(w)=∑xi∈M(y^i−yi)xi
感知机的学习算法具体采用的是随机梯度下降法,也就是极小化过程中不是一次使
M
M
M中
所有误分类点的梯度下降,而是一次随机选取一个误分类点使其梯度下降。所以权重
w
w
w
的更新公式为
w ← w + Δ w Δ w = − η ( y ^ i − y i ) x i = η ( y i − y ^ i ) x i \begin{array}{c} \boldsymbol{w} \leftarrow \boldsymbol{w}+\Delta \boldsymbol{w} \\ \\ \Delta \boldsymbol{w}=-\eta\left(\hat{y}_{i}-y_{i}\right) \boldsymbol{x}_{i}=\eta\left(y_{i}-\hat{y}_{i}\right) \boldsymbol{x}_{i} \end{array} w←w+ΔwΔw=−η(y^i−yi)xi=η(yi−y^i)xi
相应地, w w w中的某个分量 w i w_{i} wi的更新公式即为 Δ w i = η ( y − y ^ ) x i \Delta w_{i}=\eta(y-\hat{y}) x_{i} Δwi=η(y−y^)xi,最终解出来的 w w w通常不唯一。
BP神经网络
多层前馈网络:每层神经元与下一层神经元全互连,神经元之间不存在同层连接,也不
存在跨层连接。(隐层阈值
γ
h
\gamma_h
γh,输出层阈值
θ
j
\theta_j
θj)
BP代码示例
import numpy as np
#定义sigmoid函数
def sigmoid(x, deriv = False):
if(deriv == True):
return x*(1-x)
else:
return 1/(1+np.exp(-x))
#定义数据集
#input dataset
X = np.array([[0,0,1],
[0,1,1],
[1,0,1],
[1,1,1]])
#output dataset
y = np.array([[0,1,1,0]]).T
#初始化权重
weight01 = 2*np.random.random((3,4)) - 1
weight12 = 2*np.random.random((4,2)) - 1
weight23 = 2*np.random.random((2,1)) - 1
#初始化偏倚
b1 = 2*np.random.random((1,4)) - 1
b2 = 2*np.random.random((1,2)) - 1
b3 = 2*np.random.random((1,1)) - 1
bias1=np.array([b1[0],b1[0],b1[0],b1[0]])
bias2=np.array([b2[0],b2[0],b2[0],b2[0]])
bias3=np.array([b3[0],b3[0],b3[0],b3[0]])
#开始训练
for j in range(60000):
I0 = X
O0=I0
I1=np.dot(O0,weight01)+bias1
O1=sigmoid(I1)
I2=np.dot(O1,weight12)+bias2
O2=sigmoid(I2)
I3=np.dot(O2,weight23)+bias3
O3=sigmoid(I3)
f3_error = y-O3
f3_delta = f3_error*sigmoid(O3,deriv = True)
f2_error = f3_delta.dot(weight23.T)
f2_delta = f2_error*sigmoid(O2,deriv = True)
f1_error = f2_delta.dot(weight12.T)
f1_delta = f1_error*sigmoid(O1,deriv = True)
weight23 += O2.T.dot(f3_delta) #调整权重
weight12 += O1.T.dot(f2_delta)
weight01 += O0.T.dot(f1_delta)
bias3 += f3_delta #调整偏倚
bias2 += f2_delta
bias1 += f1_delta
print ("outout after Training:")
print (O3)
运行结果:
outout after Training:
[[0.00202759]
[0.99787938]
[0.99788573]
[0.00205667]]