tensorflow RNN循环神经网络 (分类例子)

在我们学习使用CNN(卷积神经网络)识别手写文字之前,在CNN中,图片被视为一个二维矩阵,然后将高度值堆叠在二维矩阵中进行识别.

在RNN中加入了时间维度,因为我们会发现一些图片或者语言或者声音会在时间轴上慢慢扩展,这有点类似于我们大脑识别事物时的相关短时记忆.

这次我们使用 RNN 来识别手写数字。

首先导入数据,定义各种RNN的参数:

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 导入数据
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# RNN各种参数定义
lr = 0.001 #学习速率
training_iters = 100000 #循环次数
batch_size = 128
n_inputs = 28 #手写字的大小是28*28,这里是手写字中的每行28列的数值
n_steps = 28 #这里是手写字中28行的数据,因为以一行一行像素值处理的话,正好是28行
n_hidden_units = 128 #假设隐藏单元有128个
n_classes = 10 #因为我们的手写字是0-9,因此最后要分成10个类

然后定义每个权重的输入、输出和形状:

# 定义输入和输出的placeholder
x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_classes])
# 对weights和biases初始值定义
weights = {
    # shape(28, 128)
    'in': tf.Variable(tf.random_normal([n_inputs, n_hidden_units])),
    # shape(128 , 10)
    'out': tf.Variable(tf.random_normal([n_hidden_units, n_classes]))
}
biases = {
    # shape(128, )
    'in':tf.Variable(tf.constant(0.1, shape=[n_hidden_units, ])),
    # shape(10, )
    'out':tf.Variable(tf.constant(0.1, shape=[n_classes, ]))
}

定义RNN的主要结构

最重要的是定义RNN的主要结构。

def RNN(X, weights, biases):
    # X在输入时是一批128个,每批中有28行,28列,因此其shape为(128, 28, 28)。为了能够进行 weights 的矩阵乘法,我们需要把输入数据转换成二维的数据(128*28, 28)
    X = tf.reshape(X, [-1, n_inputs])
    # 对输入数据根据权重和偏置进行计算, 其shape为(128batch * 28steps, 128 hidden)
    X_in = tf.matmul(X, weights['in']) + biases['in']
    # 矩阵计算完成之后,又要转换成3维的数据结构了,(128batch, 28steps, 128 hidden)
    X_in = tf.reshape(X_in, [-1, n_steps, n_hidden_units])
    # cell,使用LSTM,其中state_is_tuple用来指示相关的state是否是一个元组结构的,如果是元组结构的话,会在state中包含主线状态和分线状态
    lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_units, forget_bias=1.0, state_is_tuple=True)
    # 初始化全0state
    init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
    
    # 下面进行运算,我们使用dynamic rnn来进行运算。每一步的运算输出都会存储在outputs中,states中存储了主线状态和分线状态,因为我们前面指定了state_is_tuple=True
    # time_major用来指示关于时间序列的数据是否在输入数据中第一个维度中。在本例中,我们的时间序列数据位于第2维中,第一维的数据只是batch数据,因此要设置为False。
    outputs, states = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=init_state, time_major=False)
    
    # 计算结果,其中states[1]为分线state,也就是最后一个输出值
    results = tf.matmul(states[1], weights['out']) + biases['out']
    return results

训练循环神经网络

定义RNN的主要结构后,我们可以计算成本和:

pred = RNN(x, weights, biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
train_op = tf.train.AdamOptimizer(lr).minimize(cost)

训练时,不断输出,观察结果:

correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    step = 0
    while step*batch_size < training_iters:
        batch_xs,batch_ys = mnist.train.next_batch(batch_size)
        batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
        sess.run([train_op], feed_dict={x:batch_xs, y:batch_ys})
        if step % 20 == 0:
            print(sess.run(accuracy, feed_dict={x:batch_xs, y:batch_ys}))
        step += 1

最终结果如下:

E:PythonPython36python.exe E:/learn/numpy/lesson3/main.py
Extracting MNIST_datatrain-images-idx3-ubyte.gz
Extracting MNIST_datatrain-labels-idx1-ubyte.gz
Extracting MNIST_datat10k-images-idx3-ubyte.gz
Extracting MNIST_datat10k-labels-idx1-ubyte.gz
2018-02-20 20:30:52.769108: I C:tf_jenkinshomeworkspacerel-winMwindowsPY36tensorflowcoreplatformcpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX
0.09375
0.710938
0.8125
0.789063
0.820313
0.882813
0.828125
0.867188
0.921875
0.90625
0.921875
0.890625
0.898438
0.945313
0.914063
0.945313
0.929688
0.96875
0.96875
0.929688
0.953125
0.945313
0.960938
0.992188
0.953125
0.9375
0.929688
0.96875
0.960938
0.945313

完整代码

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# 导入数据
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# RNN各种参数定义
lr = 0.001 #学习速率
training_iters = 100000 #循环次数
batch_size = 128
n_inputs = 28 #手写字的大小是28*28,这里是手写字中的每行28列的数值
n_steps = 28 #这里是手写字中28行的数据,因为以一行一行像素值处理的话,正好是28行
n_hidden_units = 128 #假设隐藏单元有128个
n_classes = 10 #因为我们的手写字是0-9,因此最后要分成10个类
# 定义输入和输出的placeholder
x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_classes])
# 对weights和biases初始值定义
weights = {
    # shape(28, 128)
    'in': tf.Variable(tf.random_normal([n_inputs, n_hidden_units])),
    # shape(128 , 10)
    'out': tf.Variable(tf.random_normal([n_hidden_units, n_classes]))
}
biases = {
    # shape(128, )
    'in':tf.Variable(tf.constant(0.1, shape=[n_hidden_units, ])),
    # shape(10, )
    'out':tf.Variable(tf.constant(0.1, shape=[n_classes, ]))
}
def RNN(X, weights, biases):
    # X在输入时是一批128个,每批中有28行,28列,因此其shape为(128, 28, 28)。为了能够进行 weights 的矩阵乘法,我们需要把输入数据转换成二维的数据(128*28, 28)
    X = tf.reshape(X, [-1, n_inputs])
    # 对输入数据根据权重和偏置进行计算, 其shape为(128batch * 28steps, 128 hidden)
    X_in = tf.matmul(X, weights['in']) + biases['in']
    # 矩阵计算完成之后,又要转换成3维的数据结构了,(128batch, 28steps, 128 hidden)
    X_in = tf.reshape(X_in, [-1, n_steps, n_hidden_units])
    # cell,使用LSTM,其中state_is_tuple用来指示相关的state是否是一个元组结构的,如果是元组结构的话,会在state中包含主线状态和分线状态
    lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_units, forget_bias=1.0, state_is_tuple=True)
    # 初始化全0state
    init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
    # 下面进行运算,我们使用dynamic rnn来进行运算。每一步的运算输出都会存储在outputs中,states中存储了主线状态和分线状态,因为我们前面指定了state_is_tuple=True
    # time_major用来指示关于时间序列的数据是否在输入数据中第一个维度中。在本例中,我们的时间序列数据位于第2维中,第一维的数据只是batch数据,因此要设置为False。
    outputs, states = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=init_state, time_major=False)
    # 计算结果,其中states[1]为分线state,也就是最后一个输出值
    results = tf.matmul(states[1], weights['out']) + biases['out']
    return results
pred = RNN(x, weights, biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
train_op = tf.train.AdamOptimizer(lr).minimize(cost)
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
init = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init)
    step = 0
    while step*batch_size < training_iters:
        batch_xs,batch_ys = mnist.train.next_batch(batch_size)
        batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
        sess.run([train_op], feed_dict={x:batch_xs, y:batch_ys})
        if step % 20 == 0:
            print(sess.run(accuracy, feed_dict={x:batch_xs, y:batch_ys}))
        step += 1
    

© 版权声明
THE END
喜欢就支持一下吧
点赞5赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容