python神经网络编程之手写数字识别


Posted in Python onMay 08, 2021

写在之前

首先是写在之前的一些建议:

首先是关于这本书,我真的认为他是将神经网络里非常棒的一本书,但你也需要注意,如果你真的想自己动手去实现,那么你一定需要有一定的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文件我们并不陌生【或许陌生?】,他是逗号分割文件,顾名思义,它是通过逗号分隔的,所以我们可以打开看一下:

python神经网络编程之手写数字识别

眼花缭乱!!

但是细心的我们可以发现他的第一个数字都是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') # 展示一下

通过这段代码,我们可以简单的看一下每个数字是什么:

python神经网络编程之手写数字识别

很好,知道这里就足够了,那么我们接下来就是将这些数据传入了!

我们在训练的时候,需要将他们都转化成数字列表,方便处理

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:])

python神经网络编程之手写数字识别

六、源码

把源码整理一下贴出来

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加速肯定是最好的选择之一。

到此这篇关于python神经网络编程之手写数字识别的文章就介绍到这了,更多相关python手写数字识别内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
使用python实现递归版汉诺塔示例(汉诺塔递归算法)
Apr 08 Python
python迭代器实例简析
Sep 25 Python
跟老齐学Python之for循环语句
Oct 02 Python
PyQt5每天必学之拖放事件
Aug 27 Python
Python创建普通菜单示例【基于win32ui模块】
May 09 Python
Flask框架Jinjia模板常用语法总结
Jul 19 Python
Python学习笔记之迭代器和生成器用法实例详解
Aug 08 Python
python rsa实现数据加密和解密、签名加密和验签功能
Sep 18 Python
django中的数据库迁移的实现
Mar 16 Python
通过python-pptx模块操作ppt文件的方法
Dec 26 Python
pandas 操作 Excel操作总结
Mar 31 Python
你喜欢篮球吗?Python实现篮球游戏
Jun 11 Python
利用Selenium添加cookie实现自动登录的示例代码(fofa)
Python基础之教你怎么在M1系统上使用pandas
python文件目录操作之os模块
May 08 #Python
Python进阶学习之带你探寻Python类的鼻祖-元类
May 08 #Python
python实战之用emoji表情生成文字
May 08 #Python
python实现过滤敏感词
Django中的JWT身份验证的实现
May 07 #Python
You might like
造势之举?韩国总统候选人发布《星际争霸》地图
2017/04/22 星际争霸
PHPMYADMIN 简明安装教程 推荐
2010/03/07 PHP
php算开始时间到过期时间的相隔的天数
2011/01/12 PHP
PHP对象Object的概念 介绍
2012/06/14 PHP
php中存储用户ID和密码到mysql数据库的方法
2013/02/06 PHP
弹出模态框modal的实现方法及实例
2017/09/19 PHP
phpMyAdmin通过密码漏洞留后门文件
2018/11/20 PHP
JavaScript写的一个自定义弹出式对话框代码
2010/01/17 Javascript
jQuery数据缓存功能的实现思路及简单模拟
2013/05/27 Javascript
js 窗口抖动示例
2013/09/04 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
2016/06/02 Javascript
js编写的treeview使用方法
2016/11/11 Javascript
微信开发 JS-SDK 6.0.2 经常遇到问题总结
2016/12/08 Javascript
Bootstrap CSS布局之图像
2016/12/17 Javascript
Vue-resource实现ajax请求和跨域请求示例
2017/02/23 Javascript
基于JavaScript实现选项卡效果
2017/07/21 Javascript
AngularJS实现的省市二级联动功能示例【可对选项实现增删】
2017/10/26 Javascript
vue-router 中 meta的用法详解
2019/11/01 Javascript
[46:58]完美世界DOTA2联赛PWL S3 Forest vs LBZS 第一场 12.17
2020/12/19 DOTA
Python time模块详解(常用函数实例讲解,非常好)
2014/04/24 Python
浅析Python中signal包的使用
2015/11/13 Python
深入理解NumPy简明教程---数组3(组合)
2016/12/17 Python
离线安装Pyecharts的步骤以及依赖包流程
2020/04/23 Python
对Python 两大环境管理神器 pyenv 和 virtualenv详解
2018/12/31 Python
python对csv文件追加写入列的方法
2019/08/01 Python
pytorch 指定gpu训练与多gpu并行训练示例
2019/12/31 Python
Python利用 utf-8-sig 编码格式解决写入 csv 文件乱码问题
2020/02/21 Python
python 删除excel表格重复行,数据预处理操作
2020/07/06 Python
Python自动化xpath实现自动抢票抢货
2020/09/19 Python
pip已经安装好第三方库但pycharm中import时还是标红的解决方案
2020/10/09 Python
requests在python中发送请求的实例讲解
2021/02/17 Python
高清屏中使用Canvas绘图出现模糊的问题及解决方法
2019/06/03 HTML / CSS
JAVA的事件委托机制和垃圾回收机制
2014/09/07 面试题
涉外文秘个人求职的自我评价
2013/10/07 职场文书
《登鹳雀楼》教学反思
2014/04/09 职场文书
《生物入侵者》教学反思
2016/02/16 职场文书