东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 2847|回复: 1

[课堂笔记] 59、RNN实战案例:手写数字图片识别(分类)_笔记

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14418
QQ
发表于 2019-4-14 08:44:03 | 显示全部楼层 |阅读模式


59、RNN实战案例:手写数字图片识别(分类)_笔记


  1. # -*- coding: utf-8 -*-
  2. __author__ = u'东方耀 微信:dfy_88888'
  3. __date__ = '2019/4/14 9:16'
  4. __product__ = 'PyCharm'
  5. __filename__ = 'rnn_mnist_demo'


  6. """
  7.    59、RNN实战案例:手写数字图片识别(分类)
  8.    tf开发 三个模块:
  9.    1、数据提供者  api: next_batch(batch_size)
  10.    2、构建数据流图  模型结构 input LSTM fc output  metric(loss accuracy)  train_op
  11.    3、执行训练的代码 sess.run()
  12. """

  13. import tensorflow as tf
  14. from tensorflow.examples.tutorials.mnist import input_data
  15. import numpy as np
  16. import math
  17. import matplotlib.pyplot as plt

  18. tf.logging.set_verbosity(tf.logging.INFO)


  19. # 第一步:导入数据
  20. # 数据加载
  21. mnist = input_data.read_data_sets('mnist_data/', one_hot=True)

  22. # 样本数 55000
  23. print(mnist.train.num_examples)
  24. # images 特征矩阵 784个特征属性
  25. print(mnist.train.images.shape)
  26. # labels 目标属性10个 刚好是10个数字 进行了哑编码
  27. print(mnist.train.labels.shape)

  28. print('测试集shape:{}'.format(mnist.test.images.shape))
  29. print('验证集shape:{}'.format(mnist.validation.images.shape))

  30. # 手写数字识别的数据集主要包含三个部分:训练集(5.5w, mnist.train)、测试集(1w, mnist.test)、验证集(0.5w, mnist.validation)
  31. # 手写数字图片大小是28*28*1像素的图片(黑白),也就是每个图片由784维的特征描述


  32. # 第二步:设置超参并定义学习率调整策略
  33. learn_rate_base = 0.01
  34. # 时序长度 t1 t2 t3... t28  28个时刻
  35. num_timesteps = 28
  36. # 每个时刻输入的数据维度大小(像素值个数)
  37. input_size = 28
  38. # 一个LSTM的FP过程完成后 刚好就是处理了一张图片
  39. # (图片内部的像素点之间是有一定的依赖关系的)上下文关系 就可以用RNN

  40. num_lstm_layers = 2
  41. num_lstm_nodes = [128, 256]
  42. # 控制lstm梯度的大小 1.0是梯度的上限 如果梯度大于1.0就设为1.0 截断
  43. clip_lstm_grads = 1.0
  44. # 展示信息的间隔大小
  45. display_step = 10
  46. # 输入的样本维度大小信息 784 = 28*28
  47. input_dim = mnist.train.images.shape[1]
  48. # 输出的维度大小信息 10
  49. class_num = mnist.train.labels.shape[1]

  50. tf.logging.info('input_dim : %d' % input_dim)
  51. tf.logging.info('class_num : %d' % class_num)

  52. # 查看手写图片数据 10张图片数据与对应的y值
  53. # train_images, train_labels = mnist.train.next_batch(10)
  54. # print(train_images.shape)
  55. # print(train_labels.shape)
  56. # train_image = train_images[0]
  57. # train_label = train_labels[0]
  58. # print('实际值:', train_label)
  59. #
  60. # train_image = np.array(train_image)
  61. # train_image = train_image.reshape(28, 28)
  62. # fig = plt.figure()
  63. # plt.imshow(train_image, cmap='binary')
  64. # plt.show()


  65. def learn_rate_func(epoch):
  66.     """
  67.     根据给定的迭代批次,更新产生一个学习率的值 均匀分布策略
  68.     :param epoch:
  69.     :return:
  70.     """
  71.     return max(0.001, learn_rate_base * (0.9 ** int(epoch / 10)))


  72. #
  73. # 第三步:开始构建模型 设置输入数据的占位符
  74. _X = tf.placeholder(dtype=tf.float32, shape=[None, input_dim], name='X_origianl')
  75. y = tf.placeholder(tf.int32, [None, class_num], name='y')
  76. # batch_size是一个int32类型的标量tensor的占位符,
  77. # 使用batch_size可以让我们在训练和测试的时候使用不同的数据量
  78. batch_size = tf.placeholder(tf.int32, [])
  79. # # dropout的时候,保留率多少
  80. keep_prob = tf.placeholder(tf.float32, [])
  81. learn_rate = tf.placeholder(tf.float32, [])


  82. # 第四步:构建RNN LSTM 网络(直接将网络结构翻译成为这个代码)
  83. # 1. 输入的数据格式转换
  84. # X格式:[batch_size, num_timesteps, input_size]
  85. X = tf.reshape(_X, [-1, num_timesteps, input_size])

  86. # LSTM层
  87. # 开方(输入层size + 输出层size)
  88. # 初始化方法 仿照了
  89. scale = 1.0 / math.sqrt(input_size + num_lstm_nodes[-1]) / 3.0
  90. lstm_initializer = tf.random_uniform_initializer(minval=-scale, maxval=scale)
  91. with tf.variable_scope(name_or_scope='lstm_nn', initializer=lstm_initializer):
  92.     cells = []
  93.     for i in range(num_lstm_layers):
  94.         cell = tf.nn.rnn_cell.LSTMCell(num_units=num_lstm_nodes[i], name='lstm_cell')
  95.         cell = tf.nn.rnn_cell.DropoutWrapper(cell, output_keep_prob=keep_prob)
  96.         cells.append(cell)
  97.     # 多层的LSTM 将两层的cell合并封装成一个MultiRNNCell
  98.     # 将多层RNN当作单层RNN来操作了
  99.     # tf.nn.rnn_cell
  100.     cell = tf.nn.rnn_cell.MultiRNNCell(cells, state_is_tuple=True)
  101.     # 初始的中间的隐含状态 state=0
  102.     initial_state = cell.zero_state(batch_size=batch_size, dtype=tf.float32)
  103.     # 让cell去处理或计算输入的序列 rnn_outputs包含了每一步的输出
  104.     # rnn_outputs shape : [batch_size, num_timesteps, hps.num_lstm_nodes[-1]]
  105.     rnn_outputs, middle_hidden_state = tf.nn.dynamic_rnn(cell=cell, inputs=X, initial_state=initial_state)
  106.     print('rnn_outputs shape:', rnn_outputs.shape)
  107.     # last shape [batch_size, hps.num_lstm_nodes[-1]]
  108.     last = rnn_outputs[:, -1, :]
  109.     print('last shape: ', last.shape)


  110. # fc
  111. # fc_initializer = tf.uniform_unit_scaling_initializer(factor=1.0, dtype=tf.float32)
  112. fc_initializer = tf.random_uniform_initializer(-1.0, 1.0, seed=10)
  113. with tf.variable_scope(name_or_scope='fc', initializer=fc_initializer):
  114.     logits = tf.layers.dense(last, class_num, name='fc')

  115. #
  116. # 第五步:构建模型的损失函数
  117. # 第六步:构建梯度下降的优化方法(一般用Adam 动量GD)
  118. # 第七步:计算模型正确率
  119. # metrics (loss accuracy)
  120. # metrics度量层(loss 与 accuracy)
  121. # 这一层并没有变量或参数需要训练 也就不需要初始化器 所以使用name_scope
  122. with tf.name_scope(name='metrics'):
  123.     # sparse_ 用这个:强大一些
  124.     # softmax_loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=outputs, logits=logits)
  125.     # 计算_交叉熵损失函数值 用第二个版本
  126.     softmax_loss = tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=logits)
  127.     loss = tf.reduce_mean(softmax_loss)
  128.     # argmax [0, 2, 1, 5, 8, 2]  ---> 4
  129.     y_pred = tf.argmax(tf.nn.softmax(logits), axis=1, output_type=tf.int32)
  130.     y_true = tf.argmax(y, axis=1, output_type=tf.int32)
  131.     correct_pred = tf.equal(y_pred, y_true)
  132.     accuracy = tf.reduce_mean(tf.cast(correct_pred, dtype=tf.float32))


  133. # train_op 训练层
  134. with tf.name_scope(name='train_op'):
  135.     # 需要对训练变量的梯度进行clip  hps.clip_lstm_grads
  136.     # 获取所有训练的变量
  137.     # train_op = tf.train.AdamOptimizer(hps.learning_rate).minimize(loss, global_step=global_step)
  138.     train_vars = tf.trainable_variables()
  139.     for var in train_vars:
  140.         tf.logging.info('train variable name : %s' % var.name)
  141.     # tf.gradients(loss, train_vars) 损失值对所有变量的梯度
  142.     # grads得到截断后的梯度
  143.     grads, _ = tf.clip_by_global_norm(t_list=tf.gradients(loss, train_vars), clip_norm=clip_lstm_grads)
  144.     # 普通梯度下降 BGD SGD MBGD  动量(有速度) 冲量
  145.     # 将梯度应用到所有的变量
  146.     optimizer = tf.train.AdamOptimizer(learn_rate)
  147.     train_op = optimizer.apply_gradients(grads_and_vars=zip(grads, train_vars), name='train_op')



  148. # 第八步:会话中执行阶段(模型的训练与迭代)

  149. init_op = tf.global_variables_initializer()

  150. num_train_steps = 500
  151. batch_size_train = 100
  152. batch_size_test = 3000
  153. keep_prob_train = 0.8
  154. keep_prob_test = 1.0


  155. with tf.Session() as sess:
  156.     sess.run(init_op)
  157.     for step in range(num_train_steps):
  158.         batch_xs, batch_labels = mnist.train.next_batch(batch_size_train)
  159.         loss_val, accuracy_val, _ = sess.run(fetches=[loss, accuracy, train_op], feed_dict={
  160.             _X: batch_xs,
  161.             y: batch_labels,
  162.             keep_prob: keep_prob_train,
  163.             batch_size: batch_size_train,
  164.             learn_rate: learn_rate_func(step)
  165.         })
  166.         if step % display_step == 0:
  167.             tf.logging.info('Step: %5d, loss: %3.3f, accuracy: %3.3f' % (step, loss_val, accuracy_val))
  168.     # test
  169.     accuracy_test = sess.run(fetches=accuracy, feed_dict={
  170.         _X: mnist.test.images[:3000],
  171.         y: mnist.test.labels[:3000],
  172.         keep_prob: keep_prob_test,
  173.         batch_size: batch_size_test,
  174.     })
  175.     print('测试集准确率:{}'.format(accuracy_test))
  176.     pass







复制代码


手写数字图片识别1.png
手写数字图片识别2.jpg
手写数字图片识别3.jpg
888.png
999.png
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

0

主题

96

帖子

198

积分

注册会员

Rank: 2

积分
198
发表于 2019-7-2 14:06:29 | 显示全部楼层
多谢分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-3-28 20:50 , Processed in 0.197530 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表