1. 程式人生 > >ML(四)——RNN實現MNIST的識別

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是真的難理解,寫著寫著我自己都開始暈了  =。=!!!

注:本文原創,轉載請註明出處!