ML(四)——RNN實現MNIST的識別
一.說明
本文使用的程式碼來自網上的開源專案
二.什麼是RNN
三.程式碼實現MNIST的識別
首先,慣例讀入MNIST
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('MNIST_data',one_hot=True)
然後定義一些超參
HIDDEN_LAYER = 128 BATCH_SIZE = 128 INPUTS_NUM = 28 STEPS_NUM = 28 CLASS_NUM = 10 lr = 0.001
第一個:隱藏層神經元個數;
第二個:批次大小,每次傳入的圖片數量;
第三個:輸入,表示輸入資料單個序列單個時間維度上固有的長度 ,一張圖片的行是28;
第四個:步長,表示序列本身的長度,列為28的圖片對應的steps就等於28。
第五個:類別數,0~9所以10個;
最後:學習率
weights = { 'in':tf.Variable(tf.random_normal([INPUTS_NUM,HIDDEN_LAYER])),#28*128 'out':tf.Variable(tf.random_normal(([HIDDEN_LAYER,CLASS_NUM])))#128*10 } biases = { 'in':tf.Variable(tf.random_normal([HIDDEN_LAYER,])),#128 'out':tf.Variable(tf.random_normal(([CLASS_NUM,])))#10 }
由於,rnn中權值與偏置值均有兩種,方便呼叫所以用字典的形式定義
X = tf.reshape(X,[BATCH_SIZE*STEPS_NUM,INPUTS_NUM])#128*28 28 X_in = tf.matmul(X,weights['in'])+biases['in']#128*28 128 X_in = tf.reshape(X_in,[-1,STEPS_NUM,HIDDEN_LAYER])#_ 28 128 cell = tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_LAYER,forget_bias=1.0,state_is_tuple=True) #遺忘偏置值是1表示全不遺忘,0表示全遺忘 _init_state = cell.zero_state(BATCH_SIZE,tf.float32) #通過zero_state得到一個全0的初始狀態,形狀為(batch_size, state_size),這裡的state_size等於隱層神經元的數目 output,states = tf.nn.dynamic_rnn(cell,X_in,initial_state=_init_state,time_major=False) result = tf.matmul(states[1],weights['out'])+biases['out']
這就是我們定義的RNN,其中使用的是lstm;
在使用RNN時,比較重要的一點就是我們時刻要記住我們的輸入輸出形狀,每一步的形狀我基本已在程式碼後標註出來
在傳入rnn時,我們需要將圖片轉成128*28,28的形狀,在傳入cell時,要將它轉成三維的形狀
這裡就比較難理解了,RNN難理解的點也就在這——輸入與輸出
首先,要先了解什麼是“RNNCell”,它可以說是RNN的基本單元、RNN的必備單元、一個神經網路是不是RNN的重要識別標誌(這麼說可能比較片面),每個RNNCell都有一個call方法,使用方式是:output, states = call(input, state)。
舉個栗子,假設我們有一個初始狀態h0,還有輸入x1,呼叫call(x1, h0)後就可以得到(output1, h1): 再呼叫一次call(x2, h1)就可以得到(output2, h2): 也就是說,每呼叫一次RNNCell的call方法,就相當於在時間上“推進了一步”。
state_size是隱層的大小,output_size是輸出的大小,比如我們將一個batch送入模型計算,設輸入資料的形狀為(batch_size, input_size),那麼計算時得到的隱層狀態就是(batch_size, state_size),輸出就是(batch_size, output_size)。
最後我們呼叫tf.nn.dynamic_rnn一次執行多步,output的形狀為(batch_size, time_steps, cell.output_size)。states是最後一步的隱狀態,它的形狀為(batch_size, cell.state_size)
最後,我將RNN中每一步的形狀,寫出來,如果你還是理解不了,請原諒我的笨,我實在不知道還能怎麼解釋了,
x: 128*28 28
x_in: 128*28 128
x_in: 128 28 128
output: 128 28 128
states : 128 128
result : 128 10
pred = Rnn(x,weights,biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred,labels= y))
train = tf.train.AdamOptimizer(lr).minimize(cost)
correct = tf.equal(tf.argmax(pred,1),tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct,dtype=tf.float32))
之後就是訓練與計算準確率
batch_xs,batch_ys = mnist.train.next_batch(BATCH_SIZE)
batch_xs = batch_xs.reshape([BATCH_SIZE,STEPS_NUM,INPUTS_NUM])
sess.run(train,feed_dict={x:batch_xs,y:batch_ys})
if step%100 == 0:
print(sess.run(accuracy,feed_dict={x:batch_xs,y:batch_ys}))
流程與程式碼在這了,希望對你有幫助
RNN是真的難理解,寫著寫著我自己都開始暈了 =。=!!!