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

写在之前

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

首先是关于这本书,我真的认为他是将神经网络里非常棒的一本书,但你也需要注意,如果你真的想自己动手去实现,那么你一定需要有一定的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加速肯定是最好的选择之一。

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

(0)

相关推荐

  • Python如何使用神经网络进行简单文本分类

    深度学习无处不在.在本文中,我们将使用Keras进行文本分类. 准备数据集 出于演示目的,我们将使用  20个新闻组  数据集.数据分为20个类别,我们的工作是预测这些类别.如下所示: 通常,对于深度学习,我们将划分训练和测试数据. 导入所需的软件包 Python import pandas as pd import numpy as np import pickle from keras.preprocessing.text import Tokenizer from keras.models

  • Python通过TensorFlow卷积神经网络实现猫狗识别

    这份数据集来源于Kaggle,数据集有12500只猫和12500只狗.在这里简单介绍下整体思路 处理数据 设计神经网络 进行训练测试 1. 数据处理 将图片数据处理为 tf 能够识别的数据格式,并将数据设计批次. 第一步get_files() 方法读取图片,然后根据图片名,添加猫狗 label,然后再将 image和label 放到 数组中,打乱顺序返回 将第一步处理好的图片 和label 数组 转化为 tensorflow 能够识别的格式,然后将图片裁剪和补充进行标准化处理,分批次返回. 新建

  • python神经网络编程实现手写数字识别

    本文实例为大家分享了python实现手写数字识别的具体代码,供大家参考,具体内容如下 import numpy import scipy.special #import matplotlib.pyplot class neuralNetwork: def __init__(self,inputnodes,hiddennodes,outputnodes,learningrate): self.inodes=inputnodes self.hnodes=hiddennodes self.onodes

  • Python利用全连接神经网络求解MNIST问题详解

    本文实例讲述了Python利用全连接神经网络求解MNIST问题.分享给大家供大家参考,具体如下: 1.单隐藏层神经网络 人类的神经元在树突接受刺激信息后,经过细胞体处理,判断如果达到阈值,则将信息传递给下一个神经元或输出.类似地,神经元模型在输入层输入特征值x之后,与权重w相乘求和再加上b,经过激活函数判断后传递给下一层隐藏层或输出层. 单神经元的模型只有一个求和节点(如左下图所示).全连接神经网络(Full Connected Networks)如右下图所示,中间层有多个神经元,并且每层的每个

  • python机器学习之神经网络实现

    神经网络在机器学习中有很大的应用,甚至涉及到方方面面.本文主要是简单介绍一下神经网络的基本理论概念和推算.同时也会介绍一下神经网络在数据分类方面的应用. 首先,当我们建立一个回归和分类模型的时候,无论是用最小二乘法(OLS)还是最大似然值(MLE)都用来使得残差达到最小.因此我们在建立模型的时候,都会有一个loss function. 而在神经网络里也不例外,也有个类似的loss function. 对回归而言: 对分类而言: 然后同样方法,对于W开始求导,求导为零就可以求出极值来. 关于式子中

  • Python创建简单的神经网络实例讲解

    在过去的几十年里,机器学习对世界产生了巨大的影响,而且它的普及程度似乎在不断增长.最近,越来越多的人已经熟悉了机器学习的子领域,如神经网络,这是由人类大脑启发的网络.在本文中,将介绍用于一个简单神经网络的 Python 代码,该神经网络对于一个 1x3 向量,分类第一个元素是否为 10. 步骤1: 导入 NumPy. Scikit-learn 和 Matplotlib import numpy as np from sklearn.preprocessing import MinMaxScale

  • python实现BP神经网络回归预测模型

    神经网络模型一般用来做分类,回归预测模型不常见,本文基于一个用来分类的BP神经网络,对它进行修改,实现了一个回归模型,用来做室内定位.模型主要变化是去掉了第三层的非线性转换,或者说把非线性激活函数Sigmoid换成f(x)=x函数.这样做的主要原因是Sigmoid函数的输出范围太小,在0-1之间,而回归模型的输出范围较大.模型修改如下: 代码如下: #coding: utf8 '''' author: Huangyuliang ''' import json import random impo

  • Python实现Keras搭建神经网络训练分类模型教程

    我就废话不多说了,大家还是直接看代码吧~ 注释讲解版: # Classifier example import numpy as np # for reproducibility np.random.seed(1337) # from keras.datasets import mnist from keras.utils import np_utils from keras.models import Sequential from keras.layers import Dense, Act

  • Python使用循环神经网络解决文本分类问题的方法详解

    本文实例讲述了Python使用循环神经网络解决文本分类问题的方法.分享给大家供大家参考,具体如下: 1.概念 1.1.循环神经网络 循环神经网络(Recurrent Neural Network, RNN)是一类以序列数据为输入,在序列的演进方向进行递归且所有节点(循环单元)按链式连接的递归神经网络. 卷积网络的输入只有输入数据X,而循环神经网络除了输入数据X之外,每一步的输出会作为下一步的输入,如此循环,并且每一次采用相同的激活函数和参数.在每次循环中,x0乘以系数U得到s0,再经过系数W输入

  • 如何用Python 实现全连接神经网络(Multi-layer Perceptron)

    代码 import numpy as np # 各种激活函数及导数 def sigmoid(x): return 1 / (1 + np.exp(-x)) def dsigmoid(y): return y * (1 - y) def tanh(x): return np.tanh(x) def dtanh(y): return 1.0 - y ** 2 def relu(y): tmp = y.copy() tmp[tmp < 0] = 0 return tmp def drelu(x): t

  • Python实现的NN神经网络算法完整示例

    本文实例讲述了Python实现的NN神经网络算法.分享给大家供大家参考,具体如下: 参考自Github开源代码:https://github.com/dennybritz/nn-from-scratch 运行环境 Pyhton3 numpy(科学计算包) matplotlib(画图所需,不画图可不必) sklearn(人工智能包,生成数据使用) 计算过程 输入样例 none 代码实现 # -*- coding:utf-8 -*- #!python3 __author__ = 'Wsine' im

  • python机器学习之神经网络

    手写数字识别算法 import pandas as pd import numpy as np from sklearn.neural_network import MLPRegressor #从sklearn的神经网络中引入多层感知器 data_tr = pd.read_csv('BPdata_tr.txt') # 训练集样本 data_te = pd.read_csv('BPdata_te.txt') # 测试集样本 X=np.array([[0.568928884039633],[0.37

  • Python利用numpy实现三层神经网络的示例代码

    本文主要介绍了Python利用numpy实现三层神经网络的示例代码,分享给大家,具体如下: 其实神经网络很好实现,稍微有点基础的基本都可以实现出来.主要都是利用上面这个公式来做的. 这是神经网络的整体框架,一共是三层,分为输入层,隐藏层,输出层.现在我们先来讲解下从输出层到到第一个隐藏层. 使用的编译器是jupyter notebook import numpy as np #定义X,W1,B1 X = np.array([1.0, 0.5]) w1 = np.array([[0.1, 0.3,

随机推荐