神经网络构建与实战
文章目录
神经网络实现与实战
前言
有段时间没有写博客和大家交流了,今天我们来手把手和大家一起交流怎么用python构建属我们自己的神经网络,希望可以和大家一起进步!
写这篇文章的时候,我是一边写代码,一边写博客,讲解原理,遇到的所有困难,都完全模拟了大家可能遇到的问题,绝对具有典型和代表性,请大家一步一步和我一起领略,神经网络的魅力!
一、下载Anaconda
因为我们构建神经网络的时候我们需要用到这个交互式的环境,所以如果方便的话,大家可以下载我提供的这个链接里面的anaconda,这是我的网盘文件,永久有效,除非我哪天不在了,所以大家不用担心,也希望可以帮大家寻找资源省点时间。
链接:https://pan.baidu.com/s/1PdrMKvJOHTbj_LkcRm6qfw
提取码:5210
二、明确思想和目标方向
我们要通过构建神经网络,来对我们的手写图像进行识别,当然,神经网络肯定没有见过每个人的笔记,那么它依然要可以识别出来,每一个人写了什么,通过神经网络,不断优化自己,不断学习,从而实现一个高效率的识别,同时把自己也训练成为一个很厉害的识别AI。
三、理论学习
1.分类器的过渡
我们的神经网络,一开始是从分类器开始出发的。比如一些小虫子,你怎么判断他们属于哪一个类型呢?通过长度,宽度来判断,那么计算机是怎么判断的呢,我们来看看分类器,搞懂了这个,你就可以大概知道,神经网络怎么区分大家的手写笔记和内容。
我们先用一条直线把它们分开,发现确实区分了他们,但是好像没有真正的区分所有的毛虫和瓢虫,因为这里只有仅仅两只,不具有典型和代表性。
y =0.25*3.0= 0.75,所以我们进行改进,用这条新的直线来试试,发现好像更好的区分了两种虫子,直线往中间靠近了,并且我们求出他的误差,对直线的斜率进行不断改进,知道可以很好地区分这两种虫子,这就是我们起初的大概思想。
2.神经元的激活模拟
生活中,你可以看到很多东西,真正引起你的注意的东西,可能并不多,这里我们就要模拟神经元,进行信息的收集和处理,进行相应的激活,只有被激活的相关信息,才能真正的被我们的神经网络和神经元进行接收,并且做出相应的反应。我们构建S函数!
也就是这个!
四、开始创建
1.打开下载好的anaconda
打开后创建新的python3文档,重命名文件。
2.导入可用库
我会把最后的代码一起给出,请不用着急。跟着我慢慢来就好!
3.构建类和init构建神经网络框架
我们先构建我们的神经网络的节点和定义节点的函数。
class neuralNetwork:
def _init_(self,inputnodes,hiddennodes,outputnodes,learningrate):
#先构建三层网络节点,以便初始化
self.indoes = inputnodes
self.hnodes = hiddennodes
self.onodes = outputnodes
#产生正态分布的权重数据,按顺序:1、平均值为0,2、标准方差为1/根号下 传入链接数目,也就是-0.5次方,3、用节点的个数确定了权重矩阵的大小。
self.wih = numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.indoes))
self.who = numpy.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes))
#确定学习率
self.lr = learningrate
#定义神经网络S激活函数
self.activation_function = lambda x: scipy.special.expit(x)
#结束
pass
4.构建神经网络训练函数
定义好了节点的函数后,我们继续定义神经网络的训练函数。
def train(self,inputs_list,targets_list):
#构建二维矩阵,并且转置,转置是因为后面点乘需要用到。
inputs = numpy.array(inputs_list,ndmin=2).T
targets = numpy.array(targets_list,ndmin=2).T
#开始计算隐藏层的输入结果
hidden_inputs = numpy.dot(self.wih,inputs)
#通过S函数计算隐藏层节点输出
hidden_outputs = self.activation_function(hidden_inputs)
#开始计算输出层的输入结果
final_inputs = numpy.dot(self.who,hidden_outputs)
#通过S函数计算输出层节点输出
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))
pass
5.构建神经网络查询函数
我们看到,查询函数中还需要把所有的输入到输出计算一遍,最后输出我们的最终的结果。
def query(self,inputs_list):
#先把输入转置,待用
inputs = numpy.array(inputs_list,ndmin=2).T
#再通过输入计算隐藏层的输入
hidden_inputs = numpy.dot(self.wih,inputs)
#再通过S函数计算隐藏层的输出
hidden_outputs = self.activation_function(hidden_inputs)
#再计算输出层的输入
final_inputs = numpy.dot(self.who,hidden_outputs)
#通过S函数计算最终输出层的输出
final_outputs = self.activation_function(final_inputs)
#返回最终的结果
return final_outputs
6.进行神经网络的参数定义
#创建神经网络节点以及学习率
input_nodes = 784
hidden_nodes = 100
output_nodes = 10
learning_rate = 0.3
n = neuralNetwork(input_nodes,hidden_nodes,output_nodes,learning_rate)
7.神经网络对接训练
#开始真正读取训练文件进行神经网络的训练
training_data_file = open(r"C:\Users\LX\Desktop\mnist_train.csv",'r')
training_data_list = training_data_file.readlines()
training_data_file.close()
#定义神经网路的世代数
epochs = 5
for e in range(epochs):
for record in training_data_list:
#利用split函数,把数据分开
all_values = record.split(',')
#对输入的数据像素进行相应的处理
inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
targets = numpy.zeros(output_nodes) + 0.01
targets[int(all_values[0])] = 0.99
#开始进行相应的神经网络训练
n.train(inputs,targets)
pass
8.神经网络测试
#开始神经网络的测试文件对接
# test_data_file = open(r"C:\Users\LX\Desktop\mnist_test.csv",'r')
test_data_file = open(r"C:\Users\LX\Desktop\pre_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 * 0.99) + 0.01
outputs = n.query(inputs)
label = numpy.argmax(outputs)
if(label == correct_label):
scorecard.append(1)
else:
scorecard.append(0)
这里的mnist_test.csv文件,里面有足足60000个测试,我怕要弄到明天早上,所以我准备了一个pre_test文件,里面只有10个测试数据,我们先来一起尝试一下我们的结果。看看怎么样?
9.运行神经网络
我的天,一来就报错,因为我是一遍写博客,一边写代码,我会把所有输出和大家展示,我们先来处理一下这个问题,我觉得是我的缩进n有问题,我来改一下试试。
按下CTRL+[,可以很方便的一起改,再运行试试
又报错,明白了,上面的节点数据缩进没有改,我们再试试!
又报错了,看看是怎么回事,应该是我的init方法出错了。
把_init_改成__init__ ,有两个"_",再试试!
这一次没有报错了,显示服务正忙,看看行不行?
我们稍微等一下,因为电脑需要训练10000次,他也需要学习,我们给他点时间,让他学成归来,我们再来看结果。
好了,识别结束了,我们开始编写输出代码
10.可视化输出
image_array = numpy.asfarray(all_values[1:]).reshape((28,28))
matplotlib.pyplot.imshow(image_array,camp = 'Greys',interpolation='None')
终于得到了输出
看看准确度
神经网络终于认出了9,也算是成功了!
因为代码的问题,保留下的数据识别的是最后一张图片,识别成功!
11.精确度讨论
改进学习率
这是100个训练数据,10个测试数据的结果,1表示正确,0表示错误,结果很不好。
我们现在把学习率改成0.1
结果好很多
改进隐藏层点数
再增加隐藏层节点数
我们的神经网络又变得好起来了
改进世代数
结果变得不好了,我们知道,肯定是10超过了最优蜜汁点,再调整为7
还是不好,调整为6
可以看出峰值在这5~6附近了。
有没有发现神经网络好像不是很认识4和9,5和4,我们要让神经网络好好学习,让他去学60000吧!!!
再来看看!!学成归来!!!
完整代码
class neuralNetwork:
def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate):
#先构建三层网络节点,以便初始化
self.indoes = inputnodes
self.hnodes = hiddennodes
self.onodes = outputnodes
#产生正态分布的权重数据,按顺序:1、平均值为0,2、标准方差为1/根号下 传入链接数目,也就是-0.5次方,3、用节点的个数确定了权重矩阵的大小。
self.wih = numpy.random.normal(0.0,pow(self.hnodes,-0.5),(self.hnodes,self.indoes))
self.who = numpy.random.normal(0.0,pow(self.onodes,-0.5),(self.onodes,self.hnodes))
#确定学习率
self.lr = learningrate
#定义神经网络S激活函数
self.activation_function = lambda x: scipy.special.expit(x)
#结束
pass
def train(self,inputs_list,targets_list):
#构建二维矩阵,并且转置,转置是因为后面点乘需要用到。
inputs = numpy.array(inputs_list,ndmin=2).T
targets = numpy.array(targets_list,ndmin=2).T
#开始计算隐藏层的输入结果
hidden_inputs = numpy.dot(self.wih,inputs)
#通过S函数计算隐藏层节点输出
hidden_outputs = self.activation_function(hidden_inputs)
#开始计算输出层的输入结果
final_inputs = numpy.dot(self.who,hidden_outputs)
#通过S函数计算输出层节点输出
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))
pass
def query(self,inputs_list):
#先把输入转置,待用
inputs = numpy.array(inputs_list,ndmin=2).T
#再通过输入计算隐藏层的输入
hidden_inputs = numpy.dot(self.wih,inputs)
#再通过S函数计算隐藏层的输出
hidden_outputs = self.activation_function(hidden_inputs)
#再计算输出层的输入
final_inputs = numpy.dot(self.who,hidden_outputs)
#通过S函数计算最终输出层的输出
final_outputs = self.activation_function(final_inputs)
#返回最终的结果
return final_outputs
#创建神经网络节点以及学习率
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(r"C:\Users\LX\Desktop\mnist_train.csv",'r')
training_data_file = open(r"C:\Users\LX\Desktop\pre_train.csv",'r')
training_data_list = training_data_file.readlines()
training_data_file.close()
#定义神经网路的世代数
epochs = 5
for e in range(epochs):
for record in training_data_list:
#利用split函数,把数据分开
all_values = record.split(',')
#对输入的数据像素进行相应的处理
inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
targets = numpy.zeros(output_nodes) + 0.01
targets[int(all_values[0])] = 0.99
#开始进行相应的神经网络训练
n.train(inputs,targets)
pass
#开始神经网络的测试文件对接
# test_data_file = open(r"C:\Users\LX\Desktop\mnist_test.csv",'r')
test_data_file = open(r"C:\Users\LX\Desktop\pre_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 * 0.99) + 0.01
# outputs = n.query(inputs)
# label = numpy.argmax(outputs)
# if(label == correct_label):
# scorecard.append(1)
# else:
# scorecard.append(0)
for record in test_data_list:
# print(record)
all_values = record.split(',')
# image_array = numpy.asfarray(all_values[1:]).reshape((28,28))
# matplotlib.pyplot.imshow(image_array,cmap = 'Greys',interpolation='None')
correct_label = int(all_values[0])
print(correct_label,"正确的答案")
inputs = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01
outputs = n.query(inputs)
label = numpy.argmax(outputs)
print(label,"神经网络识别优化答案")
if(label == correct_label):
scorecard.append(1)
else:
scorecard.append(0)
print(scorecard)