日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > 循环神经网络 >内容正文

循环神经网络

TensorFlow2-循环神经网络

發布時間:2024/4/11 循环神经网络 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TensorFlow2-循环神经网络 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

TensorFlow2循環神經網絡

文章目錄

  • TensorFlow2循環神經網絡
    • 簡介
    • 序列數據
    • 循環神經網絡
    • 循環神經網絡單元
    • LSTM(長短時記憶單元)
    • GRU
    • RNN文本情感分類實戰
    • LSTM文本情感分類實戰
    • 補充說明

簡介

循環神經網絡(recurrent neural network)由于其對時序數據強大的處理能力,被廣泛應用于自然語言處理(NLP)領域。近些年,隨著各個研究領域的融合趨勢,RNN為基礎的一些結構如LSTM也被使用在計算機視覺中的任務中。

序列數據

序列信號(Sequence)通常通過序列嵌入(Sequence embedding)來表達,格式為[b, seq_len, feature_len]。用NLP的觀點理解,其中b批尺寸(batch size),seq_len為句子單詞數目,feature_len為表示一個單詞的向量維度(如300維的詞向量)。

如果將圖片理解為序列數據,[b, 28, 28]則表示每一行是一次采樣的結果。當然,RNN在圖片上有時有著不錯的效果,但是很多時候效果很一般,這是因為RNN本身是用來處理時序數據的,并不擅長處理圖片這類數據。

  • onehot編碼
    • 對共有1000個單詞的詞表,每個單詞用一個1000維的向量表示,其中屬于這個單詞的位置置1,其余位置為0.這是一種及其暴力簡單的編碼方式,不過有著不少的缺點:無法衡量不同單詞之間的距離(因為任意兩個單詞之間的距離是相同的)、所占存儲空間大(稀疏高維矩陣)。
  • word embedding(詞嵌入)
    • 詞嵌入的產生方法有很多,后來的研究表明比較好的兩種方法為Word2Vec和Glove(本質上二者都是上下文預測產生的)。在TF2中,keras模塊下的Embedding層用于嵌入的學習。相比于onehot那樣的編碼方式,embedding為低維密集矩陣,存儲方便的同時也保留了語義距離的信息。

循環神經網絡

如同卷積神經網絡提出的初衷一樣,如果使用全連接神經網絡處理文本信息(如處理后的詞嵌入)勢必會構建一個非常復雜的網絡,參數量相當龐大。而且這種將每個單詞的信息送入全連接網絡會忽略自然語言的一個重要問題—上下文相關。

在卷積神經網絡中,為了解決過多參數采用了參數共享(weight sharing)方法,同樣的,在循環神經網絡中,也采用類似的方法,通過同一個線性層提取語義信息。

但是,自然語言處理不僅僅需要關注每個單詞的信息,還需要關注整個句子的信息,因此需要一個記錄之前信息的記憶結構h(memory或state),在每個單詞處理是都讓它參與運算,這樣不斷累積,最后一個單詞后得到的新h(新memory)就記錄了整個句子的語義信息。

上述的模型其實可以折疊,折疊后產生的模型結構如下圖,對于不同時間點采樣的信息都是以同一種方式提取特征,上一次的信息作為后一次記憶更新的基礎,如此反復,形成循環結構,因此成為循環神經網絡(RNN)。

數學上表達如下,其中h為中間狀態,對于有的模型這個h就是輸出,對于有的模型還需要對h進行變換,需要分情況而定。
ht=fW(ht?1,xt)ht=tanh?(Whhht?1+Wxhxt)\begin{array}{c}{h_{t}=f_{W}\left(h_{t-1}, x_{t}\right)} \\ {h_{t}=\tanh \left(W_{h h} h_{t-1}+W_{x h} x_{t}\right)}\end{array} ht?=fW?(ht?1?,xt?)ht?=tanh(Whh?ht?1?+Wxh?xt?)?

在探討完結構后,還有一個關鍵的問題,就是參數的梯度求解方法,這里依據鏈式法則拆解并不難求解,其中最為關鍵的一步求解如下(梯度需要在時間軸上計算,非常復雜,人為難以完成)。
?Et?WR=∑i=0t?Et?yt?yt?ht?ht?hi?hi?WR\frac{\partial E_{t}}{\partial W_{R}}=\sum_{i=0}^{t} \frac{\partial E_{t}}{\partial y_{t}} \frac{\partial y_{t}}{\partial h_{t}} \frac{\partial h_{t}}{\partial h_{i}} \frac{\partial h_{i}}{\partial W_{R}} ?WR??Et??=i=0t??yt??Et???ht??yt???hi??ht???WR??hi??
?hk?h1=∏ikdiag?(f′(WIxi+WRhi?1))WR\frac{\partial h_{k}}{\partial h_{1}}=\prod_{i}^{k} \operatorname{diag}\left(f^{\prime}\left(W_{I} x_{i}+W_{R} h_{i-1}\right)\right) W_{R} ?h1??hk??=ik?diag(f(WI?xi?+WR?hi?1?))WR?

循環神經網絡單元

在TensorFlow2中,對循環神經網絡單元的運算進行了簡單的封裝,通過不斷將t時刻的x作為輸入送入RNN模塊中進行矩陣運算。而第二節所提出的RNN結構是最為簡單基礎的RNN結構,在keras模塊下封裝為SimpleRNNCell。該結構進行運算的輸出為out, h1 = call(x, h0),這里的out和h1是同一個東西,之所以返回兩次是為了和LSTM等結構做區分。RNNCell也可以堆疊以獲取更高層的語義信息。

實際訓練過程中,以文本信息為演示場景,共有兩種方法,一種是底層控制(較為靈活,寫起來繁瑣),一種借助keras的api堆疊SimpleRNN(較為死板,寫起來簡單)。兩種方式的輸出都是第二層RNN后t=80時的狀態(針對本例)。

LSTM(長短時記憶單元)

傳統的RNN固然表現不錯,然而RNN中的Memory的記憶能力有限且容易出現梯度彌散(gradient vanishing)現象,對此,LSTM被提出。其最核心的觀念是提出了三道門(輸入門、遺忘門、輸出門)位于sigmoid激活后,控制數據的開度(這個開度也是訓練的參數,由反向傳播自動調整)。它之所以能夠解決梯度彌散,其實可以理解為增加了一條數據通路,保證梯度至少不會消失。

目前,主流的模型中很少使用基本的RNN,而是使用LSTM和GRU(減少了LSTM的一個門,在很多情況下效果更好)。

GRU

簡化了LSTM,設計了重置門和更新門兩個門。

RNN文本情感分類實戰

這里通過兩種方式構建RNN實現文本情感分類(二分類),數據集使用IMDB電影評論數據集。第一種方法手工實現前向運算,使用SimpleRNN。第二種方法,通過簡單的keras接口實現復雜的網絡結構堆疊。其代碼如下。

""" Author: Zhou Chen Date: 2019/11/3 Desc: 底層構建單層RNN實現文本情感分類 """ import os import tensorflow as tf import numpy as np from tensorflow import keras from tensorflow.keras import layersos.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'total_words = 10000 max_sentence_len = 80 # 每個句子限制80個單詞 batch_size = 128 embedding_len = 100 # 加載數據 (x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=total_words) # 選取常見的10000個單詞 x_train = keras.preprocessing.sequence.pad_sequences(x_train, maxlen=max_sentence_len) x_test = keras.preprocessing.sequence.pad_sequences(x_test, maxlen=max_sentence_len)db_train = tf.data.Dataset.from_tensor_slices((x_train, y_train)) db_train = db_train.shuffle(1000).batch(batch_size, drop_remainder=True) db_test = tf.data.Dataset.from_tensor_slices((x_test, y_test)) db_test = db_test.shuffle(1000).batch(batch_size, drop_remainder=True) print('x_train shape', x_train.shape, tf.reduce_max(y_train), tf.reduce_min(y_train)) print('x_test shape', x_test.shape)class MyRNN(keras.Model):def __init__(self, units):super(MyRNN, self).__init__()# [b, 64]self.state0 = [tf.zeros([batch_size, units])]self.state1 = [tf.zeros([batch_size, units])]# transform text to embedding representation# [b, 80] => [b, 80, 100]self.embedding = layers.Embedding(total_words, embedding_len, input_length=max_sentence_len)# [b, 80, 100] , h_dim: 64# RNN: cell1 ,cell2, cell3# SimpleRNNself.rnn_cell0 = layers.SimpleRNNCell(units, dropout=0.5)self.rnn_cell1 = layers.SimpleRNNCell(units, dropout=0.5)# fc, [b, 80, 100] => [b, 64] => [b, 1]self.outlayer = layers.Dense(1)def call(self, inputs, training=None):# [b, 80]x = inputs# embedding: [b, 80] => [b, 80, 100]x = self.embedding(x)# rnn cell compute# [b, 80, 100] => [b, 64]state0 = self.state0state1 = self.state1for word in tf.unstack(x, axis=1): # word: [b, 100]# h1 = x*wxh+h0*whh# out0: [b, 64]out0, state0 = self.rnn_cell0(word, state0, training)# out1: [b, 64]out1, state1 = self.rnn_cell1(out0, state1, training)# out: [b, 64] => [b, 1]x = self.outlayer(out1)# p(y is pos|x)prob = tf.sigmoid(x)return probdef main():units = 64epochs = 4model = MyRNN(units)model.compile(optimizer=keras.optimizers.Adam(0.001), loss=tf.losses.BinaryCrossentropy(),metrics=['accuracy'], experimental_run_tf_function=False)model.fit(db_train, epochs=epochs, validation_data=db_test)model.evaluate(db_test)if __name__ == '__main__':main() """ Author: Zhou Chen Date: 2019/11/3 Desc: 通過層堆疊方式構建RNN實現文本情感分類 """ import os import tensorflow as tf import numpy as np from tensorflow import keras from tensorflow.keras import layers os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'batchsz = 128 total_words = 10000 max_review_len = 80 embedding_len = 100 (x_train, y_train), (x_test, y_test) = keras.datasets.imdb.load_data(num_words=total_words) # x_train:[b, 80] # x_test: [b, 80] x_train = keras.preprocessing.sequence.pad_sequences(x_train, maxlen=max_review_len) x_test = keras.preprocessing.sequence.pad_sequences(x_test, maxlen=max_review_len)db_train = tf.data.Dataset.from_tensor_slices((x_train, y_train)) db_train = db_train.shuffle(1000).batch(batchsz, drop_remainder=True) db_test = tf.data.Dataset.from_tensor_slices((x_test, y_test)) db_test = db_test.batch(batchsz, drop_remainder=True) print('x_train shape:', x_train.shape, tf.reduce_max(y_train), tf.reduce_min(y_train)) print('x_test shape:', x_test.shape)class MyRNN(keras.Model):def __init__(self, units):super(MyRNN, self).__init__()# 生成嵌入的表示# [b, 80] => [b, 80, 100]self.embedding = layers.Embedding(total_words, embedding_len,input_length=max_review_len)# [b, 80, 100] , h_dim: 64self.rnn = keras.Sequential([layers.SimpleRNN(units, dropout=0.5, return_sequences=True, unroll=True),layers.SimpleRNN(units, dropout=0.5, unroll=True)])# fc, [b, 80, 100] => [b, 64] => [b, 1]self.outlayer = layers.Dense(1)def call(self, inputs, training=None):# [b, 80]x = inputs# embedding: [b, 80] => [b, 80, 100]x = self.embedding(x)# rnn cell compute# x: [b, 80, 100] => [b, 64]x = self.rnn(x, training=training)# out: [b, 64] => [b, 1]x = self.outlayer(x)# p(y is pos|x)prob = tf.sigmoid(x)return probdef main():units = 64epochs = 4model = MyRNN(units)# model.build(input_shape=(4,80))# model.summary()model.compile(optimizer=keras.optimizers.Adam(0.001),loss=tf.losses.BinaryCrossentropy(),metrics=['accuracy'])model.fit(db_train, epochs=epochs, validation_data=db_test)model.evaluate(db_test)if __name__ == '__main__':main()

LSTM文本情感分類實戰

類似上面的實戰任務,利用LSTM實現。
代碼類似上面RNN,這里不列舉,具體可以在文末給出的Github地址找到。其中也包含GRU實現。

補充說明

  • 本文介紹了RNN、LSTM、GRU在TensorFlow2中的實現,更詳細的可以查看官方文檔。
  • 具體的代碼同步至我的Github倉庫歡迎star;博客同步至我的個人博客網站,歡迎查看其他文章。
  • 如有疏漏,歡迎指正。

總結

以上是生活随笔為你收集整理的TensorFlow2-循环神经网络的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。