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 相关文章推荐
django自定义Field实现一个字段存储以逗号分隔的字符串
Apr 27 Python
初步认识Python中的列表与位运算符
Oct 12 Python
深入理解NumPy简明教程---数组1
Dec 17 Python
python中如何正确使用正则表达式的详细模式(Verbose mode expression)
Nov 08 Python
Python 数据处理库 pandas进阶教程
Apr 21 Python
解决tensorflow测试模型时NotFoundError错误的问题
Jul 26 Python
pycharm 将python文件打包为exe格式的方法
Jan 16 Python
Python求凸包及多边形面积教程
Apr 12 Python
Python 日期时间datetime 加一天,减一天,加减一小时一分钟,加减一年
Apr 16 Python
解决windows上安装tensorflow时报错,“DLL load failed: 找不到指定的模块”的问题
May 20 Python
解决Python3.7.0 SSL低版本导致Pip无法使用问题
Sep 03 Python
python实现简单猜单词游戏
Dec 24 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
构建简单的Webmail系统
2006/10/09 PHP
php创建基本身份认证站点的方法详解
2013/06/08 PHP
简单的php新闻发布系统教程
2014/05/09 PHP
thinkphp5引入公共部分header、footer的方法详解
2018/09/14 PHP
PHP cookie,session的使用与用户自动登录功能实现方法分析
2019/06/05 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
2019/12/18 PHP
解决微信浏览器Javascript无法使用window.location.reload()刷新页面
2016/06/21 Javascript
JavaScript性能优化之函数节流(throttle)与函数去抖(debounce)
2016/08/11 Javascript
JavaScript实现自动切换图片代码
2016/10/11 Javascript
jQuery插件zTree实现获取一级节点数据的方法
2017/03/08 Javascript
详解Vue 普通对象数据更新与 file 对象数据更新
2017/04/26 Javascript
NodeJs模拟登陆正方教务
2017/04/28 NodeJs
NodeJs的fs读写删除移动监听
2017/04/28 NodeJs
微信小程序显示下拉列表功能【附源码下载】
2017/12/12 Javascript
vue如何根据网站路由判断页面主题色详解
2018/11/02 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
Nodejs监控事件循环异常示例详解
2019/09/22 NodeJs
基于VUE的v-charts的曲线显示功能
2019/10/01 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
2020/08/10 Javascript
微信小程序实现音乐播放页面布局
2020/12/11 Javascript
vue使用lodop打印控件实现浏览器兼容打印的方法
2021/02/07 Vue.js
Python获取当前路径实现代码
2017/05/08 Python
Python通过命令开启http.server服务器的方法
2017/11/04 Python
把csv文件转化为数组及数组的切片方法
2018/07/04 Python
matlab灰度图像调整及imadjust函数的用法详解
2020/02/27 Python
Python random库使用方法及异常处理方案
2020/03/02 Python
python3.8.1+selenium实现登录滑块验证功能
2020/05/22 Python
修复iPhone的safari浏览器上submit按钮圆角bug
2012/12/24 HTML / CSS
中科方德软件测试面试题
2016/04/21 面试题
会计电算化应届生求职信
2013/11/03 职场文书
上课迟到检讨书
2014/01/19 职场文书
我的五年职业生涯规划
2014/01/23 职场文书
幼儿园教研活动总结
2014/04/30 职场文书
公司募捐倡议书
2014/05/14 职场文书
晚自修旷课检讨书怎么写
2014/11/17 职场文书
2015年药店工作总结
2015/04/20 职场文书