深度学习基础模型算法原理及编程实现–01.感知机
如今深度学习技术发展风起云涌,在各个领域都有所作为,作为一个完全门外汉的我实在受不了深度学习的强大诱惑,学习了相关入门书籍及博客。学习中发现部分学习资料要不公式推导不细,要不算法实现不全,而对于刚入门或未入门的初学者来说,详细的公式推导有助于理解算法细节,程序跑出满意的结果可以增加学习信心。出于自我知识整理以及交流的目的,我将几类常用的最基本神经网络模型的算法原理及C++、python编程实现都做了整理归纳,以供大家交流,由于我自己也是刚学习,理解难免有疏忽,感觉自己目前也仅仅是对公式推导有全面的了解,但对于公式背后的物理意义还需进一步学习,同时也是利用这个机会,希望大家抽空看完后多多指导,一同摸索深度学习的自学之路。
神经网络通过学习输入数据与输出标签之间的映射关系来解决问题,神经网络由神经元组成,最早的神经元是感知机,改变感知机中的激活函数可以得到其他类型的神经元。以神经元的数学模型为基础,将神经元按照一定的拓扑结构联成网状结构,可分为前向网络(有向无环)和反馈网络(无向完备图,也称为循环网络)。前向网络结构简单,通过线性或非线性函数的多次复合计算得到,可分为输入层、中间层(隐藏层)、输出层,隐藏层层数为1的前向网络称为单隐藏前馈神经网络;隐藏层层数大于1的前向网络称为多隐层前馈神经网络,常见的前向网络有全链接、卷积神经网络及其变体等。反馈网络相对较为复杂,模型输出与历史输入或参考输入相关,常见的反馈网络有RNN及其变体等。
1感知机
感知机是二类分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别。感知机引入误分类点函数间隔之和为损失函数,利用梯度下降寻找损失函数极小值,从而获得将线性可分数据集中的正负样本点进行精确划分的超平面。感知机是一种比较简单的神经元,在上世纪中期很流行,但应用有限,不过作为入门学习还是很有必要了解一下的,下面将介绍感知机的算法原理以及编程实现。首先通过感知机模型来建立起对感知机的直观认识。
图 1感知机模型
从上图可以看出,感知机模型有输入信息、权重、偏置项、求和节点、激活函数及输出组成,其中求和节点及输出均可由其他元素表示,因此下面只对输入信息、权重、偏置项及激活函数进行说明。具体的数学公式表示如下:
net=Wx+b(1.1)
(1.1)net=Wx+b
o=f(Wx)(1.2)
(1.2)o=f(Wx)
其中xx为输入元素, WW为输入元素到节点的权重系数矩阵,表示输入相应于输出的重要性, bb为偏置系数,某种意义上将表征了阈值的负数, netnet 为节点的加权输入, ff为激活函数, oo为输出项。感知机中利用阶跃函数作为激活函数,阶跃函数的定义如下:
y=f(x)=sign(x)={1,x≥0−1,x<0(1.3)
(1.3)y=f(x)=sign(x)={1,x≥0−1,x<0
感知机利用线性方程Wx+b=0Wx+b=0构成的超平面来将特征空间区分为2个部分,不同部分内的数据集一般通过标签+1、−1+1、−1来表示。
1.1感知机的训练
对于数据集T={(x1,y1),(x2,y2),......,(xN,yN)}T={(x1,y1),(x2,y2),......,(xN,yN)},其中xixi为输入元素,yi∈{−1,+1}yi∈{−1,+1}为输出元素,感知机的作用就是寻找合适的超平面Wx+b=0Wx+b=0将正负实例点划分到该超平面的两侧,即当yi=1yi=1时,有Wxi+b>0Wxi+b>0;当yi=−1yi=−1时,有Wxi+b<0Wxi+b<0。
与一般的神经网络训练方法类似,感知机的训练同样可分为前向计算、误差项计算以及系数更新这3个部分。下面分别对其进行描述
1.1.1前向计算
对于任意输入信息 ,利用上面的式(1.1)及式(1.2)即可完成前向计算。
1.1.2误差项计算
目标函数对加权输入的导数称为误差项。计算误差项时,首先需建立目标方程,感知机中将误分类点函数间隔之和1定义为损失函数 :
E=−∑xi∈误分类点集合yi(Wxi+b)(1.4)
(1.4)E=−∑xi∈误分类点集合yi(Wxi+b)
那么误差项可表示为:
δ=−∑xi∈误分类点集合yi(1.5)
(1.5)δ=−∑xi∈误分类点集合yi
由于感知机模型较为简单,误差项对各参数的求解意义不大。为了利用梯度下降法求解问题,还需要获取损失函数对权重系数及偏置项的偏导数:
∂E∂W(j)=−∑xi∈误分类点集合yixi(j)(1.6)
(1.6)∂E∂W(j)=−∑xi∈误分类点集合yixi(j)
∂E∂b=−∑xi∈误分类点集合yi(1.7)
(1.7)∂E∂b=−∑xi∈误分类点集合yi
式(1.6)中的 表示输入项中的第 个元素,将其扩展成矢量形式,有:
∂E∂W=−∑xi∈误分类点集合yixi(1.8)
(1.8)∂E∂W=−∑xi∈误分类点集合yixi
1.1.3系数更新
W=W−η∂E∂W(1.9)
(1.9)W=W−η∂E∂W
b=b−η∂E∂b(1.10)
(1.10)b=b−η∂E∂b
这两个公式的几何意义相当于:当一个实例点被误分类,调整W和b,使分类超平面向该误分类点的移动,直至超平面移至该误分类点的另一侧使其正确分类。
1.1.4小结
(1).感知机是线性模型,只能处理线性二类分类问题,不能表示异或,因为异或为线性不可分数据集,求解过程中总是存在误分类点,算法不能收敛。但可以用多层感知机来实现:
方法1:
import numpy as np
import matplotlib.pyplot as plt
def sign(x):
y = x.copy() #浅拷贝,仅复制一层【如list1中包含list2的情况,[*,,*],浅拷贝只拷贝了其中list2的地址,并没有拷贝list2中的内容。注意其与深拷贝的区别】
y[y>0.5] = 1
y[y<=0.5] = 0
return y
x = np.linspace(-5,5,1000)
y1 = 1/(1+np.exp(-x + 1.5))
y2 = 1/(1+np.exp(-x + 0.5))
plt.figure(1)
plt.plot(x,sign(y1),'b',x,sign(y2),'r')
plt.axis([-5,5,-0.5,1.5])
y3 = 0.9*(-1*y1 + y2) + 0.3
plt.figure(2)
plt.plot(x,sign(y3),'b',x,y3,'r')
plt.xlim(0,2)
plt.ylim(-0.5,1.5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
方法2:
import numpy as np
import matplotlib.pyplot as plt
def sign(x):
y = x.copy()
y[y>0.5] = 1
y[y<=0.5] = 0
return y
x = np.linspace(-5,5,1000)
y1 = sign(1/(1+np.exp(-x + 1.5)))
y2 = sign(1/(1+np.exp(-x + 0.5)))
plt.figure(1)
plt.plot(x,y1,'b',x,y2,'r')
plt.axis([0,2,-0.5,1.5])
y3 = (-1*y1 + y2)
plt.figure(2)
plt.plot(x,sign(y3),'b-',x,y3,'r--')
plt.xlim(0,2)
plt.ylim(-0.5,1.5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#【注】python中浅复制与深复制
names = ["小明", "小红", "小黑", "小黄", "小白"]
实现浅复制的三种方法
names1 = copy.copy(names)
names2 = names[:]
names3 = list(names)
深复制的方法
deep_names = copy.deepcopy(names)
1
2
3
4
5
6
7
8
(2).感知机的解与权重系数及偏置系数的初值有关,也与误分类点的选择次序有关,感知机存在多个解,下图中给出了示意,其中黄色圆点为一类点,红色圆点为一类点,黑线为感知机求解出的超平面。
图2 感知机分类结果示意
很明显,上面几组结果都将样本点正确分类,由于没有考虑泛化能力2,这几组结果中的超平面离样本点太近了,这明显是不合理的。由于感知机的损失函数定义为误分类点的函数间隔绝对值之和,最小化损失函数等价于误分类点个数为0,即只有超平面将正负样本点正确分类,感知机就停止求解,这个条件太宽泛,所以才会导致感知机存在多个解。
1.2 编程实现
由于感知机算法编程实现比较简单,这里不再做详细说明,可直接参看上传的代码,或者自己手动编写一个。
python版本:https://pan.baidu.com/s/1qZLJ7Gg
C++版本:https://pan.baidu.com/s/1qZLJ7Gg
---------------------
【转载】
作者:drilistbox
原文:https://blog.csdn.net/drilistbox/article/details/79341381
|
|