手把手教你用Tensorflow搭建RNN

自從跟導(dǎo)師吹了波牛之后,開始將自己的研究重心轉(zhuǎn)為NLP方向。那么RNN就成了必須要了解的一個(gè)DL模型(導(dǎo)師暑假去了趟西安,學(xué)習(xí)一波DL,回來神神叨叨地說CNN到瓶頸期了,別瞎折騰了)。對(duì)于RNN,我就默認(rèn)大家都懂得其中的原理,有不明白的可以去看NG 的視頻教學(xué):https://mooc.study.163.com/smartSpec/detail/1001319001.htm。話不多說,開搞開搞?。?!


Step1 搭建環(huán)境

系統(tǒng):Windows7+TensorFlow1.9.0(cpu)+Python3.6


Step2 加載數(shù)據(jù)集

MNIST是一個(gè)手寫數(shù)字?jǐn)?shù)據(jù)庫(kù),它有55000個(gè)訓(xùn)練樣本集和10000個(gè)測(cè)試樣本集。它是MNIST數(shù)據(jù)庫(kù)的一個(gè)子集。其中每張圖片固定大小為28×28的黑白圖片。如下圖所示:

MNIST數(shù)據(jù)集

使用Tensorflow加載內(nèi)置的MNIST數(shù)據(jù)集,具體方法展示如下。

加載方法

加載完成后,打印訓(xùn)練樣本數(shù)(ntrain),測(cè)試樣本數(shù)(ntest),樣本 總維度(dim)以及分類數(shù)(nlasses)

打印結(jié)果

Step3 RNN模型

接下來我們就需要去看看,我們所要搭建的RNN模型到底長(zhǎng)啥樣。

這是從NG那邊搞來的圖,相信大家都能明白其中的奧秘吧。但當(dāng)時(shí)我在學(xué)的時(shí)候很困惑,這東西實(shí)際中咋用,搞成這副鬼樣子,真有那么神?em...下面這張圖就是利用MNIST數(shù)據(jù)集來做的一個(gè)實(shí)驗(yàn)。

簡(jiǎn)單敘述下該模型的建立過程,每一個(gè)樣本都可以看出是一個(gè)[28,28]的矩陣,那么將矩陣的每一行作為一個(gè)輸入向量,大小為[1,28],那么整個(gè)模型就擁有28個(gè)輸入神經(jīng)元,這28個(gè)神經(jīng)元我們將其統(tǒng)稱為輸入層。完成后我再輸入層與RNN層之間增加一個(gè)含有128個(gè)神經(jīng)元的隱藏層,用于對(duì)輸入層進(jìn)行特征 提取,形成一個(gè)[1,128]的向量傳入RNN中。RNN中的內(nèi)部構(gòu)造參見LSTM,形成兩個(gè)向量分別為L(zhǎng)STM_O,LSTM_S,大小都為[1,128]。其中LSTM_O為RNN模型的輸出,LSTM_S為RNN模型的內(nèi)部記憶向量,傳遞到下一個(gè)RNN神經(jīng)元。最后對(duì)LSTM_O進(jìn)行Softmax處理,通過概率分析出該樣本的類別。

接下來我們對(duì)模型中所涉及的權(quán)重、偏置以及各層神經(jīng)元數(shù)量的設(shè)置。其中W["h1"]為輸入層到隱藏層的權(quán)重,大小為[28,128],W["h2"]為隱藏層到RNN的權(quán)重,大小為[128,10]。b["b1"]與b["b2"]同理。

權(quán)重、偏置

Step4 創(chuàng)建RNN模型(關(guān)鍵步驟)

創(chuàng)建RNN

42~43行:對(duì)輸入數(shù)據(jù)進(jìn)行預(yù)處理操作。這里涉及到batch_size的問題,在訓(xùn)練時(shí)我們通常是將一批數(shù)據(jù)導(dǎo)入模型來提高模型的效率,那么批次的大小就是batch_size。即我們可以理解為我們是將一個(gè)batch_size*28*28的三維矩陣導(dǎo)入了我們的RNN模型,那么我們就要對(duì)該矩陣進(jìn)行變換從而滿足我們[None,28]的要求。

44~45行:隱藏層處理好輸入數(shù)據(jù)后形成一個(gè)[None,128]的矩陣。然后對(duì)該矩陣進(jìn)行切割,我們的RNN一共有28個(gè)輸入單元,那就切成28個(gè)咯。

46~50行:將切好的矩陣依次傳入RNN中。接下來是對(duì)RNN內(nèi)部的設(shè)置,這邊使用的是LSTM(tf.nn.rnn_cell.BasicLSTMCell()),當(dāng)然tf.nn也為我們實(shí)現(xiàn)好了其他的內(nèi)部設(shè)置方便我們調(diào)用。


Step5 超參數(shù)的定義(損,優(yōu),學(xué),準(zhǔn),初)

該步驟定義模型中我們所需要的一些超參數(shù)。Tensorflow擁有現(xiàn)成的方法,方便我們調(diào)用。

學(xué)習(xí)率:leraning_rate

損失:cost

優(yōu)化方法:optm

參數(shù)初始化:init

超參數(shù)的定義

Step6 訓(xùn)練測(cè)試

最后一步,設(shè)置好迭代次數(shù)(training_epoch)、批次大?。╞atch_size)等后,將MNIST的數(shù)據(jù)集加載到Step5中設(shè)置好的X、Y中,完成訓(xùn)練測(cè)試。沒什么好多說的,我每個(gè)模型最后的訓(xùn)練測(cè)試都這樣,照著寫吧。

訓(xùn)練測(cè)試

Step7 結(jié)果展示

總共迭代了5次,電腦跑太慢了...

準(zhǔn)確率達(dá)到93.9%,還彳亍 口 巴!

結(jié)果

附上所有代碼:

import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data

from tensorflow.contrib import rnn

# 加載數(shù)據(jù)

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

trainimgs, trainlabels, testimgs, testlabels \

= mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels

ntrain, ntest, dim, nclasses\

=trainimgs.shape[0],testimgs.shape[0],trainimgs.shape[1],trainlabels.shape[1]

#print(ntrain, ntest, dim, nclasses)

print ("MNIST loaded")

#設(shè)置參數(shù),權(quán)重,偏置

diminput = 28

dimhidden = 128

dimoutput = nclasses

nsteps = 28

W = {"h1" : tf.Variable(tf.random_normal([diminput,dimhidden])),

? ? "h2" : tf.Variable(tf.random_normal([dimhidden,dimoutput]))}

b = {"b1" : tf.Variable(tf.random_normal([dimhidden])),

? ? "b2" : tf.Variable(tf.random_normal([dimoutput]))}

# 創(chuàng)建模型

def RNN(X,W,b,nsteps):

? ? X = tf.transpose(X,[1,0,2])

? ? X = tf.reshape(X,[-1,diminput])

? ? H_1 = tf.matmul(X,W["h1"])+b["b1"]

? ? H_1 = tf.split(H_1,nsteps,0)

? ? lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(dimhidden,forget_bias=1.0)

? ? LSTM_O,LSTM_S = rnn.static_rnn(lstm_cell,H_1,dtype=tf.float32)

? ? O = tf.matmul(LSTM_O[-1],W["h2"])+b["b2"]

? ? return {"X":X,"H_1":H_1,"LSTM_O":LSTM_O,"LSTM_S":LSTM_S,"O":O}?

print ("Network ready")

# 設(shè)置損失,優(yōu)化,學(xué)習(xí)率,準(zhǔn)確率,參數(shù)初始化

learning_rate = 0.001

x? ? ? = tf.placeholder("float", [None, nsteps, diminput])

y? ? ? = tf.placeholder("float", [None, dimoutput])

myrnn? = RNN(x, W, b, nsteps)

pred? = myrnn['O']

cost? = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=pred))

optm? = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)

accr? = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred,1), tf.argmax(y,1)), tf.float32))

init? = tf.global_variables_initializer()

print ("Network Ready!")

# 訓(xùn)練,測(cè)試

#所有樣本迭代(epoch)5次

training_epochs = 5

#每進(jìn)行一次迭代選擇的樣本數(shù)

batch_size? ? ? = 16

#展示

display_step? ? = 1

sess = tf.Session()

sess.run(init)

print ("Start optimization")

for epoch in range(training_epochs):

? ? avg_cost = 0.

? ? total_batch = int(mnist.train.num_examples/batch_size)

? ? #total_batch = 100

? ? # Loop over all batches

? ? for i in range(total_batch):

? ? ? ? batch_xs, batch_ys = mnist.train.next_batch(batch_size)

? ? ? ? batch_xs = batch_xs.reshape((batch_size, nsteps, diminput))

? ? ? ? # Fit training using batch data

? ? ? ? feeds = {x: batch_xs, y: batch_ys}

? ? ? ? sess.run(optm, feed_dict=feeds)

? ? ? ? # Compute average loss

? ? ? ? avg_cost += sess.run(cost, feed_dict=feeds)/total_batch

? ? # Display logs per epoch step

? ? if epoch % display_step == 0:

? ? ? ? print ("Epoch: %03d/%03d cost: %.9f" % (epoch, training_epochs, avg_cost))

? ? ? ? feeds = {x: batch_xs, y: batch_ys}

? ? ? ? train_acc = sess.run(accr, feed_dict=feeds)

? ? ? ? print (" Training accuracy: %.3f" % (train_acc))

? ? ? ? testimgs = testimgs.reshape((ntest, nsteps, diminput))

? ? ? ? feeds = {x: testimgs, y: testlabels}

? ? ? ? test_acc = sess.run(accr, feed_dict=feeds)

? ? ? ? print (" Test accuracy: %.3f" % (test_acc))

print ("Optimization Finished.")

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容