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

作者:罗兵 时间:2023-09-30 15:03:52 

本文实例讲述了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程序设计有所帮助。

来源:http://www.cnblogs.com/hhh5460/p/5124132.html

标签:Python,numpy,神经网络
0
投稿

猜你喜欢

  • Favicon图标小常识

    2010-04-01 12:01:00
  • 教你用Python3+mysql8.0搭建Django框架

    2024-01-26 23:19:39
  • Python常用知识点汇总

    2023-02-17 09:42:44
  • 全面理解javascript的caller,callee,call,apply概念

    2007-12-02 17:44:00
  • Django 使用easy_thumbnails压缩上传的图片方法

    2023-11-10 07:47:38
  • Oracle静态注册与动态注册详解

    2024-01-19 22:31:31
  • python3.7.3版本和django2.2.3版本是否可以兼容

    2022-08-18 09:31:23
  • pycharm开发一个简单界面和通用mvc模板(操作方法图解)

    2022-10-09 06:28:39
  • python解析xml文件实例分享

    2021-11-20 07:56:14
  • vue.js 实现点击展开收起动画效果

    2024-05-29 22:47:44
  • javascript实现多栏闭合展开式广告位菜单效果实例

    2024-04-29 14:07:44
  • python unicodedata模块用法

    2021-04-05 20:53:55
  • Python如何读取PDF文档(或TXT)

    2021-10-01 06:24:36
  • MySQL注入绕开过滤的技巧总结

    2024-01-14 10:42:52
  • Python实现PS滤镜Fish lens图像扭曲效果示例

    2022-02-01 05:25:02
  • centos7通过yum安装mysql的方法

    2024-01-18 06:48:57
  • python时间日期函数与利用pandas进行时间序列处理详解

    2023-06-15 20:39:40
  • python实现绘制树枝简单示例

    2022-05-05 23:02:25
  • javascript设计模式交流(二) Prototype Pattern

    2007-11-29 14:01:00
  • PYcharm 激活方法(推荐)

    2022-07-27 01:51:21
  • asp之家 网络编程 m.aspxhome.com