1. 程式人生 > >簡單的RNN和BP多層網路之間的區別

簡單的RNN和BP多層網路之間的區別

先來個簡單的多層網路

RNN的原理和出現的原因,解決什麼場景的什麼問題

關於RNN出現的原因,RNN詳細的原理,已經有很多博文講解的非常棒了。
如下:


http://ai.51cto.com/art/201711/559441.htm


更多的例子可以百度瞭解

為什麼我寫這篇部落格

主要是我從自己學習理解RNN的時候,開始有一些困難,書上講的也是模模糊糊的,原理講解的很多,但是程式碼的關鍵點描述不太清楚,自己反覆揣測以後,終於有了一些理解,記錄下來,一方面記錄自己的成長過程,另外一方面可以讓跟我一樣有疑惑的同學可以少走彎路,當然也有可能是錯路。

多層網路
x = tf.placeholder(tf.float32,[None,256])
y = tf.placeholder(tf.float32,[None,10])

w1 = tf.Variable(tf.random_normal([256,1024]))
b1 = tf.Variable(tf.zeros([1024]))

x1 = tf.nn.relu(tf.multiply(w1,x)+b1)

w2 = tf.Variable(tf.random_normal(1024,10))
b2 = tf.Variable(tf.zeros([10]))
pred = tf.nn.softmax(tf.multiply(w2,x1)+b2)
loss = -tf.reduce_sum(pred*tf.log(y))
op = tf.train.GradientDescentOptimizer(0.001).minimize(loss)

在寫個簡單的RNN網路

import tensorflow as tf

# RNN
batch_size = 5
truncated_series_length = 50000
state_size = 4

x = tf.placeholder(tf.float32,[batch_size,truncated_series_length])
y = tf.placeholder(tf.float32,[batch_size,truncated_series_length])

'''
最關鍵的點,好多書上沒寫的,就是這個引數,是參與迴圈的引數
BP網路中沒有這個引數
'''
init_state = tf.placeholder(tf.float32,[batch_size,state_size])

# 把X,Y拆開,我的理解是為了方便看得到迴圈的時候State是如何參與迴圈的
xs = tf.unstack(x,axis=1)
ys = tf.unstack(y,axis=1)
current_state = init_state

for currentx,currenty in zip(xs,ys):
    
    w1 = tf.Variable(tf.random_normal([truncated_series_length+ state_size,truncated_series_length]))
    b1 = tf.Variable(tf.zeros([truncated_series_length]))
    #這個就是和BP的區別,把迴圈連結起來
    concatedx = tf.concat(xs,current_state)
    y1 = tf.nn.tanh(tf.multiply(w1,x) + b1)

    #區別
    current_state = y1
    #註釋掉這一層,讓看上去更容易理解為什麼叫做迴圈網路
    #w2= tf.Variable(tf.random_normal([truncated_series_length,truncated_series_length]))
    #b2 = tf.Variable(tf.zeros([truncated_series_length]))
    #y2 = tf.multiply(w2,y1)+b2

    loss = -tf.reduce_sum(y1*tf.log(currenty))

個人感覺兩個的主要區別在於BP網路中每個引數每一步都是獨立的,和下一個樣本之間不相互依賴,而RNN有一個引數參與迴圈。另外RNN的一些引數的設定,我還不是太熟悉,還有待於深入。另外很多書上講解Rnn用的是tf.contrib.layers或tf.contrib.cnn的類庫去描繪,不是太利於理解底層的東西。所以我選擇了用這種寫法去表述。不對之處請多多指教。