關(guān)于tf.nn.dynamic_rnn
tf.nn.dynamic_rnn 函數(shù)是tensorflow封裝的用來實現(xiàn)遞歸神經(jīng)網(wǎng)絡(luò)(RNN)的函數(shù)。
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
)
重要參數(shù)介紹:
- cell:LSTM、GRU等的記憶單元。cell參數(shù)代表一個LSTM或GRU的記憶單元,也就是一個cell。例如,cell = tf.nn.rnn_cell.LSTMCell((num_units),其中,num_units表示rnn cell中神經(jīng)元個數(shù),也就是下文的cell.output_size。返回一個LSTM或GRU cell,作為參數(shù)傳入。
- inputs:輸入的訓(xùn)練或測試數(shù)據(jù),一般格式為[batch_size, max_time, embed_size],其中batch_size是輸入的這批數(shù)據(jù)的數(shù)量,max_time就是這批數(shù)據(jù)中序列的最長長度,embed_size表示嵌入的詞向量的維度。
- sequence_length:是一個list,假設(shè)你輸入了三句話,且三句話的長度分別是5,10,25,那么sequence_length=[5,10,25]。
- initial_state: (可選)RNN的初始state(狀態(tài))。如果cell.state_size(一層的RNNCell)是一個整數(shù),那么它必須是一個具有適當(dāng)類型和形狀的張量[batch_size,cell.state_size]。如果cell.state_size是一個元組(多層的RNNCell,如MultiRNNCell),那么它應(yīng)該是一個張量元組,每個元素的形狀為[batch_size,s] for s in cell.state_size
- time_major:決定了輸出tensor的格式,如果為True, 張量的形狀必須為 [max_time, batch_size,cell.output_size]。如果為False, tensor的形狀必須為[batch_size, max_time, cell.output_size],cell.output_size表示rnn cell中神經(jīng)元個數(shù)。
返回值:元組(outputs, states)
- outputs:RNN的最后一層的輸出,是一個tensor
如果為time_major== False,則shape [batch_size,max_time,cell.output_size]。如果為time_major== True,則shape: [max_time,batch_size,cell.output_size]。 - state: RNN最后時間步的state,如果cell.state_size是一個整數(shù)(一般是單層的RNNCell),則state的shape:[batch_size,cell.state_size]。如果它是一個元組(一般這里是 多層的RNNCell),那么它將是一個具有相應(yīng)形狀的元組。注意:如果若RNNCell是 LSTMCells,則state將為每層cell的LSTMStateTuple的元組Tuple(LSTMStateTuple,LSTMStateTuple,LSTMStateTuple)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow .examples .tutorials .mnist import input_data
mnist=input_data .read_data_sets ('data/',one_hot= True)
trainimgs, trainlabels, testimgs, testlabels \
= mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
ntrain, ntest, dim, nclasses \
= trainimgs.shape[0], testimgs.shape[0], trainimgs.shape[1], trainlabels.shape[1]
print ("MNIST loaded")
training_epochs = 10
batch_size = 32
display_step = 1
diminput=28
dimhidden=128
dimoutput=nclasses
nsteps=28#把輸入拆分為28個小部分
weights={
'hidden':tf.Variable(tf.random_normal([diminput ,dimhidden ])),
'out':tf.Variable(tf.random_normal([dimhidden,dimoutput]))
}
biases={
'hidden':tf.Variable(tf.random_normal([dimhidden])),
'out':tf.Variable(tf.random_normal([dimoutput]))
}
def _RNN(_X,_W,_b,_nsteps,):
#_X的格式為:[bitchsize,h,w]
#_X=tf.transpose(_X,[1,0,2])#將第一維度和第二維度交換-無用
'''
tf.transpose(input, [dimension_1, dimenaion_2,..,dimension_n])
這個函數(shù)主要適用于交換輸入張量的不同維度用的,如果輸入張量是二維,就相當(dāng)是轉(zhuǎn)置。
dimension_n是整數(shù),如果張量是三維,就是用0,1,2來表示。這個列表里的每個數(shù)對應(yīng)相應(yīng)的維度。
如果是[2,1,0],就把輸入張量的第三維度和第一維度交換。
'''
_X=tf.reshape(_X,[-1,diminput])#(batchsize*28,28)
_H=tf.matmul(_X,_W['hidden'])+_b['hidden']#(batchsize*28,128)
_H=tf.reshape(_H,[-1,_nsteps,dimhidden])#(batchsize,28,128)
#算隱層時,是按照整體去算,算完之后因為要進(jìn)行RNN訓(xùn)練——分切片進(jìn)行
# _Hsplit=tf.split(_H,_nsteps,0)
''''
tf.split(dimension, num_split, input):
dimension的意思就是輸入張量的哪一個維度,如果是0就表示對第0維度進(jìn)行切割。
num_split就是切割的數(shù)量,如果是2就表示輸入張量被切成2份,每一份是一個列表。
'''
#輸入數(shù)據(jù)的格式的問題
lstm_cell=tf.nn.rnn_cell.BasicLSTMCell(dimhidden,forget_bias=1.0,state_is_tuple=True)#重點
init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
# dynamic_rnn 接收張量(batch, steps, inputs)或者(steps, batch, inputs)作為X_in
outputs, final_state=tf.nn.dynamic_rnn(lstm_cell,_H ,initial_state=init_state,time_major=False)#重點
'''
tf.nn.rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0, state_is_tuple=True):
n_hidden表示神經(jīng)元的個數(shù),
forget_bias就是LSTM門的忘記系數(shù),如果等于1,就是不會忘記任何信息。如果等于0,就都忘記。
state_is_tuple默認(rèn)就是True,官方建議用True,就是表示返回的狀態(tài)用一個元祖表示。
'''
_O=tf.matmul(final_state[1],_W['out'])+_b['out']
return{
'X': _X, 'H': _H, 'O': _O
}
print('NEtwork ready')
learning_rate = 0.001
x = tf.placeholder("float", [None, nsteps, diminput])
y = tf.placeholder("float", [None, dimoutput])
myrnn = _RNN(x, weights, biases, nsteps)
pred = myrnn['O']
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
optm = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) # Adam Optimizer
accr = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred,1), tf.argmax(y,1)), tf.float32))
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print ("Start optimization")
for epoch in range(training_epochs):
avg_cost = 0.
#total_batch = int(mnist.train.num_examples/batch_size)
total_batch = 100
# Loop over all batches
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
batch_xs = batch_xs.reshape((batch_size, nsteps, diminput))
# Fit training using batch data
feeds = {x: batch_xs, y: batch_ys}
sess.run(optm, feed_dict=feeds)
# Compute average loss
avg_cost += sess.run(cost, feed_dict=feeds) / total_batch
# Display logs per epoch step
if epoch % display_step == 0:
print("Epoch: %03d/%03d cost: %.9f" % (epoch, training_epochs, avg_cost))
feeds = {x: batch_xs, y: batch_ys}
train_acc = sess.run(accr, feed_dict=feeds)
print(" Training accuracy: %.3f" % (train_acc))
'''
testimgs = testimgs.reshape((ntest, nsteps, diminput))
feeds = {x: testimgs, y: testlabels}
test_acc = sess.run(accr, feed_dict=feeds)
print(" Test accuracy: %.3f" % (test_acc))
'''
print("Optimization Finished.")