python神經(jīng)網(wǎng)絡(luò)使用tensorflow構(gòu)建長短時記憶LSTM
LSTM簡介
1、RNN的梯度消失問題
在過去的時間里我們學習了RNN循環(huán)神經(jīng)網(wǎng)絡(luò),其結(jié)構(gòu)示意圖是這樣的:

其存在的最大問題是,當w1、w2、w3這些值小于0時,如果一句話夠長,那么其在神經(jīng)網(wǎng)絡(luò)進行反向傳播與前向傳播時,存在梯度消失的問題。
0.925=0.07,如果一句話有20到30個字,那么第一個字的隱含層輸出傳遞到最后,將會變?yōu)樵瓉淼?.07倍,相比于最后一個字的影響,大大降低。
其具體情況是這樣的:

長短時記憶網(wǎng)絡(luò)就是為了解決梯度消失的問題出現(xiàn)的。
2、LSTM的結(jié)構(gòu)
原始RNN的隱藏層只有一個狀態(tài)h,從頭傳遞到尾,它對于短期的輸入非常敏感。
如果我們再增加一個狀態(tài)c,讓它來保存長期的狀態(tài),問題就可以解決了。
對于RNN和LSTM而言,其兩個step單元的對比如下。

我們把LSTM的結(jié)構(gòu)按照時間維度展開:

我們可以看出,在n時刻,LSTM的輸入有三個:
1、當前時刻網(wǎng)絡(luò)的輸入值;
2、上一時刻LSTM的輸出值;
3、上一時刻的單元狀態(tài)。
LSTM的輸出有兩個:
1、當前時刻LSTM輸出值;
2、當前時刻的單元狀態(tài)。
3、LSTM獨特的門結(jié)構(gòu)
LSTM用兩個門來控制單元狀態(tài)cn的內(nèi)容:
1、遺忘門(forget gate),它決定了上一時刻的單元狀態(tài)cn-1有多少保留到當前時刻;
2、輸入門(input gate),它決定了當前時刻網(wǎng)絡(luò)的輸入c’n有多少保存到單元狀態(tài)。
LSTM用一個門來控制當前輸出值hn的內(nèi)容:
輸出門(output gate),它決定了當前時刻單元狀態(tài)cn有多少輸出。

tensorflow中LSTM的相關(guān)函數(shù)
tf.contrib.rnn.BasicLSTMCell
tf.contrib.rnn.BasicLSTMCell(
num_units,
forget_bias=1.0,
state_is_tuple=True,
activation=None,
reuse=None,
name=None,
dtype=None
)
- num_units:RNN單元中的神經(jīng)元數(shù)量,即輸出神經(jīng)元數(shù)量。
- forget_bias:偏置增加了忘記門。從CudnnLSTM訓練的檢查點(checkpoin)恢復時,必須手動設(shè)置為0.0。
- state_is_tuple:如果為True,則接受和返回的狀態(tài)是c_state和m_state的2-tuple;如果為False,則他們沿著列軸連接。False即將棄用。
- activation:激活函數(shù)。
- reuse:描述是否在現(xiàn)有范圍中重用變量。如果不為True,并且現(xiàn)有范圍已經(jīng)具有給定變量,則會引發(fā)錯誤。
- name:層的名稱。
- dtype:該層的數(shù)據(jù)類型。
在使用時,可以定義為:
lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
在定義完成后,可以進行狀態(tài)初始化:
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
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:上文所定義的lstm_cell。
- inputs:RNN輸入。如果time_major==false(默認),則必須是如下shape的tensor:[batch_size,max_time,…]或此類元素的嵌套元組。如果time_major==true,則必須是如下形狀的tensor:[max_time,batch_size,…]或此類元素的嵌套元組。
- sequence_length:Int32/Int64矢量大小。用于在超過批處理元素的序列長度時復制通過狀態(tài)和零輸出。因此,它更多的是為了性能而不是正確性。
- initial_state:上文所定義的_init_state。
- dtype:數(shù)據(jù)類型。
- parallel_iterations:并行運行的迭代次數(shù)。那些不具有任何時間依賴性并且可以并行運行的操作將是。這個參數(shù)用時間來交換空間。值>>1使用更多的內(nèi)存,但花費的時間更少,而較小的值使用更少的內(nèi)存,但計算需要更長的時間。
- time_major:輸入和輸出tensor的形狀格式。如果為真,這些張量的形狀必須是[max_time,batch_size,depth]。如果為假,這些張量的形狀必須是[batch_size,max_time,depth]。使用time_major=true會更有效率,因為它可以避免在RNN計算的開始和結(jié)束時進行換位。但是,大多數(shù)TensorFlow數(shù)據(jù)都是批處理主數(shù)據(jù),因此默認情況下,此函數(shù)為False。
- scope:創(chuàng)建的子圖的可變作用域;默認為“RNN”。
在LSTM的最后,需要用該函數(shù)得出結(jié)果。
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn( lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
返回的是一個元組 (outputs, state):
outputs:LSTM的最后一層的輸出,是一個tensor。如果為time_major== False,則它的shape為[batch_size,max_time,cell.output_size]。如果為time_major== True,則它的shape為[max_time,batch_size,cell.output_size]。
states:states是一個tensor。state是最終的狀態(tài),也就是序列中最后一個cell輸出的狀態(tài)。一般情況下states的形狀為 [batch_size, cell.output_size],但當輸入的cell為BasicLSTMCell時,states的形狀為[2,batch_size, cell.output_size ],其中2也對應著LSTM中的cell state和hidden state。
整個LSTM的定義過程為:
def add_input_layer(self,):
#X最開始的形狀為(256 batch,28 steps,28 inputs)
#轉(zhuǎn)化為(256 batch*28 steps,128 hidden)
l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='to_2D')
#獲取Ws和Bs
Ws_in = self._weight_variable([self.input_size, self.cell_size])
bs_in = self._bias_variable([self.cell_size])
#轉(zhuǎn)化為(256 batch*28 steps,256 hidden)
with tf.name_scope('Wx_plus_b'):
l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in
# (batch * n_steps, cell_size) ==> (batch, n_steps, cell_size)
# (256*28,256)->(256,28,256)
self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='to_3D')
def add_cell(self):
#神經(jīng)元個數(shù)
lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
#每一次傳入的batch的大小
with tf.name_scope('initial_state'):
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
#不是主列
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
def add_output_layer(self):
#設(shè)置Ws,Bs
Ws_out = self._weight_variable([self.cell_size, self.output_size])
bs_out = self._bias_variable([self.output_size])
# shape = (batch,output_size)
# (256,10)
with tf.name_scope('Wx_plus_b'):
self.pred = tf.matmul(self.cell_final_state[-1], Ws_out) + bs_out
全部代碼
該例子為手寫體識別例子,將手寫體的28行分別作為每一個step的輸入,輸入維度均為28列。
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
mnist = input_data.read_data_sets("MNIST_data",one_hot = "true")
BATCH_SIZE = 256 # 每一個batch的數(shù)據(jù)數(shù)量
TIME_STEPS = 28 # 圖像共28行,分為28個step進行傳輸
INPUT_SIZE = 28 # 圖像共28列
OUTPUT_SIZE = 10 # 共10個輸出
CELL_SIZE = 256 # RNN 的 hidden unit size,隱含層神經(jīng)元的個數(shù)
LR = 1e-3 # learning rate,學習率
def get_batch(): #獲取訓練的batch
batch_xs,batch_ys = mnist.train.next_batch(BATCH_SIZE)
batch_xs = batch_xs.reshape([BATCH_SIZE,TIME_STEPS,INPUT_SIZE])
return [batch_xs,batch_ys]
class LSTMRNN(object): #構(gòu)建LSTM的類
def __init__(self, n_steps, input_size, output_size, cell_size, batch_size):
self.n_steps = n_steps
self.input_size = input_size
self.output_size = output_size
self.cell_size = cell_size
self.batch_size = batch_size
#輸入輸出
with tf.name_scope('inputs'):
self.xs = tf.placeholder(tf.float32, [None, n_steps, input_size], name='xs')
self.ys = tf.placeholder(tf.float32, [None, output_size], name='ys')
#直接加層
with tf.variable_scope('in_hidden'):
self.add_input_layer()
#增加LSTM的cell
with tf.variable_scope('LSTM_cell'):
self.add_cell()
#直接加層
with tf.variable_scope('out_hidden'):
self.add_output_layer()
#計算損失值
with tf.name_scope('cost'):
self.compute_cost()
#訓練
with tf.name_scope('train'):
self.train_op = tf.train.AdamOptimizer(LR).minimize(self.cost)
#正確率計算
self.correct_pre = tf.equal(tf.argmax(self.ys,1),tf.argmax(self.pred,1))
self.accuracy = tf.reduce_mean(tf.cast(self.correct_pre,tf.float32))
def add_input_layer(self,):
#X最開始的形狀為(256 batch,28 steps,28 inputs)
#轉(zhuǎn)化為(256 batch*28 steps,128 hidden)
l_in_x = tf.reshape(self.xs, [-1, self.input_size], name='to_2D')
#獲取Ws和Bs
Ws_in = self._weight_variable([self.input_size, self.cell_size])
bs_in = self._bias_variable([self.cell_size])
#轉(zhuǎn)化為(256 batch*28 steps,256 hidden)
with tf.name_scope('Wx_plus_b'):
l_in_y = tf.matmul(l_in_x, Ws_in) + bs_in
# (batch * n_steps, cell_size) ==> (batch, n_steps, cell_size)
# (256*28,256)->(256,28,256)
self.l_in_y = tf.reshape(l_in_y, [-1, self.n_steps, self.cell_size], name='to_3D')
def add_cell(self):
#神經(jīng)元個數(shù)
lstm_cell = tf.contrib.rnn.BasicLSTMCell(self.cell_size, forget_bias=1.0, state_is_tuple=True)
#每一次傳入的batch的大小
with tf.name_scope('initial_state'):
self.cell_init_state = lstm_cell.zero_state(self.batch_size, dtype=tf.float32)
#不是主列
self.cell_outputs, self.cell_final_state = tf.nn.dynamic_rnn(
lstm_cell, self.l_in_y, initial_state=self.cell_init_state, time_major=False)
def add_output_layer(self):
#設(shè)置Ws,Bs
Ws_out = self._weight_variable([self.cell_size, self.output_size])
bs_out = self._bias_variable([self.output_size])
# shape = (batch,output_size)
# (256,10)
with tf.name_scope('Wx_plus_b'):
self.pred = tf.matmul(self.cell_final_state[-1], Ws_out) + bs_out
def compute_cost(self):
self.cost = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(logits = self.pred,labels = self.ys)
)
def _weight_variable(self, shape, name='weights'):
initializer = np.random.normal(0.0,1.0 ,size=shape)
return tf.Variable(initializer, name=name,dtype = tf.float32)
def _bias_variable(self, shape, name='biases'):
initializer = np.ones(shape=shape)*0.1
return tf.Variable(initializer, name=name,dtype = tf.float32)
if __name__ == '__main__':
#搭建 LSTMRNN 模型
model = LSTMRNN(TIME_STEPS, INPUT_SIZE, OUTPUT_SIZE, CELL_SIZE, BATCH_SIZE)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
#訓練10000次
for i in range(10000):
xs, ys = get_batch() #提取 batch data
if i == 0:
#初始化data
feed_dict = {
model.xs: xs,
model.ys: ys,
}
else:
feed_dict = {
model.xs: xs,
model.ys: ys,
model.cell_init_state: state #保持 state 的連續(xù)性
}
#訓練
_, cost, state, pred = sess.run(
[model.train_op, model.cost, model.cell_final_state, model.pred],
feed_dict=feed_dict)
#打印精確度結(jié)果
if i % 20 == 0:
print(sess.run(model.accuracy,feed_dict = {
model.xs: xs,
model.ys: ys,
model.cell_init_state: state #保持 state 的連續(xù)性
}))
以上就是python神經(jīng)網(wǎng)絡(luò)使用tensorflow構(gòu)建長短時記憶LSTM的詳細內(nèi)容,更多關(guān)于tensorflow長短時記憶網(wǎng)絡(luò)LSTM的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python使用鄰接矩陣實現(xiàn)圖及Dijkstra算法問題
這篇文章主要介紹了Python使用鄰接矩陣實現(xiàn)圖及Dijkstra算法問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12
Python使用Transformers實現(xiàn)機器翻譯功能
近年來,機器翻譯技術(shù)飛速發(fā)展,從傳統(tǒng)的基于規(guī)則的翻譯到統(tǒng)計機器翻譯,再到如今流行的神經(jīng)網(wǎng)絡(luò)翻譯模型,尤其是基于Transformer架構(gòu)的模型,翻譯效果已經(jīng)有了質(zhì)的飛躍,本文將詳細介紹如何使用Transformers庫來實現(xiàn)一個機器翻譯模型,需要的朋友可以參考下2024-11-11
python無限生成不重復(字母,數(shù)字,字符)組合的方法
今天小編就為大家分享一篇python無限生成不重復(字母,數(shù)字,字符)組合的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12
python實現(xiàn)txt文件格式轉(zhuǎn)換為arff格式
這篇文章主要為大家詳細介紹了python實現(xiàn)txt文件格式轉(zhuǎn)換為arff格式的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05

