tensorflow RNN循環神經網絡 (分類例子)-【老魚學tensorflow】


之前我們學習過用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

定義好了 RNN 主體結構后, 我們就可以來計算 cost 和 train_op:

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)

訓練時, 不斷輸出 accuracy, 觀看結果:

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

最終 accuracy 的結果如下:

E:\Python\Python36\python.exe E:/learn/numpy/lesson3/main.py
Extracting MNIST_data\train-images-idx3-ubyte.gz
Extracting MNIST_data\train-labels-idx1-ubyte.gz
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
2018-02-20 20:30:52.769108: I C:\tf_jenkins\home\workspace\rel-win\M\windows\PY\36\tensorflow\core\platform\cpu_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
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM