tensorflow學習之(十一)RNN+LSTM神經網絡的構造


#RNN 循環神經網絡
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
tf.set_random_seed(1)   # set random seed

# 導入數據
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)

# hyperparameters
lr = 0.001                  # learning rate
training_iters = 1000000     # train step 上限 循環次數
batch_size = 128
n_inputs = 28               # MNIST data input (img shape: 28*28) 指圖片一行有28個像素,RNN每次提取一行
n_steps = 28                # time steps 指圖片有28行,所以RNN需要提取28次
n_hidden_units = 128        # neurons in hidden layer
n_classes = 10              # MNIST classes (0-9 digits)

# x y placeholder
x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_classes])

# 對 weights biases 初始值的定義
weights = {
    # shape (28, 128)
    'in': tf.Variable(tf.random_normal([n_inputs, n_hidden_units])),
    # shape (128, 10)
    'out': tf.Variable(tf.random_normal([n_hidden_units, n_classes]))
}
biases = {
    # shape (128, )
    'in': tf.Variable(tf.constant(0.1, shape=[n_hidden_units, ])),
    # shape (10, )
    'out': tf.Variable(tf.constant(0.1, shape=[n_classes, ]))
}

def RNN(X, weights, biases):
    #hidden layer for input to cell
    ##############################
    #X(128batch,28steps,28inputs) ==>(128*28,28inputs)
    X = tf.reshape(X,[-1,n_inputs])
    #X_in ==> (128batch * 28steps,128hidden)
    X_in = tf.matmul(X,weights['in'])+biases['in']
    # X_in ==> (128batch , 28steps,128hidden)
    X_in = tf.reshape(X_in,[-1,n_steps,n_hidden_units])


    #cell
    #############################
    lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_units, forget_bias=1.0,state_is_tuple=True)
    # forget_bias=1.0不忘記任何的輸入
    # lstm cell is divided into two parts(c_state,m_state) c_state為主線,m_state為分線
    # (可以理解為c_state為之前一直留下來的記憶,m_state為當前產生的記憶)

    _init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
    # 初始化全零 state _init_state會生成一個元組(c_state,m_state)
    # rnn計算時會保留每一步的計算結果在state中,就是lstm的記憶

    outputs, final_state = tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=_init_state,time_major=False)
    # time_major=False 因為28steps在第二個維度(128batch , 28steps,128hidden),若在第一個維度(28steps,128batch,128hidden),time_major=True
    # final_state是最后的state,而outputs是每一步的結果
    # X_in 為輸入層傳過來的值[128,28,128]

    '''
    BasicLSTMCell代表每一個lstm單元(即每個時刻的處理單元)
    第一個參數代表單個lstm單元中隱藏層的大小
    因為每個時刻的輸入也是一個向量,所以lstm隱藏層單元不是只有一個。
    lstm中處理的全部都是向量,沒有單獨的數字
    '''

    '''
    tf.nn.dynamic_rnn(
        cell,
        inputs,
        sequence_length=None,
        initial_state=None,
        dtype=None,
        parallel_iterations=None,
        swap_memory=False,
        time_major=False,
        scope=None
    )
    參數說明:tf.nn.dynamic_rnn(lstm_cell, X_in, initial_state=init_state, time_major=False)
    cell:RNNCell 實例。
    inputs:RNN輸入。如果time_major==False(默認),必須要是形如[batch_size,max_time]的張量,或者這些元素的嵌套元組。 
        如果time_major == True,必須是形如[max_time, batch_size, ...]的張量,  或者這些元素的嵌套元組. 
        這也可能是一個滿足這個屬性的(可能嵌套的)張量元組. 前兩個維度必須匹配所有輸入,否則排名和其他形狀組件可能會有所不同. 
        在這種情況下,每個時間步的單元輸入將復制這些元組的結構,除了時間維(從中獲取時間)。 
        在每個時間步的單元格輸入將是張量或(可能嵌套的)張量元組,每個張量元素的尺寸為[batch_size,...]。
    sequence_length:(可選)一個int32 / int64向量,大小為[batch_size]。 用於在批量元素的序列長度超過時復制通過狀態和零輸出輸出。所以它比正確性更重要。
    initial_state:(可選)RNN的初始狀態。 如果cell.state_size是一個整數,則它必須是形如 [batch_size,cell.state_size]的張量。
        如果cell.state_size是一個元組,它應該是一個在cell.state_size中具有形狀[batch_size,s]的張量元組。
    dtype:(可選)初始狀態和預期輸出的數據類型。 如果未提供initial_state或RNN狀態具有異構dtype,則為必需。
    parallel_iterations:(默認:32)。 並行運行的迭代次數。 那些沒有任何時間依賴性並且可以並行運行的操作將會是。
        此參數為空間換取時間。 值>> 1使用更多的內存,但花費的時間更少,而更小的值使用更少的內存,但計算需要更長的時間。
    swap_memory:透明地交換前向推理中產生的張量,但是需要GPU支持back prop。 
        這允許對通常不適合單個GPU的RNN進行訓練,並且性能損失非常小(或沒有)。
    time_major:輸入和輸出張量的形狀格式,如果time_major == True,則這些張量必須為[max_time,batch_size,depth]。
        如果為false,則這些張量必須為[batch_size,max_time,depth]。 使用time_major = True可以提高效率,因為它避免了RNN計算開始和結束時的轉置。 但是,大多數TensorFlow數據都是批處理主數據,所以默認情況下,此功能接受輸入並以批處理主要形式發出輸出。
    scope:用於創建子圖的VariableScope; 默認為“rnn”。
    返回值:
    output:RNN輸出張量。如果time_major == False (default),輸出張量形如[batch_size, max_time, cell.output_size]。
    ast_states是由(c,h)組成的tuple,均為[batch,列數]。
    '''
    #hidden layer for output as the final results 輸出隱藏層
    ##############################################
    #第一種計算results的方法
    #使用final_state[1]的原因,final_state包含兩個state(c_state,m_state),final_state[1]為分線劇情的結果
    #results = tf.matmul(final_state[1], weights['out']) + biases['out'] #final_state[1]指分線(m_state)的結果=outputs[-1]

    #第二種計算results的方法 把 outputs 變成 列表 [(batch, outputs)..] * steps
    outputs = tf.unstack(tf.transpose(outputs, [1, 0, 2]))
    results = tf.matmul(outputs[-1], weights['out']) + biases['out']  # 選取最后一個 output,為分類結果

    return results

pred = RNN(x, weights, biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=pred))
train_op = tf.train.AdamOptimizer(lr).minimize(cost)

correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

# init= tf.initialize_all_variables() # tf 馬上就要廢棄這種寫法
# 替換成下面的寫法:
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    step = 0
    while step * batch_size < training_iters:
        batch_xs, batch_ys = mnist.train.next_batch(batch_size)
        batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
        sess.run([train_op], feed_dict={
            x: batch_xs,
            y: batch_ys,
        })
        if step % 20 == 0:
            print(sess.run(accuracy, feed_dict={
            x: batch_xs,
            y: batch_ys,
        }))
        step += 1

 


免責聲明!

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



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