精华内容
下载资源
问答
  • 手写数字分类
    千次阅读
    2021-11-05 23:28:59

    学习tensorflow使用神经网络实现MNIST手写数字分类的过程中遇到了很多问题,这里记录下来并总结

    环境:

    • windows11下的VM15,Ubuntu20.04,tensor环境,需要的包统一用conda install进行安装
    • IDE为pycharm2021,实际自己练习时使用jupyter效果可能会更好

    导包:

    from tensorflow import keras
    

    第一步没什么好说的,tensorflow是一个和pytorch齐名的框架,keras是作为tensorflow的核心接口

    感兴趣可以使用单击tensorflow或者pytorch,再使用Ctrl+鼠标左键进行查看

    获得数据集:

    # 数据集 mnist
    from tensorflow.keras.datasets import mnist
    # 获取数据
    (X_train, y_train),(X_test,y_test) =  mnist.load_data()
    

    这样我们得到了训练集、测试集和标记,但是mnist具体是什么样子的我们不清楚

    先看一下数据类型,再看shape

    print(type(X_train))
    print(X_train.shape)
    
    <class 'numpy.ndarray'>
    (60000, 28, 28)
    

    这里可以下载mnist数据

    http://yann.lecun.com/exdb/mnist/

    四个文件都是ubyte文件,无法用软件打开,需要代码进行读取

    # 将训练集数据形状从(60000,28,28)修改为(60000,784)
    X_train = X_train.reshape(len(X_train),-1)
    X_test = X_test.reshape(len(X_test),-1)
    print(X_test.shape)
    

    查看一些图片:

    先编写一个将数据转化为图片的函数

    import matplotlib.pyplot as plt
    # 查看一些图片
    def plot_images(imgs):
        """绘制几个样本图片
        :param show: 是否显示绘图
        :return:
        """
        sample_num = min(9, len(imgs))
        img_figure = plt.figure(1)
        img_figure.set_figwidth(5)
        img_figure.set_figheight(5)
        for index in range(0, sample_num):
            ax = plt.subplot(3, 3, index + 1)
            ax.imshow(imgs[index].reshape(28, 28), cmap='gray')
            ax.grid(False)
        plt.margins(0, 0)
        plt.show()
    

    这里我一开始看到是很懵的,如果你和我一样基础不好,但是也想完整学下去,和我一起耐心查看(大神绕道)

    • 首先我们要知道图片是二维的,是由像素构成的,比如28*28个像素,然后我们得到的X_train是3维的,总计60000,所以一开始我们查看X_shape的结果是(60000, 28, 28)这样的数据,也就是我们要想得到图片的话,我们只需要每次都得到28*28的数据,至于怎么把这28*28的数据变成图片,matplotlib已经封装好了,感兴趣的话可以深究。
    • 接着这个函数会让我们输出9张图片
    • figure函数同样可以使用Ctrl+鼠标左键查看,这里的1是第一次作图的意思
    • 接下来设置图片的大小,也可设置成自己喜欢的大小
    • 然后从0到9生成9张图,其中subplot有3个参数,分别是行、列、第几张图,这里是3行3列
    • 这里imshow就是我们刚刚将的封装好的画图
    • grid消除网格线,不妨设置成True试着玩一下
    • 最后使用plt.show()全部输出
    plot_images(X_train)
    

    这样就生成了一张图片,里面包含9张子图片

    回顾

    在之前的鸢尾花数据集处理中,我们用sklearn的逻辑回归进行分类,流程大致如下:

    • 数据集获取
    • 数据集分类
    • 数据集规则化
    • 模型训练
    • 模型预测
    • 交叉验证

    在这个例子中也类似的流程

    对数据进行处理

    首先我们知道了,我们要60000*28*28的数据,要处理的是28*28的数据,那我们可以先取出来看一下

    print(X_train[1])
    print(len(X_train[1]))
    

    把数据类型修改成float类型的,并且压缩到[-1,1]

    # 将数据集图像像素点的数据类型从 uint8 修改为 float32
    X_train = X_train.astype('float32')
    X_test = X_test.astype('float32')
    
    # 把数据集图像的像素值从 0-255 放缩到[-1,1]之间
    X_train = (X_train - 127)/127
    X_test = (X_test - 127)/127
    
    # 数据集类别个数
    nb_classes = 10
    
    from tensorflow.python.keras.utils import np_utils
    # 把 y_train 和 y_test 变成了 one-hot 的形式,即之前是 0-9 的一个数值,
    # 现在是一个大小为 10 的向量,它属于哪个数字,就在哪个位置为 1,其他位置都是 0。
    print(y_train[1])
    y_train = np_utils.to_categorical(y_train,nb_classes)
    y_test = np_utils.to_categorical(y_test,nb_classes)
    print(y_train[1])
    

    这里需要说明的是np_utils包,如果看到其他的导包和我们的不一样也没关系,这个包是因为keras升级之后在env的位置变化不同,怎么导包最简单呢?按pycharm提示的做就好

    0
    [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
    

    搭建神经网络框架

    现在,我们可以来设计我们的神经网络了

    如之前鸢尾花一样,我们可以一路写下来,但是也可以写成函数,后面更方便

    在这里,对于keras,有两种类型的模型,一种是序贯模型,一种是函数式模型

    序贯模型(Sequential)及一条路走到底,最简单,这次我们用这个

    from tensorflow.python.keras import Sequential
    from tensorflow.keras.layers import Dense,Activation,Dropout
    def create_model():
        """
        采用 keras 搭建神经网络模型
        :return: 神经网络模型
        """
        # 选择模型,选择序贯模型(Sequential())
        model = Sequential()
        # 添加全连接层,共 512 个神经元
        model.add(Dense(512, input_shape=(784,), kernel_initializer='he_normal'))
    
        # 添加激活层,激活函数选择 relu
        model.add(Activation('relu'))
    
        # 添加全连接层,共 512 个神经元
        model.add(Dense(512, kernel_initializer='he_normal'))
    
        # 添加激活层,激活函数选择 relu
        model.add(Activation('relu'))
    
        # 添加全连接层,共 10 个神经元
        model.add(Dense(nb_classes))
    
        # 添加激活层,激活函数选择 softmax
        model.add(Activation('softmax'))
    
        return model
    

    这个函数脉络比较清晰,3组,每组都是Dense+Activation

    Dense即每一层的神经元,每一层都可以自己设置神经元的个数,但是最后一层一定要是10,第一层输入要是784

    Activation即激活函数

    model = create_model()
    

    训练并测试

    接下来便是训练和测试我们的神经网络

    def fit_and_predict(model, model_path):
        """
        训练模型、模型评估、保存模型
        :param model: 搭建好的模型
        :param model_path:保存模型路径
        :return:
        """
        # 编译模型
        model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    
        # 模型训练
        model.fit(X_train, y_train, epochs=5, batch_size=64, verbose=1, validation_split=0.05)
    
        # 保存模型
        model.save(model_path)
    
        # 模型评估,获取测试集的损失值和准确率
        loss, accuracy = model.evaluate(X_test, y_test)
    
        # 打印结果
        print('Test loss:', loss)
        print("Accuracy:", accuracy)
    

    自定义训练模型,传入神经网络模型和路径(这里也可以不加路径,加路径是下次可以直接使用)

    • 编译,第一个参数是优化方法,第二个参数定义loss,第三个参数是评估方法
    • 训练,传入训练集、训练标记、循环次数、batch_size、模型日志
    • 保存模型可不保存

    最后,我们进行调用

    fit_and_predict(model, model_path='./model.h5')
    
    Epoch 1/5
    891/891 [==============================] - 12s 13ms/step - loss: 0.4352 - accuracy: 0.8644 - val_loss: 0.1091 - val_accuracy: 0.9703
    Epoch 2/5
    891/891 [==============================] - 39s 43ms/step - loss: 0.1306 - accuracy: 0.9582 - val_loss: 0.0824 - val_accuracy: 0.9773
    Epoch 3/5
    891/891 [==============================] - 11s 13ms/step - loss: 0.0956 - accuracy: 0.9694 - val_loss: 0.0767 - val_accuracy: 0.9803
    Epoch 4/5
    891/891 [==============================] - 8s 8ms/step - loss: 0.0771 - accuracy: 0.9750 - val_loss: 0.0736 - val_accuracy: 0.9827
    Epoch 5/5
    891/891 [==============================] - 8s 9ms/step - loss: 0.0629 - accuracy: 0.9795 - val_loss: 0.0885 - val_accuracy: 0.9780
    313/313 [==============================] - 169s 531ms/step - loss: 0.1071 - accuracy: 0.9685
    Test loss: 0.10707166790962219
    Accuracy: 0.968500018119812
    
    更多相关内容
  • 十分简单的,易于理解的CNN神经网络用于手写数字分类,基于TensorFlow,适合初学者掌握理解。
  • 使用BP神经网络实现一个手写数字识别,同时使用GUI对识别过程进行可视化
  • 手写数字分类

    2021-02-10 03:34:23
    手写数字分类
  • 基于深度学习的手写数字分类问题研究.pdf
  • 本代码利用MATLAB自建5层CNN模型完成手写数字字体识别,全套代码 100%可用。
  • 【theano-windows】学习笔记九——softmax手写数字分类-附件资源
  • 十分简单的BP神经网络程序,只有单层神经网络,适合初学者掌握TensorFlow。
  • 基于tensorflow+CNN的MNIST数据集手写数字分类-附件资源
  • Matlab聚类分析软件-手写数字分类软件.rar matlab实现智能计算与识别的软件,相信能给大家很大的帮助 一、手写数字分类软件。 二、聚类分析软件。 软件安装说明: 一、手写数字分类软件。 1) 打开“手写数字...
  • 本文无需了解任何AI先验知识(当然有更好),快速入门AI基本脉络,手把手教你一步步搭建神经网络,并解决一个分类手写数字的实际问题。

    基于Pytorch实现MNIST手写数字分类任务

    运行环境
    系统:Win10 CPU
    解释器:Python
    依赖包:Anaconda Pytorch

    前言


    本文无需了解任何AI先验知识(当然有更好),快速入门AI基本脉络,手把手教你一步步搭建神经网络,并解决一个分类手写数字的实际问题。

    基本流程:

    • 搭建环境,导入依赖包
    • 下载MNIST数据集,并做预处理
    • Dataset转化为Pytorch能识别的DataLoader
    • 构建神经网络,设置各层神经元及优化方式
    • 训练神经网络,进入学习阶段
    • 测试神经网络,进入推理阶段

    实现细节


    搭建环境,安装依赖包

    !conda install pytorch-cpu -c pytorch    # 导入pytorch依赖包
    !pip install torchvision                 #  pytorch关于图像视频的包
    

    导入依赖包

    import torch
    import torchvision
    from sklearn.datasets import fetch_openml
    import matplotlib.pyplot as plt
    # % matplotlib inline
    
    import torch
    from torch.utils.data import TensorDataset, DataLoader
    from sklearn.model_selection import train_test_split
    
    from torch import nn
    
    import numpy as np
    

    数据集预处理

    # pre-processing
    
    mnist = fetch_openml('mnist_784', data_home='.')
    X = mnist.data / 255
    y = mnist.target
    
    # dataloader
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=1/7, random_state=0)  # 数据切分,训练集:测试集=6:1
    
    X_train = np.array(X_train)          # 将list转为numpy格式
    X_test = np.array(X_test)
    y_train = list(map(int, y_train))    # 将label的str类型转为int
    y_test = list(map(int, y_test))
    X_train = torch.Tensor(X_train)      # 转为浮点tensor
    X_test = torch.Tensor(X_test)
    y_train = torch.LongTensor(y_train)  # 转为整型tensor
    y_test = torch.LongTensor(y_test)
    
    ds_train = TensorDataset(X_train, y_train)  # 转为Dataset
    ds_test = TensorDataset(X_test, y_test)
    
    # 转为Pytorch可以直接操作彻底DataLoader
    loader_train = DataLoader(ds_train, batch_size=(64), shuffle=True)
    loader_test = DataLoader(ds_test, batch_size=(64), shuffle=True)
    

    搭建神经网络,Keras风格,选其一即可

    # build nn with keras sytle
    model = nn.Sequential()                             # 获取网络模型句柄
    model.add_module('fc1', nn.Linear(28*28*1, 100))    # 第一层神经元,输入层
    model.add_module('relu1', nn.ReLU())                # 第一层激活函数
    model.add_module('fc2', nn.Linear(100, 100))        # 第二层神经元,中间层
    model.add_module('relu2', nn.ReLU())                # 第二层激活函数
    model.add_module('fc3', nn.Linear(100, 10))         # 第三层神经元,输出层
    print(model)
    

    输出结果如下:

    Sequential(
    (fc1): Linear(in_features=784, out_features=100, bias=True)
    (relu1): ReLU()
    (fc2): Linear(in_features=100, out_features=100, bias=True)
    (relu2): ReLU()
    (fc3): Linear(in_features=100, out_features=10, bias=True)
    )

    搭建神经网络,Chainer风格,选其一即可

    # build nn with chainer style
    
    import torch.nn as nn
    import torch.nn.functional as F
    
    class Net(nn.Module):
        
        def __init__(self, n_in, n_mid, n_out):
            super(Net, self).__init__()
            self.fc1 = nn.Linear(n_in, n_mid)
            self.fc2 = nn.Linear(n_mid, n_mid)
            self.fc3 = nn.Linear(n_mid, n_out)
            
        def forward(self, x):
            h1 = F.relu(self.fc1(x))
            h2 = F.relu(self.fc2(h1))
            output = self.fc3(h2)
            return output
        
        
    model = Net(n_in=28*28*1, n_mid=100, n_out=10)
    print(model)
    
    

    输出结果如下:

    Net(
    (fc1): Linear(in_features=784, out_features=100, bias=True)
    (fc2): Linear(in_features=100, out_features=100, bias=True)
    (fc3): Linear(in_features=100, out_features=10, bias=True)
    )

    损失函数设置

    # loss function
    
    from torch import optim
    
    loss_fn = nn.CrossEntropyLoss()                       # 选取交叉熵作为误差函数
    optimizer = optim.Adam(model.parameters(), lr=0.01)   # 设置优化器参数,学习率0.01
    

    训练神经网络,设计学习阶段和推理阶段

    # learning and predict process
    
    # 训练阶段
    def train(epoch):
        model.train()
        
        for data, targets in loader_train:
            optimizer.zero_grad()
            outputs = model(data)
            loss = loss_fn(outputs, targets)
            loss.backward()
            optimizer.step()
            
        print("epoch{}:结束\n".format(epoch))
    
    # 推理阶段
    def test():
        model.eval()
        correct = 0
        
        with torch.no_grad():
            for data, targets in loader_test:
                outputs = model(data)
                _, predicted = torch.max(outputs.data, 1)
                correct += predicted.eq(targets.data.view_as(predicted)).sum()
        
        data_sum = len(loader_test.dataset)
        print("\n 测试数据的准确率 : {}/{} ({:.0f}%)\n".
             format(correct, data_sum, 100. * correct / data_sum))
            
    # 训练前的分类准确率
    test()
    # 训练3个epoch过程
    for epoch in range(3):
        train(epoch)
    # 训练后的分类准确率
    test()
    
    
    

    输出结果如下:

    测试数据的准确率 : 981/10000 (10%)
    epoch0:结束
    epoch1:结束
    epoch2:结束
    测试数据的准确率 : 9596/10000 (96%)

    推理分类特定图片

    # predict particular picture
    
    # 推理第8505张图片的数字类别
    index = 8505
    model.eval()
    data = X_test[index]
    
    output = model(data)
    _, predicted = torch.max(output.data, 0)
    print("预测结果是{}".format(predicted))
    
    X_test_show = (X_test[index]).numpy()
    plt.imshow(X_test_show.reshape(28, 28), cmap='gray')
    print("这一图像数据的正确标签是{:.0f}".format(y_test[index]))
    
    

    输出结果如下:

    测试数据的准确率 : 9548/10000 (95%)
    预测结果是0
    这一图像数据的正确标签是0
    在这里插入图片描述

    问题讨论


    DataLoader的用途?

    • pytorch与外界数据沟通的桥梁
    • dataloader能供pytorch直接使用
    • dataloader作为python自带的numpy数据类型中转
    • 过程:numpy -> tensor -> dataset -> dataloader

    遗留:

    • _,predict = torch.max(), 下划线_是啥意思?
    • conda和spyder的环境依赖关系是?

    参考资料


    1. 边做边学深度强化学习,link

    声明:本文主体代码来自于书籍《边做边学深度强化学习》,只是在手敲其代码的过程中,添加一些自己的理解,详情可以查阅对应章节。

    展开全文
  • MNIST手写数字分类器 使用numpy库实现多层神经网络。 该实现是《一书中Michael Nielsen的实现的修改版本。 简要背景: 如果您熟悉神经网络的基础知识,请随时跳过本节。 对于在阅读有关Neural Networks的任何内容...
  • 基于线性感知器的手写数字分类(SVM,支持向量机),附带测试集和训练集。有详细的代码介绍和分类流程说明,有利于读者深入理解基本原理和操作流程
  • 一套能够正确识别手写体的软件系统,使用matlab为开发平台。
  • 基于SVM的手写数字分类 (python实现)代码+数据.rar
  • MNIST数据集手写数字分类

    千次阅读 2020-01-01 20:48:54
    目录 0.编程环境 1、下载并解压数据集 2、完整代码 3、数据准备 ...4.4 查看手写数字图 5、搭建神经网络 6、变量初始化 7、模型训练 9、模型测试 MNIST是Mixed National Institue of Standards an...

    参考   MNIST数据集手写数字分类 - 云+社区 - 腾讯云

    目录

    0.编程环境

    1、下载并解压数据集

    2、完整代码

    3、数据准备

    4、数据观察

    4.1 查看变量mnist的方法和属性

    4.2 对比三个集合

    4.3 mnist.train.images观察

    4.4 查看手写数字图

    5、搭建神经网络

    6、变量初始化

    7、模型训练

    9、模型测试


    MNIST是Mixed National Institue of Standards and Technology database的简称,中文叫做美国国家标准与技术研究所数据库

    0.编程环境

    安装tensorflow命令:pip install tensorflow
    操作系统:Win10
    python版本:3.6
    集成开发环境:jupyter notebook
    tensorflow版本:1.6

    1、下载并解压数据集

    MNIST数据集下载链接: 百度网盘 请输入提取码 密码: wa9p
    下载压缩文件MNIST_data.rar完成后,选择解压到当前文件夹不要选择解压到MNIST_data。
    文件夹结构如下图所示:

    2、完整代码

    此章给读者能够直接运行的完整代码,使读者有编程结果的感性认识。
    如果下面一段代码运行成功,则说明安装tensorflow环境成功。
    想要了解代码的具体实现细节,请阅读后面的章节。

    import warnings
    warnings.filterwarnings('ignore')
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    batch_size = 100
    X_holder = tf.placeholder(tf.float32)
    y_holder = tf.placeholder(tf.float32)
    
    Weights = tf.Variable(tf.zeros([784, 10]))
    biases = tf.Variable(tf.zeros([1,10]))
    predict_y = tf.nn.softmax(tf.matmul(X_holder, Weights) + biases)
    loss = tf.reduce_mean(-tf.reduce_sum(y_holder * tf.log(predict_y), 1))
    optimizer = tf.train.GradientDescentOptimizer(0.5)
    train = optimizer.minimize(loss)
    
    session = tf.Session()
    init = tf.global_variables_initializer()
    session.run(init)
    
    for i in range(500):
        images, labels = mnist.train.next_batch(batch_size)
        session.run(train, feed_dict={X_holder:images, y_holder:labels})
        if i % 25 == 0:
            correct_prediction = tf.equal(tf.argmax(predict_y, 1), tf.argmax(y_holder, 1))
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
            accuracy_value = session.run(accuracy, feed_dict={X_holder:mnist.test.images, y_holder:mnist.test.labels})
            print('step:%d accuracy:%.4f' %(i, accuracy_value))
    

    上面一段代码的运行结果如下:

    Extracting MNIST_data\train-images-idx3-ubyte.gz
    Extracting MNIST_data\train-labels-idx1-ubyte.gz
    Extracting MNIST_data\t10k-images-idx3-ubyte.gz
    Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
    step:0 accuracy:0.4747
    step:25 accuracy:0.8553
    step:50 accuracy:0.8719
    step:75 accuracy:0.8868
    step:100 accuracy:0.8911
    step:125 accuracy:0.8998
    step:150 accuracy:0.8942
    step:175 accuracy:0.9050
    step:200 accuracy:0.9026
    step:225 accuracy:0.9076
    step:250 accuracy:0.9071
    step:275 accuracy:0.9049
    step:300 accuracy:0.9055
    step:325 accuracy:0.9101
    step:350 accuracy:0.9097
    step:375 accuracy:0.9116
    step:400 accuracy:0.9102
    step:425 accuracy:0.9113
    step:450 accuracy:0.9155
    step:475 accuracy:0.9151

    从上面的运行结果可以看出,经过500步训练,模型准确率到达0.9151左右。

    3、数据准备

    import warnings
    warnings.filterwarnings('ignore')
    import tensorflow as tf
    from tensorflow.examples.tutorials.mnist import input_data
    
    mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
    batch_size = 100
    X_holder = tf.placeholder(tf.float32)
    y_holder = tf.placeholder(tf.float32)

    第1行代码导入warnings库,第2行代码表示不打印警告信息;
    第3行代码导入tensorflow库,取别名tf;
    第4行代码人从tensorflow.examples.tutorials.mnist库中导入input_data文件;
    本文作者使用anaconda集成开发环境,input_data文件所在路径:C:\ProgramData\Anaconda3\Lib\site-packages\tensorflow\examples\tutorials\mnist,如下图所示:

                                                   


    第6行代码调用input_data文件的read_data_sets方法,需要2个参数,第1个参数的数据类型是字符串,是读取数据的文件夹名,第2个关键字参数ont_hot数据类型为布尔bool,设置为True,表示预测目标值是否经过One-Hot编码;
    第7行代码定义变量batch_size的值为100;
    第8、9行代码中placeholder中文叫做占位符,将每次训练的特征矩阵X和预测目标值y赋值给变量X_holder和y_holder。

    4、数据观察

    本章内容主要是了解变量mnist中的数据内容,并掌握变量mnist中的方法使用。

    4.1 查看变量mnist的方法和属性

    dir(mnist)[-10:]

    上面一段代码的运行结果如下:

    ['_asdict',
    '_fields',
    '_make',
    '_replace',
    '_source',
    'count',
    'index',
    'test',
    'train',
    'validation']

    为了节省篇幅,只打印最后10个方法和属性。
    我们会用到的是其中test、train、validation这3个方法。

    4.2 对比三个集合

    train对应训练集,validation对应验证集,test对应测试集。
    查看3个集合中的样本数量,代码如下:

    print(mnist.train.num_examples)
    print(mnist.validation.num_examples)
    print(mnist.test.num_examples)

    上面一段代码的运行结果如下:

    55000
    5000
    10000

    对比3个集合的方法和属性

    从上面的运行结果可以看出,3个集合的方法和属性基本相同。
    我们会用到的是其中images、labels、next_batch这3个属性或方法。

    4.3 mnist.train.images观察

    查看mnist.train.images的数据类型和矩阵形状。

    images = mnist.train.images
    type(images), images.shape

    上面一段代码的运行结果如下:

    (numpy.ndarray, (55000, 784))

    从上面的运行结果可以看出,在变量mnist.train中总共有55000个样本,每个样本有784个特征。
    原图片形状为28*28,28*28=784,每个图片样本展平后则有784维特征。
    选取1个样本,用3种作图方式查看其图片内容,代码如下:

    import matplotlib.pyplot as plt
    
    image = mnist.train.images[1].reshape(-1, 28)
    plt.subplot(131)
    plt.imshow(image)
    plt.axis('off')
    plt.subplot(132)
    plt.imshow(image, cmap='gray')
    plt.axis('off')
    plt.subplot(133)
    plt.imshow(image, cmap='gray_r')
    plt.axis('off')
    plt.show()
    

    上面一段代码的运行结果如下图所示:

    从上面的运行结果可以看出,调用plt.show方法时,参数cmap指定值为graygray_r符合正常的观看效果。

    4.4 查看手写数字图

    从训练集mnist.train中选取一部分样本查看图片内容,即调用mnist.train的next_batch方法随机获得一部分样本,代码如下:

    import matplotlib.pyplot as plt
    import math
    import numpy as np
    
    def drawDigit(position, image, title):
        plt.subplot(*position)
        plt.imshow(image.reshape(-1, 28), cmap='gray_r')
        plt.axis('off')
        plt.title(title)
        
    def batchDraw(batch_size):
        images,labels = mnist.train.next_batch(batch_size)
        image_number = images.shape[0]
        row_number = math.ceil(image_number ** 0.5)
        column_number = row_number
        plt.figure(figsize=(row_number, column_number))
        for i in range(row_number):
            for j in range(column_number):
                index = i * column_number + j
                if index < image_number:
                    position = (row_number, column_number, index+1)
                    image = images[index]
                    title = 'actual:%d' %(np.argmax(labels[index]))
                    drawDigit(position, image, title)
    
    batchDraw(196)
    plt.show()

    上面一段代码的运行结果如下图所示,本文作者对难以辨认的数字做了红色方框标注:

    5、搭建神经网络

    Weights = tf.Variable(tf.zeros([784, 10]))
    biases = tf.Variable(tf.zeros([1,10]))
    predict_y = tf.nn.softmax(tf.matmul(X_holder, Weights) + biases)
    loss = tf.reduce_mean(-tf.reduce_sum(y_holder * tf.log(predict_y), 1))
    optimizer = tf.train.GradientDescentOptimizer(0.5)
    train = optimizer.minimize(loss)

     该神经网络只有输入层和输出层,没有隐藏层。
    第1行代码定义形状为784*10的权重矩阵Weights;
    第2行代码定义形状为1*10的偏置矩阵biases;
    第3行代码定义先通过矩阵计算,再使用激活函数softmax得出的每个分类的预测概率predict_y;
    第4行代码定义损失函数loss,多分类问题使用交叉熵作为损失函数。
    交叉熵的函数如下图所示,其中p(x)是实际值,q(x)是预测值

                             
    第5行代码定义优化器optimizer,使用梯度下降优化器;
    第6行代码定义训练步骤train,即最小化损失。

    6、变量初始化

    init = tf.global_variables_initializer()
    session = tf.Session()
    session.run(init)
    

    对于神经网络模型,重要是其中的W、b这两个参数。
    开始神经网络模型训练之前,这两个变量需要初始化。
    第1行代码调用tf.global_variables_initializer实例化tensorflow中的Operation对象。

    第2行代码调用tf.Session方法实例化会话对象;
    第3行代码调用tf.Session对象的run方法做变量初始化。

    7、模型训练

    for i in range(500):
        images, labels = mnist.train.next_batch(batch_size)
        session.run(train, feed_dict={X_holder:images, y_holder:labels})
        if i % 25 == 0:
            correct_prediction = tf.equal(tf.argmax(predict_y, 1), tf.argmax(y_holder, 1))
            accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
            accuracy_value = session.run(accuracy, feed_dict={X_holder:mnist.test.images, y_holder:mnist.test.labels})
            print('step:%d accuracy:%.4f' %(i, accuracy_value))

    第1行代码表示模型迭代训练500次;
    第2行代码调用mnist.train对象的next_batch方法,选出数量为batch_size的样本;
    第3行代码是模型训练,每运行1次此行代码,即模型训练1次;
    第4-8行代码是每隔25次训练打印模型准确率。
    上面一段代码的运行结果如下:

    step:0 accuracy:0.3161
    step:25 accuracy:0.8452
    step:50 accuracy:0.8668
    step:75 accuracy:0.8860
    step:100 accuracy:0.8906
    step:125 accuracy:0.8948
    step:150 accuracy:0.9008
    step:175 accuracy:0.9027
    step:200 accuracy:0.8956
    step:225 accuracy:0.9102
    step:250 accuracy:0.9022
    step:275 accuracy:0.9097
    step:300 accuracy:0.9039
    step:325 accuracy:0.9076
    step:350 accuracy:0.9137
    step:375 accuracy:0.9111
    step:400 accuracy:0.9069
    step:425 accuracy:0.9097
    step:450 accuracy:0.9150
    step:475 accuracy:0.9105

    9、模型测试

    import math
    import matplotlib.pyplot as plt
    import numpy as np
    
    def drawDigit2(position, image, title, isTrue):
        plt.subplot(*position)
        plt.imshow(image.reshape(-1, 28), cmap='gray_r')
        plt.axis('off')
        if not isTrue:
            plt.title(title, color='red')
        else:
            plt.title(title)
            
    def batchDraw2(batch_size):
        images,labels = mnist.test.next_batch(batch_size)
        predict_labels = session.run(predict_y, feed_dict={X_holder:images, y_holder:labels})
        image_number = images.shape[0]
        row_number = math.ceil(image_number ** 0.5)
        column_number = row_number
        plt.figure(figsize=(row_number+8, column_number+8))
        for i in range(row_number):
            for j in range(column_number):
                index = i * column_number + j
                if index < image_number:
                    position = (row_number, column_number, index+1)
                    image = images[index]
                    actual = np.argmax(labels[index])
                    predict = np.argmax(predict_labels[index])
                    isTrue = actual==predict
                    title = 'actual:%d\npredict:%d' %(actual,predict)
                    drawDigit2(position, image, title, isTrue)
    
    batchDraw2(100)
    plt.show()

    上面一段代码的运行结果如下图所示:

    展开全文
  • 使用opencv扩展模块进行机器学习SVM进行手写数字分类
  • 神经网络设计是设计复杂深度学习算法/应用的基础,本文将介绍如何设计一个三层神经网络模型来实现手写数字分类。首先介绍如何利用高级编程语言Python搭建神经网络训练和推断框架来实现手写数字分类的训练和使用。 ...

    前言

    本文做的是《智能计算系统》配套实验教程中下属的基于三层神经网络实现手写数字分类,神经网络设计是设计复杂深度学习算法应用的基础,本文将介绍如何设计一个三层神经网络模型来实现手写数字分类。首先介绍如何利用高级编程语言Python搭建神经网络训练和推断框架来实现手写数字分类的训练和使用。
    本文实验文档下载http://forum.cambricon.com/uploadfile/user/file/20210401/1617260726402285.pdf


    一、神经网络组成

    一个完整的神经网络通常由多个基本的网络层堆叠而成。本实验中的三层全连接神经网络由三个全连接层构成,在每两个全连接层之间会插入ReLU激活函数引入非线性变换,最后使用Softmax层计算交叉嫡损失,如下图所示。因此本实验中使用的基本单元包括全连接层、ReLU激活函数、Softmax损失函数。更多关于神经网络中基本单元的介绍详见《智能计算系统》教材l第2.3节。
    在这里插入图片描述

    二、代码实现

    1.引入库

    import numpy as np
    import struct
    import os
    

    2.导入数据集

    MNIST_DIR = "mnist_data"
    TRAIN_DATA = "train-images-idx3-ubyte"
    TRAIN_LABEL = "train-labels-idx1-ubyte"
    TEST_DATA = "t10k-images-idx3-ubyte"
    TEST_LABEL = "t10k-labels-idx1-ubyte"
    

    数据集链接http://yann.lecun.com/exdb/mnist/
    数据集下载后一定记得解压

    3.全连接层

    class FullyConnectedLayer(object):
        def __init__(self, num_input, num_output):  # 全连接层初始化
            self.num_input = num_input
            self.num_output = num_output
        def init_param(self, std=0.01):  # 参数初始化
            self.weight = np.random.normal(loc=0, scale=std, size=(self.num_input, self.num_output))
            self.bias = np.zeros([1, self.num_output])
        def forward(self, input):  # 前向传播计算
            self.input = input
            self.output = np.dot(self.input,self.weight)+self.bias
            return self.output
        def backward(self, top_diff):  # 反向传播的计算
            self.d_weight =np.dot(self.input.T,top_diff) 
            self.d_bias = top_diff #
            bottom_diff = np.dot(top_diff,self.weight.T) 
            return bottom_diff
        def update_param(self, lr):  # 参数更新
            self.weight = self.weight - lr * self.d_weight   
            self.bias = self.bias - lr * self.d_bias    
        def load_param(self, weight, bias):  # 参数加载
            assert self.weight.shape == weight.shape
            assert self.bias.shape == bias.shape
            self.weight = weight
            self.bias = bias
        def save_param(self):  # 参数保存
            return self.weight, self.bias
    

    4.ReLU激活函数层

    class ReLULayer(object):
        def forward(self, input):  # 前向传播的计算
            self.input = input
            output = np.maximum(self.input,0)  
            return output
        def backward(self, top_diff):  # 反向传播的计算
            b = self.input
            b[b>0] =1
            b[b<0] = 0
            bottom_diff = np.multiply(b,top_diff)
            return bottom_diff
    

    5.Softmax损失层

    class SoftmaxLossLayer(object):
        def forward(self, input):  # 前向传播的计算
            input_max = np.max(input, axis=1, keepdims=True)
            input_exp = np.exp(input- input_max)#(64,10)
            partsum = np.sum(input_exp,axis=1)
            sum = np.tile(partsum,(10,1))
            self.prob = input_exp / sum.T
            return self.prob
        def get_loss(self, label):   # 计算损失
            self.batch_size = self.prob.shape[0]
            self.label_onehot = np.zeros_like(self.prob)
            self.label_onehot[np.arange(self.batch_size), label] = 1.0
            loss = -np.sum(self.label_onehot*np.log(self.prob)) / self.batch_size
            return loss
        def backward(self):  # 反向传播的计算
            bottom_diff = (self.prob - self.label_onehot)/self.batch_size
            return bottom_diff
    

    6.网络训练与推断模块

    #网络训练与推断模块
    class MNIST_MLP(object):
        def __init__(self, batch_size=64, input_size=784, hidden1=32, hidden2=16, out_classes=10, lr=0.01, max_epoch=1,print_iter=100):
            self.batch_size = batch_size
            self.input_size = input_size
            self.hidden1 = hidden1
            self.hidden2 = hidden2
            self.out_classes = out_classes
            self.lr = lr
            self.max_epoch = max_epoch
            self.print_iter = print_iter
    
        def build_model(self):  # 建立网络结构
            #建立三层神经网络结构
            self.fc1 = FullyConnectedLayer(self.input_size, self.hidden1)
            self.relu1 = ReLULayer()
            self.fc2 = FullyConnectedLayer(self.hidden1, self.hidden2)  
            self.relu2 = ReLULayer()  
            self.fc3 = FullyConnectedLayer(self.hidden2, self.out_classes)
            self.softmax = SoftmaxLossLayer()
            self.update_layer_list = [self.fc1, self.fc2, self.fc3]
    
        def init_model(self):
            for layer in self.update_layer_list:
                layer.init_param()
    
        def shuffle_data(self):
            np.random.shuffle(self.train_data)
    
        def load_mnist(self, file_dir, is_images='True'):
            bin_file = open(file_dir, 'rb')
            bin_data = bin_file.read()
            bin_file.close()
            if is_images:
                fmt_header = '>iiii'
                magic, num_images, num_rows, num_cols = struct.unpack_from(fmt_header, bin_data, 0)
            else:
                fmt_header = '>ii'
                magic, num_images = struct.unpack_from(fmt_header, bin_data, 0)
                num_rows, num_cols = 1, 1
            data_size = num_images * num_rows * num_cols
            mat_data = struct.unpack_from('>' + str(data_size) + 'B', bin_data, struct.calcsize(fmt_header))
            mat_data = np.reshape(mat_data, [num_images, num_rows * num_cols])
            return mat_data
    
        def load_data(self):
            #  调用函数 load_mnist 读取和预处理 MNIST 中训练数据和测试数据的图像和标记
            train_images = self.load_mnist(os.path.join(MNIST_DIR, TRAIN_DATA), True)
            train_labels = self.load_mnist(os.path.join(MNIST_DIR, TRAIN_LABEL), False)
            test_images = self.load_mnist(os.path.join(MNIST_DIR, TEST_DATA), True)
            test_labels = self.load_mnist(os.path.join(MNIST_DIR, TEST_LABEL), False)
            self.train_data = np.append(train_images, train_labels, axis=1)
            self.test_data = np.append(test_images, test_labels, axis=1)
    
        def forward(self, input):  # 神经网络的前向传播
            # 神经网络的前向传播
            h1 = self.fc1.forward(input)
            h1 = self.relu1.forward(h1)
            h2 = self.fc2.forward(h1)
            h2 = self.relu2.forward(h2)
            h3 = self.fc3.forward(h2)
            self.prob = self.softmax.forward(h3)
            return self.prob
    
        def backward(self):  # 神经网络的反向传播
            # 神经网络的反向传播
            dloss = self.softmax.backward()
            dh2 = self.fc3.backward(dloss)
            dh2 = self.relu2.backward(dh2)
            dh1 = self.fc2.backward(dh2)
            dh1 = self.relu1.backward(dh1)
            dh1 = self.fc1.backward(dh1)
    
        def update(self, lr):
            for layer in self.update_layer_list:
                layer.update_param(lr)
    
        def save_model(self, param_dir):
            params = {}
            params['w1'], params['b1'] = self.fc1.save_param()
            params['w2'], params['b2'] = self.fc2.save_param()
            params['w3'], params['b3'] = self.fc3.save_param()
            np.save(param_dir, params)
    
        def train(self):
            max_batch_1 = self.train_data.shape[0] / self.batch_size
            max_batch = int(max_batch_1)
            for idx_epoch in range(self.max_epoch):
                mlp.shuffle_data()
                for idx_batch in range(max_batch):
                    batch_images = self.train_data[idx_batch * self.batch_size:(idx_batch + 1) * self.batch_size, :-1]
                    batch_labels = self.train_data[idx_batch * self.batch_size:(idx_batch + 1) * self.batch_size, -1]
                    prob = self.forward(batch_images)
                    loss = self.softmax.get_loss(batch_labels)
                    self.backward()
                    self.update(self.lr)
                    if idx_batch % self.print_iter == 0:
                        print('Epoch %d, iter %d, loss: %.6f' % (idx_epoch, idx_batch, loss))
    
        def load_model(self, param_dir):
            params = np.load(param_dir).item()
            self.fc1.load_param(params['w1'], params['b1'])
            self.fc2.load_param(params['w2'], params['b2'])
            self.fc3.load_param(params['w3'], params['b3'])
    
        def evaluate(self):
            pred_results = np.zeros([self.test_data.shape[0]])
            for idx in range(int(self.test_data.shape[0] / self.batch_size)):
                batch_images = self.test_data[idx * self.batch_size:(idx + 1) * self.batch_size, :-1]
                prob = self.forward(batch_images)
                pred_labels = np.argmax(prob, axis=1)
                pred_results[idx * self.batch_size:(idx + 1) * self.batch_size] = pred_labels
            accuracy = np.mean(pred_results == self.test_data[:, -1])
            print('Accuracy in test set: %f' % accuracy)
    
    

    7.完整流程

    if __name__ == '__main__':
        h1, h2, e = 128, 64, 20
        mlp = MNIST_MLP(hidden1=h1, hidden2=h2,max_epoch=e)
        mlp.load_data()
        mlp.build_model()
        mlp.init_model()
        mlp.train()
        mlp.save_model('mlp-%d-%d-%depoch.npy' % (h1,h2,e))
        mlp.load_model('mlp-%d-%d-%depoch.npy' % (h1, h2, e))
        mlp.evaluate()
    

    三、代码debug

    pycharm在初次运行时,会在以下代码报错:

    mlp.load_model('mlp-%d-%d-%depoch.npy' % (h1, h2, e))
    

    ValueError: Object arrays cannot be loaded when allow_pickle=False

    经过上网查看原因后,发现是numpy版本太高引起,所以我上网查看后参照这篇博客https://blog.csdn.net/weixin_39338645/article/details/91872181

    解决方法:
    点击报错处,进入源代码(.py),注释掉693行:

    #if not allow_pickle:
        #raise ValueError("Object arrays cannot be loaded when "
                       #  "allow_pickle=False")
     
        # Now read the actual data.
        if dtype.hasobject:
            # The array contained Python objects. We need to unpickle the data.
            #if not allow_pickle:
                #raise ValueError("Object arrays cannot be loaded when "
                               #  "allow_pickle=False")
            if pickle_kwargs is None:
                pickle_kwargs = {}
            try:
                array = pickle.load(fp, **pickle_kwargs)
            except UnicodeError as err:
                if sys.version_info[0] >= 3:
                    # Friendlier error message
    

    四、结果展示

    在不改变网络结构的条件下我通过自行调节参数主要体现在:

    if __name__ == '__main__':
        h1, h2, e = 128, 64, 20
    
    class MNIST_MLP(object):
        def __init__(self, batch_size=64, input_size=784, hidden1=32, hidden2=16, out_classes=10, lr=0.01, max_epoch=1,print_iter=100):
    

    在这里插入图片描述

    展开全文
  • # 运用CNN分析MNIST手写数字分类 #公众号:海之鹰工作室(HaizhiyingWork) # wxID: marketAcademy 技术问题可以骚扰 import torch import numpy as np from torch.utils.data import DataLoader from ...
  • python--基于三层神经网络实现手写数字分类

    千次阅读 多人点赞 2021-02-03 20:10:56
    基于三层神经网络实现手写数字分类源码及数据集背景知识神经网络的组成全连接层激活函数层Softmax激活层神经网络训练精度评估实验内容 源码及数据集 https://download.csdn.net/download/qq_46102127/15020486 背景...
  • MNIST+SVM手写数字分类

    2021-04-23 13:08:52
    一、参考链接:1.https://www.cnblogs.com/yaowuyangwei521/p/9975714.html2.https://www.cnblogs.com/pinard/p/6126077.html3.降低维度之后分类,并可视化结果...
  • 手写数字分类命令行工具和简单的网络应用程序。 此示例托管在 抽象的 神经网络分类器 NeuralNetwork.py层神经网络的实现。 handwritten_classifier.py :用于训练和测试 NeuralNetwork.py 的命令行工具 由于...
  • Softmax回归模型实现MNIST手写数字分类(python代码详解) 关键点: Softmax回归处理多分类问题,其是Logistic回归在多分类问题上的推广 softmax回归使用交叉熵损失函数来学习最优的参数矩阵W,对样本进行分类 ...
  • 基于概率统计贝叶斯方法的手写数字分类器设计论文,附源代码,通过贝叶斯决策分类,能够实现0-9手写数字识别的功能。
  • 在讲述完机器学习算法之后,本小节将会带领大家一步一步根据算法原理来自己实现算法设计,而不是直接调用现有的机器学习算法库,通过该阶段的学习与训练,... 目录 一、数据集展示与说明 二、构建分类器 三、数据转化
  • 对手写数字采用支持向量机算法进行识别分类,并能进行参数调优等功能
  • 本章利用前述PyTorch的基本使用方法,来完成一个对MNIST数据集的手写数字图片分类任务。 1 模型构建 1.1 模型定义 首先我们继承torch.nn.Module类,创建一个自定义的网络模型,继承时至少需要重写两个方法:__init__...
  • BP神经网络以及在手写数字分类中python代码的详细注释-附件资源

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 65,354
精华内容 26,141
关键字:

手写数字分类

友情链接: pojie.rar