《python神经网络编程》是一本不错的神经网络编程入门的图书,书中实现了简单的三层BP神经网络,并且完成了手写数字识别的任务。
源码和数据集下载:https://download.csdn.net/download/qq_37521566/16201460
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 27 11:42:48 2021
@author: xin
"""
import numpy
import scipy.special
import matplotlib.pyplot
#神经网络
class NeuralNetwork:
#初始化神经网络
def __init__(self,inputnodes,hiddennodes,outputnodes,learninggrate):
#设定输入层、隐藏层、输出层的节点个数
self.inodes=inputnodes
self.hnodes=hiddennodes
self.onodes=outputnodes
#设定初始链接权重矩阵
self.wih=numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.inodes));
self.who=numpy.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes));
#设定学习率
self.lr=learninggrate
#激活函数是S函数
self.activation_function=lambda x:scipy.special.expit(x)
#训练神经网络
def train(self,input_list,target_list):
#将输入列表转为二维矩阵
inputs=numpy.array(input_list,ndmin=2).T
targets=numpy.array(target_list,ndmin=2).T
#计算隐藏层的输入
hidden_inputs=numpy.dot(self.wih, inputs)
#计算隐藏层的输出
hidden_outputs=self.activation_function(hidden_inputs)
#计算最后输出层的输入
final_inputs=numpy.dot(self.who,hidden_outputs)
#计算最后输出层的输出
final_outputs=self.activation_function(final_inputs)
#误差计算
output_errors=targets-final_outputs
#根据链接权重反向计算误差, 为每个隐藏层节点重组这些误差
hidden_errors=numpy.dot(self.who.T,output_errors)
#更新隐藏层是输出层之间的权重
self.who+=self.lr*numpy.dot((output_errors*final_outputs*(1.0-final_outputs)),numpy.transpose(hidden_outputs))
#更新输入层和隐藏层之间的权重
self.wih+=self.lr*numpy.dot((hidden_errors*hidden_outputs*(1.0-hidden_outputs)),numpy.transpose(inputs))
#神经网络的查询
def query(self,inputs_list):
#将输入列表转为二维矩阵
inputs=numpy.array(inputs_list,ndmin=2).T
#计算隐藏层的输入
hidden_inputs=numpy.dot(self.wih, inputs)
#计算隐藏层的输出
hidden_ouputs=self.activation_function(hidden_inputs)
#计算最后输出层的输入
final_inputs=numpy.dot(self.who,hidden_ouputs)
#计算最后输出层的输出
final_outputs=self.activation_function(final_inputs)
return final_outputs
#输入层、隐藏层、输出层神经元的个数
input_nodes=784
hidden_nodes=100
output_nodes=10
#学习率
learning_rate=0.3
#创建一个神经网络对象
NN=NeuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)
#加载训练集
training_data_file=open("mnist_dataset/mnist_train.csv",'r')
training_data_list=training_data_file.readlines()
training_data_file.close()
#训练神经网络
#遍历神经网络的训练集所有记录
for record in training_data_list:
#用','分割记录
all_values=record.split(',')
#改变输入数据大小
inputs=(numpy.asfarray(all_values[1:])/255*0.99)+0.01
#创建目标输出
targets=numpy.zeros(output_nodes)+0.01
targets[int(all_values[0])]=0.99
NN.train(inputs,targets)
#加载测试集
test_data_file=open("mnist_dataset/mnist_test.csv",'r')
test_data_list=test_data_file.readlines();
test_data_file.close()
scorecard=[]
for record in test_data_list:
#用','分割记录
all_values=record.split(',')
correct_label=int(all_values[0])
#改变输入数据大小
inputs=(numpy.asfarray(all_values[1:])/255*0.99)+0.01
#查询神经网络
outputs=NN.query(inputs)
#输出里的最大值所在下标即为预测值
label=numpy.argmax(outputs)
if(label==correct_label):
scorecard.append(1)
else :
scorecard.append(0)
scorecard_array=numpy.asarray(scorecard)
print("performance= ",scorecard_array.sum()/scorecard_array.size)