python神经网络编程之手写数字识别
作者:神仙盼盼 发布时间:2022-01-12 20:50:04
写在之前
首先是写在之前的一些建议:
首先是关于这本书,我真的认为他是将神经网络里非常棒的一本书,但你也需要注意,如果你真的想自己动手去实现,那么你一定需要有一定的python基础,并且还需要有一些python数据科学处理能力
然后希望大家在看这边博客的时候对于神经网络已经有一些了解了,知道什么是输入层,什么是输出层,并且明白他们的一些理论,在这篇博客中我们仅仅是展开一下代码;
然后介绍一下本篇博客的环境等:
语言:Python3.8.5
环境:jupyter
库文件: numpy | matplotlib | scipy
一、代码框架
我们即将设计一个神经网络对象,它可以帮我们去做数据的训练,以及数据的预测,所以我们将具有以下的三个方法:
首先我们需要初始化这个函数,我们希望这个神经网络仅有三层,因为再多也不过是在隐藏层去做文章,所以先做一个简单的。那么我们需要知道我们输入层、隐藏层和输出层的节点个数;训练函数,我们需要去做训练,得到我们需要的权重。通过我们已有的权重,将给定的输入去做输出。
二、准备工作
现在我们需要准备一下:
1.将我们需要的库导入
import numpy as np
import scipy.special as spe
import matplotlib.pyplot as plt
2.构建一个类
class neuralnetwork:
# 我们需要去初始化一个神经网络
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
pass
def train(self, inputs_list, targets_list):
pass
def query(self, inputs_list):
pass
3.我们的主函数
input_nodes = 784 # 输入层的节点数
hidden_nodes = 88 # 隐藏层的节点数
output_nodes = 10 # 输出层的节点数
learn_rate = 0.05 # 学习率
n = neuralnetwork(input_nodes, hidden_nodes, output_nodes, learn_rate)
4.导入文件
data_file = open("E:\sklearn_data\神经网络数字识别\mnist_train.csv", 'r')
data_list = data_file.readlines()
data_file.close()
file2 = open("E:\sklearn_data\神经网络数字识别\mnist_test.csv")
answer_data = file2.readlines()
file2.close()
这里需要介绍以下这个数据集,训练集在这里,测试集在这里
三、框架的开始
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
self.inodes = inputnodes # 输入层节点设定
self.hnodes = hiddennodes # 影藏层节点设定
self.onodes = outputnodes # 输出层节点设定
self.lr = learningrate # 学习率设定,这里可以改进的
self.wih = (np.random.normal(0.0, pow(self.hnodes, -0.5),(self.hnodes, self.inodes))) # 这里是输入层与隐藏层之间的连接
self.who = (np.random.normal(0.0, pow(self.onodes, -0.5),(self.onodes, self.hnodes))) # 这里是隐藏层与输出层之间的连接
self.activation_function = lambda x: spe.expit(x) # 返回sigmoid函数
Δw j,k =α∗E k ∗ sigmoid (O k )∗(1−sigmoid(O k ))⋅O j ⊤
def query(self, inputs_list):
inputs = np.array(inputs_list, ndmin=2).T # 输入进来的二维图像数据
hidden_inputs = np.dot(self.wih, inputs) # 隐藏层计算,说白了就是线性代数中的矩阵的点积
hidden_outputs = self.activation_function(hidden_inputs) # 将隐藏层的输出是经过sigmoid函数处理
final_inputs = np.dot(self.who, hidden_outputs) # 原理同hidden_inputs
final_outputs = self.activation_function(final_inputs) # 原理同hidden_outputs
return final_outputs # 最终的输出结果就是我们预测的数据
这里我们对预测这一部分做一个简单的解释:我们之前的定义输出的节点是10个,对应的是十个数字。
而为什么会通过神经网络能达到这个亚子,我推荐这本书深度学习的数学 这本书的理论讲解非常不错!!!
四、训练模型构建
之前的部分相对而言还是比较简单的,那么接下来就是如何去构建训练模型了。
def train(self, inputs_list, targets_list):
# 前期和识别过程是一样的,说白了我们与要先看看现在的预测结果如何,只有根据这次的预期结果才能去修改之前的权重
inputs = np.array(inputs_list, ndmin=2).T
hidden_inputs = np.dot(self.wih, inputs)
hidden_outputs = self.activation_function(hidden_inputs)
final_inputs = np.dot(self.who, hidden_outputs)
final_outputs = self.activation_function(final_inputs)
# 接下来将标签拿迟来
targets = np.array(targets_list, ndmin=2).T
# 得到我们的数据预测的误差,这个误差将是向前反馈的基础
output_errors = targets - final_outputs
# 这部分是根据公式得到的反向传播参数
hidden_errors = np.dot(self.who.T, output_errors)
# 根据我们的反馈参数去修改两个权重
self.who += self.lr * np.dot((output_errors * final_outputs * ( 1.0-final_outputs)), np.transpose(hidden_outputs))
self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0-hidden_outputs)), np.transpose(inputs))
如此我们的基础神经网络构建完成了。
五、手写数字的识别
接下来神经网络是完成的,那么我们究竟该如何去将数据输入呢?
csv文件我们并不陌生【或许陌生?】,他是逗号分割文件,顾名思义,它是通过逗号分隔的,所以我们可以打开看一下:
眼花缭乱!!
但是细心的我们可以发现他的第一个数字都是0~9,说明是我们的标签,那么后面的应该就是图像了,通过了解我们知道这个后面的数据是一个28*28的图像。
all_value = data_list[0].split(',') # split分割成列表
image_array = np.asfarray(all_value[1:]).reshape((28,28)) # 将数据reshape成28*28的矩阵
plt.imshow(image_array, cmap='Greys', interpolation='None') # 展示一下
通过这段代码,我们可以简单的看一下每个数字是什么:
很好,知道这里就足够了,那么我们接下来就是将这些数据传入了!
我们在训练的时候,需要将他们都转化成数字列表,方便处理
data = [] # 用来保存训练过程的数据
sum_count = 0 # 统计总识别的正确的个数
for i in range(15): # 训练的轮数
count = 0 # 单次训练识别正确的个数
for j in range(len(data_list)): # 对60000张图片开始训练, 没有划分数据集的过程主要是别人直接给了,我也懒得自己去做了,主要就是展示一下神经网络嘛~
target = np.zeros(10)+0.01 # 生成初始标签集合,用来和结果对比
line_ = data_list[j].split(',') # 对每一行的数据处理切割
imagearray = np.asfarray(line_) # 将切割完成的数据转换成数字列表
target[int(imagearray[0])] = 1.0 # 将正确答案挑出来
n.train(imagearray[1:]/255*0.99+0.01, target) # 丢入训练,丢入的时候注意将数据转换成0.01~1.0之间的结果
for line in answer_data: # 对10000组测试集测试
all_values = line.split(',')
answer = n.query((np.asfarray(all_values[1:])/255*0.99)+0.01)
if answer[int(all_values[0])] > 0.85: # 查看对应位置是否达到自定义的阈值?
count += 1
sum_count += count
string = "训练进度 %05f\n本轮准确度 %05f\n总准确度 %05f\n\n"%(i/120,count/len(answer_data), sum_count/(len(answer_data)*(i+1)))
data.append([i/120,count/len(answer_data), sum_count/(len(answer_data)*(i+1))]) # 将数据保存方便生成训练曲线
print(string)
```
接下来我们将结果图片展示以下吧~
```python
data = np.array(data)
plt.plot(range(len(data)), data[:, 1:])
六、源码
把源码整理一下贴出来
import numpy as np
import scipy.special as spe
import matplotlib.pyplot as plt
class neuralnetwork:
# 我们需要去初始化一个神经网络
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
self.inodes = inputnodes
self.hnodes = hiddennodes
self.onodes = outputnodes
self.lr = learningrate
self.wih = (np.random.normal(0.0, pow(self.hnodes, -0.5),(self.hnodes, self.inodes)))
self.who = (np.random.normal(0.0, pow(self.onodes, -0.5),(self.onodes, self.hnodes)))
self.activation_function = lambda x: spe.expit(x) # 返回sigmoid函数
def train(self, inputs_list, targets_list):
inputs = np.array(inputs_list, ndmin=2).T
hidden_inputs = np.dot(self.wih, inputs)
hidden_outputs = self.activation_function(hidden_inputs)
final_inputs = np.dot(self.who, hidden_outputs)
final_outputs = self.activation_function(final_inputs)
targets = np.array(targets_list, ndmin=2).T
output_errors = targets - final_outputs
hidden_errors = np.dot(self.who.T, output_errors)
self.who += self.lr * np.dot((output_errors * final_outputs * ( 1.0-final_outputs)), np.transpose(hidden_outputs))
self.wih += self.lr * np.dot((hidden_errors * hidden_outputs * (1.0-hidden_outputs)), np.transpose(inputs))
def query(self, inputs_list):
inputs = np.array(inputs_list, ndmin=2).T
hidden_inputs = np.dot(self.wih, inputs)
hidden_outputs = self.activation_function(hidden_inputs)
final_inputs = np.dot(self.who, hidden_outputs)
final_outputs = self.activation_function(final_inputs)
return final_outputs
input_nodes = 784
hidden_nodes = 88
output_nodes = 10
learn_rate = 0.05
n = neuralnetwork(input_nodes, hidden_nodes, output_nodes, learn_rate)
data_file = open("E:\sklearn_data\神经网络数字识别\mnist_train.csv", 'r')
data_list = data_file.readlines()
data_file.close()
file2 = open("E:\sklearn_data\神经网络数字识别\mnist_test.csv")
answer_data = file2.readlines()
file2.close()
data = []
sum_count = 0
for i in range(15):
count = 0
for j in range(len(data_list)):
target = np.zeros(10)+0.01
line_ = data_list[j].split(',')
imagearray = np.asfarray(line_)
target[int(imagearray[0])] = 1.0
n.train(imagearray[1:]/255*0.99+0.01, target)
for line in answer_data:
all_values = line.split(',')
answer = n.query((np.asfarray(all_values[1:])/255*0.99)+0.01)
if answer[int(all_values[0])] > 0.85:
count += 1
sum_count += count
string = "训练进度 %05f\n本轮准确度 %05f\n总准确度 %05f\n\n"%(i/120,count/len(answer_data), sum_count/(len(answer_data)*(i+1)))
data.append([i/120,count/len(answer_data), sum_count/(len(answer_data)*(i+1))])
print(string)
data = np.array(data)
plt.plot(range(len(data)), data[:, 1:])
可以说是相对简单的一个程序,但却是包含着神经网络最基础的思想!值得好好康康~
七、思考
如何识别其他手写字体等?
我的想法:通过图像处理,将像素规定到相近大小【尺度放缩】
图像大小运行速度问题
我的想法:如何快速的矩阵运算,通过C语言是否可以加速?相较于darknet这个神经网络仅有三层,运算速度并不是十分理想。当然cuda编程对于GPU加速肯定是最好的选择之一。
来源:https://blog.csdn.net/qq_44961028/article/details/116429010


猜你喜欢
- windows系统MySQL安装教程下载1.登录https://dev.mysql.com/downloads/installer/选择Mi
- 代码如下:url="http://www.cidianwang.com/" wstr=getHTTPPage(
- MVC模式MVC, 全名Model View Controller, 是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Mo
- 这篇文章主要介绍了python中的Elasticsearch操作汇总,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习
- 虽然大多数web文档的顶部都有doctype声明,但很多人都没有注意它。它是在你新建一个文档时,由web创作软件草率处理的众多细节之一。虽然
- python 封装tokenimport datetimeclass MyJwt:def __init__(self): &n
- *在起初pip install matplotlib时,主动安装到当时最新版本(matplotlib==3.3.2),在StackOverf
- 想用C++写项目,数据库是必须的,所以这两天学了一下C++操作MySQL数据库的方法。也没有什么教程,就是在网上搜的知识,下面汇总一下。 连
- 使用PyTorch进行训练和测试时一定注意要把实例化的model指定train/eval,eval()时,框架会自动把BN和DropOut固
- 开发时,通常打开Debug模式会快速定位开发时的一些问题。项目开始部署时,关闭Debug模式,url.py路由静态文件和图片写法:# url
- 之前介绍过通过cookie 绕过验证码实现登录的方法。这里并不多余,会增加分析和另外一种方法实现登录。1、思路介绍 1.1、直接看
- 前言特别说明: 本文只适合新手学习这篇文章带我们入门go语言的定义变量的方式,其实和javascript很相似,所以特意总结在此。在go语言
- 问题你的程序获取了一个目录中的文件名列表,但是当它试着去打印文件名的时候程序崩溃, 出现了 UnicodeEncodeError 异常和一条
- 前言闲暇时间抽个空写了个三国杀武将手册的小程序,中间有个需求设计的是合成武将皮肤图、竖排的武将姓名、以及小程序码,然后提供保存图片到相册,最
- Python 模块概念python中的模块是什么?简而言之,在python中,一个文件(以“.py”为后缀名的文件)就叫做一个模块,每一个模
- unsigned 既为非负数,用此类型可以增加数据长度! 例如如果 tinyint最大是127,那 tinyint unsigned 最大
- 本文研究的主要是python实现Adapter模式的相关内容,具体实现代码如下。Adapter模式有两种实现方式一种是类方式。#理解 #就是
- 0x01 生成shellcode首先通过下列命令生成一个shellcode,使用msfvenom -p选项来指定paylaod,这里选用wi
- PHP mysqli_sqlstate() 函数返回最后一个 MySQL 操作的 SQLSTATE 错误代码:<?php// 假定数据
- 前言写这次博客其实事出有因,前几天呢,一个非常优秀的学姐在QQ空间里晒了自己的CSDN博客的总阅读量,达到了7万+,很厉害了,而且确实她的博