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中引用与复制用法实例分析
Jun 04 Python
python 时间戳与格式化时间的转化实现代码
Mar 23 Python
python 生成器生成杨辉三角的方法(必看)
Apr 10 Python
Python文件和流(实例讲解)
Sep 12 Python
完美解决python中ndarray 默认用科学计数法显示的问题
Jul 14 Python
详解python如何在django中为用户模型添加自定义权限
Oct 15 Python
Python matplotlib生成图片背景透明的示例代码
Aug 30 Python
Django使用uwsgi部署时的配置以及django日志文件的处理方法
Aug 30 Python
python 使用while写猜年龄小游戏过程解析
Oct 07 Python
Python数据分析库pandas高级接口dt的使用详解
Dec 11 Python
教你用Python matplotlib库制作简单的动画
Jun 11 Python
Python语言内置数据类型
Feb 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
Symfony学习十分钟入门经典教程
2016/02/03 PHP
快速保存网页中所有图片的方法
2006/06/23 Javascript
JS在可编辑的div中的光标位置插入内容的方法
2014/11/20 Javascript
Javascript的动态增加类的实现方法
2016/10/20 Javascript
JS封装的三级联动菜单(使用时只需要一行js代码)
2016/10/24 Javascript
关于页面刷新vuex数据消失问题解决方案
2017/07/03 Javascript
bootstrap响应式工具使用详解
2017/11/29 Javascript
微信小程序实现提交input信息到后台的方法示例
2019/01/19 Javascript
详解Vuex下Store的模块化拆分实践
2019/07/31 Javascript
vue 实现路由跳转时更改页面title
2019/11/05 Javascript
[01:27]2014DOTA2展望TI 剑指西雅图IG战队专访
2014/06/30 DOTA
python读取TXT到数组及列表去重后按原来顺序排序的方法
2015/06/26 Python
使用Python对Access读写操作
2017/03/30 Python
python妙用之编码的转换详解
2017/04/21 Python
python实现扫描日志关键字的示例
2018/04/28 Python
详解python Todo清单实战
2018/11/01 Python
Python使用ctypes调用C/C++的方法
2019/01/29 Python
python 批量修改 labelImg 生成的xml文件的方法
2019/09/09 Python
Python:合并两个numpy矩阵的实现
2019/12/02 Python
Python爬虫之Selenium中frame/iframe表单嵌套页面
2020/12/04 Python
html+css3实现的登录界面
2020/12/09 HTML / CSS
基于Html5实现的react拖拽排序组件示例
2018/08/13 HTML / CSS
Lands’ End官网:经典的美国生活方式品牌
2016/08/14 全球购物
香港莎莎官网Sasa.com:亚洲著名国际化妆品商城
2019/11/10 全球购物
高分子材料与工程专业推荐信
2013/12/01 职场文书
《乌鸦和狐狸》教学反思
2014/02/08 职场文书
建议书怎么写
2014/03/12 职场文书
物业品质提升方案
2014/06/08 职场文书
计划生育标语
2014/06/23 职场文书
九寨沟导游词
2015/02/02 职场文书
建筑工地资料员岗位职责
2015/04/13 职场文书
2019暑期安全倡议书!
2019/06/27 职场文书
高中议论文(范文2篇)
2019/08/19 职场文书
MySQL RC事务隔离的实现
2022/03/31 MySQL
Golang 切片(Slice)实现增删改查
2022/04/22 Golang
详解Go语言中配置文件使用与日志配置
2022/06/01 Golang