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

article/2025/6/20 10:49:09

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

这里写图片描述

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

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

这里写图片描述

数据的第一个值代表图片对应的数字,我们需要把这种对应信息通过代码表现出来:

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

上面代码的输出结果为:
这里写图片描述

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

#初始化网络
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_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.01targets[int(all_values[0])] = 0.99n.train(inputs, targets)

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

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

test_data_file = open("/Users/chenyi/Documents/人工智能/mnist_test_10.csv")
test_data_list = test_data_file.readlines()
test_data_file.close()
import numpy
import 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.csv
http://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.01targets[int(all_values[0])] = 0.99n.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.01targets[int(all_values[0])] = 0.99n.train(inputs, targets)

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

更详细的讲解和代码调试演示过程,请点击链接](http://study.163.com/provider-search?keyword=Coding%E8%BF%AA%E6%96%AF%E5%B0%BC)

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
这里写图片描述


http://chatgpt.dhexx.cn/article/KIXED1dX.shtml

相关文章

android中的ImageView,ImageView加载网络图片

android中的ImageView&#xff0c;ImageView加载网路图片 在布局文件中加入标签&#x1f3f7;️ <ImageViewandroid:layout_width"300dp"android:layout_height"200dp"android:background"#111111"android:id"id/imageView_pic1"a…

css用网络图片做背景图片,网络编程css为图片设置背景图片

网络编程css为图片设置背景图片 广告 CSS的功能是非常强大的&#xff0c;对于元素的表现以及页面的布局&#xff0c;都提供了非常强大的功能&#xff0c;这主要在于我们灵活的运行&#xff0c;在这方面提供了丰富且富含价值的各种教程与信息。对于图片的使用&#xff0c;其实更…

硬核!一文梳理经典图网络模型

作者 | Chilia 哥伦比亚大学 nlp搜索推荐 整理 | NewBeeNLP 图神经网络已经在NLP、CV、搜索推荐广告等领域广泛应用&#xff0c;今天我们就来整体梳理一些经典常用的图网络模型&#xff1a;DeepWalk、GCN、Graphsage、GAT&#xff01; 1. DeepWalk [2014] DeepWalk是…

图网络入门

目录 图网络基础知识 Graph Embedding 基础图网络模型 GCN GraphSAGE GAT 其他图网络模型 图网络基础知识 图网络的应用场景有很多&#xff0c;目前在工业界的主要应用是在推荐和风控领域&#xff0c;其他包括社交网络、交通网络、化学分子、3D点云等也都有一些应用。 …

图网络(Graph Network, GN)

目录 什么是图网络&#xff1f; 图网络框架 图网络内容 图的定义 GN块的内部结构 图网络中的关系归纳偏置 什么是图网络&#xff1f; 图网络是2018年由DeepMind、谷歌大脑、MIT和爱丁堡大学等公司和机构的27位科学家共同发表的论文《Relational inductive biases, deep …

图网络分类以及一些通用框架

图网络大体分类 递归图神经网络&#xff08;Recurrent Graph Neural Networks&#xff09;图卷积神经网络&#xff08;Graph Convolution Networks&#xff09;图注意力网络&#xff08;Graph Attention Networks&#xff09;图自编码器&#xff08;Graph Auto-encoder&#x…

泛型的使用和作用

概述 泛型的使用 多态与泛型 两者要一致&#xff0c;Animal 和cat要一致 泛型的作用 提高 Java 程序的类型安全 通过前面的学习我们知道&#xff0c; 在集合中可以添加 Object 类型的对象&#xff0c; 如果在不使用泛型的情况下定义了一个 ArrayList 对象&#xff0c; 那 么各…

java泛型(java泛型的作用)

java泛型的基本使用是什么&#xff1f; add("test1"); String test1 (String)strList。get(0); System。out。println("Test 1 : " test1); } public void testGeneric() { List strList new ArrayList(); strList。 Java泛型的规则和限制有哪些呢&…

java泛型的作用及实现原理

一、泛型的介绍 泛型是Java 1.5的新特性&#xff0c;泛型的本质是参数化类型&#xff0c;也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中&#xff0c;分别称为泛型类、泛型接口、泛型方法。 Java泛型被引入的好处是安全简单。在Java …

泛型(一)--泛型的作用和定义

一、泛型的作用 泛型是.net中十分常见的一种特性。它是在.net 2.0的时候加入。那为什么要在.net 2.0的时候加入泛型这个特性呢&#xff1f;我们首先来看一段代码。 using System;namespace 泛型{class Program{static void Main(string[] args){int iParameter 1;string sPar…

什么叫泛型?有什么作用?

作者&#xff1a;Java3y 链接&#xff1a;https://www.zhihu.com/question/272185241/answer/366129174 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 一、什么是泛型&#xff1f; Java泛型设计原则&#xff1a;…

Java泛型的作用及优点有哪些

Java泛型是J2 SE1.5中引入的一个新特性,其本质是参数化类型,也就是说所操作的数据类型被指定为一个参数这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 作用 第一是泛化。可以用T代表任意类型Java语言中引入泛型是一个较大的功能增强不…

第十章 泛型

10.1 泛型的理解和好处 10.1.1使用传统方法的问题分析 1&#xff09;不能加入到集合ArrayList中的数据类型进行约束(不安全) 2&#xff09;遍历的时候&#xff0c;需要进行类型转换&#xff0c;如果集合中的数据量较大&#xff0c;对效率有影响 10.1.2泛型的好处 1)编译时…

简述泛型的基本使用和作用

前言 在上一篇文章中&#xff0c;给大家讲解了泛型的概念、作用、使用场景&#xff0c;以及泛型集合、泛型接口和泛型类的用法&#xff0c;但受限于篇幅&#xff0c;并没有把泛型的内容讲解完毕。所以今天我们会继续学习泛型方法、泛型擦除&#xff0c;以及通配符等的内容&…

军职在线大学计算机基础(自主模式),《军职在线》中国哲学经典著作导读(自主模式)...

《军职在线》中国哲学经典着作导读(自主模式) 1《周易》导读 测试题C A C B D C D B B D D A B C D C D B A B 2《道德经》导读 测试题D C D C C C D A D C D B C C C A B A A B 3《庄子》导读 测试题D C D A A C B A A C A A C A D C B 4《论语》导读 测试题B B C ED B A A A …

台湾国立大学(林轩田)《机器学习技法》(第7讲)blending and bagging

课程地址&#xff1a;https://class.coursera.org/ntumlone-001/class 课件讲义&#xff1a;http://download.csdn.net/download/malele4th/10212756 注明&#xff1a;文中图片来自《机器学习技法》课程和部分博客 建议&#xff1a;建议读者学习林轩田老师原课程&#xff0c…

大学有新民之道,则大学生者负新民工作之实际责任者也。

梅贻琦&#xff0c;&#xff08;1889-1962&#xff09;&#xff0c;字月涵&#xff0c;为梅曾臣长子。自1914年由美国吴士脱大学学成归国&#xff0c;即到清华担任教学和教务长等多种职务。1931年&#xff0c;梅贻琦出任清华校长&#xff0c;自此后一直到他在台湾去世&#xff…

【转载】中庸与技术书

2019独角兽企业重金招聘Python工程师标准>>> 转自&#xff1a;图灵社区 原文作者&#xff1a;刘祺 原文地址&#xff1a;http://www.ituring.com.cn/article/213657 本次转载已经过原作者同意&#xff0c;二次转载请自行联系原作者 #中庸与技术书 在我写这篇文章之前…

《大学》《中庸》全文及翻译 (转载)

《大学》全文及翻译 原文&#xff1a; 大学之道&#xff0c;在明明德&#xff0c;在亲民&#xff0c;在止于至善。知止而后有定&#xff0c;定而后能静&#xff0c;静而后能安&#xff0c;安而后能虑&#xff0c;虑而后能得。物有本末&#xff0c;事有终始&#xff0c;知所先后…

[C语言]求一个数是否是2的n次方

设a8&#xff0c;a的二进制数为1000&#xff0c;若为16&#xff0c;则是 0001 0000&#xff0c;2的n次方转为二进制则只保留一个 1 &#xff0c; 其余位置全是0&#xff0c;因此只要判断这个数的二进制是否只有一个 1 &#xff0c;则知道这个数是否是2的n次方。 //求一个数是…