RNN靜態與動態


靜態、多層RNN:

import
numpy as np import tensorflow as tf # 導入 MINST 數據集 from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("/data/", one_hot=True) #網絡模型參數 n_input = 28 # MNIST data 輸入 (img shape: 28*28) n_steps = 28 # timesteps n_hidden = 128 # hidden layer num of features n_classes = 10 # MNIST 列別 (0-9 ,一共10類) #訓練參數 batch_size = 128 learning_rate = 0.001 training_iters = 10000 display_step = 10 # tf Graph input x = tf.placeholder("float", [None, n_steps, n_input]) y = tf.placeholder("float", [None, n_classes]) #構建網絡 stacked_rnn = [] for _ in range(3): stacked_rnn.append(tf.contrib.rnn.LSTMCell(n_hidden)) mcell = tf.contrib.rnn.MultiRNNCell(stacked_rnn) x1=tf.unstack(x,n_steps,1)#在axis=1進行解包分解。 outputs, states = tf.contrib.rnn.static_rnn(mcell, x1, dtype=tf.float32)#inputs must be a sequence
#最后一層全連接 outputs[-1] pred = tf.contrib.layers.fully_connected(outputs[-1],n_classes,activation_fn = None) # Define loss and optimizer cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) # Evaluate model correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1)) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) # 啟動session with tf.Session() as sess: sess.run(tf.global_variables_initializer()) step = 1 # Keep training until reach max iterations while step * batch_size < training_iters: batch_x, batch_y = mnist.train.next_batch(batch_size) # Reshape data to get 28 seq of 28 elements batch_x = batch_x.reshape((batch_size, n_steps, n_input)) # Run optimization op (backprop) sess.run(optimizer, feed_dict={x: batch_x, y: batch_y}) if step % display_step == 0: # 計算批次數據的准確率 acc = sess.run(accuracy, feed_dict={x: batch_x, y: batch_y}) # Calculate batch loss loss = sess.run(cost, feed_dict={x: batch_x, y: batch_y}) print ("Iter " + str(step*batch_size) + ", Minibatch Loss= " + \ "{:.6f}".format(loss) + ", Training Accuracy= " + \ "{:.5f}".format(acc)) step += 1 print (" Finished!")
# 計算准確率 for 128 mnist test images test_len = 100 test_data = mnist.test.images[:test_len].reshape((-1, n_steps, n_input)) test_label = mnist.test.labels[:test_len] print ("Testing Accuracy:", sess.run(accuracy, feed_dict={x: test_data, y: test_label}))

 

在學習RNN這一章的時候,遇到static_rnn中輸入數據 x 的格式:

[None, n_steps, n_input] 進行變換→ x1=tf.unstack(x,n_steps,1)

之后再傳入:outputs, states = tf.contrib.rnn.static_rnn(mcell, x1, dtype=tf.float32)

很難理解,為什么要這樣做,數據又進行了怎樣的變換。

 


以下,為stack和unstack的詳細舉例:

  • tf.stack(values, axis=0, name=’stack’)
    以指定的軸axis,將一個維度為R的張量數組轉變成一個維度為R+1的張量。即將一組張量以指定的軸,提高一個維度。

假設要轉變的張量數組values的長度為N,其中的每個張量的形狀為(A, B, C)。
如果軸axis=0,則轉變后的張量的形狀為(N, A, B, C)。
如果軸axis=1,則轉變后的張量的形狀為(A, N, B, C)。
如果軸axis=2,則轉變后的張量的形狀為(A, B, N, C)。其它情況依次類推。

舉例如下:
‘x’ is [1, 4], 形狀是(2),維度為1
‘y’ is [2, 5], 形狀是(2),維度為1
‘z’ is [3, 6], 形狀是(2),維度為1
stack([x, y, z]) => [[1, 4], [2, 5], [3, 6]] # axis的值默認為0。輸出的形狀為(3, 2)
stack([x, y, z], axis=1) => [[1, 2, 3], [4, 5, 6]] # axis的值為1。輸出的形狀為(2, 3)

‘x’ is [[1,1,1,1],[2,2,2,2],[3,3,3,3]],形狀是(3,4),維度為2
‘y’ is [[4,4,4,4],[5,5,5,5],[6,6,6,6]],形狀是(3,4),維度為2
stack([x,y]) => [[[1,1,1,1],[2,2,2,2],[3,3,3,3]], [[4,4,4,4],[5,5,5,5],[6,6,6,6]]] # axis的值默認為0。輸出的形狀為(2, 3, 4)
stack([x,y],axis=1) => [[[1,1,1,1],[4,4,4,4]],[[2,2,2,2],[5,5,5,5]],[[3,3,3,3],[6,6,6,6]]] # axis的值為1。輸出的形狀為(3, 2, 4)
stack([x,y],axis=2) => [[[1,4],[1,4],[1,4],[1,4]],[[2,5],[2,5],[2,5],[2,5]],[[3,6],[3,6],[3,6],[3,6]]]# axis的值為2。輸出的形狀為(3, 4, 2)

axis可這樣理解:stack就是要將一組相同形狀的張量提高一個維度。axis就是這些張量里,將axis指定的維度用所有這些張量數組代替。如axis=2,表示指定在第2個維度,原來的元素用整個張量數組里的元素代替,即從(A, B, C)轉變為(A, B, N, C)

參數:
values: 一個有相同形狀與數據類型的張量數組。
axis: 以軸axis為中心來轉變的整數。默認是第一個維度即axis=0。支持負數。取值范圍為[-(R+1), R+1)
name: 這個操作的名字(可選)
返回:被提高一個維度后的張量
異常: ValueError: 如果軸axis超出范圍[-(R+1), R+1).


  • tf.unstack()

tf.unstack(value, num=None, axis=0, name=’unstack’)
以指定的軸axis,將一個維度為R的張量數組轉變成一個維度為R-1的張量。即將一組張量以指定的軸,減少一個維度。正好和stack()相反。

將張量value分割成num個張量數組。如果num沒有指定,則是根據張量value的形狀來指定。如果value.shape[axis]不存在,則拋出ValueError的異常。

 

假如一個張量的形狀是(A, B, C, D)。
如果axis == 0,則輸出的張量是value[i, :, :, :],i取值為[0,A),每個輸出的張量的形狀為(B,C,D)。
如果axis == 1,則輸出的張量是value[:, i, :, :],i取值為[0,B),每個輸出的張量的形狀為(A,C,D)。
如果axis == 2,則輸出的張量是value[:, :, i, :],i取值為[0,C),每個輸出的張量的形狀為(A,B,D)。依次類推。

舉例如下:
‘x’ is [[1,1,1,1],[2,2,2,2],[3,3,3,3]] # 形狀是(3,4),維度為2
unstack(x,axis=0) =>以指定的維度0為軸,轉變成3個形狀為(4)張量[1,1,1,1],[2,2,2,2],[3,3,3,3]
unstack(x,axis=1) =>以指定的維度1為軸,轉變成4個形狀為(3)張量[1,2,3],[1,2,3],[1,2,4],[1,2,3]

axis可這樣理解:unstack就是要將一個張量降低為低一個維度的張量數組。axis就是將axis指定的維度,用所有這個張量里同維度的數據代替。

參數:
value: 一個將要被降維的維度大於0的張量。
num: 整數。指定的維度axis的長度。如果設置為None(默認值),將自動求值。
axis: 整數.以軸axis指定的維度來轉變 默認是第一個維度即axis=0。支持負數。取值范圍為[-R, R)
name: 這個操作的名字(可選)
返回:
從張量value降維后的張量數組。
異常:
ValueError: 如果num沒有指定並且無法求出來。
ValueError: 如果axis超出范圍 [-R, R)。


經過下面的例子理解后,上面的1對應axis=1, nsteps對應函數中的num參數,表示axis=1的長度。該操作將數據 x 按照序列數目切開。我們傳入的 x 是個3維tensor,將其按照序列數切開,得到了n_steps個 二維的tensor, [batchsize, n_input]


免責聲明!

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



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