Python methods based on neural network structure to flexibly define numpy

This article describes the example Python numpy flexible definition based neural network structure method. Share to you for your reference, as follows:

Numpy with the flexibility to define the neural network architecture can also be applied numpy powerful matrix calculation function!

A usage

1) Define a three-layer neural network:

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

Description:
  The number of input layer nodes: 3
  number of hidden layer nodes: 4
  Number of output layer nodes: 2

2) define a five-layer neural network:

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

Description:
  The number of input layer nodes: 3
  Number of nodes in the hidden layer 1: 5
  hidden layer node number 2: 7
  hidden layer nodes Number 3: 4
  the number of output layer nodes: 2

Second, the realization

He realized the following way (@ hhh5460) original. Important: 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])) # 全零

Here is my complete code learning Stanford Machine Learning course, completely knocked out of their own:

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)) # 预测

Finally, we recommend a very wide python learning resource gathering, [click to enter] , here are my collection before learning experience, study notes, there is a chance of business experience, and calmed down to zero on the basis of information to project combat , we can at the bottom, leave a message, do not know to put forward, we will study together progress

Published 43 original articles · won praise 13 · views 50000 +

Guess you like

Origin blog.csdn.net/haoxun11/article/details/105056519