赞
踩
python实现神经网络模型算法
今天,厾罗和大家分享用Python实现神经网络模型算法,仅用于技术学习交流。
实现技巧
1.导入依赖库
主要是安装相关的依赖库。本文实现的环境为:python 3.7。
-
- from __future__ import division
- import math
- import random
- import pandas as pd
2.构建BP神经网络类
主要是构建三层反向传播神经网络类。
-
- """ 三层反向传播神经网络 """
- class NN:
- def __init__(self, ni, nh, no):
- self.ni = ni + 1 # 输入层节点
- self.nh = nh + 1 # 隐藏层节点
- self.no = no # 输出层种类
- self.ai = [1.0] * self.ni
- self.ah = [1.0] * self.nh
- self.ao = [1.0] * self.no
- self.wi = self.makeMatrix(self.ni, self.nh) # 输出层到隐藏层的映射矩阵
- self.wo = self.makeMatrix(self.nh, self.no) # 隐藏层到输出层的映射矩阵
- for i in range(self.ni):
- for j in range(self.nh):
- self.wi[i][j] = self.rand(-0.2, 0.2)
- for j in range(self.nh):
- for k in range(self.no):
- self.wo[j][k] = self.rand(-2, 2)
-
- #前向传播,激活神经网络的所有节点
- def update(self, inputs):
- if len(inputs) != self.ni - 1:
- print(len(inputs),self.ni - 1)
- raise ValueError('与输入层节点数不符!')
- for i in range(self.ni - 1):
- self.ai[i] = inputs[i]
- for j in range(self.nh): # self.nh表示隐藏层的节点数
- sum = 0.0 # 激活项a = g(z) z = Θ^T x ;sum相当于z,每次循环归零
- for i in range(self.ni): #通过循环z = Θ^T x ,因为Θ、x均为向量
- sum = sum + self.ai[i] * self.wi[i][j] #〖 Z〗^((2))=Θ^((1)) a^((1))
- self.ah[j] = self.sigmoid(sum) # a^((2))=g(z^((2))),这里使用sigmoid()函数作为激活函数
- for k in range(self.no):
- sum = 0.0
- for j in range(self.nh):
- sum = sum + self.ah[j] * self.wo[j][k] #〖 Z〗^((3))=Θ^((2)) a^((2))
- self.ao[k] = self.sigmoid(sum) # a^((3))=g(z^((3)))
- return self.ao[:]
-
- #反向传播,计算节点激活项的误差
- def backPropagate(self, targets, lr): # targets为某样本实际种类分类,lr为梯度下降算法的学习率
- output_deltas = [0.0] * self.no
- for k in range(self.no):
- error = targets[k] - np.round_(self.ao[k])
- output_deltas[k] = self.dsigmoid(self.ao[k]) * error
- # 计算隐藏层的误差
- hidden_deltas = [0.0] * self.nh
- for j in range(self.nh):
- error = 0.0
- for k in range(self.no):
- error = error + output_deltas[k] * self.wo[j][k]
- hidden_deltas[j] = self.dsigmoid(self.ah[j]) * error
-
- # 更新输出层权重
- for j in range(self.nh): # 反向传播算法,求出每个节点的误差后,反向更新权重
- for k in range(self.no):
- change = output_deltas[k] * self.ah[j]
- self.wo[j][k] = self.wo[j][k] + lr * change
- # 更新输入层权重
- for i in range(self.ni):
- for j in range(self.nh):
- change = hidden_deltas[j] * self.ai[i]
- self.wi[i][j] = self.wi[i][j] + lr * change
- # 计算误差
- error = 0.0
- for k in range(self.no):
- error += 0.5 * (targets[k] - np.round_(self.ao[k])) ** 2
- return error
-
- #用测试集输出准确率
- def test(self, patterns):
- count = 0
- num=0
- for p in patterns:
- target = p[1]
- result = self.update(p[0])
- print(p[0], ':', target, '->', np.round_(result))
- num=0
- for k in range(self.no):
- if (target[k] == np.round_(result[k])):
- num +=1
- print(num)
- if num==3:
- count +=1
- print("******************",(target) == (np.round_(result)),"******************")
- accuracy = int(float(count / len(patterns))*100)
- print('accuracy: %-.9f' % accuracy,"%")
-
- #输出训练过后神经网络的权重矩阵
- def weights(self):
- print('输入层权重:')
- for i in range(self.ni):
- print(self.wi[i])
- print()
- print('输出层权重:')
- for j in range(self.nh):
- print(self.wo[j])
-
- #用训练集训练神经网络
- def train(self, patterns, iterations=1000, lr=0.1):
- for i in range(iterations):
- error = 0.0
- for p in patterns:
- inputs = p[0]
- targets = p[1]
- self.update(inputs)
- error = error + self.backPropagate(targets, lr)
- if i % 100 == 0:
- print("percent:",int(i/iterations*100),"%",' error: %-.9f' % error)
-
- #生成区间[a, b)内的随机数
- def rand(self, a, b):
- return (b - a) * random.random() + a
-
- # 生成大小 I*J 的矩阵,默认零矩阵
- def makeMatrix(self, I, J, fill=0.0):
- m = []
- for i in range(I):
- m.append([fill] * J)
- return m
-
- # 函数 sigmoid,bp神经网络前向传播的激活函数
- def sigmoid(self, x):
- return 1.0 / (1.0 + math.exp(-x))
-
- # 函数 sigmoid 的导数,反向传播时使用
- def dsigmoid(self, x):
- return x * (1 - x)
3.读取数据并进行预处理
主要是读取构建分类模型的数据,并进行预处理。
- data = []
- raw = pd.read_csv('iris.csv')
- raw_data = raw.values
- raw_feature = raw_data[1:, 1:5]
- for i in range(len(raw_feature)):
- ele = []
- ele.append(list(raw_feature[i]))
- if raw_data[i][5] == 0:
- ele.append([0, 0,1])
- elif raw_data[i][5] == 1:
- ele.append([0,1, 0])
- elif raw_data[i][5] == 2:
- ele.append([1, 1,1])
- else:
- ele.append([0, 0,0])
- data.append(ele)
4.利用构建的BP神经网络预测类,创建神经网络模型
主要是用BP神经网络预测类创建神经网络类模型。
nn = NN(4, 10, 3)
5.BP分类模型训练及预测
主要是划分训练集和测试集,并进行BP分类模型训练和预测。
- training = data[1:100]
- test = data[101:]
- nn.train(training, iterations=1000)
- nn.test(test)
完整源代码
-
- from __future__ import division
- import math
- import random
- import pandas as pd
- import numpy as np
-
- """ 三层反向传播神经网络 """
- class NN:
- def __init__(self, ni, nh, no):
- self.ni = ni + 1 # 输入层节点
- self.nh = nh + 1 # 隐藏层节点
- self.no = no # 输出层种类
- self.ai = [1.0] * self.ni
- self.ah = [1.0] * self.nh
- self.ao = [1.0] * self.no
- self.wi = self.makeMatrix(self.ni, self.nh) # 输出层到隐藏层的映射矩阵
- self.wo = self.makeMatrix(self.nh, self.no) # 隐藏层到输出层的映射矩阵
- for i in range(self.ni):
- for j in range(self.nh):
- self.wi[i][j] = self.rand(-0.2, 0.2)
- for j in range(self.nh):
- for k in range(self.no):
- self.wo[j][k] = self.rand(-2, 2)
-
- #前向传播,激活神经网络的所有节点
- def update(self, inputs):
- if len(inputs) != self.ni - 1:
- print(len(inputs),self.ni - 1)
- raise ValueError('与输入层节点数不符!')
- for i in range(self.ni - 1):
- self.ai[i] = inputs[i]
- for j in range(self.nh): # self.nh表示隐藏层的节点数
- sum = 0.0 # 激活项a = g(z) z = Θ^T x ;sum相当于z,每次循环归零
- for i in range(self.ni): #通过循环z = Θ^T x ,因为Θ、x均为向量
- sum = sum + self.ai[i] * self.wi[i][j] #〖 Z〗^((2))=Θ^((1)) a^((1))
- self.ah[j] = self.sigmoid(sum) # a^((2))=g(z^((2))),这里使用sigmoid()函数作为激活函数
- for k in range(self.no):
- sum = 0.0
- for j in range(self.nh):
- sum = sum + self.ah[j] * self.wo[j][k] #〖 Z〗^((3))=Θ^((2)) a^((2))
- self.ao[k] = self.sigmoid(sum) # a^((3))=g(z^((3)))
- return self.ao[:]
-
- #反向传播,计算节点激活项的误差
- def backPropagate(self, targets, lr): # targets为某样本实际种类分类,lr为梯度下降算法的学习率
- output_deltas = [0.0] * self.no
- for k in range(self.no):
- error = targets[k] - np.round_(self.ao[k])
- output_deltas[k] = self.dsigmoid(self.ao[k]) * error
- # 计算隐藏层的误差
- hidden_deltas = [0.0] * self.nh
- for j in range(self.nh):
- error = 0.0
- for k in range(self.no):
- error = error + output_deltas[k] * self.wo[j][k]
- hidden_deltas[j] = self.dsigmoid(self.ah[j]) * error
-
- # 更新输出层权重
- for j in range(self.nh): # 反向传播算法,求出每个节点的误差后,反向更新权重
- for k in range(self.no):
- change = output_deltas[k] * self.ah[j]
- self.wo[j][k] = self.wo[j][k] + lr * change
- # 更新输入层权重
- for i in range(self.ni):
- for j in range(self.nh):
- change = hidden_deltas[j] * self.ai[i]
- self.wi[i][j] = self.wi[i][j] + lr * change
- # 计算误差
- error = 0.0
- for k in range(self.no):
- error += 0.5 * (targets[k] - np.round_(self.ao[k])) ** 2
- return error
-
- #用测试集输出准确率
- def test(self, patterns):
- count = 0
- num=0
- for p in patterns:
- target = p[1]
- result = self.update(p[0])
- print(p[0], ':', target, '->', np.round_(result))
- num=0
- for k in range(self.no):
- if (target[k] == np.round_(result[k])):
- num +=1
- print(num)
- if num==3:
- count +=1
- print("******************",(target) == (np.round_(result)),"******************")
- accuracy = int(float(count / len(patterns))*100)
- print('accuracy: %-.9f' % accuracy,"%")
-
- #输出训练过后神经网络的权重矩阵
- def weights(self):
- print('输入层权重:')
- for i in range(self.ni):
- print(self.wi[i])
- print()
- print('输出层权重:')
- for j in range(self.nh):
- print(self.wo[j])
-
- #用训练集训练神经网络
- def train(self, patterns, iterations=1000, lr=0.1):
- for i in range(iterations):
- error = 0.0
- for p in patterns:
- inputs = p[0]
- targets = p[1]
- self.update(inputs)
- error = error + self.backPropagate(targets, lr)
- if i % 100 == 0:
- print("percent:",int(i/iterations*100),"%",' error: %-.9f' % error)
-
- #生成区间[a, b)内的随机数
- def rand(self, a, b):
- return (b - a) * random.random() + a
-
- # 生成大小 I*J 的矩阵,默认零矩阵
- def makeMatrix(self, I, J, fill=0.0):
- m = []
- for i in range(I):
- m.append([fill] * J)
- return m
-
- # 函数 sigmoid,bp神经网络前向传播的激活函数
- def sigmoid(self, x):
- return 1.0 / (1.0 + math.exp(-x))
-
- # 函数 sigmoid 的导数,反向传播时使用
- def dsigmoid(self, x):
- return x * (1 - x)
-
- if __name__ == '__main__':
- data = []
- raw = pd.read_csv('iris.csv')
- raw_data = raw.values
- raw_feature = raw_data[1:, 1:5]
- for i in range(len(raw_feature)):
- ele = []
- ele.append(list(raw_feature[i]))
- if raw_data[i][5] == 0:
- ele.append([0, 0,1])
- elif raw_data[i][5] == 1:
- ele.append([0,1, 0])
- elif raw_data[i][5] == 2:
- ele.append([1, 1,1])
- else:
- ele.append([0, 0,0])
- data.append(ele)
- nn = NN(4, 10, 3)
- training = data[1:100]
- test = data[101:]
- nn.train(training, iterations=1000)
- nn.test(test)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。