初学tensorflow-RNN

使用RNN对MNIST数据集分类

1、 功能包导入

import tensorflow.compat.v1 as tf
tf.disable_eager_execution()
from tensorflow.examples.tutorials.mnist import input_data

2、数据集下载

mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

3、参数配置

lr = 0.001#学习率
training_iters = 100#训练轮数
batch_size = 128
n_inputs = 28
n_steps = 28
n_hidden_units = 128
n_classes = 10

  • lr为网络学习率,training_iters为训练轮数,batch_size为每次丢入网络的simple,n_inputs是输入层的结点个数(MNIST每张图片是28*28,每行28个像素点作为网络的输入,28步后可以将整张图片全部输入),n_steps是步数(28步之后可以将整张图片输入)。n_hidden_units为隐层个数,即ceil中的结点个数.n_classes是10个类别。

4、权重、偏置初始化

weights = {
'in': tf.Variable(tf.random_normal([n_inputs, n_hidden_units])),
'out': tf.Variable(tf.random_normal([n_hidden_units, n_classes]))
}# (28, 128)、# (128, 10)
biases = {
'in': tf.Variable(tf.constant(0.1, shape=[n_hidden_units, ])),
'out': tf.Variable(tf.constant(0.1, shape=[n_classes, ]))
}# (128, )、# (10, )
  • 输入数据,经过权重与偏置计算到达ceil,在ceil处理之后通过权重与偏置计算输出。
  • 以上为输入与输出的权重、偏置。

5、网络输入

#input
xs = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
ys = tf.placeholder(tf.float32, [None, n_classes])
  • MNIST数据为simple784,需要将其还原为2828结构。
  • 10分类,采用one_hot编码,同样需要将label重塑为[simple.10]结构。

6、RNN隐层

def RNN(X, weights, biases):#输入,权重,偏置
    X = tf.reshape(X, [-1, 28])#(128 * 28, 28 )
    X_in = tf.matmul(X, weights['in']) + biases['in']#(128 * 28, 128 )
    X_in = tf.reshape(X_in, [-1, n_steps, n_hidden_units])#(128 ,28, 128 )#时间序列
    cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_units, forget_bias=1.0, state_is_tuple=True)
    init_state = cell.zero_state(batch_size=batch_size, dtype=tf.float32)
    outputs, final_state = tf.nn.dynamic_rnn(cell, X_in, initial_state=init_state, time_major=False)#time_major代表时间序列
    outputs = tf.unstack(tf.transpose(outputs, [1, 0, 2]))
    results = tf.matmul(outputs[-1], weights['out']) + biases['out']#(另外一种定义方法,不理解)results = tf.matmul(final_state[1], weights['out']) + biases['out']#应该是仅仅考虑了短期记忆
    return results
pred = RNN(xs, weights, biases)
  • 形参(输入数据、权重、偏置)
  • 将数据重塑为[simple*28,28]结构,使数据能够根据权重进行计算,计算完成后需要继续重塑,目的是能够以时间序列输入至ceil中,重塑后的结构为[simple.28.128],(其中simple是进入的数据个数,28是时间序列,128是数据根据权重计算出来的新维度)。
  • init_state中,需要对batch_size进行初始化,目的是为每张图片增添一个可传递的记忆状态。(每张图片分28步进行,RNN根据之前的记忆与当前的输入进行分类或回归)
  • tf.nn.dynamic_rnn暂时理解为融合当前数据与记忆得出的结果。
    图片来源为https://www.zhihu.com/question/41949741?sort=created

7、网络编译

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=ys))
train_op = tf.train.AdamOptimizer(lr).minimize(cost)
  • 采用交叉熵损失计算方法与Adam优化器

8、参数初始化与网络训练

with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)
    for i in range(training_iters):
        batch_xs, batch_ys = mnist.train.next_batch(128)
        batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
        sess.run(train_op, feed_dict={xs: batch_xs, ys: batch_ys})

9、代码已上传本人github,其主要根据莫烦代码修改而成。

参考文献:

1、RNN输入输出详解
2、莫烦tensorflow教程

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2015-2021 高腾腾
  • Powered by Hexo Theme Ayer
  • PV: UV:

谢谢大爷

支付宝
微信