精华内容
下载资源
问答
  • 手写体数字识别

    2018-08-19 10:14:22
    手写体数字识别的训练数据和测试数据。。
  • matlab手写体数字识别

    千人学习 2019-10-09 09:35:59
    matlab手写体数字识别
  • MATLAB手写体数字识别
  • Python手写体数字识别

    2017-01-25 23:13:17
    基于sklearn的手写体数字识别
  • 摘要:通过对手写体数字识别技术的研究,本文建立了一个脱机手写体数字识别系统,对手写体数字的识别提出了一些新的思路,并对识别过程中所采用的关键算法进行了阐述。本文提出了二次毛刺去除法对手写体数字图像进行...
  • 手写体数字识别.rar

    2019-07-05 15:33:22
    BAT算法工程师深入详细地讲解手写体数字识别,带你轻松入门深度学习!
  • 手写体数字识别.zip

    2019-11-28 12:53:03
    本课题主要的研究的工作基于TensorFlow深度学习框架,,并完成一个完整手写体数字识别系统。本课题中对卷积神经网络模型结构,手写MINIST的60000个样本进行学习,对10000个样本的测试对比。
  • 手写体数字识别

    写在前面: 我是「虐猫人薛定谔i」,一个不满足于现状,有梦想,有追求的00后
    \quad
    本博客主要记录和分享自己毕生所学的知识,欢迎关注,第一时间获取更新。
    \quad
    不忘初心,方得始终。
    \quad

    ❤❤❤❤❤❤❤❤❤❤

    在这里插入图片描述

    数据介绍

    数据集用的是MNIST,这个应该是比较经典的数据集了,其中的手写体数字识别,可以说是人工智能领域的HelloWorld了

    设计思路

    在网络结构上,使用了两个卷积层,两个全连接层,使用ReLU函数作为激活函数。

    conv1
    conv2
    fc1
    fc2

    整个流程分为三大部分:
    1、数据加载及预处理
    2、网络结构的定义
    3、训练模型,进行测试

    代码

    import torch
    import torch.nn as nn
    import torch.optim as optim
    from torchvision import datasets
    from torchvision import transforms
    from torch.autograd import Variable
    
    batch_size = 64
    epoch = 5
    LR = 0.001
    # 获取手写数字的训练集和测试集
    train_dataset = datasets.MNIST(root='./res/data',
                                   transform=transforms.ToTensor(),
                                   train=True,
                                   download=True)
    test_dataset = datasets.MNIST(root='./res/data',
                                  transform=transforms.ToTensor(),
                                  download=True)
    train_loader = torch.utils.data.DataLoader(dataset=train_dataset,
                                               batch_size=batch_size,
                                               shuffle=True)
    test_loader = torch.utils.data.DataLoader(dataset=test_dataset,
                                              batch_size=batch_size,
                                              shuffle=True)
    
    
    # 定义网络结构
    class Net(nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            self.conv1 = nn.Sequential(nn.Conv2d(1, 6, 3, 1, 2), nn.ReLU(),
                                       nn.MaxPool2d(2, 2))
            self.conv2 = nn.Sequential(nn.Conv2d(6, 16, 5), nn.ReLU(),
                                       nn.MaxPool2d(2, 2))
            self.fc1 = nn.Sequential(nn.Linear(16 * 5 * 5, 120),
                                     nn.BatchNorm1d(120), nn.ReLU())
            self.fc2 = nn.Sequential(nn.Linear(120, 84), nn.BatchNorm1d(84),
                                     nn.ReLU(), nn.Linear(84, 10))
    
        def forward(self, x):
            x = self.conv1(x)
            x = self.conv2(x)
            x = x.view(x.size()[0], -1)
            x = self.fc1(x)
            x = self.fc2(x)
            return x
    
    
    # 训练模型
    net = Net()
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(net.parameters(), lr=LR)
    for epoch in range(epoch):
        sum_loss = 0.0
        for i, data in enumerate(train_loader):
            inputs, labels = data
            inputs, labels = Variable(inputs), Variable(labels)
            optimizer.zero_grad()
            outputs = net(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            sum_loss += loss.item()
            if i % 100 == 99:
                print("[%d, %d] loss is %.03f" %
                      (epoch + 1, i + 1, sum_loss / 100))
                sum_loss = 0.0
        # 测试模型
        net.eval()
        correct = 0
        for data_test in test_loader:
            images, labels = data_test
            images, labels = Variable(images), Variable(labels)
            output_test = net(images)
            _, pred = torch.max(output_test, 1)
            correct += (pred == labels).sum()
        print("Test acc is {}".format(correct.item()/len(test_dataset)))
    
    

    在这里插入图片描述

    结果

    (pytorch) PS D:\Code\Python> & C:/Users/Martin/anaconda3/envs/pytorch/python.exe d:/Code/Python/hwdrByPyTorch.py
    [1, 100] loss is 0.705
    [1, 200] loss is 0.191
    [1, 300] loss is 0.129
    [1, 400] loss is 0.111
    [1, 500] loss is 0.097
    [1, 600] loss is 0.084
    [1, 700] loss is 0.070
    [1, 800] loss is 0.070
    [1, 900] loss is 0.071
    Test acc is 0.9866166666666667
    [2, 100] loss is 0.090
    [2, 200] loss is 0.078
    [2, 300] loss is 0.061
    [2, 400] loss is 0.068
    [2, 500] loss is 0.055
    [2, 600] loss is 0.046
    [2, 700] loss is 0.045
    [2, 800] loss is 0.048
    [2, 900] loss is 0.051
    Test acc is 0.9852166666666666
    [3, 100] loss is 0.036
    [3, 200] loss is 0.041
    [3, 300] loss is 0.037
    [3, 400] loss is 0.036
    [3, 500] loss is 0.033
    [3, 600] loss is 0.035
    [3, 700] loss is 0.039
    [3, 800] loss is 0.044
    [3, 900] loss is 0.039
    Test acc is 0.9891
    [4, 100] loss is 0.029
    [4, 200] loss is 0.021
    [4, 300] loss is 0.030
    [4, 400] loss is 0.023
    [4, 500] loss is 0.028
    [4, 600] loss is 0.031
    [4, 700] loss is 0.027
    [4, 800] loss is 0.035
    [4, 900] loss is 0.039
    Test acc is 0.9929666666666667
    [5, 100] loss is 0.022
    [5, 200] loss is 0.025
    [5, 300] loss is 0.021
    [5, 400] loss is 0.024
    [5, 500] loss is 0.025
    [5, 600] loss is 0.029
    [5, 700] loss is 0.027
    [5, 800] loss is 0.032
    [5, 900] loss is 0.029
    Test acc is 0.9923666666666666
    (pytorch) PS D:\Code\Python> 
    

    在这里插入图片描述
    从结果中可以看到,在测试集上模型的准确率达到了98%以上。

    总结

    1、可以考虑在训练结束后,将模型保存下来,以便后续使用
    2、代码中可以加入断点续训,避免由于训练中断,导致继续训练还要从头开始
    在这里插入图片描述

    展开全文
  • 手写体数字识别软件

    2014-06-03 12:33:37
    可脱机工作,基于SVM和HOG的手写体数字识别。最后用MFC做的可操作界面。
  • 基于神经网络的手写体数字识别,它是用matlab实现的,其中用3种不同的神经的网络方法实现了手写体数字的识别
  • 手写体数字识别1 下载数据包2 解压数据包3 打开代码文件4 图片转为文本代码5 加载训练数据6 训练数据7 抽某一个文件进行测试 1 下载数据包 GitHub链接(速度慢):手写Beyes算法之手写体数字识别 码云链接...

    作者:Irain
    QQ:2573396010
    微信:18802080892

    1 下载数据包

    GitHub链接(速度慢):手写Beyes算法之手写体数字识别

    在这里插入图片描述
    在这里插入图片描述

    码云链接(速度快):手写Beyes(knn)算法之手写体数字识别

    在这里插入图片描述
    在这里插入图片描述

    2 解压数据包

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3 打开代码文件

    在这里插入图片描述
    在这里插入图片描述

    4 图片转为文本代码

    在这里插入图片描述
    在这里插入图片描述

    import os
    from PIL import Image
    def pictureTotxt(data_name): 
        '''
        处理bmp图片转为txt文本
        
        Args:
          data_name: 数据类型名称
        Return: None
        '''
        if not os.path.exists("%s_digital_txt" %(data_name)): # 创建txt文本文件夹
            os.mkdir("%s_digital_txt" %(data_name))
        lists = os.listdir("%s_digital_pictures" %(data_name)) # 获取所有手写体图片名称
        for list in lists: # 图片转换文本
            im = Image.open("%s_digital_pictures/%s" % (data_name,list)) # 打开手写体图片
            fh = open("%s_digital_txt/%s.txt" % (data_name,list.split(".")[0]),"a") # 打开txt文本
            width = im.size[0]  # 图片宽
            height = im.size[1]  # 图片高
            for k in range(0,width):  #  存入txt文本
                for j in range(0,height):
                    cl = im.getpixel((k,j))  # bmp图片的像素只有一个数
                    if(cl == 0):  # 0:黑色
                        fh.write("0") # 黑色为0
                    else:
                        fh.write("1") # 白色为1
                fh.write("\n")        
            fh.close() # 关闭文件
    

    5 加载训练数据

    在这里插入图片描述

    def datatoarray(fname):
        '''
        加载txt文本数据
        
        Args:
          fname: 文本名称
        Return: None
        '''
        arr = []
        fh = open(fname) # 打开txt文本
        for i in range(0,28):
            thisline = fh.readline() # 读取文本内容
            for j in range(0,28):
                arr.append(int(thisline[j]))
        fh.close()
        return arr
    
    def seplabel(fname):
        '''
        获取文本类别
        
        Args:
          fname: 文本名称、名称格式例子:0_0.txt
        Return: None
        '''
        filestr = fname.split(".")[0]
        label = int(filestr.split("_")[0]) 
        return label
        
    def traindata():
        '''
        加载训练数据
    
        Return: None
        '''
        labels = []
        trainfile = os.listdir("train_digital_txt/") # 获取手写体图片名
        num = len(trainfile)
        # 长度784列,每一行存储一个文本
        trainarr = np.zeros((num ,784)) # 数组存储训练数据,行:文件总数,列:784=28*28    
        print("相对路径:train_digital_pictures/") # 转换数据目录
        print("所有训练txt文本数量:",num) #  num:所有txt文本数量
        for i in range(0,num):
            thisfname = trainfile[i]
            thislabel = seplabel(thisfname)
            labels.append(thislabel)  # 记录txt文本对应的数字编号
            trainarr[i,:] = datatoarray("train_digital_txt/%s"  %(thisfname)) # 加载txt文本数据    
        num = 0
        for arrs in trainarr: # 统计有用数据数量 
            for arr in arrs:
                if arr == 1:
                    num += 1
                    break
        print("统计有用数据数量 :",num)
        return trainarr, labels
    

    6 训练数据

    在这里插入图片描述

    class Bayes(object):
        def __init__(self):
            self.length = -1
            self.labelweight = dict() # 权重:类别占总类别总数的比例
            self.vectorcount = dict()
    
        def fit(self, dataSet:list, labels:list):
            print("-"*40,"开始训练数据","-"*35)
            if(len(dataSet) != len(labels)):
                raise ValueError("测试组与类别组的长度不一样")
            self.length = len(dataSet[0])  # 测试数据特征值的长度
            labelsnum = len(labels)  #  类别所有的数量
            norlabels = set(labels)  #  不重复类别的数量
            for item in norlabels:
                thislabel = item
                self.labelweight[thislabel] = labels.count(thislabel)/labelsnum  # 权重:每个类别的占比
            for vector, label in zip(dataSet, labels):
                if(label not in self.vectorcount):
                    self.vectorcount[label] = []
                self.vectorcount[label].append(vector)
            for i in range(0,10):            
                print("类别%s所占比例%s"%(i,self.labelweight[i]))
            print("-"*40,"数据训练结束","-"*35)
            return self
    

    7 抽某一个文件进行测试

    在这里插入图片描述
    在这里插入图片描述

    train_data, labels = traindata()
    def test_one(train_data,labels,testfile):
        '''
        抽某一个文件进行测试
        
        Args:
          trainarr: 训练集
          labels: 训练集类别
          testfile: 文本名称
        Return: None
        '''
        labelsall = [0,1,2,3,4,5,6,7,8,9]
        testdata=datatoarray("test_digital_txt/" + testfile)  # 获取测试样本
        bys = Bayes()
        bys.fit(train_data,labels)
        rst = bys.btest(testdata,labelsall)
        print("%s的测试结果:%s"%(testfile,rst))
    

    8 测试数据

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    测试结果:
    准确率:84.1%、正确次数:1851
    出错率高的数字:2、3、4、5、8、9
    数字6出错次数最少11、出错率0.5%、错判次数最多的数字0
    数字9出错次数最多68、出错率3.1%、错判次数最多的数字7
    程序运行消耗时间:108.9分

    def testdata(self):
            '''
            Beyes算法测试
        
            Return: None
            '''
            
            print("-"*40,"开始测试数据","-"*35)
            start = time.time() # 开始时间
            #trainarr, labels = traindata()
            errors = [] # 所有出错的数字类别
            errors_num = [] #  每个数字类别出错的次数
            errors_rating = [] # 每个数字类别的错误率
            errors_maxdigital = [] # 每个数字类别错判次数最多的数字
            maxdigital = [] # 每个数字类别所有错判的数字
            testlist = os.listdir("test_digital_txt/" ) # 获取手写体图片名
            num = len(testlist)
            print("文件存储相对路径:test_digital_txt/") # 转换数据目录
            print("所有测试txt文本数量:",num) #  num:所有txt文本数量 
            # 长度784列,每一行存储一个文件
            # 以一个数组存储所有训练数据,行:文件总数,列:784
            testarr = np.zeros((num,784))
            ten = 0
            print("")
            print("-"*40,"类别",ten,"-"*40)
            print("")                
            for i in range(0,num):
                thisfname = testlist[i]
                thisdata = datatoarray("test_digital_txt/%s"  %(thisfname))
                labelsall = [0,1,2,3,4,5,6,7,8,9]
                rst = self.btest(thisdata,labelsall)
                
                if str(rst) != thisfname.split("_")[0]: # 预测错误
                    print("%s样本预测出错:" %(thisfname),rst)
                    errors.append(int(thisfname.split("_")[0])) # 记录出错数字类别
                    maxdigital.append(rst) # 判错数字
                
                if (i+1)%220 == 0:  # 某个数字类别预测结束
                    errors_num.append(errors.count(ten)) # 计算某数字类别的出错次数
                    errors_rating.append(errors_num[ten]/2200) # 计算某数字类别出错率
                    if maxdigital: # 某数字类别判错次数最大的数字
                        errors_maxdigital.append(max(maxdigital, key=maxdigital.count))
                    else:
                        errors_maxdigital.append("None") # 没有,存入None
                    print("数字%s出错情况:出错次数%s、出错率%.1f%s、错判次数最多的数字%s" %(ten,errors_num[ten],(errors_rating[ten]*100),"%",errors_maxdigital[ten]))
                    maxdigital = [] # 清空,记录下一个数字类别
                    ten += 1
            accuracy = (2200 - len(errors)) # 预测正确的所有次数
            accuracy_rating = accuracy/2200  # 正确率
            elapsed = (time.time() - start)  # 开始时间与结束时间之差
            print("-"*40,"数据测试结束","-"*35)
            print("准确率:%.1f%、正确次数:%s" %((accuracy_rating*100),accuracy))
            for k in range(0,10):
                print("数字%s出错情况:出错次数%s、出错率%.1f%s、错判次数最多的数字%s" %(k,errors_num[k],(errors_rating[k]*100),"%",errors_maxdigital[k]))
            print("程序运行消耗时间:%.1f分" %(elapsed/60))
    

    发布:2020年5月20日

    展开全文
  • TensorFlow 手写体数字识别 以下资料来源于极客时间学习资料 • 手写体数字 MNIST 数据集介绍 MNIST 数据集介绍  MNIST 是一套手写体数字的图像数据集,包含 60,000 个训练样例和 10,000 个测试样例, 由...

    TensorFlow 手写体数字识别

      以下资料来源于极客时间学习资料

    • 手写体数字 MNIST 数据集介绍

    MNIST 数据集介绍
     
      MNIST 是一套手写体数字的图像数据集,包含 60,000 个训练样例和 10,000 个测试样例,
    由纽约大学的 Yann LeCun 等人维护。
     

     

     

    获取 MNIST 数据集

     

     

     

    MNIST 手写体数字介绍
     
      MNIST 图像数据集使用形如[28,28]的二阶数组来表示每个手写体数字,数组中
    的每个元素对应一个像素点,即每张图像大小固定为 28x28 像素。

      MNIST 数据集中的图像都是256阶灰度图,即灰度值 0 表示白色(背景),255 表示
    黑色(前景),使用取值为[0,255]的uint8数据类型表示图像。为了加速训练,我
    们需要做数据规范化,将灰度值缩放为[0,1]的float32数据类型。

     

     

     

     

     

    下载和读取 MNIST 数据集
     
      一个曾广泛使用(如 chapter-2/basic-model.ipynb),如今被废弃的(deprecated)方法:

     

     

    tf.contrib.learn 模块已被废弃
      需要注意的是,tf.contrib.learn 整个模块均已被废弃:
     
     
    使用 Keras 加载 MNIST 数据集
    tf.kera.datasets.mnist.load_data(path=‘mnist.npz’)
    Arguments:
    • path:本地缓存 MNIST 数据集(mnist.npz)的相对路径(~/.keras/datasets)
    Returns:
      Tuple of Numpy arrays: `(x_train, y_train), (x_test, y_test)`.

     

     

     

    MNIST 数据集 样例可视化
     

     

     

     

     

    • MNIST Softmax 网络介绍

     

    感知机模型
     
      1957年,受 Warren McCulloch 和 Walter Pitts 在神经元建模方面工作的启发,心理学家 Frank
    Rosenblatt 参考大脑中神经元信息传递信号的工作机制,发明了神经感知机模型 Perceptron 。 

     

     

     

    神经网络 
     
      在机器学习和认知科学领域,人工神经网络(ANN),简称神经网络(NN)是一种模仿生物
    神经网络(动物的中枢神经系统,特别是大脑)的结构和功能的数学模型或计算模型,用于
    对函数进行估计或近似。神经网络是多层神经元的连接,上一层神经元的输出,作为下一层
    神经元的输入。

     

     

     

    线性不可分

     

     

    激活函数(Activation Function) 
     
      为了实现神经网络的非线性建模能力,解决一些线性不可分的问题,我们通常使用激活函数
    来引入非线性因素。激活函数都采用非线性函数,常用的有Sigmoid、tanh、ReLU等。

     

     

     

    全连接层( fully connected layers,FC )
     
      全连接层是一种对输入数据直接做线性变换的线性计算层。它是神经网络中最常用的一种层,
    用于学习输出数据和输入数据之间的变换关系。全连接层可作为特征提取层使用,在学习特
    征的同时实现特征融合;也可作为最终的分类层使用,其输出神经元的值代表了每个输出类
    别的概率。

     

     

     

    前向传播

     

     

     简化形式:

     

     

     

     

    后向传播( Back Propagation, BP) 
     
      BP算法的基本思想是通过损失函数对模型参数进行求导,并根据复合函数求导常用的 “链式法则” 将不同层的模型参
    数的梯度联系起来,使得计算所有模型参数的梯度更简单。BP算法的思想早在 1960s 就被提出来了。 直到1986年,
    David Rumelhart 和 Geoffrey Hinton 等人发表了一篇后来成为经典的论文,清晰地描述了BP算法的框架,才使得BP算
    法真正流行起来,并带来了神经网络在80年代的辉煌。 

     

     

     

     

    MNIST Softmax 网络 
     
      将表示手写体数字的形如 [784] 的一维向量作为输入;中间定义2层 512 个神经元的隐藏层,具
    备一定模型复杂度,足以识别手写体数字;最后定义1层10个神经元的全联接层,用于输出10
    个不同类别的“概率”。
    Softmax :
      在数学,尤其是概率论和相关领域中,Softmax函数,或称归一化指数函数,是逻辑函数的一种推广。
    Softmax函数实际上是有限项离散概率分布的梯度对数归一化。

     

     

     

     

    • 实战 MNIST Softmax 网络

     

    MNIST Softmax 网络层

    代码: 

    加载 MNIST 数据集    
    from keras.datasets import mnist
    
    (x_train, y_train), (x_test, y_test) = mnist.load_data('mnist/mnist.npz')
    
    print(x_train.shape, type(x_train))
    print(y_train.shape, type(y_train))
    '''
    (60000, 28, 28) <class 'numpy.ndarray'>
    (60000,) <class 'numpy.ndarray'>
    '''
    
    数据处理:规范化
    # 将图像本身从[28,28]转换为[784,]
    X_train = x_train.reshape(60000, 784)
    X_test = x_test.reshape(10000, 784)
    print(X_train.shape, type(X_train))
    print(X_test.shape, type(X_test))
    '''
    (60000, 784) <class 'numpy.ndarray'>
    (10000, 784) <class 'numpy.ndarray'>
    '''
    
    # 将数据类型转换为float32
    X_train = X_train.astype('float32')
    X_test = X_test.astype('float32')
    # 数据归一化
    X_train /= 255
    X_test /= 255
    
    统计训练数据中各标签数量
    import numpy as np
    import matplotlib.pyplot as plt
    
    label, count = np.unique(y_train, return_counts=True)
    print(label, count)
    '''
    [0 1 2 3 4 5 6 7 8 9] [5923 6742 5958 6131 5842 5421 5918 6265 5851 5949]
    '''
    
    fig = plt.figure()
    plt.bar(label, count, width = 0.7, align='center')
    plt.title("Label Distribution")
    plt.xlabel("Label")
    plt.ylabel("Count")
    plt.xticks(label)
    plt.ylim(0,7500)
    
    for a,b in zip(label, count):
        plt.text(a, b, '%d' % b, ha='center', va='bottom',fontsize=10)
    
    plt.show()

     

    
    
    
    数据处理:one-hot 编码
    from keras.utils import np_utils
    
    n_classes = 10
    print("Shape before one-hot encoding: ", y_train.shape)
    Y_train = np_utils.to_categorical(y_train, n_classes)
    print("Shape after one-hot encoding: ", Y_train.shape)
    Y_test = np_utils.to_categorical(y_test, n_classes)
    '''
    Shape before one-hot encoding:  (60000,)
    Shape after one-hot encoding:  (60000, 10)
    '''
    
    print(y_train[0])
    print(Y_train[0])
    '''
    5
    [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
    '''
    
    使用 Keras sequential model 定义神经网络
    softmax 网络层
    from keras.models import Sequential from keras.layers.core import Dense, Activation model = Sequential() model.add(Dense(512, input_shape=(784,))) model.add(Activation('relu')) model.add(Dense(512)) model.add(Activation('relu')) model.add(Dense(10)) model.add(Activation('softmax')) 编译模型
    model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
    训练模型,并将指标保存到 history 中
    history = model.fit(X_train,
                        Y_train,
                        batch_size=128,
                        epochs=5,
                        verbose=2,
                        validation_data=(X_test, Y_test))
    '''
    
    
    Train on 60000 samples, validate on 10000 samples
    Epoch 1/5
     - 5s - loss: 0.2240 - acc: 0.9331 - val_loss: 0.1050 - val_acc: 0.9668
    Epoch 2/5
     - 5s - loss: 0.0794 - acc: 0.9753 - val_loss: 0.0796 - val_acc: 0.9756
    Epoch 3/5
     - 5s - loss: 0.0494 - acc: 0.9847 - val_loss: 0.0714 - val_acc: 0.9774
    Epoch 4/5
     - 6s - loss: 0.0353 - acc: 0.9886 - val_loss: 0.0906 - val_acc: 0.9731
    Epoch 5/5
     - 6s - loss: 0.0277 - acc: 0.9909 - val_loss: 0.0735 - val_acc: 0.9782
    '''
    
    可视化指标
    fig = plt.figure()
    plt.subplot(2,1,1)
    plt.plot(history.history['acc'])
    plt.plot(history.history['val_acc'])
    plt.title('Model Accuracy')
    plt.ylabel('accuracy')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc='lower right')
    
    plt.subplot(2,1,2)
    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.title('Model Loss')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc='upper right')
    plt.tight_layout()
    
    plt.show()

     

    
    
    保存模型
    
    import os
    import tensorflow.gfile as gfile
    
    save_dir = "./mnist/model/"
    
    if gfile.Exists(save_dir):
        gfile.DeleteRecursively(save_dir)
    gfile.MakeDirs(save_dir)
    
    model_name = 'keras_mnist.h5'
    model_path = os.path.join(save_dir, model_name)
    model.save(model_path)
    print('Saved trained model at %s ' % model_path)
    '''
    Saved trained model at ./mnist/model/keras_mnist.h5 
    '''
    
    加载模型
    from keras.models import load_model
    
    mnist_model = load_model(model_path)
    
    统计模型在测试集上的分类结果
    loss_and_metrics = mnist_model.evaluate(X_test, Y_test, verbose=2)
        
    print("Test Loss: {}".format(loss_and_metrics[0]))
    print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))
    
    predicted_classes = mnist_model.predict_classes(X_test)
    
    correct_indices = np.nonzero(predicted_classes == y_test)[0]
    incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
    print("Classified correctly count: {}".format(len(correct_indices)))
    print("Classified incorrectly count: {}".format(len(incorrect_indices)))
    '''
    Test Loss: 0.07348056956584333
    Test Accuracy: 97.82%
    Classified correctly count: 9782
    Classified incorrectly count: 218
    '''

     

     

     

     

     

    • MNIST CNN 网络介绍

     

    CNN 简介
     
      CNN模型是一种以卷积为核心的前馈神经网络模型。 20世纪60年代,Hubel和Wiesel在研究猫脑
    皮层中用于局部敏感和方向选择的神经元时发现其独特的网络结构可以有效地降低反馈神经网
    络的复杂性,继而提出了卷积神经网络(ConvoluTIonal Neural Networks,简称CNN)。

     

     

     

    卷积(Convolution)
     
      卷积是分析数学中的一种基础运算,其中对输入数据做运算时所用到的函数称为卷积核。
    设:f(x), g(x)是R上的两个可积函数,作积分: 

     

      可以证明,关于几乎所有的实数x,上述积分是存在的。这样,随着x的不同取值,这个积分就
    定义了一个如下的新函数,称为函数f与g的卷积

     

     

     

    卷积层(Convolutional Layer, conv) 
     
      卷积层是使用一系列卷积核与多通道输入数据做卷积的线性计算层。卷积层的提出是为了利用
    输入数据(如图像)中特征的局域性和位置无关性来降低整个模型的参数量。卷积运算过程与
    图像处理算法中常用的空间滤波是类似的。因此,卷积常常被通俗地理解为一种“滤波”过程,
    卷积核与输入数据作用之后得到了“滤波”后的图像,从而提取出了图像的特征。

     

     

     

    池化层(Pooling) 
     
      池化层是用于缩小数据规模的一种非线性计算层。为了降低特征维度,我们需要对输入数据进
    行采样,具体做法是在一个或者多个卷积层后增加一个池化层。池化层由三个参数决定:(1)
    池化类型,一般有最大池化和平均池化两种;(2)池化核的大小k;(3)池化核的滑动间隔s。
    下图给出了一种的池化层示例。其中,2x2大小的池化窗口以2个单位距离在输入数据上滑动。
    在池化层中,如果采用最大池化类型,则输出为输入窗口内四个值的最大值;如采用平均池化
    类型,则输出为输入窗口内四个值的平均值

     

     

    Dropout 层 
     
      Dropout 是常用的一种正则化方法,Dropout层是一种正则化层。全连接层参数量非常庞大(占
    据了CNN模型参数量的80%~90%左右),发生过拟合问题的风险比较高,所以我们通常需要
    一些正则化方法训练带有全连接层的CNN模型。在每次迭代训练时,将神经元以一定的概率值
    暂时随机丢弃,即在当前迭代中不参与训练。

     

    Flatten 
     
      将卷积和池化后提取的特征摊平后输入全连接网络,这里与 MNIST softmax 网络的输入层类似。
    MNIST CNN 输入特征,MNIST Softmax 输入原图。

     

     

    MNIST CNN 示意图

     

     

     

     

     

    • 实战 MNIST CNN 网络

     代码

    加载 MNIST 数据集
    from keras.datasets import mnist
    
    (x_train, y_train), (x_test, y_test) = mnist.load_data('mnist/mnist.npz')
    
    print(x_train.shape, type(x_train))
    print(y_train.shape, type(y_train))
    '''
    (60000, 28, 28) <class 'numpy.ndarray'>
    (60000,) <class 'numpy.ndarray'>
    '''
    
    数据处理:规范化
    from keras import backend as K
    
    img_rows, img_cols = 28, 28
    
    if K.image_data_format() == 'channels_first':
        x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
        x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
        input_shape = (1, img_rows, img_cols)
    else:
        x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
        x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
        input_shape = (img_rows, img_cols, 1)
    
    
    print(x_train.shape, type(x_train))
    print(x_test.shape, type(x_test))
    '''
    (60000, 28, 28, 1) <class 'numpy.ndarray'>
    (10000, 28, 28, 1) <class 'numpy.ndarray'>
    '''
    
    # 将数据类型转换为float32
    X_train = x_train.astype('float32')
    X_test = x_test.astype('float32')
    # 数据归一化
    X_train /= 255
    X_test /= 255
    
    print(X_train.shape[0], 'train samples')
    print(X_test.shape[0], 'test samples')
    '''
    60000 train samples
    10000 test samples
    '''
    
    统计训练数据中各标签数量
    import numpy as np
    import matplotlib.pyplot as plt
    
    label, count = np.unique(y_train, return_counts=True)
    print(label, count)
    '''
    [0 1 2 3 4 5 6 7 8 9] [5923 6742 5958 6131 5842 5421 5918 6265 5851 5949]
    '''
    
    fig = plt.figure()
    plt.bar(label, count, width = 0.7, align='center')
    plt.title("Label Distribution")
    plt.xlabel("Label")
    plt.ylabel("Count")
    plt.xticks(label)
    plt.ylim(0,7500)
    
    for a,b in zip(label, count):
        plt.text(a, b, '%d' % b, ha='center', va='bottom',fontsize=10)
    
    plt.show()
    
    数据处理:one-hot 编码
    from keras.utils import np_utils
    
    n_classes = 10
    print("Shape before one-hot encoding: ", y_train.shape)
    Y_train = np_utils.to_categorical(y_train, n_classes)
    print("Shape after one-hot encoding: ", Y_train.shape)
    Y_test = np_utils.to_categorical(y_test, n_classes)
    '''
    Shape before one-hot encoding:  (60000,)
    Shape after one-hot encoding:  (60000, 10)
    '''
    
    print(y_train[0])
    print(Y_train[0])
    '''
    5
    [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
    '''
    
    使用 Keras sequential model 定义 MNIST CNN 网络
    from keras.models import Sequential
    from keras.layers import Dense, Dropout, Flatten
    from keras.layers import Conv2D, MaxPooling2D
    
    model = Sequential()
    ## Feature Extraction
    # 第1层卷积,32个3x3的卷积核 ,激活函数使用 relu
    model.add(Conv2D(filters=32, kernel_size=(3, 3), activation='relu',
                     input_shape=input_shape))
    
    # 第2层卷积,64个3x3的卷积核,激活函数使用 relu
    model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu'))
    
    # 最大池化层,池化窗口 2x2
    model.add(MaxPooling2D(pool_size=(2, 2)))
    
    # Dropout 25% 的输入神经元
    model.add(Dropout(0.25))
    
    # 将 Pooled feature map 摊平后输入全连接网络
    model.add(Flatten())
    
    ## Classification
    # 全联接层
    model.add(Dense(128, activation='relu'))
    
    # Dropout 50% 的输入神经元
    model.add(Dropout(0.5))
    
    # 使用 softmax 激活函数做多分类,输出各数字的概率
    model.add(Dense(n_classes, activation='softmax'))
    
    查看 MNIST CNN 模型网络结构
    model.summary()
    '''_________________________________________________________________
    Layer (type)                 Output Shape              Param #   
    =================================================================
    conv2d_1 (Conv2D)            (None, 26, 26, 32)        320       
    _________________________________________________________________
    conv2d_2 (Conv2D)            (None, 24, 24, 64)        18496     
    _________________________________________________________________
    max_pooling2d_1 (MaxPooling2 (None, 12, 12, 64)        0         
    _________________________________________________________________
    dropout_1 (Dropout)          (None, 12, 12, 64)        0         
    _________________________________________________________________
    flatten_1 (Flatten)          (None, 9216)              0         
    _________________________________________________________________
    dense_1 (Dense)              (None, 128)               1179776   
    _________________________________________________________________
    dropout_2 (Dropout)          (None, 128)               0         
    _________________________________________________________________
    dense_2 (Dense)              (None, 10)                1290      
    =================================================================
    Total params: 1,199,882
    Trainable params: 1,199,882
    Non-trainable params: 0
    _________________________________________________________________
    '''
    
    for layer in model.layers:
        print(layer.get_output_at(0).get_shape().as_list())
    '''
    [None, 26, 26, 32]
    [None, 24, 24, 64]
    [None, 12, 12, 64]
    [None, 12, 12, 64]
    [None, None]
    [None, 128]
    [None, 128]
    [None, 10]
    '''
    
    编译模型
    model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
    
    训练模型,并将指标保存到 history 中
    history = model.fit(X_train,
                        Y_train,
                        batch_size=128,
                        epochs=5,
                        verbose=2,
                        validation_data=(X_test, Y_test))
    '''
    Train on 60000 samples, validate on 10000 samples
    Epoch 1/5
     - 64s - loss: 0.2603 - acc: 0.9205 - val_loss: 0.0581 - val_acc: 0.9825
    Epoch 2/5
     - 68s - loss: 0.0924 - acc: 0.9729 - val_loss: 0.0420 - val_acc: 0.9855
    Epoch 3/5
     - 69s - loss: 0.0714 - acc: 0.9786 - val_loss: 0.0325 - val_acc: 0.9891
    Epoch 4/5
     - 68s - loss: 0.0582 - acc: 0.9820 - val_loss: 0.0322 - val_acc: 0.9889
    Epoch 5/5
     - 68s - loss: 0.0497 - acc: 0.9849 - val_loss: 0.0310 - val_acc: 0.9900
    '''
    
    可视化指标
    fig = plt.figure()
    plt.subplot(2,1,1)
    plt.plot(history.history['acc'])
    plt.plot(history.history['val_acc'])
    plt.title('Model Accuracy')
    plt.ylabel('accuracy')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc='lower right')
    
    plt.subplot(2,1,2)
    plt.plot(history.history['loss'])
    plt.plot(history.history['val_loss'])
    plt.title('Model Loss')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.legend(['train', 'test'], loc='upper right')
    plt.tight_layout()
    
    plt.show()
    保存模型
    import os
    import tensorflow.gfile as gfile
    
    save_dir = "./mnist/model/"
    
    if gfile.Exists(save_dir):
        gfile.DeleteRecursively(save_dir)
    gfile.MakeDirs(save_dir)
    
    model_name = 'keras_mnist.h5'
    model_path = os.path.join(save_dir, model_name)
    model.save(model_path)
    print('Saved trained model at %s ' % model_path)
    '''
    Saved trained model at ./mnist/model/keras_mnist.h5 
    '''
    
    加载模型
    from keras.models import load_model
    
    mnist_model = load_model(model_path)
    
    统计模型在测试集上的分类结果
    loss_and_metrics = mnist_model.evaluate(X_test, Y_test, verbose=2)
        
    print("Test Loss: {}".format(loss_and_metrics[0]))
    print("Test Accuracy: {}%".format(loss_and_metrics[1]*100))
    
    predicted_classes = mnist_model.predict_classes(X_test)
    
    correct_indices = np.nonzero(predicted_classes == y_test)[0]
    # incorrect_indices = np.nonzero(predicted_classes != y_test)[0]
    incorrect_indices = np.nonzero(predicted_classes != y_test)
    print("Classified correctly count: {}".format(len(correct_indices)))
    # print("Classified incorrectly count: {}".format(len(incorrect_indices)))
    print("Classified incorrectly count: {}".format(incorrect_indices))
    type(incorrect_indices)
    '''
    Test Loss: 0.03102766538519645
    Test Accuracy: 99.0%
    Classified correctly count: 9900
    Classified incorrectly count: (array([ 321,  582,  659,  674,  717,  740,  947, 1014, 1033, 1039, 1112,
           1182, 1226, 1232, 1242, 1260, 1319, 1326, 1393, 1414, 1527, 1530,
           1549, 1709, 1717, 1737, 1790, 1878, 1901, 2035, 2040, 2043, 2109,
           2118, 2130, 2135, 2293, 2387, 2454, 2462, 2597, 2630, 2654, 2896,
           2921, 2939, 2995, 3005, 3030, 3073, 3422, 3503, 3520, 3558, 3597,
           3727, 3767, 3780, 3808, 3853, 3906, 3941, 3968, 4075, 4176, 4238,
           4248, 4256, 4294, 4497, 4536, 4571, 4639, 4740, 4761, 4807, 4860,
           4956, 5246, 5749, 5937, 5955, 6071, 6091, 6166, 6576, 6597, 6625,
           6651, 6783, 8527, 9009, 9015, 9019, 9024, 9530, 9664, 9729, 9770,
           9982], dtype=int64),)
    '''
    Out[25]: tuple

     

    转载于:https://www.cnblogs.com/LXL616/p/11247954.html

    展开全文
  • matlab代码,不使用库函数。基于Dropout的手写体数字识别。 matlab代码,不使用库函数。基于Dropout的手写体数字识别
  • 手写体数字识别系统

    2011-09-22 17:02:17
    手写体数字识别系统可以识别手写数字,并可训练样本库;程序源代码!!!
  • 为了提高基于BP神经网络的手写体数字识别分类器的准确率与训练速度,针对基于BP神经网络的手写体数字识别分类器,从代价函数、权值初始化、正则方法消除过拟合几个方面对BP神经网络算法进行了改进。并使用MNIST数据...
  • VC++手写体数字识别

    2011-10-21 10:51:31
    VC++手写体数字识别 BP神级 毕业论文
  • 基于知识库的手写体数字识别
  • 基于 MATLAB 的手写体数字识别算法的实现与分析 摘要 手写体数字识别是利用计算机自动辨认手写体阿拉伯数字的一种技术是光学字符识别技术的一个分支手写体数字识别在邮政编码务财报表银行票据各种凭证以及调查表格的...
  • 基于概率神经网络的手写体数字识别

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,647
精华内容 658
关键字:

手写体数字识别