使用python实现ANN


Posted in Python onDecember 20, 2017

本文实例为大家分享了python实现ANN的具体代码,供大家参考,具体内容如下

1.简要介绍神经网络

神经网络是具有适应性的简单单元组成的广泛并行互联的网络。它的组织能够模拟生物神经系统对真实世界物体做做出的反应。神经网络的最基本的成分是神经元模型,也就是最简单的神经元模型。

“M-P模型”

使用python实现ANN

如上图所示,神经元接收到来自n个其他神经元传递过来的输入信号,这些信号通过带权重的链接进行传递。神经元接收到的总输入值将与神经元的阈值进行比较,然后通过“激活函数”处理以产生神经元的输出

激活函数:

理想的激活函数应该是阶跃函数,也就是它能够将输入值映射成为输出值0或1。其中“0”代表神经元抑制,“1”代表神经元兴奋。但是由于阶跃函数不连续且不可导,因此实际上常常使用sigmoid函数当做神经元的激活函数。它能够将可能在较大范围内变化的输出值挤压到(0,1)之间这个范围内。因此有时也成为挤压函数。常用的sigmoid函数是回归函数

f(x) = 1/(1+e^(-x))

如下图所示:

使用python实现ANN

感知机:

感知机是最简单的神经网络,它由两层神经元组成。输入层接受外界信号后传递给输出层。输出层是M-P神经元。感知机也成为阈值逻辑单元。感知机可以通过采用监督学习来逐步增强模式划分的能力,达到学习的目的。

使用python实现ANN

感知机能够实现简单的逻辑运算。

一般的,对于给定训练数据集,权重Wi以及阈值θ可以通过学习得到。其中阈值(bias)可以通过学习得到。在输出神经元中,阈值可以看做是一个固定输入为-1,0的哑结点,所对应的连接权重为Wn+1,从而使得权重和阈值的学习统一为权重的学习。

感知机的学习规则非常简单,对于训练样本(X,y),若当前感知机输出为y',则感知机做如下调整

使用python实现ANN

其中,η属于(0,1),称为“学习率”

若感知机对训练样例预测正确,则感知机不发生变化,否则将根据错误的程度进行权重的调整。

需要注意的是,感知机只有输出神经元进行激活函数处理,因此它的学习能力非常有限,也就是因为它只有一层功能神经元。

可以证明,若两类模式实现性可分的,即存在一个超平面可以将他们分开,则利用感知机一定会收敛,可以求得一个权向量。否则,感知机的学习过程将会发生震荡,导致参数难以稳定下来,不等求得合适的解。例如,单层感知机不能解决抑或问题。

如果想要解决非线性可分问题,考虑使用多层功能神经元。

前馈神经网络

每层神经元与下一层神经元全互联,神经元之间不存在同层链接,也不存在跨曾链接。其中输入层神经元有由外界进行输入,隐藏层与输出层神经元对信号进行加工,最终结果由输出层神经元进行输出。输入层神经元仅仅起到接受输入的功能,并不进行函数处理。

所谓的神经网络的学习过程,也就是根据训练数据来调整神经元之间的“连接权”以及每个功能神经元的阈值,换句话说,神经网络能够“学习”到的东西,全部都蕴含在“连接权”与“阈值”之中

BP算法(误差逆传播算法)

BP算法,也成为反向传播算法

•在感知器算法中我们实际上是在利用理想输出与实际输出之间的误差作为增量来修正权值,然而在多层感知器中,我们只能计算出输出层的误差,中间隐层由于不直接与外界连接,其误差无法估计。

•反向传播算法(BP算法)的思想:从后向前反向逐层传播输出层的误差,以间接计算隐层的误差。算法可以分为两个阶段:
?正向过程:从输入层经隐层逐层正向计算各单元的输出;
?反向过程:由输出误差逐层反向计算隐层各单元的误差,并用此误差修正前层的权值。

B-P算法的学习过程如下:
(1)选择一组训练样例,每一个样例由输入信息和期望的输出结果两部分组成。
(2)从训练样例集中取一样例,把输入信息输入到网络中。
(3)分别计算经神经元处理后的各层节点的输出。
(4)计算网络的实际输出和期望输出的误差。
(5)从输出层反向计算到第一个隐层,并按照某种能使误差向减小方向发展的原则,调整网络中各神经元的连接权值。
(6)对训练样例集中的每一个样例重复(3)-(5)的步骤,直到对整个训练样例集的误差达到要求时为止。
•优点:
?理论基础牢固,推导过程严谨,物理概念清晰,通用性好等。所以,它是目前用来训练前馈多层网络较好的算法。
•缺点:
?BP算法的收敛速度一般来说比较慢;
?BP算法只能收敛于局部最优解,不能保证收敛于全局最优解;
?当隐层元的数量足够多时,网络对训练样本的识别率很高,但对测试样本的识别率有可能很差,即网络的推广能力有可能较差。
具体的公式在这里不再给出,因为相关的资料也有很多,可以随时查阅。
可以证明:
只需要一个包含足够多的神经元的因曾,多层前馈网络能够以任意精度逼近任意复杂度的连续函数。而主要的问题是:如何设置隐层神经元的个数?
考虑采用”试错法“
因为前馈网络具有强大地表示能力,因此BP算法有时会出现过拟合的现象,对于过拟合,采用的主要策略是早停正则化
早停:将数据集分为训练集和验证集,训练集用来计算梯度,更新连接权值和阈值,验证集用来估计误差,若训练集误差降低但验证集误差升高,则立即停止训练。返回具有最小验证集误差的连接权和阈值。
正则化:在误差目标函数中增加一个用来描述网络复杂度的部分。例如连接权与阈值的平方和,仍令Ek为第k个训练样例上误差,Wi表示链接权和阈值,则误差目标函数定义为:

使用python实现ANN

其中λ属于(0,1),用对经验误差与网络复杂度这两项进行这种,使用”交叉验证“

2.使用python和机器学习库sklearn库编程实现:

# coding=utf-8 
# 使用Python构建ANN 
 
import numpy as np 
 
# 双曲函数 
def tanh(x): 
 return np.tanh(x) 
 
# 双曲函数的微分 
def tanh_deriv(x): 
 return 1.0 - np.tanh(x) * np.tanh(x) 
 
# 逻辑函数 
def logistics(x): 
 return 1 / (1+np.exp(-x)) 
 
# 逻辑函数的微分 
def logistics_derivative(x): 
 return logistics(x)*(1-logistics(x)) 
 
# 使用类 面向对象的技巧 建立ANN 
class NeuralNetwork: 
 # 构造函数 layers指的是每层内有多少个神经元 layers内的数量表示有几层 
 # acvitation 为使用的激活函数名称 有默认值 tanh 表示使用tanh(x) 
 def __init__(self,layers,activation='tanh'): 
  if activation == 'logistic': 
   self.activation = logistics 
   self.activation_deriv = logistics_derivative 
  elif activation == 'tanh': 
   self.activation = tanh 
   self.activation = tanh_deriv 
 
  self.weight =[] 
  # len(layers)-1的目的是 输出层不需要赋予相应的权值 
  for i in range(1,len(layers) - 1): 
   # 第一句是对当前层与前一层之间的连线进行权重赋值,范围在 -0.25 ~ 0.25之间 
   self.weight.append((2*np.random.random((layers[i-1]+1,layers[i]+1))-1)*0.25) 
   # 第二句是对当前层与下一层之间的连线进行权重赋值,范围在 -0.25 ~ 0.25之间 
   self.weight.append((2*np.random.random((layers[i]+1,layers[i+1]))-1)*0.25) 
 
 def fit(self,X,y,learning_rate = 0.2,epochs = 10000): 
  # self是指引当前类的指针 X表示训练集 通常模拟成一个二维矩阵,每一行代表一个样本的不同特征 
  # 每一列代表不同的样本 y指的是classLabel 表示的是输出的分类标记 
  # learning_rate是学习率,epochs表示循环的次数 
  X = np.atleast_2d(X) 
  # 将X转换为numpy2维数组 至少是2维的 
  temp = np.ones([X.shape[0],X.shape[1]+1]) 
  # X.shape[0]返回的是X的行数 X.shape[1]返回的是X的列数 
  temp[:,0:-1] = X # :指的是所有的行 0:-1指的是从第一列到除了最后一列 
  X = temp # 偏向的赋值 
  y = np.array(y)  # 将y转换为numpy array的形式 
 
  # 使用抽样的算法 每次随机选一个 x中的样本 
  for k in range(epochs): 
   # randint(X.shape[0])指的是从0~X.shape[0] 之间随机生成一个int型的数字 
   i = np.random.randint(X.shape[0]) 
   a = [X[i]] # a是从x中任意抽取的一行数据 
 
   #正向更新 
   for l in range(len(self.weight)): # 循环遍历每一层 
    # dot是求内积的运算 将内积运算的结果放在非线性转换方程之中 
    a.append(self.activation(np.dot(a[l], self.weight[l]))) 
 
   error = y[i] - a[-1] # 求误差 a[-1]指的是最后一层的classLabel 
   deltas = [error * self.activation_deriv(a[-1])] 
 
   # 开始反向传播 从最后一层开始,到第0层,每次回退1层 
   for l in range(len(a) - 2,0,-1): 
    deltas.append(deltas[-1].dot(self.weight[l].T)*self.activation_deriv(a[l])) 
   deltas.reverse() 
 
   for i in range(len(self.weight)): 
    layer = np.atleast_2d(a[i]) 
    delta = np.atleast_2d(deltas[i]) # delta存的是误差 
    self.weight[i] += learning_rate * layer.T.dot(delta) # 误差与单元格的值的内积 
 
 # 预测过程 
 def predict(self,x): 
  x=np.array(x) 
  temp = np.ones(x.shape[0]+1) 
  temp[0:-1] = x 
  a = temp 
  for l in range(0,len(self.weight)): 
   a = self.activation(np.dot(a,self.weight[l])) 
  return a

使用简单的程序进行测试

# coding=utf-8 
 
from ANN import NeuralNetwork 
import numpy as np 
 
nn = NeuralNetwork([2, 2, 1], 'tanh') 
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) 
y = np.array([0, 1, 1, 0]) 
nn.fit(X, y) 
for i in [[0, 0], [0, 1], [1, 0], [1, 1]]: 
 print(i, nn.predict(i))

执行后,输出的结果为:

使用python实现ANN

End.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之用Python计算
Sep 12 Python
详解Python中的循环语句的用法
Apr 09 Python
Python使用cookielib模块操作cookie的实例教程
Jul 12 Python
Python实现可设置持续运行时间、线程数及时间间隔的多线程异步post请求功能
Jan 11 Python
Python使用wxPython实现计算器
Jan 30 Python
python中的文件打开与关闭操作命令介绍
Apr 26 Python
更换Django默认的模板引擎为jinja2的实现方法
May 28 Python
python中使用zip函数出现错误的原因
Sep 28 Python
python 将对象设置为可迭代的两种实现方法
Jan 21 Python
django haystack实现全文检索的示例代码
Jun 24 Python
浅析Python 条件控制语句
Jul 15 Python
基于python实现MQTT发布订阅过程原理解析
Jul 27 Python
python 计算数组中每个数字出现多少次--“Bucket”桶的思想
Dec 19 #Python
浅谈Python实现贪心算法与活动安排问题
Dec 19 #Python
Python实现感知器模型、两层神经网络
Dec 19 #Python
python实现感知器
Dec 19 #Python
python绘制简单折线图代码示例
Dec 19 #Python
matplotlib设置legend图例代码示例
Dec 19 #Python
matplotlib中legend位置调整解析
Dec 19 #Python
You might like
phpmyadmin 常用选项设置详解版
2010/03/07 PHP
使用PHP获取汉字的拼音(全部与首字母)
2013/06/27 PHP
php实现获取及设置用户访问页面语言类
2014/09/24 PHP
php防止用户重复提交表单
2015/11/02 PHP
PHP汉字转换拼音的函数代码
2015/12/30 PHP
dojo 之基础篇
2007/03/24 Javascript
jquery对表单操作2
2011/04/06 Javascript
JavaScript中undefined和null的区别
2017/05/03 Javascript
webpack学习笔记之优化缓存、合并、懒加载
2017/08/24 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
2018/04/18 jQuery
七行JSON代码把你的网站变成移动应用过程详解
2019/07/09 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
ES6的异步操作之promise用法和async函数的具体使用
2019/12/06 Javascript
详解在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入)
2020/07/11 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
2020/07/17 Javascript
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
[39:52]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第一场
2018/04/04 DOTA
[07:20]2018DOTA2国际邀请赛寻真——逐梦Mineski
2018/08/10 DOTA
python登录QQ邮箱发信的实现代码
2013/02/10 Python
Python算法应用实战之队列详解
2017/02/04 Python
python中如何使用正则表达式的集合字符示例
2017/10/09 Python
python GUI库图形界面开发之PyQt5时间控件QTimer详细使用方法与实例
2020/02/26 Python
Python读取配置文件(config.ini)以及写入配置文件
2020/04/08 Python
python用opencv 图像傅里叶变换
2021/01/04 Python
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
英国现代家具和照明购物网站:Heal’s
2019/10/30 全球购物
乌克兰珠宝大卖场:Zlato.ua
2020/09/27 全球购物
名词解释型面试题(主要是网络)
2013/12/27 面试题
商学院大学生求职的自我评价
2014/03/12 职场文书
乡镇三严三实学习心得体会
2014/10/13 职场文书
长城的导游词
2015/01/30 职场文书
2016公司中秋节寄语
2015/12/07 职场文书
2016年秋季运动会广播稿
2015/12/21 职场文书
四年级语文教学反思
2016/03/03 职场文书
2019终止劳动合同协议书最新范本!
2019/07/09 职场文书
redis三种高可用方式部署的实现
2021/05/11 Redis