深度學習之LSTM案例分析(一)

#背景知識

見《深度學習之tensorflow(六)》【https://blog.csdn.net/m0_37621024/article/details/88680580

 

#《深度學習之tensorflow(六)》中的代碼

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

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

#輸入圖片是28*28
n_inputs = 28 #輸入一行,一行有28個數據
max_time = 28 #一共28行
lstm_size = 100 #隱層單元
n_classes = 10 #10個分類
batch_size = 50 #每批次50個樣本
n_batch = mnist.train.num_examples // batch_size #計算一共有多少個批次

#這裏的none表示第一個維度可以是任意的長度
x = tf.placeholder(tf.float32,[None,784]) '''784=28*28'''
#正確的標籤
y = tf.placeholder(tf.float32,[None,10])

#初始化權值
weights = tf.Variable(tf.truncated_normal([lstm_size,n_classes], stddev=0.1)) '''*1'''
#初始化偏置值
biases = tf.Variable(tf.constant(0.1, shape=[n_classes]))

#定義RNN網絡
def RNN(X,weights,biases):
    # inputs=[batch_size, max_time, n_inputs]
    inputs = tf.reshape(X,[-1,max_time,n_inputs]) '''*2'''
    #定義LSTM基本CELL
    lstm_cell = tf.contrib.rnn.BasicLSTMCell(lstm_size) '''*3'''
    # final_state[0]是cell_state
    # final_state[1]是hidden_state
    outputs,final_state = tf.nn.dynamic_rnn(lstm_cell,inputs,dtype=tf.float32) '''*4'''
    results = tf.nn.softmax(tf.matmul(final_state[1],weights) + biases) '''*5'''
    return results

#計算RNN的返回值
prediction = RNN(x, weights, biases)
#損失函數
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y))
#使用AdamOptimizer進行優化
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
#結果存放在一個布爾型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1)) #argmax返回一維張量中最大的值所在的位置
#求準確率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32)) #把correct_prediction變爲float32類型
#初始化
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(6): '''6次迭代'''
        for batch in range(n_batch): '''每一批次計算:'''
            batch_xs,batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
            
        acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
        print('Iter ' + str(epoch) + 'Testing Accuracy= ' + str(acc))

註釋:

*1:tf.truncated_normal函數

tf.truncated_normal(
    shape,
    mean=0.0,
    stddev=1.0,
    dtype=tf.float32,
    seed=None,
    name=None
)

從截斷的正態分佈中輸出隨機值. 

生成的值遵循具有指定平均值和標準偏差的正態分佈,不同之處在於其平均值大於 2 個標準差的值將被丟棄並重新選擇.

{ 函數參數:

  • shape:一維整數張量或 Python 數組,輸出張量的形狀.
  • mean:dtype 類型的 0-D 張量或 Python 值,截斷正態分佈的均值.
  • stddev:dtype 類型的 0-D 張量或 Python 值,截斷前正態分佈的標準偏差.
  • dtype:輸出的類型.
  • seed:一個 Python 整數.用於爲分發創建隨機種子.查看tf.set_random_seed行爲.
  • name:操作的名稱(可選).

函數返回值:

tf.truncated_normal函數返回指定形狀的張量填充隨機截斷的正常值. }

https://www.w3cschool.cn/tensorflow_python/tensorflow_python-fibz28ss.html

 

*2:tf.reshape函數

reshape(
    tensor,
    shape,
    name=None
)

{ 參數:

  • tensor:一個Tensor.
  • shape:一個Tensor;必須是以下類型之一:int32,int64;用於定義輸出張量的形狀.
  • name:操作的名稱(可選).

返回值:

該操作返回一個Tensor.與tensor具有相同的類型. }

例如:

# tensor 't' is [1, 2, 3, 4, 5, 6, 7, 8, 9]
# tensor 't' has shape [9]
reshape(t, [3, 3]) ==> [[1, 2, 3],
                        [4, 5, 6],
                        [7, 8, 9]]

# tensor 't' is [[[1, 1], [2, 2]],
#                [[3, 3], [4, 4]]]
# tensor 't' has shape [2, 2, 2]
reshape(t, [2, 4]) ==> [[1, 1, 2, 2],
                        [3, 3, 4, 4]]

# tensor 't' is [[[1, 1, 1],
#                 [2, 2, 2]],
#                [[3, 3, 3],
#                 [4, 4, 4]],
#                [[5, 5, 5],
#                 [6, 6, 6]]]
# tensor 't' has shape [3, 2, 3]
# pass '[-1]' to flatten 't'
reshape(t, [-1]) ==> [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6]

# -1 can also be used to infer the shape

# -1 is inferred to be 9:
reshape(t, [2, -1]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
                         [4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 2:
reshape(t, [-1, 9]) ==> [[1, 1, 1, 2, 2, 2, 3, 3, 3],
                         [4, 4, 4, 5, 5, 5, 6, 6, 6]]
# -1 is inferred to be 3:
reshape(t, [ 2, -1, 3]) ==> [[[1, 1, 1],
                              [2, 2, 2],
                              [3, 3, 3]],
                             [[4, 4, 4],
                              [5, 5, 5],
                              [6, 6, 6]]]

# tensor 't' is [7]
# shape `[]` reshapes to a scalar
reshape(t, []) ==> 7

https://www.w3cschool.cn/tensorflow_python/tensorflow_python-bumd2ide.html

 

*3:tf.contrib.rnn

TensorFlow RNN和單元(contrib)
用於構造 RNN 單元和附加 RNN 操作的模塊

所有 RNN 單元的基本界面:
tf.contrib.rnn.RNNCell

用於 TensorFlow 核心 RNN 方法的核心 RNN 單元:
tf.contrib.rnn.BasicRNNCell
tf.contrib.rnn.BasicLSTMCell
tf.contrib.rnn.GRUCell
tf.contrib.rnn.LSTMCell
tf.contrib.rnn.LayerNormBasicLSTMCell

存儲分離“RNNCell”狀態的類:
tf.contrib.rnn.LSTMStateTuple

核心 RNN 單元包裝器(RNNCells 包裝其他 RNNCells):
tf.contrib.rnn.MultiRNNCell
tf.contrib.rnn.LSTMBlockWrapper
tf.contrib.rnn.DropoutWrapper
tf.contrib.rnn.EmbeddingWrapper
tf.contrib.rnn.InputProjectionWrapper
tf.contrib.rnn.OutputProjectionWrapper
tf.contrib.rnn.DeviceWrapper
tf.contrib.rnn.ResidualWrapper

阻止RNNCells:
tf.contrib.rnn.LSTMBlockCell
tf.contrib.rnn.GRUBlockCell

熔融RNNCells:
tf.contrib.rnn.FusedRNNCell
tf.contrib.rnn.FusedRNNCellAdaptor
tf.contrib.rnn.TimeReversedFusedRNN
tf.contrib.rnn.LSTMBlockFusedCell

LSTM樣細胞:
tf.contrib.rnn.CoupledInputForgetGateLSTMCell
tf.contrib.rnn.TimeFreqLSTMCell
tf.contrib.rnn.GridLSTMCell

RNNCell包裝:
tf.contrib.rnn.AttentionCellWrapper
tf.contrib.rnn.CompiledWrapper

TensorFlow 構造循環神經網絡

TensorFlow 提供了一些構建循環神經網絡的方法:
tf.contrib.rnn.static_rnn
tf.contrib.rnn.static_state_saving_rnn
tf.contrib.rnn.static_bidirectional_rnn
tf.contrib.rnn.stack_bidirectional_dynamic_rnn

https://www.w3cschool.cn/tensorflow_python/tensorflow_python-l8ba28vr.html

 

*4:tf.nn.dynamic_rnn函數

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
)

{ 參數:

  • cell:RNNCell的一個實例.
  • inputs:RNN輸入.如果time_major == False(默認),則是一個shape爲[batch_size, max_time, ...]Tensor,或者這些元素的嵌套元組.如果time_major == True,則是一個shape爲[max_time, batch_size, ...]Tensor,或這些元素的嵌套元組.這也可能是滿足此屬性的Tensors(可能是嵌套的)元組.前兩個維度必須匹配所有輸入,否則秩和其他形狀組件可能不同.在這種情況下,在每個時間步輸入到cell將複製這些元組的結構,時間維度(從中獲取時間)除外.在每個時間步輸入到個cell將是一個Tensor或(可能是嵌套的)Tensors元組,每個元素都有維度[batch_size, ...].
  • sequence_length:(可選)大小爲[batch_size]的int32/int64的向量.超過批處理元素的序列長度時用於複製狀態和零輸出.所以它更多的是正確性而不是性能.
  • initial_state:(可選)RNN的初始狀態.如果cell.state_size是整數,則必須是具有適當類型和shape爲[batch_size, cell.state_size]Tensor.如果cell.state_size是一個元組,則應該是張量元組,在cell.state_size中爲s設置shape[batch_size, s].
  • dtype:(可選)初始狀態和預期輸出的數據類型.如果未提供initial_state或RNN狀態具有異構dtype,則是必需的.
  • parallel_iterations:(默認值:32).並行運行的迭代次數.適用於那些沒有任何時間依賴性並且可以並行運行的操作.該參數用於交換空間的時間.遠大於1的值會使用更多內存但佔用更少時間,而較小值使用較少內存但計算時間較長.
  • swap_memory:透明地交換推理中產生的張量,但是需要從GPU到CPU的支持.這允許訓練通常不適合單個GPU的RNN,具有非常小的(或沒有)性能損失.
  • time_majorinputsoutputsTensor的形狀格式.如果是true,則這些 Tensors的shape必須爲[max_time, batch_size, depth].如果是false,則這些Tensors的shape必須爲[batch_size, max_time, depth].使用time_major = True更有效,因爲它避免了RNN計算開始和結束時的轉置.但是,大多數TensorFlow數據都是batch-major,因此默認情況下,此函數接受輸入並以batch-major形式發出輸出.
  • scope:用於創建子圖的VariableScope;默認爲“rnn”.

返回:

一對(outputs, state),其中:

  • outputs:RNN輸出Tensor.

    如果time_major == False(默認),這將是shape爲[batch_size, max_time, cell.output_size]Tensor.

    如果time_major == True,這將是shape爲[max_time, batch_size, cell.output_size]Tensor.

    注意,如果cell.output_size是整數或TensorShape對象的(可能是嵌套的)元組,那麼outputs將是一個與cell.output_size具有相同結構的元祖,它包含與cell.output_size中的形狀數據有對應shape的Tensors.

  • state:最終的狀態.如果cell.state_size是int,則會形成[batch_size, cell.state_size].如果它是TensorShape,則將形成[batch_size] + cell.state_size.如果它是一個(可能是嵌套的)int或TensorShape元組,那麼這將是一個具有相應shape的元組.如果單元格是LSTMCells,則state將是包含每個單元格的LSTMStateTuple的元組.

可能引發的異常:

  • TypeError:如果cell不是RNNCell的實例.
  • ValueError:如果輸入爲None或是空列表. }

示例:

# create a BasicRNNCell
rnn_cell = tf.nn.rnn_cell.BasicRNNCell(hidden_size)

# 'outputs' is a tensor of shape [batch_size, max_time, cell_state_size]

# defining initial state
initial_state = rnn_cell.zero_state(batch_size, dtype=tf.float32)

# 'state' is a tensor of shape [batch_size, cell_state_size]
outputs, state = tf.nn.dynamic_rnn(rnn_cell, input_data,
                                   initial_state=initial_state,
                                   dtype=tf.float32)

''''''
# create 2 LSTMCells
rnn_layers = [tf.nn.rnn_cell.LSTMCell(size) for size in [128, 256]]

# create a RNN cell composed sequentially of a number of RNNCells
multi_rnn_cell = tf.nn.rnn_cell.MultiRNNCell(rnn_layers)

# 'outputs' is a tensor of shape [batch_size, max_time, 256]
# 'state' is a N-tuple where N is the number of LSTMCells containing a
# tf.contrib.rnn.LSTMStateTuple for each cell
outputs, state = tf.nn.dynamic_rnn(cell=multi_rnn_cell,
                                   inputs=data,
                                   dtype=tf.float32)

 

*5:tf.nn.softmax函數

tf.nn.softmax(
    logits,
    axis=None,
    name=None,
    dim=None
)

計算softmax激活。(棄用的參數)

有些參數已被棄用。它們將在將來的版本中刪除。更新說明:不推薦使用dim,而是使用axis。

此函數執行相當於:

softmax = tf.exp(logits) / tf.reduce_sum(tf.exp(logits), axis)

{ 參數:

  • logits:一個非空的Tensor。必須是下列類型之一:half, float32,float64。
  • axis:將在其上執行維度softmax。默認值爲-1,表示最後一個維度。
  • name:操作的名稱(可選)。
  • dim:axis的已棄用的別名。

返回:

一個Tensor,與logits具有相同的類型和shape。

可能引發的異常:

  • InvalidArgumentError:如果logits爲空或axis超出logits的最後一個維度。 }

 


(Placeholder)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章