手把手教你搭建BP神经网络,并实现手写mnist手写数字识别

一、BP神经网络(back propagation neual network)过程原理:
1、数学基础:矩阵乘法、高数、不多做赘述直接上公式
2、推倒过程如下图片所示:
手把手教你搭建BP神经网络,并实现手写mnist手写数字识别_第1张图片
二、BP神经网络基于python的实现
代码:
可以直接使用,需要下载手写数字识别图像的文件,训练集:http://www.pjreddie.com/media/files/mnist_train.csv
测试集:http://www.pjreddie.com/media/files/mnist_train.csv ,下载完成后只需要在file操作时改成自己的文件路径
即可运行,得到训练的最终结果

import numpy
import scipy.special
import matplotlib.pyplot
#创建神经网络类,以便于实例化成不同的实例
class NeuralNetwork:
    def __init__(self,input_nodes,hidden_nodes,output_nodes,learning_rate):
    	#初始化输入层、隐藏层、输出层的节点个数、学习率
        self.inodes=input_nodes
        self.hnodes=hidden_nodes
        self.onodes=output_nodes
        #定义输入层与隐藏层之间的初始权重参数
        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=learning_rate
        #定义激活函数sigmoid
        self.activation_function=lambda x: scipy.special.expit(x)
        pass
    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-final_outputs)),
                                    numpy.transpose(hidden_outputs))
        self.wih+=self.lr*numpy.dot((hidden_errors*hidden_outputs*(1-hidden_outputs)),
                                    (numpy.transpose(inputs)))
        pass
    #相当于sklearn中的predict功能,预测新样本的种类
    def query(self,inputs_list):
        inputs=numpy.array(inputs_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)
        return final_outputs


#手写数字为28*28大小,所以在变成一维数据之后,需要有这么多的输入点,隐藏层神经元可以自行定义;输出层神经元为分类的总个数
input_nodes =784
hidden_nodes =200
output_nodes =10
#定义学习率
learning_rate =0.1
#用我们的类创建一个神经网络实例
n=NeuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
training_data_file=open('./data/mnist_train.csv','r')
training_data_list=training_data_file.readlines()
training_data_file.close()
#进行5次epochs
epochs=5
for e in range(epochs):
    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
        #训练网络更新权重值
        n.train(inputs,targets)
        pass
    pass
test_data_file=open('./data/mnist_test.csv','r')
test_data_list=test_data_file.readlines()
test_data_file.close()
#通过类方法query输出test数据集中的每一个样本的训练标签和实例标签进行对比。
scorecord=[]
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=n.query(inputs)
    label=numpy.argmax(outputs)
    if  (label==correct_label):
        scorecord.append(1)
    else:
        scorecord.append(0)
        pass
    pass
scorecord_array=numpy.asarray(scorecord)
print("accuracy=",scorecord_array.sum()/scorecord_array.size)

最终我们可以达到一个0.9722的准确度。

你可能感兴趣的:(深度学习)