从零开始神经网络:keras框架实现数字图像识别详解!

接口实现可参考:keras框架实现手写数字识别

思路:

我们的代码要导出三个接口,分别完成以下功能:

  1. 初始化initialisation,设置输入层,中间层,和输出层的节点数。
  2. 训练train:根据训练数据不断的更新权重值
  3. 查询query,把新的数据输入给神经网络,网络计算后输出答案。(推理)

keras框架初始化解析:

[1]
'''
我们先给出如下代码框架:
'''
class  NeuralNetWork:def __init__(self):#初始化网络,设置输入层,中间层,和输出层节点数passdef  train(self):#根据输入的训练数据更新节点链路权重passdef  query(self):#根据输入数据计算并输出答案pass[2]
'''
我们先完成初始化函数,我们需要在这里设置输入层,中间层和输出层的节点数,这样就能决定网络的形状和大小。
当然我们不能把这些设置都写死,而是根据输入参数来动态设置网络的形态。
由此我们把初始化函数修正如下:
'''
class  NeuralNetWork:def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate#passdef  train(self):#根据输入的训练数据更新节点链路权重passdef  query(self):#根据输入数据计算并输出答案pass[3]
'''
此处举例说明:
如此我们就可以初始化一个3层网络,输入层,中间层和输出层都有3个节点
'''
input_nodes = 3
hidden_nodes = 3
output_nodes = 3learning_rate = 0.3
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)[4]
'''
初始化权重矩阵。
由于权重不一定都是正的,它完全可以是负数,因此我们在初始化时,把所有权重初始化为-0.5到0.5之间
'''
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate'''初始化权重矩阵,我们有两个权重矩阵,一个是wih表示输入层和中间层节点间链路权重形成的矩阵一个是who,表示中间层和输出层间链路权重形成的矩阵'''self.wih = numpy.random.rand(self.hnodes, self.inodes) - 0.5self.who = numpy.random.rand(self.onodes, self.inodes) - 0.5pass[5]
'''
接着我们先看query函数的实现,它接收输入数据,通过神经网络的层层计算后,在输出层输出最终结果。
输入数据要依次经过输入层,中间层,和输出层,并且在每层的节点中还得执行激活函数以便形成对下一层节点的输出信号。
我们知道可以通过矩阵运算把这一系列复杂的运算流程给统一起来。
'''
import numpy
def  query(self, inputs):#根据输入数据计算并输出答案hidden_inputs = numpy.dot(self.wih, inputs)pass[6]
'''
hidden是个一维向量,每个元素对应着中间层某个节点从上一层神经元传过来后的信号量总和.
于是每个节点就得执行激活函数,得到的结果将作为信号输出到下一层.
sigmod函数在Python中可以直接调用,我们要做的就是准备好参数。
我们先把这个函数在初始化函数中设定好,
'''
import scipy.specialclass  NeuralNetWork:def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate'''初始化权重矩阵,我们有两个权重矩阵,一个是wih表示输入层和中间层节点间链路权重形成的矩阵一个是who,表示中间层和输出层间链路权重形成的矩阵'''self.wih = numpy.random.rand(self.hnodes, self.inodes) - 0.5self.who = numpy.random.rand(self.onodes, self.inodes) - 0.5'''scipy.special.expit对应的是sigmod函数.lambda是Python关键字,类似C语言中的宏定义.我们调用self.activation_function(x)时,编译器会把其转换为spicy.special_expit(x)。'''self.activation_function = lambda x:scipy.special.expit(x)pass'''
由此我们就可以分别调用激活函数计算中间层的输出信号,以及输出层经过激活函数后形成的输出信号,
'''
def  query(self, inputs):#根据输入数据计算并输出答案#计算中间层从输入层接收到的信号量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)print(final_outputs)return final_outputs

keras框架训练解析:

import numpy
[1]
'''
自我训练过程分两步:
第一步是计算输入训练数据,给出网络的计算结果,这点跟我们前面实现的query()功能很像。
第二步是将计算结果与正确结果相比对,获取误差,采用误差反向传播法更新网络里的每条链路权重。我们先用代码完成第一步.inputs_list:输入的训练数据;
targets_list:训练数据对应的正确结果。
'''
def  train(self, inputs_list, targets_list):#根据输入的训练数据更新节点链路权重'''把inputs_list, targets_list转换成numpy支持的二维矩阵.T表示做矩阵的转置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_list, nmin=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)[2]
'''
上面代码根据输入数据计算出结果后,我们先要获得计算误差.
误差就是用正确结果减去网络的计算结果。
在代码中对应的就是(targets - final_outputs).
'''
def  train(self, inputs_list, targets_list):#根据输入的训练数据更新节点链路权重'''把inputs_list, targets_list转换成numpy支持的二维矩阵.T表示做矩阵的转置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_list, nmin=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_outputshidden_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[3]
'''
使用实际数据来训练我们的神经网络
'''
#open函数里的路径根据数据存储的路径来设定
data_file = open("dataset/mnist_test.csv")
data_list = data_file.readlines()
data_file.close()
len(data_list)
data_list[0]
'''
这里我们可以利用画图.py将输入绘制出来
'''[4]
'''
从绘制的结果看,数据代表的确实是一个黑白图片的手写数字。
数据读取完毕后,我们再对数据格式做些调整,以便输入到神经网络中进行分析。
我们需要做的是将数据“归一化”,也就是把所有数值全部转换到0.01到1.0之间。
由于表示图片的二维数组中,每个数大小不超过255,由此我们只要把所有数组除以255,就能让数据全部落入到0和1之间。
有些数值很小,除以255后会变为0,这样会导致链路权重更新出问题。
所以我们需要把除以255后的结果先乘以0.99,然后再加上0.01,这样所有数据就处于0.01到1之间。
'''
scaled_input = image_array / 255.0 * 0.99 + 0.01

keras框架运行解析:

import numpy
import matplotlib.pyplot as plt[1]
#open函数里的路径根据数据存储的路径来设定
data_file = open("dataset/mnist_test.csv")
data_list = data_file.readlines()
data_file.close()
print(len(data_list))
print(data_list[0])#把数据依靠','区分,并分别读入
all_values = data_list[0].split(',')
#第一个值对应的是图片的表示的数字,所以我们读取图片数据时要去掉第一个数值
image_array = numpy.asfarray(all_values[1:]).reshape((28, 28))#最外层有10个输出节点
onodes = 10
targets = numpy.zeros(onodes) + 0.01
targets[int(all_values[0])] = 0.99
print(targets)  #targets第8个元素的值是0.99,这表示图片对应的数字是7(数组是从编号0开始的).[2]
'''
根据上述做法,我们就能把输入图片给对应的正确数字建立联系,这种联系就可以用于输入到网络中,进行训练。
由于一张图片总共有28*28 = 784个数值,因此我们需要让网络的输入层具备784个输入节点。
这里需要注意的是,中间层的节点我们选择了100个神经元,这个选择是经验值。
中间层的节点数没有专门的办法去规定,其数量会根据不同的问题而变化。
确定中间层神经元节点数最好的办法是实验,不停的选取各种数量,看看那种数量能使得网络的表现最好。
'''
#初始化网络
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("dataset/mnist_train.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)[3]
'''
最后我们把所有测试图片都输入网络,看看它检测的效果如何
'''
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)#计算图片判断的成功率
scores_array = numpy.asarray(scores)
print("perfermance = ", scores_array.sum() / scores_array.size)[4]
'''
在原来网络训练的基础上再加上一层外循环
但是对于普通电脑而言执行的时间会很长。
epochs 的数值越大,网络被训练的就越精准,但如果超过一个阈值,网络就会引发一个过拟合的问题.
'''
#加入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)

画图部分实现:

import numpy
import matplotlib.pyplot as plt
#%matplotlib inline#open函数里的路径根据数据存储的路径来设定
data_file = open("dataset/mnist_test.csv")
data_list = data_file.readlines()
data_file.close()
print(len(data_list))
print(data_list[0])#把数据依靠','区分,并分别读入
all_values = data_list[0].split(',')
#第一个值对应的是图片的表示的数字,所以我们读取图片数据时要去掉第一个数值
image_array = numpy.asfarray(all_values[1:]).reshape((28, 28))
plt.imshow(image_array, cmap='Greys', interpolation='None')
plt.show()#数据预处理(归一化)
scaled_input = image_array / 255.0 * 0.99 + 0.01
print(scaled_input)

综合起来:数字图像识别代码:

数据集来自于mnist
可采用from tensorflow.keras.datasets import mnist方法下载

import numpy
import scipy.specialclass  NeuralNetWork:def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate'''初始化权重矩阵,我们有两个权重矩阵,一个是wih表示输入层和中间层节点间链路权重形成的矩阵一个是who,表示中间层和输出层间链路权重形成的矩阵'''#self.wih = numpy.random.rand(self.hnodes, self.inodes) - 0.5#self.who = numpy.random.rand(self.onodes, self.hnodes) - 0.5self.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) )  )'''每个节点执行激活函数,得到的结果将作为信号输出到下一层,我们用sigmoid作为激活函数'''self.activation_function = lambda x:scipy.special.expit(x)passdef  train(self,inputs_list, targets_list):#根据输入的训练数据更新节点链路权重'''把inputs_list, targets_list转换成numpy支持的二维矩阵.T表示做矩阵的转置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_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_outputshidden_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))passdef  query(self,inputs):#根据输入数据计算并输出答案#计算中间层从输入层接收到的信号量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)print(final_outputs)return final_outputs#初始化网络
'''
由于一张图片总共有28*28 = 784个数值,因此我们需要让网络的输入层具备784个输入节点
'''
input_nodes = 784
hidden_nodes = 200
output_nodes = 10
learning_rate = 0.1
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)#读入训练数据
#open函数里的路径根据数据存储的路径来设定
training_data_file = open("dataset/mnist_train.csv",'r')
training_data_list = training_data_file.readlines()
training_data_file.close()#加入epocs,设定网络的训练循环次数
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 * 0.99 + 0.01#设置图片与数值的对应关系targets = numpy.zeros(output_nodes) + 0.01targets[int(all_values[0])] = 0.99n.train(inputs, targets)test_data_file = open("dataset/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])print("该图片对应的数字为:",correct_number)#预处理数字图片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_number:scores.append(1)else:scores.append(0)
print(scores)#计算图片判断的成功率
scores_array = numpy.asarray(scores)
print("perfermance = ", scores_array.sum() / scores_array.size)

实现结果:

在这里插入图片描述
可以发现有部分数据预测错误有部分数据预测正确,正确率在60%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据学习第一贴

搞了这么久的开发,一直没有养成发博客的习惯,今天开始对大数据所需内容进行总结性记录,并对以后遇到的问题形成一个自己的知识库。就这些!转载于:https://blog.51cto.com/13921538/2299765

推荐算法的先验算法的连接_数据挖掘专注于先验算法

推荐算法的先验算法的连接So here we are diving into the world of data mining this time, let’s begin with a small but informative definition;因此,这一次我们将进入数据挖掘的世界,让我们从一个小的但内容丰富的定义开始; 什么是数…

Android 页面多状态布局管理

一、现状 页面多状态布局是开发中常见的需求,即页面在不同状态需要显示不同的布局,实现的方式也比较多,最简单粗暴的方式就是在 XML 中先将不同状态对应的布局隐藏起来,根据需要改变其可见状态,如果多个界面公用相同的…

Tensorflow入门神经网络代码框架

Tensorflow—基本用法 使用图 (graph) 来表示计算任务.在被称之为 会话 (Session) 的上下文 (context) 中执行图.使用 tensor 表示数据.通过 变量 (Variable) 维护状态.使用 feed 和 fetch 可以为任意的操作(arbitrary operation)赋值或者从其中获取数据。 • TensorFlow 是一…

手把手教你把代码丢入github 中

手把手教你把代码丢入github 中 作为一个小运维一步步教你们怎么把代码放入到github 中 首先呢我们下载一个git的客户端 https://git-scm.com/downloads/ 下载一个最新版的2.16.2 下载后那就安装吧。如果看不懂英文就选择默认安装的方式吧。但是你得记住你的软件安装的位置 小…

时间序列模式识别_空气质量传感器数据的时间序列模式识别

时间序列模式识别 1. Introduction 2. Exploratory Data Analysis ∘ 2.1 Pattern Changes ∘ 2.2 Correlation Between Features 3. Anomaly Detection and Pattern Recognition ∘ 3.1 Point Anomaly Detection (System Fault) ∘ 3.2 Collective Anomaly Detection (Externa…

oracle 性能优化 07_诊断事件

2019独角兽企业重金招聘Python工程师标准>>> 一、诊断事件 诊断事件无官方技术文档支持,使用存在风险,慎用。使用诊断事件可以获取问题更多的信息,调整系统运行 特性,启用某些内部功能。用于系统故障的诊断。跟踪应…

Tensorflow框架:卷积神经网络实战--Cifar训练集

Cifar-10数据集包含10类共60000张32*32的彩色图片,每类6000张图。包括50000张训练图片和 10000张测试图片 代码分为数据处理部分和卷积网络训练部分: 数据处理部分: #该文件负责读取Cifar-10数据并对其进行数据增强预处理 import os impo…

计算机科学速成课36:自然语言处理

词性 短语结构规则 分析树 语音识别 谱图 快速傅里叶变换 音素 语音合成 转载于:https://www.cnblogs.com/davidliu2018/p/9149252.html

linux内存初始化初期内存分配器——memblock

2019独角兽企业重金招聘Python工程师标准>>> 1.1.1 memblock 系统初始化的时候buddy系统,slab分配器等并没有被初始化好,当需要执行一些内存管理、内存分配的任务,就引入了一种内存管理器bootmem分配器。 当buddy系统和slab分配器初始化好后&…

数据科学学习心得_学习数据科学

数据科学学习心得苹果 | GOOGLE | 现货 | 其他 (APPLE | GOOGLE | SPOTIFY | OTHERS) Editor’s note: The Towards Data Science podcast’s “Climbing the Data Science Ladder” series is hosted by Jeremie Harris. Jeremie helps run a data science mentorship startup…

Keras框架:Alexnet网络代码实现

网络思想: 1、一张原始图片被resize到(224,224,3); 2、使用步长为4x4,大小为11的卷积核对图像进行卷积,输出的特征层为96层, 输出的shape为(55,55,96); 3、使用步长为2的最大池化层进行池化,此时…

PHP对象传递方式

<?phpheader(content-type:text/html;charsetutf-8);class Person{public $name;public $age;}$p1 new Person;$p1->name 金角大王;$p1->age 400;//这个地方&#xff0c;到底怎样?$p2 $p1;$p2->name 银角大王;echo <pre>;echo p1 name . $p1->n…

微软Azure CDN现已普遍可用

微软宣布Azure CDN一般可用&#xff08;GA&#xff09;&#xff0c;客户现在可以从微软的全球CDN网络提供内容。最新版本是对去年五月份发布的公众预览版的跟进。\\今年5月&#xff0c;微软与Verizon和Akamai一起推出了原生CDN产品。现在推出了GA版本&#xff0c;根据发布博文所…

数据科学生命周期_数据科学项目生命周期第1部分

数据科学生命周期This is series of how to developed data science project.这是如何开发数据科学项目的系列。 This is part 1.这是第1部分。 All the Life-cycle In A Data Science Projects-1. Data Analysis and visualization.2. Feature Engineering.3. Feature Selec…

Keras框架:VGG网络代码实现

VGG概念&#xff1a; VGG之所以经典&#xff0c;在于它首次将深度学习做得非常“深”&#xff0c;达 到了16-19层&#xff0c;同时&#xff0c;它用了非常“小”的卷积核&#xff08;3X3&#xff09;。 网络框架&#xff1a; VGG的结构&#xff1a; 1、一张原始图片被resize…

Django笔记1

内容整理1.创建django工程django-admin startproject 工程名2.创建APPcd 工程名python manage.py startapp cmdb3.静态文件project.settings.pySTATICFILES_dirs {os.path.join(BASE_DIR, static),}4.模板路径DIRS > [os.path.join(BASE_DIR, templates),]5.settings中mid…

BZOJ 2003 [Hnoi2010]Matrix 矩阵

题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id2003 题解 考虑搜索。 确定了第一行和第一列&#xff0c;那么就确定了整个矩阵&#xff0c;因此搜索的范围可以降到399个位置。 首先搜索第一行&#xff0c;显然每个不是第一行第一列的位置都可以由三个位置唯一确定…

Keras框架:resent50代码实现

Residual net概念 概念&#xff1a; Residual net(残差网络)&#xff1a;将靠前若干层的某一层数据输出直接跳过多层引入到后面数据层的输入 部分。 残差神经单元&#xff1a;假定某段神经网络的输入是x&#xff0c;期望输出是H(x)&#xff0c;如果我们直接将输入x传到输出作…

MySQL数据库的回滚失败(JAVA)

这几天在学习MySQL数据的知识&#xff0c;有一个小测试&#xff0c;用来测试数据库的提交和回滚。 刚开始的时候真的没把这个当回事&#xff0c;按照正常的步骤来讲的话&#xff0c;如下所示&#xff0c;加载驱动&#xff0c;获取数据库的连接&#xff0c;并且把数据库的自动提…