太阳不下山 发表于 2021-6-23 22:28:20

python实现单隐层神经网络基本模型

  应朋友之请写了一份python实现单隐层BP Ann model的code,好久没写博客,就顺便发上来。这篇代码比较干净利落,比较纯粹的描述了Ann的基本原理,初学机器学习的同学可以参考。

模型中几个比较重要的参数:1.学习率学习率是影响模型收敛的重要因素,一般来说要根据具体场景灵活调整,过高的学习率会使得函数快速发散。2.隐元数量一般来说,增加隐层中神经元的数量比直接增加隐层更加有效,这也是单隐层神经网络的特点。对于复杂程度不算太高的问题而言,单隐层的效果优于多隐层。3.随机种子位数代码中增加了这一参数,来控制初始化连接权与阈值的精度。由于神经网络中初始权重与阈值是随机生成的,那么其随机精度会对结果产生一定的影响。在输入元、隐元的数量较多时,调整随机精度会起到减小误差的作用。
代码中举了一个非常简单的训练示例,笔者自拟了一个规则:    输入两个变量,当变量A = 变量B时,返回类型1,矩阵化为。当变量A != 变量B时,返回类型2,矩阵化为。
让神经网络去学习这个simple的规则,并给出20条测试数据去验证。最终使用了5000条训练数据,就获得了100%的正确分类能力。
#---Author:伍思磊---Mail:wusilei@1006.tv---2015/7/27

import random
import math
---神经网络Model
class Ann:
#构造函数 初始化模型参数
def __init__(self, i_num, h_num, o_num):

      #可调参数
      self.learn_rate = 0.1    #学习率
      self.num_long = 2      #输出结果位数
      self.random_long = 10    #随机种子位数
      #输入参数
      self.input_num = i_num   #输入层 数量
      self.hidden_num = h_num#隐层 数量
      self.output_num = o_num#输出层 数量

      #模型参数
      self.input = []          #输入层
      self.hidden = []         #隐层
      self.output = []         #输出层
      self.error = []          #误差
      self.expectation = []    #期望
      self.weight_ih = self.__ini_weight(self.input_num, self.hidden_num)   #输入层->隐层 连接权
      self.weight_ho = self.__ini_weight(self.hidden_num, self.output_num)#隐层->输出层 连接权
      self.threshold_h = self.__ini_threshold(self.hidden_num)            #隐层 阈值
      self.threshold_o = self.__ini_threshold(self.output_num)            #输出层 阈值
        #初始连接权生成器
  def __ini_weight(self, x, y):

      result = []
      long = math.pow(10, self.random_long)
      for i in range(0, x, 1):
            res = []
            for j in range(0, y, 1):
                num = round(random.randint(-1*long,long)/long, self.random_long)
                res.insert(j, num)
            result.insert(i, res)
      return result  #初始阈值生成器
  def __ini_threshold(self, n):

      result = []
      long = pow(10, self.random_long)
      for i in range(0, n, 1):
            num = round(random.randint(-1*long,long)/long, self.random_long)
            result.insert(i, num)
      return result  #激励函数 sigma
  def excitation(self, value):

      sigma = 1/(1+(math.exp(-1*value)))
      return sigma  #输入数据
  def input_param(self, data, expectation = []):

      self.input = []
      for value in data:
            self.input.append(value)
      if(expectation):
            self.expectation = []
            for value in expectation:
                self.expectation.append(value)  #隐层计算
  def count_hidden(self):

      self.hidden = []
      for h in range(0, self.hidden_num, 1):
            Hval = 0
            for i in range(len(self.input)):
                Hval += self.input * self.weight_ih
            Hval = self.excitation(Hval+self.threshold_h)
            self.hidden.insert(h, Hval)  #输出层计算
  def count_output(self):

      self.output = []
      for o in range(0, self.output_num, 1):
            Oval = 0
            for h in range(len(self.hidden)):
                Oval += self.hidden * self.weight_ho
            Oval += self.threshold_o
            Oval = round(Oval, self.num_long)
            self.output.insert(o, Oval)  #误差计算
  def count_error(self):

      self.error = []
      for key in range(len(self.output)):
            self.error.insert(key, self.expectation - self.output)  #连接权反馈训练 输入层->隐层
  def train_weight_ih(self):

      for i in range(len(self.weight_ih)):
            for h in range(len(self.weight_ih)):
                tmp = 0
                for o in range(0, self.output_num, 1):
                  tmp += self.weight_ho * self.error
                self.weight_ih = self.weight_ih + self.learn_rate * self.hidden * (1 - self.hidden) * self.input * tmp
              #连接权反馈训练 隐层->输出层
  def train_weight_ho(self):

      for h in range(len(self.weight_ho)):
            for o in range(len(self.weight_ho)):
                self.weight_ho = self.weight_ho + self.learn_rate * self.hidden * self.error
               
    #阈值反馈训练 隐层
    def train_threshold_h(self):
      for h in range(len(self.threshold_h)):
            tmp = 0
            for o in range(0, self.output_num, 1):
                tmp += self.weight_ho * self.error
            self.threshold_h = self.threshold_h + self.learn_rate * self.hidden * (1 - self.hidden) * tmp
              #阈值反馈训练 输出层
  def train_threshold_o(self):

      for o in range(len(self.threshold_o)):
            self.threshold_o = self.threshold_o + self.error  #反馈训练
  def train(self):

      self.train_weight_ih()
      self.train_weight_ho()
      self.train_threshold_h()
      self.train_threshold_o()  #归一化函数
  def normal_num(self, max, min, data):

      data = (data - min)/(max - min)
      return data  #寻找集合的最大值和最小值

---业务部分(示例)

要训练的规则,输入两个值,如果两值相等返回,反之返回

  def testFunc(val):
  if(val == val):

      return
    else:
      return
构造神经网络模型

  ann = Ann(2,3,2)

生成训练数据,随机生成5000组随机数组

  data = []
  for i in range(0, 10000, 1):
  x = random.randint(0,1)
  y = random.randint(0,1)
  data.append()

取得训练数据中的最大值和最小值

  for i in range(len(data)):
  for j in range(len(data)):

      if(i == 0 and j == 0):
            max = min = data
      elif(data > max):
            max = data
      elif(data < min):
            min = data
训练数据归一化

  dataNormal = []
  for i in range(len(data)):
  dataNormal.insert(i, [])
  for j in range(len(data)):

      dataNormal.append(ann.normal_num(max, min, data))
计算训练数据期望值,并进行反馈训练

  for i in range(len(data)):
  #计算期望值
  exp = testFunc(data)
  #输入训练数据与期望
  ann.input_param(dataNormal, exp)
  #计算隐层
  ann.count_hidden()
  #计算输出层
  ann.count_output()
  #计算误差
  ann.count_error()
  #反馈训练
  ann.train()

生成测试数据,随机生成20组

  testdata = []
  for i in range(0, 20, 1):
  x = random.randint(0,1)
  y = random.randint(0,1)
  testdata.append()

进行测试,同时输出神经网络预测值与实际期望值

  for i in range(len(testdata)):
  exp = testFunc(testdata)
  ann.input_param(testdata)
  ann.count_hidden()
  ann.count_output()
  print("Ann:")
  print(ann.output)
  print("Exp:")
  print(exp)
print("\r")

页: [1]
查看完整版本: python实现单隐层神经网络基本模型