#背景知識
見《深度學習之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_major
:inputs
和outputs
Tensor的形狀格式.如果是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)