用python实现数字图片识别神经网络--启动网络的自我训练流程,展现网络数字图片识别效果

上一节,咱们完成了网络训练代码的实现,还有一些问题须要作进一步的确认。网络的最终目标是,输入一张手写数字图片后,网络输出该图片对应的数字。因为网络须要从0到9一共十个数字中挑选出一个,因而咱们的网络最终输出层应该有十个节点,每一个节点对应一个数字。假设图片对应的是数字0,那么输出层网络中,第一个节点应该输出一个高百分比,其余节点输出低百分比,若是图片对应的数字是9,那么输出层最后一个节点应该输出高百分比,其余节点输出低百分比,例以下图:node

屏幕快照 2018-05-07 下午5.10.59.png数组

高比率,若是网络认为图片对应的数字是0,那么编号为0的节点输出0.95的高比率。最后一个例子是颇有意思,编号为4和9的神经元都输出一个不低的比率,这代表图片对应的数字很像4和9,但神经网络认为是9的几率是4的几率的两倍以上。网络

还记得上一节咱们准备好要输入网络的数据吗:app

这里写图片描述函数

数据的第一个值表明图片对应的数字,咱们须要把这种对应信息经过代码表现出来:学习

#最外层有10个输出节点onodes = 10
targets = numpy.zeros(onodes) + 0.01
targets[int(all_values[0])] = 0.99print(targets)

上面代码的输出结果为:测试

image.png大数据

targets第8个元素的值是0.99,这表示图片对应的数字是7,记住数组是从编号0开始的。根据这种作法,咱们就能把输入图片给对应的正确数字创建联系,这种联系就能够用于输入到网络中,进行训练。因为一张图片总共有28*28 = 764个数值,所以咱们须要让网络的输入层具有764个输入节点,因而网络的初始化以及将数据输入网络进行训练的实现代码为:人工智能

#初始化网络input_nodes = 784hidden_nodes = 100output_nodes = 10learning_rate = 0.3n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)#读入训练数据#open函数里的路径根据数据存储的路径来设定training_data_file = open("/Users/chenyi/Documents/人工智能/mnist_train_100.csv")
trainning_data_list = training_data_file.readlines()
training_data_file.close()#把数据依靠','区分,并分别读入for record in trainning_data_list:
    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)

这里须要注意的是,中间层的节点咱们选择了100个神经元,这个选择实际上是经验值,也就是中间层的节点数其实没有专门的办法去规定,其数量会根据不一样的问题而变化,肯定中间层神经元节点数最好的办法是实验,你不停的选取各类数量,看看那种数量能使得网络的表现最好就行。spa

上面代码把一百条数据输入网络进行训练,如今咱们看看训练后的网络它的表现怎样。咱们先从加载另外一组数据,取出其中一张手写数字图片,将其输入到网络中,看看网络的判断结果如何:

test_data_file = open("/Users/chenyi/Documents/人工智能/mnist_test_10.csv")
test_data_list = test_data_file.readlines()
test_data_file.close()import numpyimport matplotlib.pyplot
%matplotlib inline#把数据依靠','区分,并分别读入all_values = data_list[0].split(',')#第一个值对应的是图片的表示的数字,因此咱们读取图片数据时要去掉第一个数值image_array = numpy.asfarray(all_values[1:]).reshape((28, 28))
matplotlib.pyplot.imshow(image_array, cmap='Greys', interpolation='None')

这段代码咱们在上一节讲解过,咱们把测试数据里面的第一张手写数字图片先绘制出来,代码运行结果以下:

 

这里写图片描述

经过人眼观察,咱们基本肯定这种图片对应的是数字7,那么网络识别它的结果如何呢,咱们将这张图片的数字输入到网络看看其识别结果:

n.query(numpy.asfarray(all_values[1:]) / 255.0  * 0.99 + 0.01)

上面这行代码运行后结果以下:

 

这里写图片描述

前面咱们讨论过最外层节点输出的意义,最外层节点有十个,分别对应0到9十个数字,哪一个节点输出的数值高,那意味着网络认为图片对应哪一个数字,咱们看到网络输出中,对应编号为7的节点输出值最大,为0.68,也就是说网络把图片识别为数字7,这与咱们的观察是一致的,这么说咱们辛辛苦苦打造的网络是有效的,前面那么多的铺垫到如今终于有了收获。

咱们原来给网络输入的训练数据来自trainning_set,而如今给网络判断的图片来自testing_set,所以网络从未见过这张图片,它能识别这张图片是数字7,这种能力是经过分析训练图片,不断改进链路权重值的结果。实现网络的Python代码不过百来行,他竟然就能实现了咱们所认为的人工智能,如此看来人工智能彷佛并不是那么神秘。

接着咱们把全部测试图片都输入网络,看看它检测的效果如何,代码以下:

scores = []for record in test_data_list:
    all_values = record.split(',')
    correct_number = int(all_values[0])    print("该图片对应的数字为:",correct_number)    #预处理数字图片
    inputs = (numpy.asfarray(all_values[1:])) / 255.0 * 0.99 + 0.01    #让网络判断图片对应的数字
    outputs = n.query(inputs)    #找到数值最大的神经元对应的编号
    label = numpy.argmax(outputs)    print("out put reslut is : ", label)    #print("网络认为图片的数字是:", label)
    if label == correct_number:
        scores.append(1)    else:
        scores.append(0)print(scores)

上面代码把测试数据集里的10张图片所有加载,而后输入到网络中,看看网络对每张数字图片的识别效果如何,上面代码运行后结果以下:

这里写图片描述

从输出结果看,有些图片网络仍是识别错了,最后代码打印出一个数组,里面的1表示识别正确,0表示识别错误,从数组内容看,有4张图片网络给出了错误答案。此次的结果多少使人有些沮丧,咱们计算一下图片判断的成功率:

scores_array = numpy.asarray(scores)print("perfermance = ", scores_array.sum() / scores_array.size)

代码运行后结果以下:

这里写图片描述

由此看来,网络识别的成功率只有六成。为了提高成功率,咱们必须加大网络的训练力度,原来咱们训练网络时只使用了100条数据,如今咱们使用60000条数据,而后用10000条数据做为测试集,咱们从如下两个连接获取相应的数据集:

http://www.pjreddie.com/media/files/mnist_train.csvhttp://www.pjreddie.com/media/files/mnist_test.csv

而后咱们把原来代码作一点小修改,加载上面的数据来对网络进行训练和测试:

#初始化网络input_nodes = 784
hidden_nodes = 100
output_nodes = 10
learning_rate = 0.3
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)#读入训练数据#open函数里的路径根据数据存储的路径来设定training_data_file = open("/Users/chenyi/Documents/人工智能/mnist_train.csv")
trainning_data_list = training_data_file.readlines()print(len(trainning_data_list))
training_data_file.close()#把数据依靠','区分,并分别读入for record in trainning_data_list:
    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)
    
test_data_file = open("/Users/chenyi/Documents/人工智能/mnist_test.csv")
test_data_list = test_data_file.readlines()
test_data_file.close()
scores = []for record in test_data_list:
    all_values = record.split(',')
    correct_number = 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_number:
        scores.append(1)    else:
        scores.append(0)
scores_array = numpy.asarray(scores)print("perfermance = ", scores_array.sum() / scores_array.size)

上面代码跟之前是同样的,只不过加载的数据文件不一样而已,此次咱们用60000条数据来训练网络,而后用10000条数据来检测网络的准确性,上面代码执行后结果以下:

 

这里写图片描述

从结果上看,当训练网络的数据流增大后,网络识别的正确性由原来的0.6提高到0.9,咱们再次用新训练后的网络识别原来那十张数字图片,获得结果以下:

这里写图片描述

通过大数据训练后的网络,对图片的识别率达到了百分之百,这意味着当用于训练网络的数据越多,网络识别的效果就越好,这就是为什么在某种程度上说,人工智能也是大公司的大杀器,由于只有大公司才能拥有足量的数据。

在整个过程,咱们一直保持着学习率不变,实际上学习率的大小对网络的训练效果有很大影响,你们能够把该参数改为0.6,0.1等不一样的值去看看结果,另外也能够修改中间层的节点数看看有什么效果。二手叉车哪家好

这里咱们引入在第一节时提到的一个概念叫epocs,它表示网络进行几回训练循环,对其使用的代码以下:

#加入epocs,设定网络的训练循环次数epochs = 10for e in range(epochs):    #把数据依靠','区分,并分别读入
    for record in trainning_data_list:
        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)

也就是在原来网络训练的基础上再加上一层外循环,上面代码运行后执行的对于普通电脑而言执行的时间会很长。通常来讲,epochs 的数值越大,网络被训练的就越精准,但若是超过一个阈值,网络就会引起一个过渡拟合的问题,也就是网络会对老数据识别的很精准,但对新数据识别的效率反而变得愈来愈低,你们能够自行尝试一下不一样的学习率和epochs组合,看看网络的识别精度是否有所提升,另外你们也能够修改中间层的节点数看看其对网络的识别精度是否有显著影响,在我电脑上把epochs设置成7时,成功率能提高到95%。

相关文章
相关标签/搜索