手写数字辨识应该说的深度学习入门的HelloWorld,仔细认真的搞完这个的话,对后面其他模型结构的实验学习是非常有帮助的,那话不多说,go~

一般三步搞定

  1. 搭建网络模型
  2. 训练网络模型
  3. 测试网络模型

一、搭建网络模型

mnist_inference.py
这里就是定义一个网络模型,你也可以改成什么
AlexNet、ZFNet、ResNet、GoogleNet、VGG、
你有兴趣你就这么去玩,然后来对比~
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 来哇来哇,我们来定义一个网络吧~~~~
# 一个.py文件中最好不要超过80行,不然可读性降低,你自己也看着不爽,这里我注释写的比较多...
import tensorflow as tf
# 定义神经网络相关的参数
INPUT_NODE = 784
OUTPUT_NODE = 10
LAYER1_NODE = 500IMAGE_SIZE = 28
NUM_CHANNELS = 1
NUM_LABELS = 10# 第一层卷积层的尺寸和深度
CONV1_DEEP = 32
CONV1_SIZE = 5
# 第二层卷积层的尺寸和深度
CONV2_DEEP = 64
CONV2_SIZE = 5
# 全连接层的节点个数
FC_SIZE = 512# 定义神经网络的前向传播过程。
# 这里添加了一个新的参数train,用于区别训练过程和测试过程。
# 在这个程序中将用到dropout方法,dropout可以进一步提升模型可靠性并防止过拟合,dropout过程只在训练时使用def inference(input_tensor, train, regularizer):# 第一个卷积层# 使用了全0填充,所以32个5*5的filter得到28*28*32的矩阵with tf.variable_scope('layer1-conv1'):# 初始化input_tensor与conv1之间的weights参数# weight总参数为5*5*32*1,最后的1表示通道数# (灰度图像单通道,RGB三通道)# tf.get_variable("变量名","维度[2,3]如:表示2行3列","变量初始化方式"),详细见# http://www.tensorfly.cn/tfdoc/how_tos/variable_scope.htmlconv1_weights = tf.get_variable("weight", [CONV1_SIZE, CONV1_SIZE, NUM_CHANNELS, CONV1_DEEP],initializer=tf.truncated_normal_initializer(stddev=0.1))# 初始化是bias变量,维度为32,每个featureMap对应一个biasconv1_biases = tf.get_variable("bias", [CONV1_DEEP], initializer=tf.constant_initializer(0.0))# 使用边长为5,深度为32的过滤器,过滤器移动的步长为1,且使用全0填充conv1 = tf.nn.conv2d(input_tensor, conv1_weights, strides=[1, 1, 1, 1], padding='SAME')relu1 = tf.nn.relu(tf.nn.bias_add(conv1, conv1_biases))# 实现第二层池化层的前向传播过程。# 这里选用最大池化层,池化层过滤器的边长为2,使用全0填充且移动的步长为2。# 这一层的输入是上一层的输出,也就是28*28*32的矩阵。输出为14*14*32的矩阵。with tf.name_scope('layer2-pool'):pool1 = tf.nn.max_pool(relu1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')# 声明第三层卷积层的变量并实现前向传播过程。# 这一层的输入为14*14*32的矩阵,输出为14*14*64的矩阵。with tf.variable_scope('layer3-conv2'):# 这里的第三个参数为什么是CONV1_DEEP,就要深入去看LeNet在这层的连接方式了# 我要是记得没错的话是叠加的方式# https://blog.csdn.net/m0_37970224/article/details/87893898#第二卷积层的weightsconv2_weights = tf.get_variable("weight", [CONV2_SIZE, CONV2_SIZE, CONV1_DEEP, CONV2_DEEP],initializer=tf.truncated_normal_initializer(stddev=0.1))conv2_biases = tf.get_variable("bias", [CONV2_DEEP], initializer=tf.constant_initializer(0.0))# 使用边长为5,深度为64的过滤器,过滤器移动的步长为1,且使用全0填充conv2 = tf.nn.conv2d(pool1, conv2_weights, strides=[1, 1, 1, 1], padding='SAME')relu2 = tf.nn.relu(tf.nn.bias_add(conv2, conv2_biases))# 实现第四层池化层的前向传播过程。# 这一层和第二层的结构是一样的。这一层的输入为14*14*64的矩阵,输出为7*7*64的矩阵。with tf.name_scope('layer4-poo2'):pool2 = tf.nn.max_pool(relu2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')# 将第四层池化层的输出转化为第五层全连接层的输入格式。# 第四层的输出为7*7*64的矩阵,然而第五层全连接层需要的输入格式为向量,所以在这里需要将这个7*7*64的矩阵拉直成一个向量。# pool2.get_shape函数可以得到第四层输出矩阵的维度而不需要手工计算。# 注意因为每一层神经网络的输入输出都为一个batch的矩阵,所以这里得到的维度也包含了一个batch中数据的个数。# 如果不好理解的话,假设batch=1pool_shape = pool2.get_shape().as_list()# 计算将矩阵拉直成向量之后的长度,这个长度就是矩阵长度及深度的乘积。# 注意这里pool_shape[0]为一个batch中样本的个数。nodes = pool_shape[1] * pool_shape[2] * pool_shape[3]# 通过tf.reshape函数将第四层的输出变成一个batch的向量。reshaped = tf.reshape(pool2, [pool_shape[0], nodes])# 声明第五层全连接层的变量并实现前向传播过程。# 这一层的输入是拉直之后的一组向量,向量长度为7*7*64=3136,输出是一组长度为512的向量。# 这一层和之前在第5章中介绍的基本一致,唯一的区别是引入了dropout的概念。# dropout在训练时会随机将部分节点的输出改为0。# dropout可以避免过拟合问题,从而使得模型在测试数据上的效果更好。# dropout一般只在全连接层而不是卷积层或者池化层使用。with tf.variable_scope('layer5-fc1'):fc1_weights = tf.get_variable("weight", [nodes, FC_SIZE],initializer=tf.truncated_normal_initializer(stddev=0.1))# 只有全连接层的权重需要加入正则化if regularizer != None:tf.add_to_collection('losses', regularizer(fc1_weights))fc1_biases = tf.get_variable('bias', [FC_SIZE], initializer=tf.constant_initializer(0.1))fc1 = tf.nn.relu(tf.matmul(reshaped, fc1_weights)+fc1_biases)if train:fc1 = tf.nn.dropout(fc1, 0.5)# 声明第六层全连接层的变量并实现前向传播过程。# 这一层的输入是一组长度为512的向量,输出是一组长度为10的向量。# 这一层的输出通过Softmax之后就得到了最后的分类结果。with tf.variable_scope('layer6-fc2'):fc2_weights = tf.get_variable("weight", [FC_SIZE, NUM_LABELS],initializer=tf.truncated_normal_initializer(stddev=0.1))if regularizer != None:tf.add_to_collection('losses', regularizer(fc2_weights))fc2_biases = tf.get_variable('bias', [NUM_LABELS], initializer=tf.constant_initializer(0.1))logit = tf.matmul(fc1, fc2_weights) + fc2_biases# 返回第六层的输出return logit

二、训练网络模型

mnist_train.py
模型搭建好了,那就开始训练啦~
那么问题来啦~
我如何又快又棒棒的训练好一个模型呢?
答:give u some trick1. 正则化2. 滑动平均3. 指数衰减学习率4. dropout5. .......
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# mnist_inference中的网络模型搭建好了,那我们就开始训练吧哈~~~~
import os
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data# 加载mnist_inference.py中定义的常量和前向传播的函数
from mnist import mnist_inference# 配置神经网络的参数
BATCH_SIZE = 100
LEARNING_RATE_BASE = 0.01       # 基础学习率
LEARNING_RATE_DECAY = 0.99      # 学习率的衰减率,意思就是让学习率动态变化
REGULARAZTION_RATE = 0.0001     # 修正率
TRAINING_STEPS = 30000          # 训练轮数
MOVING_AVERAGE_DECAY = 0.99     # 滑动平均衰减
# 模型保存的路径和文件名
MODEL_SAVE_PATH = "model/"
MODEL_NAME = "model.ckpt"# 设置好参数了,那就开始训练起来吧啦啦啦啦~
def train(mnist):# 定义输入输出placeholder# 调整输入数据placeholder的格式,输入为一个四维矩阵# placeholder是先占个坑的意思,坑中的数据在程序运行的时候再指定,# 避免生成大量常量来提供输入数据,需要指定数据类型# 来,我们来定义输入x,100个样例干进去,每个样例是28*28*1(width * height * channel)x = tf.placeholder(tf.float32, [BATCH_SIZE,                             # 第一维表示一个batch中样例的个数mnist_inference.IMAGE_SIZE,             # 第二维和第三维表示图片的尺寸mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS],          # 第四维表示图片的深度,对于RBG格式的图片,深度为3name='x-input')y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')# 选择l2正则化,准备干到网络里面去regularizer = tf.contrib.layers.l2_regularizer(REGULARAZTION_RATE)# 走你,第二个参数True表示正在训练y = mnist_inference.inference(x, True, regularizer)# 接下来干一件大事,定义loss function,add some training trick# 步长 如果为True,会把它加入到GraphKeys.TRAINABLE_VARIABLES,才能对它使用Optimizer# https://blog.csdn.net/gg_18826075157/article/details/78368924global_step = tf.Variable(0, trainable=False)# 定义损失函数、学习率、滑动平均操作以及训练过程variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)variable_averages_op = variable_averages.apply(tf.trainable_variables())cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y, labels=tf.argmax(y_, 1))cross_entropy_mean = tf.reduce_mean(cross_entropy)loss = cross_entropy_mean + tf.add_n(tf.get_collection('losses'))learning_rate = tf.train.exponential_decay(LEARNING_RATE_BASE, global_step, mnist.train.num_examples/BATCH_SIZE, LEARNING_RATE_DECAY)train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)with tf.control_dependencies([train_step, variable_averages_op]):train_op = tf.no_op(name='train')# 初始化Tensorflow持久化类saver = tf.train.Saver()with tf.Session() as sess:tf.global_variables_initializer().run()# 验证和测试的过程将会有一个独立的程序来完成# 轮了30000轮,batchsize为100for i in range(TRAINING_STEPS):# 一个batch的训练,更新参数一次xs, ys = mnist.train.next_batch(BATCH_SIZE)# 类似地将输入的训练数据格式调整为一个四维矩阵,并将这个调整后的数据传入sess.run过程reshaped_xs = np.reshape(xs, (BATCH_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.NUM_CHANNELS))_, loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: reshaped_xs, y_: ys})# 每1000轮保存一次模型if i%1000 == 0:# 输出当前的训练情况。这里只输出了模型在当前训练batch上的损失函数大小。通过损失函数的大小可以大概了解训练的情况。# 在验证数据集上的正确率信息会有一个单独的程序来生成。print("After %d training step(s), loss on training batch is %f." % (step, loss_value))# 保存当前的模型。注意这里隔出了global_step参数,这样可以让每个被保存模型的文件名末尾加上训练的轮数,比如“model.ckpt-1000”表示训练1000轮后得到的模型saver.save(sess, os.path.join(MODEL_SAVE_PATH, MODEL_NAME), global_step=global_step)def main(argv=None):mnist = input_data.read_data_sets("dataset/", one_hot=True)train(mnist)if __name__ == '__main__':tf.app.run()

三、验证网络模型

mnist_eval.py
切出一部分数据来做验证
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data# 加载mnist_inference.py 和 mnist_train.py中定义的常量和函数
from mnist import mnist_inference
from mnist import mnist_train# 每10秒加载一次最新的模型,并在测试数据上测试最新模型的正确率
EVAL_INTERVAL_SECS = 10def evaluate(mnist):with tf.Graph().as_default() as g:# 定义输入输出的格式x = tf.placeholder(tf.float32, [mnist.validation.num_examples,           # 第一维表示样例的个数mnist_inference.IMAGE_SIZE,             # 第二维和第三维表示图片的尺寸mnist_inference.IMAGE_SIZE,mnist_inference.NUM_CHANNELS],          # 第四维表示图片的深度,对于RBG格式的图片,深度为5name='x-input')y_ = tf.placeholder(tf.float32, [None, mnist_inference.OUTPUT_NODE], name='y-input')validate_feed = {x: np.reshape(mnist.validation.images, (mnist.validation.num_examples, mnist_inference.IMAGE_SIZE, mnist_inference.IMAGE_SIZE, mnist_inference.NUM_CHANNELS)),y_: mnist.validation.labels}# 直接通过调用封装好的函数来计算前向传播的结果。# 因为测试时不关注正则损失的值,所以这里用于计算正则化损失的函数被设置为None。y = mnist_inference.inference(x, False, None)# 使用前向传播的结果计算正确率。# 如果需要对未知的样例进行分类,那么使用tf.argmax(y, 1)就可以得到输入样例的预测类别了。correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))# 通过变量重命名的方式来加载模型,这样在前向传播的过程中就不需要调用求滑动平均的函数来获取平局值了。# 这样就可以完全共用mnist_inference.py中定义的前向传播过程variable_averages = tf.train.ExponentialMovingAverage(mnist_train.MOVING_AVERAGE_DECAY)variable_to_restore = variable_averages.variables_to_restore()saver = tf.train.Saver(variable_to_restore)# 每隔EVAL_INTERVAL_SECS秒调用一次计算正确率的过程以检测训练过程中正确率的变化while True:with tf.Session() as sess:# tf.train.get_checkpoint_state函数会通过checkpoint文件自动找到目录中最新模型的文件名ckpt = tf.train.get_checkpoint_state(mnist_train.MODEL_SAVE_PATH)if ckpt and ckpt.model_checkpoint_path:# 加载模型saver.restore(sess, ckpt.model_checkpoint_path)# 通过文件名得到模型保存时迭代的轮数global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]accuracy_score = sess.run(accuracy, feed_dict=validate_feed)print("After %s training step(s), validation accuracy = %f" % (global_step, accuracy_score))else:print("No checkpoint file found")returntime.sleep(EVAL_INTERVAL_SECS)def main(argv=None):mnist = input_data.read_data_sets("dataset/", one_hot=True)evaluate(mnist)if __name__ == '__main__':tf.app.run()

mnist手写数字辨识实战——改进的LeNet相关推荐

  1. 用tensorflow搭建RNN(LSTM)进行MNIST 手写数字辨识

    用tensorflow搭建RNN(LSTM)进行MNIST 手写数字辨识 循环神经网络RNN相比传统的神经网络在处理序列化数据时更有优势,因为RNN能够将加入上(下)文信息进行考虑.一个简单的RNN如 ...

  2. MNIST手写数字辨识

    多层感知器 相关库 import matplotlib.pyplot as plt import numpy as np from keras.datasets import mnist from k ...

  3. Pytorch+CNN+MNIST手写数字识别实战

    文章目录 1.MNIST 2.数据预处理 2.1相关包 2.2数据载入和预处理 3.网络结构 4.优化器.损失函数.网络训练以及可视化分析 4.1定义优化器 4.2网络训练 4.3可视化分析 5.测试 ...

  4. FlyAi实战之MNIST手写数字识别练习赛(准确率99.55%)

    欢迎关注WX公众号:[程序员管小亮] 文章目录 欢迎关注WX公众号:[程序员管小亮] 一.介绍 二.代码实现 1_数据加载 2_归一化 3_定义网络结构 4_设置优化器和退火函数 5_数据增强 6_拟 ...

  5. 用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别 (zz)

    用MXnet实战深度学习之一:安装GPU版mxnet并跑一个MNIST手写数字识别 我想写一系列深度学习的简单实战教程,用mxnet做实现平台的实例代码简单讲解深度学习常用的一些技术方向和实战样例.这 ...

  6. MOOC网深度学习应用开发1——Tensorflow基础、多元线性回归:波士顿房价预测问题Tensorflow实战、MNIST手写数字识别:分类应用入门、泰坦尼克生存预测

    Tensorflow基础 tensor基础 当数据类型不同时,程序做相加等运算会报错,可以通过隐式转换的方式避免此类报错. 单变量线性回归 监督式机器学习的基本术语 线性回归的Tensorflow实战 ...

  7. GAN实战之Pytorch 使用CGAN生成指定MNIST手写数字

    有关条件GAN(cgan)的相关原理,可以参考: GAN系列之CGAN原理简介以及pytorch项目代码实现 其他类型的GAN原理介绍以及应用,可以查看我的GANs专栏 一.数据集介绍,加载数据 依旧 ...

  8. 深度学习数字仪表盘识别_【深度学习系列】手写数字识别实战

    上周在搜索关于深度学习分布式运行方式的资料时,无意间搜到了paddlepaddle,发现这个框架的分布式训练方案做的还挺不错的,想跟大家分享一下.不过呢,这块内容太复杂了,所以就简单的介绍一下padd ...

  9. MNIST手写数字识别准确度提升最全、最实用的方法

    MNIST手写数字识别是所有学习AI同学的入门必经过程,MNIST识别准确率提升修炼是精通AI模型的必经课程,MNIST识别准确率开刚始大家一般都能达到90%左右,再往上提高还需要费较大的精力去修改模 ...

  10. 如何为MNIST手写数字分类开发CNN

    导言 MNIST手写数字分类问题是计算机视觉和深度学习中使用的标准数据集. 虽然数据集得到了有效的解决,但它可以作为学习和实践如何开发,评估和使用卷积深度学习神经网络从头开始进行图像分类的基础.这包括 ...

最新文章

  1. 因“薪水太高”被欠薪3个月、后又遭解雇?程序员愤怒反击!
  2. 活跃用户数怎么计算_不懂LTV,怎么做用户增长?详解用户生命周期价值计算方法...
  3. JZOJ 4822. 【NOIP2016提高A组集训第1场10.29】完美标号
  4. 如何实现一个跨库连表SQL生成器?
  5. Subst DOS命令
  6. 真正的出路只有一个(哈佛大学的幸福课)
  7. 手把手带你入门Python爬虫(一、工欲善其事必先利其器)
  8. typecho反序列化漏洞复现
  9. 2019牛客暑期多校训练营(第七场)-C Governing sand
  10. 单片机,嵌入式,PLC三者之间有什么区别,学习方向如何选择
  11. linux 蓝牙编程avrcp,bluetooth(蓝牙) AVRCP协议概念及代码流程解析
  12. Delphi开发Android用虚拟摇杆VirtualJoystic
  13. 3d max 材质编辑器操作实例——自定义球
  14. 数字信号和模拟信号的区别
  15. Android——距离传感器(PROXIMITY)的应用
  16. AireOS WLC配置AP Group
  17. 工作八年的程序员,却拿着毕业三年的工资,再不开窍就真晚了...
  18. apfs扩容_如何在MacOS High Sierra上调整APFS容器的大小
  19. 金蝶加密服务器ip地址修改密码,金蝶加密服务器在哪里设置密码
  20. OMAPL138调试笔记

热门文章

  1. Java学习资料整合
  2. 最新emoji表情代码大全_2019七夕节最新撩妹句子大全,浪漫的七夕节表情包集锦...
  3. 服务器记事本找回文本,如何还原记事本中已删除的内容
  4. Windows超级管理器简介
  5. 一元云购 java源码
  6. ThinkPHP商城系统与外部系统用户互通,集成UCenter
  7. Cadence Gerber文件制作过程
  8. 计算机桌面桌面设置动态视频教程,如何在计算机上设置动态桌面?电脑设置动态视频桌面图形教程...
  9. php 数组添加键值对,php怎么为数组增加键值对
  10. a4如何打印双面小册子_a4如何排版打印双面小册子?