使用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 相关文章推荐
Python3搜索及替换文件中文本的方法
May 22 Python
django1.8使用表单上传文件的实现方法
Nov 04 Python
详解django自定义中间件处理
Nov 21 Python
对python_discover方法遍历所有执行的用例详解
Feb 13 Python
flask框架单元测试原理与用法实例分析
Jul 23 Python
Django用户认证系统 Web请求中的认证解析
Aug 02 Python
python matplotlib包图像配色方案分享
Mar 14 Python
QT5 Designer 打不开的问题及解决方法
Aug 20 Python
Python3 用什么IDE开发工具比较好
Nov 28 Python
Python 微信公众号文章爬取的示例代码
Nov 30 Python
Python页面加载的等待方式总结
Feb 28 Python
用Python生成会跳舞的美女
Jan 18 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
PHP音乐采集(部分代码)
2007/02/14 PHP
php判断当前操作系统类型
2015/10/28 PHP
深入解析PHP中foreach语句控制数组循环的用法
2015/11/30 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
2015/12/14 PHP
PHP请求远程地址设置超时时间的解决方法
2016/10/29 PHP
ThinkPHP使用getlist方法实现数据搜索功能示例
2017/05/08 PHP
JavaScript 程序编码规范
2010/11/23 Javascript
Javascript学习笔记一 之 数据类型
2010/12/15 Javascript
在javascript中对于DOM的加强
2013/04/11 Javascript
JavaScript使用slice函数获取数组部分元素的方法
2015/04/06 Javascript
js实现图片点击左右轮播
2015/07/08 Javascript
JS实现网页标题随机显示名人名言的方法
2015/11/03 Javascript
为什么JavaScript没有块级作用域
2016/05/22 Javascript
jQuery网页定位导航特效实现方法
2016/12/19 Javascript
原生JS实现图片懒加载(lazyload)实例
2017/06/13 Javascript
BootStrap Fileinput上传插件使用实例代码
2017/07/28 Javascript
Node.js+Express+Mysql 实现增删改查
2019/04/03 Javascript
[03:01]DOTA2英雄基础教程 露娜
2014/01/07 DOTA
Python获取系统默认字符编码的方法
2015/06/04 Python
总结python爬虫抓站的实用技巧
2016/08/09 Python
深入理解Python中变量赋值的问题
2017/01/12 Python
python的多重继承的理解
2017/08/06 Python
使用Flask集成bootstrap的方法
2018/07/24 Python
Python3.5面向对象编程图文与实例详解
2019/04/24 Python
Python和Anaconda和Pycharm安装教程图文详解
2020/02/04 Python
python多进程 主进程和子进程间共享和不共享全局变量实例
2020/04/25 Python
Python unittest单元测试openpyxl实现过程解析
2020/05/27 Python
python更新数据库中某个字段的数据(方法详解)
2020/11/18 Python
贝斯特韦斯特酒店集团官网:Best Western
2019/01/03 全球购物
合作意向书格式及范文
2014/03/31 职场文书
激励员工的口号
2014/06/16 职场文书
2014年高中生自我评价范文
2014/09/26 职场文书
如何写辞职书
2015/02/26 职场文书
农村婚礼司仪主持词
2015/06/29 职场文书
《中彩那天》教学反思
2016/02/24 职场文书
使用springMVC所需要的pom配置
2021/09/15 Java/Android