Python基于numpy灵活定义神经网络结构的方法


Posted in Python onAugust 19, 2017

本文实例讲述了Python基于numpy灵活定义神经网络结构的方法。分享给大家供大家参考,具体如下:

用numpy可以灵活定义神经网络结构,还可以应用numpy强大的矩阵运算功能!

一、用法

1). 定义一个三层神经网络:

'''示例一'''
nn = NeuralNetworks([3,4,2]) # 定义神经网络
nn.fit(X,y) # 拟合
print(nn.predict(X)) #预测

说明:

输入层节点数目:3

隐藏层节点数目:4

输出层节点数目:2

2).定义一个五层神经网络:

'''示例二'''
nn = NeuralNetworks([3,5,7,4,2]) # 定义神经网络
nn.fit(X,y) # 拟合
print(nn.predict(X)) #预测

说明:

输入层节点数目:3

隐藏层1节点数目:5

隐藏层2节点数目:7

隐藏层3节点数目:4

输出层节点数目:2

二、实现

如下实现方式为本人(@hhh5460)原创。 要点: dtype=object

import numpy as np
class NeuralNetworks(object):
  ''''''
  def __init__(self, n_layers=None, active_type=None, n_iter=10000, error=0.05, alpha=0.5, lamda=0.4):
    '''搭建神经网络框架'''
    # 各层节点数目 (向量)
    self.n = np.array(n_layers) # 'n_layers必须为list类型,如:[3,4,2] 或 n_layers=[3,4,2]'
    self.size = self.n.size # 层的总数
    # 层 (向量)
    self.z = np.empty(self.size, dtype=object) # 先占位(置空),dtype=object !如下皆然
    self.a = np.empty(self.size, dtype=object)
    self.data_a = np.empty(self.size, dtype=object)
    # 偏置 (向量)
    self.b = np.empty(self.size, dtype=object)
    self.delta_b = np.empty(self.size, dtype=object)
    # 权 (矩阵)
    self.w = np.empty(self.size, dtype=object)
    self.delta_w = np.empty(self.size, dtype=object)
    # 填充
    for i in range(self.size):
      self.a[i] = np.zeros(self.n[i]) # 全零
      self.z[i] = np.zeros(self.n[i]) # 全零
      self.data_a[i] = np.zeros(self.n[i]) # 全零
      if i < self.size - 1:
        self.b[i] = np.ones(self.n[i+1])  # 全一
        self.delta_b[i] = np.zeros(self.n[i+1]) # 全零
        mu, sigma = 0, 0.1 # 均值、方差
        self.w[i] = np.random.normal(mu, sigma, (self.n[i], self.n[i+1])) # # 正态分布随机化
        self.delta_w[i] = np.zeros((self.n[i], self.n[i+1])) # 全零

下面完整代码是我学习斯坦福机器学习教程,完全自己敲出来的:

import numpy as np
'''
参考:http://ufldl.stanford.edu/wiki/index.php/%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C
'''
class NeuralNetworks(object):
  ''''''
  def __init__(self, n_layers=None, active_type=None, n_iter=10000, error=0.05, alpha=0.5, lamda=0.4):
    '''搭建神经网络框架'''
    self.n_iter = n_iter # 迭代次数
    self.error = error # 允许最大误差
    self.alpha = alpha # 学习速率
    self.lamda = lamda # 衰减因子 # 此处故意拼写错误!
    if n_layers is None:
      raise '各层的节点数目必须设置!'
    elif not isinstance(n_layers, list):
      raise 'n_layers必须为list类型,如:[3,4,2] 或 n_layers=[3,4,2]'
    # 节点数目 (向量)
    self.n = np.array(n_layers)
    self.size = self.n.size # 层的总数
    # 层 (向量)
    self.a = np.empty(self.size, dtype=object) # 先占位(置空),dtype=object !如下皆然
    self.z = np.empty(self.size, dtype=object)
    # 偏置 (向量)
    self.b = np.empty(self.size, dtype=object)
    self.delta_b = np.empty(self.size, dtype=object)
    # 权 (矩阵)
    self.w = np.empty(self.size, dtype=object)
    self.delta_w = np.empty(self.size, dtype=object)
    # 残差 (向量)
    self.data_a = np.empty(self.size, dtype=object)
    # 填充
    for i in range(self.size):
      self.a[i] = np.zeros(self.n[i]) # 全零
      self.z[i] = np.zeros(self.n[i]) # 全零
      self.data_a[i] = np.zeros(self.n[i]) # 全零
      if i < self.size - 1:
        self.b[i] = np.ones(self.n[i+1])  # 全一
        self.delta_b[i] = np.zeros(self.n[i+1]) # 全零
        mu, sigma = 0, 0.1 # 均值、方差
        self.w[i] = np.random.normal(mu, sigma, (self.n[i], self.n[i+1])) # # 正态分布随机化
        self.delta_w[i] = np.zeros((self.n[i], self.n[i+1])) # 全零
    # 激活函数
    self.active_functions = {
      'sigmoid': self.sigmoid,
      'tanh': self.tanh,
      'radb': self.radb,
      'line': self.line,
    }
    # 激活函数的导函数
    self.derivative_functions = {
      'sigmoid': self.sigmoid_d,
      'tanh': self.tanh_d,
      'radb': self.radb_d,
      'line': self.line_d,
    }
    if active_type is None:
      self.active_type = ['sigmoid'] * (self.size - 1) # 默认激活函数类型
    else:
      self.active_type = active_type
  def sigmoid(self, z):
    if np.max(z) > 600:
      z[z.argmax()] = 600
    return 1.0 / (1.0 + np.exp(-z))
  def tanh(self, z):
    return (np.exp(z) - np.exp(-z)) / (np.exp(z) + np.exp(-z))
  def radb(self, z):
    return np.exp(-z * z)
  def line(self, z):
    return z
  def sigmoid_d(self, z):
    return z * (1.0 - z)
  def tanh_d(self, z):
    return 1.0 - z * z
  def radb_d(self, z):
    return -2.0 * z * np.exp(-z * z)
  def line_d(self, z):
    return np.ones(z.size) # 全一
  def forward(self, x):
    '''正向传播(在线)''' 
    # 用样本 x 走一遍,刷新所有 z, a
    self.a[0] = x
    for i in range(self.size - 1):
      self.z[i+1] = np.dot(self.a[i], self.w[i]) + self.b[i] 
      self.a[i+1] = self.active_functions[self.active_type[i]](self.z[i+1]) # 加了激活函数
  def err(self, X, Y):
    '''误差'''
    last = self.size-1
    err = 0.0
    for x, y in zip(X, Y):
      self.forward(x)
      err += 0.5 * np.sum((self.a[last] - y)**2)
    err /= X.shape[0]
    err += sum([np.sum(w) for w in self.w[:last]**2])
    return err
  def backward(self, y):
    '''反向传播(在线)'''
    last = self.size - 1
    # 用样本 y 走一遍,刷新所有delta_w, delta_b
    self.data_a[last] = -(y - self.a[last]) * self.derivative_functions[self.active_type[last-1]](self.z[last]) # 加了激活函数的导函数
    for i in range(last-1, 1, -1):
      self.data_a[i] = np.dot(self.w[i], self.data_a[i+1]) * self.derivative_functions[self.active_type[i-1]](self.z[i]) # 加了激活函数的导函数
      # 计算偏导
      p_w = np.outer(self.a[i], self.data_a[i+1]) # 外积!感谢 numpy 的强大!
      p_b = self.data_a[i+1]
      # 更新 delta_w, delta_w
      self.delta_w[i] = self.delta_w[i] + p_w
      self.delta_b[i] = self.delta_b[i] + p_b
  def update(self, n_samples):
    '''更新权重参数'''
    last = self.size - 1
    for i in range(last):
      self.w[i] -= self.alpha * ((1/n_samples) * self.delta_w[i] + self.lamda * self.w[i])
      self.b[i] -= self.alpha * ((1/n_samples) * self.delta_b[i])
  def fit(self, X, Y):
    '''拟合'''
    for i in range(self.n_iter):
      # 用所有样本,依次
      for x, y in zip(X, Y):
        self.forward(x) # 前向,更新 a, z;
        self.backward(y) # 后向,更新 delta_w, delta_b
      # 然后,更新 w, b
      self.update(len(X))
      # 计算误差
      err = self.err(X, Y)
      if err < self.error:
        break
      # 整千次显示误差(否则太无聊!)
      if i % 1000 == 0:
        print('iter: {}, error: {}'.format(i, err))
  def predict(self, X):
    '''预测'''
    last = self.size - 1
    res = []
    for x in X:
      self.forward(x)
      res.append(self.a[last])
    return np.array(res)
if __name__ == '__main__':
  nn = NeuralNetworks([2,3,4,3,1], n_iter=5000, alpha=0.4, lamda=0.3, error=0.06) # 定义神经网络
  X = np.array([[0.,0.], # 准备数据
         [0.,1.],
         [1.,0.],
         [1.,1.]])
  y = np.array([0,1,1,0])
  nn.fit(X,y)     # 拟合
  print(nn.predict(X)) # 预测

更多关于Python相关内容可查看本站专题:《Python数学运算技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
初学Python实用技巧两则
Aug 29 Python
python清除指定目录内所有文件中script的方法
Jun 30 Python
利用python代码写的12306订票代码
Dec 20 Python
使用paramiko远程执行命令、下发文件的实例
Oct 01 Python
Python实现嵌套列表去重方法示例
Dec 28 Python
简单实现python画圆功能
Jan 25 Python
Python类和对象的定义与实际应用案例分析
Dec 27 Python
在Django admin中编辑ManyToManyField的实现方法
Aug 09 Python
python NumPy ndarray二维数组 按照行列求平均实例
Nov 26 Python
Jupyter notebook运行Spark+Scala教程
Apr 10 Python
python实现定时发送邮件到指定邮箱
Dec 23 Python
python基础入门之普通操作与函数(三)
Jun 13 Python
Python正则捕获操作示例
Aug 19 #Python
python 删除大文件中的某一行(最有效率的方法)
Aug 19 #Python
在java中如何定义一个抽象属性示例详解
Aug 18 #Python
python中将函数赋值给变量时需要注意的一些问题
Aug 18 #Python
python中子类调用父类函数的方法示例
Aug 18 #Python
Python设计实现的计算器功能完整实例
Aug 18 #Python
python中类和实例如何绑定属性与方法示例详解
Aug 18 #Python
You might like
tp5修改(实现即点即改)
2019/10/18 PHP
在Laravel 中实现是否关注的示例
2019/10/22 PHP
js的逻辑运算符 ||
2010/05/31 Javascript
情人节之礼 js项链效果
2012/02/13 Javascript
javascript与jquery中跳出循环的区别总结
2013/11/04 Javascript
js 赋值包含单引号双引号问题的解决方法
2014/02/26 Javascript
使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)
2014/05/06 Javascript
基于zepto.js实现仿手机QQ空间的大图查看组件ImageView.js详解
2015/03/05 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
2015/12/25 Javascript
封装属于自己的JS组件
2016/01/27 Javascript
基于jQuery实现点击列表加载更多效果
2016/05/31 Javascript
微信公众号  提示:Unauthorized API function 问题解决方法
2016/12/05 Javascript
vue-router跳转页面的方法
2017/02/09 Javascript
JS与jQuery实现ListBox上移,下移,左移,右移操作功能示例
2018/05/31 jQuery
nodejs简单抓包工具使用详解
2019/08/23 NodeJs
Vue切换Tab动态渲染组件的操作
2020/09/21 Javascript
python开启多个子进程并行运行的方法
2015/04/18 Python
用Python编写简单的定时器的方法
2015/05/02 Python
详解Python的Django框架中的Cookie相关处理
2015/07/22 Python
Python中的条件判断语句基础学习教程
2016/02/07 Python
python爬虫入门教程--优雅的HTTP库requests(二)
2017/05/25 Python
CentOS 6.5中安装Python 3.6.2的方法步骤
2017/12/03 Python
Python面向对象编程之继承与多态详解
2018/01/16 Python
python计算日期之间的放假日期
2018/06/05 Python
python基于K-means聚类算法的图像分割
2019/10/30 Python
python tkinter控件布局项目实例
2019/11/04 Python
pycharm快捷键汇总
2020/02/14 Python
Vans(范斯)德国官网:美国南加州的原创极限运动潮牌
2017/05/02 全球购物
印度手工编织服装和家居用品商店:Fabindi
2019/10/07 全球购物
当当网软件测试笔试题
2015/11/24 面试题
客服工作职责
2013/12/11 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
个人融资协议书
2014/10/02 职场文书
惊天动地观后感
2015/06/10 职场文书
Oracle更换为MySQL遇到的问题及解决
2021/05/21 Oracle
python中redis包操作数据库的教程
2022/04/19 Python