国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

這篇具有很好參考價值的文章主要介紹了深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

概述

循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,RNN)是一種具有循環(huán)連接的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),被廣泛應(yīng)用于自然語言處理、語音識別、時序數(shù)據(jù)分析等任務(wù)中。相較于傳統(tǒng)神經(jīng)網(wǎng)絡(luò),RNN的主要特點在于它可以處理序列數(shù)據(jù),能夠捕捉到序列中的時序信息。

RNN的基本單元是一個循環(huán)單元(Recurrent Unit),它接收一個輸入和一個來自上一個時間步的隱藏狀態(tài),并輸出當(dāng)前時間步的隱藏狀態(tài)。在傳統(tǒng)的RNN中,循環(huán)單元通常使用tanh或ReLU等激活函數(shù)。

基本循環(huán)神經(jīng)網(wǎng)絡(luò)

原理

基本的 循環(huán)神經(jīng)網(wǎng)絡(luò),結(jié)構(gòu)由 輸入層、一個隱藏層和輸出層 組成。

深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
   x x x是輸入向量, o o o是輸出向量, s s s表示隱藏層的值; U U U是輸入層到隱藏層的權(quán)重矩陣, V V V是隱藏層到輸出層的權(quán)重矩陣。循環(huán)神經(jīng)網(wǎng)絡(luò)的隱藏層的值s不僅僅取決于當(dāng)前這次的輸入 x x x,還取決于上一次隱藏層的值 s s s。權(quán)重矩陣W就是隱藏層上一次的值作為這一次的輸入的權(quán)重。
  
將上圖的基本RNN結(jié)構(gòu)在時間維度展開(RNN是一個鏈式結(jié)構(gòu),每個時間片使用的是相同的參數(shù),t表示t時刻):
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
現(xiàn)在看上去就會清楚許多,這個網(wǎng)絡(luò)在t時刻接收到輸入 x t x_t xt?之后,隱藏層的值是 s t s_t st?,輸出值是 o t o_t ot?。關(guān)鍵一點是 s t s_t st?的值不僅僅取決于 x t x_t xt?,還取決于 s t ? 1 s_{t?1} st?1?
公式1: s t = f ( U ? x t + W ? s t ? 1 + B 1 ) s_t=f(U?x_t+W?s_{t?1}+B1) st?=f(U?xt?+W?st?1?+B1)
公式2: o t = g ( V ? s t + B 2 ) o_t=g(V?s_t+B2) ot?=g(V?st?+B2)

  • 式1是隱藏層的計算公式,它是循環(huán)層。U是輸入x的權(quán)重矩陣,W是上一次隱藏層值 S t ? 1 S_{t?1} St?1?作為這一次的輸入的權(quán)重矩陣,f是激活函數(shù)。
  • 式2是輸出層的計算公式,V是輸出層的權(quán)重矩陣,g是激活函數(shù),B1,B2是偏置假設(shè)為0。

隱含層有兩個輸入,第一是U與 x t x_t xt?向量的乘積,第二是上一隱含層輸出的狀態(tài) s t ? 1 s_t?1 st??1和W的乘積。等于上一個時刻計算的 s t ? 1 s_t?1 st??1需要緩存一下,在本次輸入 x t x_t xt?一起計算,共同輸出最后的 o t o_t ot?。

如果反復(fù)把式1帶入式2,我們將得到:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
從上面可以看出,循環(huán)神經(jīng)網(wǎng)絡(luò)的輸出值ot,是受前面歷次輸入值、、、、、、、、 x t x_t xt?、 x t ? 1 x_{t?1} xt?1?、 x t ? 2 x_{t?2} xt?2? x t ? 3 x_{t?3} xt?3?、…影響的,這就是為什么循環(huán)神經(jīng)網(wǎng)絡(luò)可以往前看任意多個輸入值的原因。這樣其實不好,因為如果太前面的值和后面的值已經(jīng)沒有關(guān)系了,循環(huán)神經(jīng)網(wǎng)絡(luò)還考慮前面的值的話,就會影響后面值的判斷。

上面是整個單向單層NN的前向傳播過程

為了更快理解輸入x輸入格式下面使用nlp中Word Embedding講解下。

Word Embedding

首先我們需要對輸入文本x進行編碼,使之成為計算機可以讀懂的語言,在編碼時,我們期望句子之間保持詞語間的相似行,詞的向量表示是進行機器學(xué)習(xí)和深度學(xué)習(xí)的基礎(chǔ)。

word embedding的一個基本思路就是,我們把一個詞映射到語義空間的一個點,把一個詞映射到低維的稠密空間,這樣的映射使得語義上比較相似的詞,他在語義空間的距離也比較近,如果兩個詞的關(guān)系不是很接近,那么在語義空間中向量也會比較遠。

深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
如上圖英語和西班牙語映射到語義空間,語義相同的數(shù)字他們在語義空間分布的位置是相同的
簡單回顧一下word embedding,對于nlp來說,我們輸入的是一個個離散的符號,對于神經(jīng)網(wǎng)絡(luò)來說,它處理的都是向量或者矩陣。所以第一步,我們需要把一個詞編碼成向量。最簡單的就是one-hot的表示方法。如下圖所示:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
python代碼(one-hot),比如

import numpy as np

word_array = ['apple', 'kiwi', 'mango']
word_dict = {'apple': 0, 'banana': 1, 'orange': 2, 'grape': 3, 'melon': 4, 'peach': 5, 'pear': 6, 'kiwi': 7, 'plum': 8, 'mango': 9}

# 創(chuàng)建一個全為0的矩陣
one_hot_matrix = np.zeros((len(word_array), len(word_dict)))

# 對每個單詞進行one-hot編碼
for i, word in enumerate(word_array):
    word_index = word_dict[word]
    one_hot_matrix[i, word_index] = 1

print(one_hot_matrix)

輸出:

[[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]   #這就是apple的one-hot編碼
 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]    #這就是kiwi的one-hot編碼
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]    #這就是mango的one-hot編碼

行表示每個單詞,列表示語料庫,每個列對應(yīng)一個語料單詞,也就是特征列

雖然one-hot編碼是一種簡單有效的特征表示方法,但它也存在一些缺點:

  1. 高維度表示:使用one-hot編碼時,每個特征都需要創(chuàng)建一個很大的稀疏向量,維度與特征的唯一值數(shù)量相等。這會導(dǎo)致高維度的輸入數(shù)據(jù),增加了計算和存儲的開銷。特別是在處理具有大量離散特征的問題時,會導(dǎo)致非常龐大的特征空間。

  2. 維度獨立性:one-hot編碼將每個特征都表示為獨立的二進制特征,沒有考慮到特征之間的相關(guān)性和語義關(guān)系。這可能會導(dǎo)致模型難以捕捉到特征之間的相互作用和關(guān)聯(lián)性,從而影響了模型的性能。

  3. 無法處理未知特征:one-hot編碼要求特征的唯一值在訓(xùn)練集中都出現(xiàn)過,否則會出現(xiàn)問題。如果在測試集或?qū)嶋H應(yīng)用中遇到了未在訓(xùn)練集中出現(xiàn)的特征值,就無法進行one-hot編碼,這可能導(dǎo)致模型無法處理這些未知特征。

  4. 特征稀疏性:由于one-hot編碼的特征向量是稀疏的,大部分元素都是0,這會導(dǎo)致數(shù)據(jù)稀疏性增加,對于一些算法(如線性模型)可能會帶來一些問題。

綜上所述,盡管one-hot編碼在某些情況下是一種簡單有效的特征表示方法,但它也存在一些缺點,特別是在處理高維度離散特征、考慮特征間關(guān)系和處理未知特征值時可能會遇到問題。

使用nn.Embedding替代one-hot編碼的原因主要有兩點:

  1. 維度靈活性:使用one-hot編碼時,每個特征都需要創(chuàng)建一個很大的稀疏向量,維度與特征的唯一值數(shù)量相等。這會導(dǎo)致高維度的輸入,增加了計算和存儲的開銷。而使用嵌入(embedding)可以將離散特征映射為低維度的連續(xù)向量表示,減少了存儲和計算的成本。

  2. 語義關(guān)系和相似性:嵌入向量可以捕捉到特征之間的語義關(guān)系和相似性。例如,在自然語言處理任務(wù)中,使用嵌入向量可以將單詞映射為連續(xù)的向量表示,使得具有相似語義含義的單詞在嵌入空間中距離較近。這樣的特性可以幫助模型更好地理解和學(xué)習(xí)特征之間的關(guān)系,提升模型的性能。

因此,使用nn.Embedding替代one-hot編碼可以提高模型的效率和性能,特別是在處理高維度的離散特征時。

好的,我們來看一個簡單的例子來手推nn.embedding的兩個參數(shù)的作用。

假設(shè)我們有一個句子分類任務(wù),我們的輸入是一個句子,每個單詞都是一個特征。我們有5個不同的單詞,分別是[“I”, “l(fā)ove”, “deep”, “l(fā)earning”, “!” ]。

我們可以使用nn.embedding來將這些單詞映射為嵌入向量(在坐標系中有一個位置指向了這個單詞)。假設(shè)我們將每個單詞嵌入為一個3維的向量。這里,num_embeddings為5,表示我們有5個不同的單詞;embedding_dim為3,表示每個單詞嵌入為一個3維的向量。

我們可以用下面的表格來表示每個單詞的嵌入向量:

單詞 嵌入向量
“I” [0.1, 0.2, 0.3]
“l(fā)ove” [0.4, 0.5, 0.6]
“deep” [0.7, 0.8, 0.9]
“l(fā)earning” [0.2, 0.3, 0.4]
“!” [0.5, 0.6, 0.7]

通過nn.embedding,我們可以將句子中的每個單詞轉(zhuǎn)換為對應(yīng)的嵌入向量。例如,句子"I love deep learning!"可以轉(zhuǎn)換為以下嵌入向量序列:

[[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9], [0.2, 0.3, 0.4], [0.5, 0.6, 0.7]]

這樣,我們就可以將離散的單詞特征轉(zhuǎn)換為連續(xù)的嵌入向量,在深度學(xué)習(xí)模型中使用。

以下是pytorch(python入門)的使用

 # 創(chuàng)建詞匯表
        vocab = {"I": 0, "love": 1, "deep": 2, "learning": 3, "!": 4}
        strings=["I", "love", "deep", "learning", "!" ]
        # 將字符串序列轉(zhuǎn)換為整數(shù)索引序列
        input = t.LongTensor([vocab[word] for word in strings])
        #注意第一個參數(shù)是詞匯表的個數(shù),并不是輸入單詞的長度,你在這里就算填100也不影響最終的輸出維度,這個輸入值影響的是算出來的行向量值
        #nn.Embedding模塊會隨機初始化嵌入矩陣。在深度學(xué)習(xí)中,模型參數(shù)通常會使用隨機初始化的方法來開始訓(xùn)練,以便模型能夠在訓(xùn)練過程中學(xué)習(xí)到合適的參數(shù)值。
        #在nn.Embedding中,嵌入矩陣的每個元素都會被隨機初始化為一個小的隨機值,這些值將作為模型在訓(xùn)練過程中學(xué)習(xí)的可訓(xùn)練參數(shù),可以使用manual_seed固定。
        t.manual_seed(1234)
        embedding=nn.Embedding(len(vocab),3)
        print(embedding(input))

輸出結(jié)果為:
tensor([[-0.1117, -0.4966, 0.1631],
[-0.8817, 0.0539, 0.6684],
[-0.0597, -0.4675, -0.2153],
[ 0.8840, -0.7584, -0.3689],
[-0.3424, -1.4020, 0.3206]], grad_fn=)

注意Embedding第一個參數(shù)不是輸入的字符的長度,而是詞匯表的長度,比如有詞匯表
{“I”: 0, “l(fā)ove”: 1, “deep”: 2, “l(fā)earning”: 3, “!”: 4},而輸入input可能是:i love,此時應(yīng)該傳入的是5而不是2,因為預(yù)測最后隱藏層需要做個全連接用來預(yù)測當(dāng)前輸入單詞對于整個詞匯表的所有單詞的概率。

pytorch rnn

以下是pytorch使用rnn最簡單的一個例子,用來熟悉pytorch rnn
注意pytorch的rnn并不處理隱藏層到輸出層的邏輯,他只是關(guān)注隱藏層的輸出結(jié)果,如果需要將隱藏層轉(zhuǎn)換為結(jié)果輸出,可以在添加一個全連接層即可,這里暫不關(guān)注這部分

#%%

import torch
import torch.nn as nn

# 定義輸入數(shù)據(jù)
input_size = 10   # 輸入特征的維度
sequence_length = 5   # 時間步個數(shù)
batch_size = 3   # 批次大小

# 創(chuàng)建隨機輸入數(shù)據(jù)
#輸入數(shù)據(jù)的維度為(sequence_length, batch_size, input_size),表示有sequence_length個時間步,
#每個時間步有batch_size個樣本,每個樣本的特征維度為input_size。
input_data = torch.randn(sequence_length, batch_size, input_size)
print("輸入數(shù)據(jù)",input_data)
# 定義RNN模型
# 定義RNN模型時,我們指定了輸入特征的維度input_size、隱藏層的維度hidden_size、隱藏層的層數(shù)num_layers等參數(shù)。
# batch_first=False表示輸入數(shù)據(jù)的維度中批次大小是否在第一個維度,我們在第二個維度上。
rnn = nn.RNN(input_size, hidden_size=20, num_layers=1, batch_first=False)
"""
在前向傳播過程中,我們將輸入數(shù)據(jù)傳遞給RNN模型,并得到輸出張量output和最后一個時間步的隱藏狀態(tài)hidden。
輸出張量的大小為(sequence_length, batch_size, hidden_size),表示每個時間步的隱藏層輸出。
最后一個時間步的隱藏狀態(tài)的大小為(num_layers, batch_size, hidden_size)。
"""
# 前向傳播,第二個參數(shù)h0未傳遞,默認為0
output, hidden = rnn(input_data)
print("最后一個隱藏層",hidden.shape)
print("輸出所有隱藏層",output.shape)

# 打印每個隱藏層的權(quán)重和偏置項
# weight_ih表示輸入到隱藏層的權(quán)重,weight_hh表示隱藏層到隱藏層的權(quán)重,注意這里使出是轉(zhuǎn)置的結(jié)果。
# bias_ih表示輸入到隱藏層的偏置,bias_hh表示隱藏層到隱藏層的偏置。
for name, param in rnn.named_parameters():
    if 'weight' in name or 'bias' in name:
        print(name, param.data)

輸出

最后一個隱藏層 torch.Size([1, 3, 20])
輸出所有隱藏層 torch.Size([5, 3, 20])

深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

權(quán)重為什么是10行20列參數(shù)卷積神經(jīng)網(wǎng)絡(luò)的原理
數(shù)據(jù)最外層的行的長度決定了前向傳播時間序列的個數(shù)。
這個input_size是輸入數(shù)據(jù)的維度,比如一個單詞轉(zhuǎn)換為one-hot后列就是字典的特征長度
這個hidden_size是隱藏層神經(jīng)元的個數(shù)也就是最終隱藏層輸入的特征數(shù)。
num_layer中是堆疊的多層隱藏層。

常見的結(jié)構(gòu)

RNN(循環(huán)神經(jīng)網(wǎng)絡(luò))常用的結(jié)果類型包括單輸入單輸出、單輸入多輸出、多輸入多輸出和多輸入單輸出。下面我將詳細解釋每種結(jié)果類型以及它們的應(yīng)用場景。

  1. 單輸入單輸出(Single Input Single Output,SISO):這是最常見的RNN結(jié)果類型,輸入是一個序列,輸出是一個單一的預(yù)測值。例如,給定一段文本,預(yù)測下一個詞語;給定一段時間序列數(shù)據(jù),預(yù)測下一個時間步的值。這種結(jié)果類型適用于許多序列預(yù)測任務(wù),如語言模型、時間序列預(yù)測等。
    舉個例子,假設(shè)我們要預(yù)測房屋價格,可能會使用多個特征,如房屋的面積、臥室數(shù)量、浴室數(shù)量等。這樣,我們可以將這些特征組合成一個特征向量作為模型的輸入,而模型的輸出則是預(yù)測的房屋價格。因此,線性回歸可以用來解決多特征到單個輸出的問題,因此被稱為單輸入單輸出模型。

  2. 單輸入多輸出(Single Input Multiple Output,SIMO):這種結(jié)果類型中,輸入是一個序列,但輸出是多個預(yù)測值。例如,給定一段文本,同時預(yù)測下一個詞語和該詞語的詞性標簽;給定一段音頻信號,同時預(yù)測語音情感和說話者身份。這種結(jié)果類型適用于需要同時預(yù)測多個相關(guān)任務(wù)的情況。

  3. 多輸入多輸出(Multiple Input Multiple Output,MIMO):這種結(jié)果類型中,有多個輸入序列和多個輸出序列。例如,在機器翻譯任務(wù)中,輸入是源語言的句子序列,輸出是目標語言的句子序列;在對話系統(tǒng)中,輸入是用戶的問題序列,輸出是系統(tǒng)的回答序列。這種結(jié)果類型適用于需要處理多個輸入和輸出序列的任務(wù),mimo有兩種一種輸入和輸出個數(shù)相等和不相等。

  4. 多輸入單輸出(Multiple Input Single Output,MISO):這種結(jié)果類型中,有多個輸入序列,但只有一個輸出。例如,在圖像描述生成任務(wù)中,輸入是圖像序列,輸出是對圖像的描述;在自動駕駛中,輸入是多個傳感器的數(shù)據(jù)序列,輸出是車輛的控制命令。這種結(jié)果類型適用于需要將多個輸入序列映射到單個輸出序列的任務(wù)。

線性回歸是一種簡單的機器學(xué)習(xí)模型,它的輸入可以是多個特征,但是輸出只有一個。這里的“單輸入單輸出”是指模型的輸入是一個向量(多個特征的組合),輸出是一個標量(一個預(yù)測值)。在線性回歸中,我們通過對輸入特征進行線性組合,得到一個預(yù)測值。因此,盡管輸入可以是多個元素,但輸出只有一個。

深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

雙向循環(huán)神經(jīng)網(wǎng)絡(luò)

普通的RNN只能依據(jù)之前時刻的時序信息來預(yù)測下一時刻的輸出,但在有些問題中,當(dāng)前時刻的輸出不僅和之前的狀態(tài)有關(guān),還可能和未來的狀態(tài)有關(guān)系。

比如預(yù)測一句話中缺失的單詞不僅需要根據(jù)前文來判斷,還需要考慮它后面的內(nèi)容,真正做到基于上下文判斷。

BRNN有兩個RNN上下疊加在一起組成的,輸出由這兩個RNN的狀態(tài)共同決定。
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
先對圖片和公式中的符號集中說明,需要時方便查看:

  • h t 1 h_t^1 ht1?表示t 時刻,Cell1 中從左到右獲得的 memory(信息);
  • W 1 , U 1 W^1,U^1 W1,U1 表示圖中 Cell1 的可學(xué)習(xí)參數(shù),W是隱藏層的參數(shù)U是輸入層參數(shù);
  • f 1 f_1 f1? 表示 Cell1 的激活函數(shù);
  • h t 2 h_t^2 ht2? 表示 t 時刻,Cell2 中從右到左獲得的 memory;
  • W 2 W^2 W2, U 2 U^2 U2 表示圖中 Cell2 的可學(xué)習(xí)參數(shù);
  • f 2 f_2 f2? 表示 Cell2 的激活函數(shù);
  • V V V 是輸出層的參數(shù),可以理解為 MLP;
  • f 3 f_3 f3? 是輸出層的激活函數(shù);
  • y t y_t yt? 是 t 時刻的輸出值;

在圖1-1中,對于 t 時刻的輸入 x t x_t xt? ,可以結(jié)合從左到右的 memory h t ? 1 1 h^1_{t-1} ht?11? , 獲得當(dāng)前時刻的 memory h t 1 h^1_t ht1?:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
同理也可以結(jié)合從右到左的 memory h t ? 1 2 h^2_{t?1} ht?12? , 獲得當(dāng)前時刻的 memory h t 2 h^2_t ht2?:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
然后將 h t 1 h^1_t ht1? h t 2 h^2_t ht2? 首尾級聯(lián)在一起通過輸出層網(wǎng)絡(luò) V V V 得到輸出 y t y_t yt? :
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
這樣對于任何一個時刻 t 可以看到從不同方向獲得的 memory, 使模型更容易優(yōu)化,加速了模型的收斂速度。

pytorch rnn

下面是一個使用PyTorch中nn.RNN模塊實現(xiàn)雙向RNN的最簡單例子:

import torch
import torch.nn as nn

# 定義輸入數(shù)據(jù)
input_size = 10   # 輸入特征的維度
sequence_length = 5   # 時間步個數(shù)
batch_size = 3   # 批次大小

# 創(chuàng)建隨機輸入數(shù)據(jù)
input_data = torch.randn(sequence_length, batch_size, input_size)

# 定義雙向RNN模型
rnn = nn.RNN(input_size, hidden_size=20, num_layers=1, batch_first=False, bidirectional=True)

# 前向傳播
output, hidden = rnn(input_data)

# 輸出結(jié)果
print("輸出張量大?。?, output.size())
print("最后一個時間步的隱藏狀態(tài)大?。?, hidden.size())

輸出

輸出張量大小: torch.Size([5, 3, 40])
最后一個時間步的隱藏狀態(tài)大?。?torch.Size([2, 3, 20])

這個例子中,輸入數(shù)據(jù)的維度和之前的例子相同。

定義雙向RNN模型時,我們在RNN模型的參數(shù)中設(shè)置bidirectional=True,表示我們希望構(gòu)建一個雙向RNN模型。

在前向傳播過程中,我們將輸入數(shù)據(jù)傳遞給雙向RNN模型,并得到輸出張量output和最后一個時間步的隱藏狀態(tài)hidden。輸出張量的大小為(sequence_length, batch_size, hidden_sizenum_directions),其中num_directions為2,表示正向和反向兩個方向。最后一個時間步的隱藏狀態(tài)的大小為(num_layersnum_directions, batch_size, hidden_size)。

雙向RNN可以同時利用過去和未來的信息,可以更好地捕捉到時間序列數(shù)據(jù)中的特征。你可以根據(jù)需要調(diào)整輸入數(shù)據(jù)的大小、RNN模型的參數(shù)等進行實驗。

雙向RNN的輸出通常是正向和反向隱藏狀態(tài)的組合,它們被存儲在一個數(shù)組中。具體來說,如果使用PyTorch中的nn.RNN模塊實現(xiàn)雙向RNN,輸出張量的形狀將是(sequence_length,batch_size, hidden_size * 2),其中hidden_size * 2表示正向和反向隱藏狀態(tài)的大小之和。這個輸出張量包含了每個時間步上正向和反向隱藏狀態(tài)的信息,可以在后續(xù)的任務(wù)中使用。
雙向rnn的最后的隱藏層大小是(2, batch_size, hidden_size)

Deep RNN(多層 RNN)

前文我們介紹的 RNN,是數(shù)據(jù)在時間維度上的變換。不論時間維度多長,只有一個 RNN 模塊, 即只有一組待學(xué)習(xí)參數(shù) (W, U),屬于單層 RNN。deep RNN 也叫做多層 RNN,顧名思義它由多個 RNN 級聯(lián)組成,是輸入數(shù)據(jù)在空間維度上變換。如圖, 這是 L 層的 RNN 架構(gòu)。每一層是一個單獨的RNN,共有L個RNN。
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

在每一層的水平方向,只有一組可學(xué)習(xí)參數(shù),如第 l l l 層的參數(shù) W l U l W^lU^l WlUl。水平方向是數(shù)據(jù)沿著時間維度變換,變換機制與單個 RNN 的機制一致,具體參考式上一篇文章。在每個時刻 t 的垂直方向,共有 L 組可學(xué)習(xí)參數(shù)( W i , U i W^i,U^i Wi,Ui) i = 1, 2, …, L。在第 l l l 層的第 t 時刻 Cell 的輸入數(shù)據(jù)來自 2 個方向:一個是來自上一層的輸出 h t l ? 1 h^{l?1}_t htl?1? :
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
一個是來自第 l l l 層, t ? 1 t ? 1 t?1 時刻的 memory 數(shù)據(jù) h t ? 1 l h^l_{t?1} ht?1l? :
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
所以 Cell 的輸出 h t l h^l_t htl?
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
本質(zhì)上,Deep RNN 在單個 RNN 的基礎(chǔ)上,將當(dāng)前時刻的輸入修改為上層的輸出。這樣 RNN 便完成了空間上的數(shù)據(jù)變換。額外提一下:DeepRNN的每一層也可以是一個雙向RNN。

pytorch rnn

下面是一個使用nn.RNN模塊實現(xiàn)多層RNN的最簡單例子:

import torch
import torch.nn as nn

# 定義輸入數(shù)據(jù)和參數(shù)
input_size = 5
hidden_size = 10
num_layers = 2
batch_size = 3
sequence_length = 4

# 創(chuàng)建輸入張量
input_tensor = torch.randn(sequence_length, batch_size, input_size)

# 創(chuàng)建多層RNN模型
rnn = nn.RNN(input_size, hidden_size, num_layers)

# 前向傳播
output, hidden = rnn(input_tensor)

# 打印輸出張量和隱藏狀態(tài)的大小
print("Output shape:", output.shape)
print("Hidden state shape:", hidden.shape)

在上面的例子中,我們首先定義了輸入數(shù)據(jù)的維度、RNN模型的參數(shù)(輸入大小、隱藏狀態(tài)大小和層數(shù)),以及批次大小和序列長度。然后,我們創(chuàng)建了一個輸入張量,其形狀為(sequence_length, batch_size, input_size)。接下來,我們使用nn.RNN模塊創(chuàng)建一個多層RNN模型,其中包含兩層。最后,我們通過將輸入張量傳遞給RNN模型的前向方法來進行前向傳播,并打印輸出張量和隱藏狀態(tài)的大小。

請注意,輸出張量的形狀為(sequence_length, batch_size, hidden_size),其中sequence_length和batch_size保持不變,hidden_size是隱藏狀態(tài)的大小。隱藏狀態(tài)的形狀為(num_layers, batch_size, hidden_size),其中num_layers是RNN模型的層數(shù)。

RNN缺點

梯度爆炸和消失問題

實踐中前面介紹的幾種RNNs并不能很好的處理較長的序列,RNN在訓(xùn)練中很容易發(fā)生梯度爆炸和梯度消失,這導(dǎo)致梯度不能在較長序列中一直傳遞下去,從而使RNN無法捕捉到長距離的影響。

通常來說,梯度爆炸更容易處理一些。因為梯度爆炸的時候,我們的程序會收到NaN錯誤。我們也可以設(shè)置一個梯度閾值,當(dāng)梯度超過這個閾值的時候可以直接截取。

梯度消失更難檢測,而且也更難處理一些??偟膩碚f,我們有三種方法應(yīng)對梯度消失問題:

1、合理的初始化權(quán)重值。初始化權(quán)重,使每個神經(jīng)元盡可能不要取極大或極小值,以躲開梯度消失的區(qū)域。

2、使用relu代替sigmoid和tanh作為激活函數(shù)。。

3、使用其他結(jié)構(gòu)的RNNs,比如長短時記憶網(wǎng)絡(luò)(LTSM)和Gated Recurrent Unit(GRU),這是最流行的做法

短期記憶

假如需要判斷用戶的說話意圖(問天氣、問時間、設(shè)置鬧鐘…),用戶說了一句“what time is it?”我們需要先對這句話進行分詞:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
然后按照順序輸入 RNN ,我們先將 “what”作為 RNN 的輸入,得到輸出「01」
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
然后,我們按照順序,將“time”輸入到 RNN 網(wǎng)絡(luò),得到輸出「02」。

這個過程我們可以看到,輸入 “time” 的時候,前面 “what” 的輸出也產(chǎn)生了影響(隱藏層中有一半是黑色的)。
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
以此類推,前面所有的輸入都對未來的輸出產(chǎn)生了影響,大家可以看到圓形隱藏層中包含了前面所有的顏色。如下圖所示:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
當(dāng)我們判斷意圖的時候,只需要最后一層的輸出「05」,如下圖所示:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
RNN 的缺點也比較明顯
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
通過上面的例子,我們已經(jīng)發(fā)現(xiàn),短期的記憶影響較大(如橙色區(qū)域),但是長期的記憶影響就很?。ㄈ绾谏途G色區(qū)域),這就是 RNN 存在的短期記憶問題。

  1. RNN 有短期記憶問題,無法處理很長的輸入序列
  2. 訓(xùn)練 RNN 需要投入極大的成本

RNN 的優(yōu)化算法

LSTM – 長短期記憶網(wǎng)絡(luò)

RNN 是一種死板的邏輯,越晚的輸入影響越大,越早的輸入影響越小,且無法改變這個邏輯。
LSTM 做的最大的改變就是打破了這個死板的邏輯,而改用了一套靈活了邏輯——只保留重要的信息。
簡單說就是:抓重點!
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
舉個例子,我們先快速的閱讀下面這段話:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
當(dāng)我們快速閱讀完之后,可能只會記住下面幾個重點:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
LSTM 類似上面的劃重點,他可以保留較長序列數(shù)據(jù)中的「重要信息」,忽略不重要的信息。這樣就解決了 RNN 短期記憶的問題。

原理

原始RNN的隱藏層只有一個狀態(tài),即h,它對于短期的輸入非常敏感。那么如果我們再增加一個門(gate)機制用于控制特征的流通和損失,即c,讓它來保存長期的狀態(tài),這就是長短時記憶網(wǎng)絡(luò)(Long Short Term Memory,LSTM)。
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
新增加的狀態(tài)c,稱為單元狀態(tài)。我們把LSTM按照時間維度展開:
其中圖像上的標識 σ \sigma σ標識使用sigmod激活到[0-1], tanh ? \tanh tanh激活到[-1,1]
? 是一個數(shù)學(xué)符號,表示逐元素乘積(element-wise product)或哈達瑪積(Hadamard product)。當(dāng)兩個相同維度的矩陣、向量或張量進行逐元素相乘時,可以使用 ? 符號來表示。

例如,對于兩個向量 [a1,a2,a3] ? [b1, b2, b3]=[a1b1,a2b2,a3*b3],它們的逐元素乘積可以表示
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
可以看到在t時刻,

LSTM的輸入有三個:當(dāng)前時刻網(wǎng)絡(luò)的輸出值 x t x_t xt?、上一時刻LSTM的輸出值 h t ? 1 h_{t?1} ht?1?、以及上一時刻的記憶單元向量 c t ? 1 c_{t?1} ct?1?

LSTM的輸出有兩個:當(dāng)前時刻LSTM輸出值 h t h_t ht?、當(dāng)前時刻的隱藏狀態(tài)向量 h t h_t ht?、和當(dāng)前時刻的記憶單元狀態(tài)向量 c t c_t ct?。

注意:記憶單元c在LSTM 層內(nèi)部結(jié)束工作,不向其他層輸出。LSTM的輸出僅有隱藏狀態(tài)向量h。

LSTM 的關(guān)鍵是單元狀態(tài),即貫穿圖表頂部的水平線,有點像傳送帶。這一部分一般叫做單元狀態(tài)(cell state)它自始至終存在于LSTM的整個鏈式系統(tǒng)中。
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

遺忘門

f t f_t ft?叫做遺忘門,表示 C t ? 1 C_{t?1} Ct?1?的哪些特征被用于計算 C t C_t Ct?。 f t f_t ft?是一個向量,向量的每個元素均位于(0~1)范圍內(nèi)。通常我們使用 sigmoid 作為激活函數(shù),sigmoid 的輸出是一個介于于(0~1)區(qū)間內(nèi)的值,但是當(dāng)你觀察一個訓(xùn)練好的LSTM時,你會發(fā)現(xiàn)門的值絕大多數(shù)都非常接近0或者1,其余的值少之又少。
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

輸入門

C t C_t Ct? 表示單元狀態(tài)更新值,由輸入數(shù)據(jù) x t x_t xt?和隱節(jié)點 h t ? 1 h_{t?1} ht?1?經(jīng)由一個神經(jīng)網(wǎng)絡(luò)層得到,單元狀態(tài)更新值的激活函數(shù)通常使用tanh。 i t i_t it?叫做輸入門,同 f t f_t ft? 一樣也是一個元素介于(0~1)區(qū)間內(nèi)的向量,同樣由 x t x_t xt? h t ? 1 h_{t?1} ht?1?經(jīng)由sigmoid激活函數(shù)計算而成
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

輸出門

最后,為了計算預(yù)測值 y t y^t yt和生成下個時間片完整的輸入,我們需要計算隱節(jié)點的輸出 h t h_t ht?。
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

lstm寫詩

首先我們研究下pytorch中l(wèi)stm的用法
單層lstm

sequence_length =3
batch_size =2
input_size =4
#這里如果是輸入比如[張三,李四,王五],一般實際使用需要通過embedding后生成一個[時間步是3,批量1(這里是1,但是如果是真實數(shù)據(jù)集可能有分批處理,就是實際的批次值),3(三個值的坐標表示一個張三或者李四)]
input=t.randn(sequence_length,batch_size,input_size)
lstmModel=nn.LSTM(input_size,3,1)
#其中,output是RNN每個時間步的輸出,hidden是最后一個時間步的隱藏狀態(tài)。
output, (h, c) =lstmModel(input)
#因為是3個時間步,每個時間步都有一個隱藏層,每個隱藏層都有2條數(shù)據(jù),隱藏層的維度是3,最終(3,2,3)
print("LSTM隱藏層輸出的維度",output.shape)
#
print("LSTM隱藏層最后一個時間步輸出的維度",h.shape)
print("LSTM隱藏層最后一個時間步細胞狀態(tài)",c.shape)

輸出

LSTM隱藏層輸出的維度 torch.Size([3, 2, 3])
LSTM隱藏層最后一個時間步輸出的維度 torch.Size([1, 2, 3])
LSTM隱藏層最后一個時間步細胞狀態(tài) torch.Size([1, 2, 3])

雙層lstm

sequence_length =3
batch_size =2
input_size =4
input=t.randn(sequence_length,batch_size,input_size)
lstmModel=nn.LSTM(input_size,3,num_layers=2)
#其中,output是RNN每個時間步的輸出,hidden是最后一個時間步的隱藏狀態(tài)。
output, (h, c) =lstmModel(input)
print("2層LSTM隱藏層輸出的維度",output.shape)
print("2層LSTM隱藏層最后一個時間步輸出的維度",h.shape)
print("2層LSTM隱藏層最后一個時間步細胞狀態(tài)",c.shape)

輸出:
2層LSTM隱藏層輸出的維度 torch.Size([3, 2, 3])
2層LSTM隱藏層最后一個時間步輸出的維度 torch.Size([2, 2, 3])
2層LSTM隱藏層最后一個時間步細胞狀態(tài) torch.Size([2, 2, 3])

2層的話輸出的是最后一層的隱藏層的輸出,h,c是一個時間步就有兩層的隱藏層和記憶細胞

開始寫詩的例子
這是項目的目錄結(jié)構(gòu)
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)

加載數(shù)據(jù)

實驗數(shù)據(jù)來自Github上中文愛好者收集的5萬多首唐詩,作者在此基礎(chǔ)上進行了一些數(shù)據(jù)處理,由于數(shù)據(jù)處理很耗時間,且不是pytorch學(xué)習(xí)的重點,這里省略。作者提供了一個numpy的壓縮包tang.npz,下載地址
數(shù)據(jù)具體結(jié)構(gòu)可參考,以下代碼main部分

from torch.utils.data import  Dataset,DataLoader
import numpy as np
class PoetryDataset(Dataset):
    def __init__(self,root):
        self.data=np.load(root, allow_pickle=True)
    def __len__(self):
        return len(self.data["data"])
    def __getitem__(self, index):
        return self.data["data"][index]
    def getData(self):
        return self.data["data"],self.data["ix2word"].item(),self.data["word2ix"].item()
if __name__=="__main__":
    datas=PoetryDataset("./tang.npz").data
    # data是一個57580 * 125的numpy數(shù)組,即總共有57580首詩歌,每首詩歌長度為125個字符(不足125補空格,超過125的丟棄)
    print(datas["data"].shape)
    #這里都字符已經(jīng)轉(zhuǎn)換成了索引
    print(datas["data"][0])
    # 使用item將numpy轉(zhuǎn)換為字典類型,ix2word存儲這下標對應(yīng)的字,比如{0: '憁', 1: '耀'}
    ix2word = datas['ix2word'].item()
    print(ix2word)
    # word2ix存儲這字對應(yīng)的小標,比如{'憁': 0, '耀': 1}
    word2ix = datas['word2ix'].item()
    print(word2ix)
    # 將某一首古詩轉(zhuǎn)換為索引表示,轉(zhuǎn)換后:[5272, 4236, 3286, 6933, 6010, 7066, 774, 4167, 2018, 70, 3951]
    str="床前明月光,疑是地上霜"
    print([word2ix[i] for i in str])
    #將第一首古詩打印出來
    print([ix2word[i] for i in datas["data"][0]])

定義模型
import torch.nn as nn
class Net(nn.Module):
    """
        :param vocab_size 表示輸入單詞的格式
        :param embedding_dim 表示將一個單詞映射到embedding_dim維度空間
        :param hidden_dim 表示lstm輸出隱藏層的維度
    """
    def __init__(self, vocab_size, embedding_dim, hidden_dim):
        super(Net, self).__init__()
        self.hidden_dim = hidden_dim
        #Embedding層,將單詞映射成vocab_size行embedding_dim列的矩陣,一行的坐標代表第一行的詞
        self.embeddings = nn.Embedding(vocab_size, embedding_dim)
        #兩層lstm,輸入詞向量的維度和隱藏層維度
        self.lstm = nn.LSTM(embedding_dim, self.hidden_dim, num_layers=2, batch_first=False)
        #最后將隱藏層的維度轉(zhuǎn)換為詞匯表的維度
        self.linear1 = nn.Linear(self.hidden_dim, vocab_size)

    def forward(self, input, hidden=None):
        #獲取輸入的數(shù)據(jù)的時間步和批次數(shù)
        seq_len, batch_size = input.size()
        #如果沒有傳入上一個時間的隱藏值,初始一個,注意是2層
        if hidden is None:
            h_0 = input.data.new(2, batch_size, self.hidden_dim).fill_(0).float()
            c_0 = input.data.new(2, batch_size, self.hidden_dim).fill_(0).float()
        else:
            h_0, c_0 = hidden
        #將輸入的數(shù)據(jù)embeddings為(input行數(shù),embedding_dim)
        embeds = self.embeddings(input)     # (seq_len, batch_size, embedding_dim), (1,1,128)
        output, hidden = self.lstm(embeds, (h_0, c_0))      #(seq_len, batch_size, hidden_dim), (1,1,256)
        output = self.linear1(output.view(seq_len*batch_size, -1))      # ((seq_len * batch_size),hidden_dim), (1,256) → (1,8293)
        return output, hidden

訓(xùn)練

下述代碼:input, target = (data[:-1, :]), (data[1:, :])解釋:

在使用LSTM進行詞預(yù)測時,輸入和標簽的設(shè)置是為了將輸入序列和目標序列對齊。

在語言模型中,我們希望根據(jù)前面的單詞來預(yù)測下一個單詞。因此,輸入序列是前面的單詞,而目標序列是下一個單詞。

考慮以下例子:
假設(shè)我們有一個句子:“I love deep learning.”
我們可以將其分解為以下形式的輸入和目標序列:
輸入序列:[“I”, “l(fā)ove”, “deep”]
目標序列:[“l(fā)ove”, “deep”, “l(fā)earning”]

在這個例子中,輸入序列是前面的單詞[“I”, “l(fā)ove”, “deep”],而目標序列是相應(yīng)的下一個單詞[“l(fā)ove”, “deep”, “l(fā)earning”]。

在代碼中,data是一個包含所有單詞的數(shù)據(jù)集,其中每一行代表一個單詞。將data切片為input和target時,我們使用data[:-1, :]作為輸入序列,即除了最后一個單詞。而data[1:, :]作為目標序列,即從第二個單詞開始。

這樣設(shè)置輸入和目標序列的目的是為了將輸入和標簽對齊,使得模型可以根據(jù)前面的單詞來預(yù)測下一個單詞。

import fire
import torch.nn as nn
import torch as t
from data.dataset import PoetryDataset
from models.model import Net
num_epochs=5
data_root="./data/tang.npz"
batch_size=10
def train(**kwargs):
    datasets=PoetryDataset(data_root)
    data,ix2word,word2ix=datasets.getData()
    lenData=len(data)
    data = t.from_numpy(data)
    dataloader = t.utils.data.DataLoader(data, batch_size=batch_size, shuffle=True, num_workers=1)
    #總共有8293的詞。模型定義:vocab_size, embedding_dim, hidden_dim = 8293 * 128 * 256
    model=Net(len(word2ix),128,256)
    #定義損失函數(shù)
    criterion = nn.CrossEntropyLoss()
    model=model.cuda()
    optimizer = t.optim.Adam(model.parameters(), lr=1e-3)
    iteri=0
    filename = "example.txt"
    totalIter=lenData*num_epochs/batch_size
    for epoch in range(num_epochs):  # 最大迭代次數(shù)為8
        for i, data in enumerate(dataloader):  # 一批次數(shù)據(jù) 128*125
            data = data.long().transpose(0,1).contiguous() .cuda()
            optimizer.zero_grad()
            input, target = (data[:-1, :]), (data[1:, :])
            output, _ = model(input)
            loss = criterion(output, target.view(-1))  # torch.Size([15872, 8293]), torch.Size([15872])
            loss.backward()
            optimizer.step()
            iteri+=1
            if(iteri%500==0):
                print(str(iteri+1)+"/"+str(totalIter)+"epoch")
            if (1 + i) % 1000 == 0:  # 每575個batch可視化一次
                with open(filename, "a") as file:
                    file.write(str(i) + ':' + generate(model, '床前明月光', ix2word, word2ix)+"\n")
    t.save(model.state_dict(), './checkpoints/model_poet_2.pth')
def generate(model, start_words, ix2word, word2ix):     # 給定幾個詞,根據(jù)這幾個詞生成一首完整的詩歌
    txt = []
    for word in start_words:
        txt.append(word)
    input = t.Tensor([word2ix['<START>']]).view(1,1).long()      # tensor([8291.]) → tensor([[8291.]]) → tensor([[8291]])
    input = input.cuda()
    hidden = None
    num = len(txt)
    for i in range(48):      # 最大生成長度
        output, hidden = model(input, hidden)
        if i < num:
            w = txt[i]
            input = (input.data.new([word2ix[w]])).view(1, 1)
        else:
            top_index = output.data[0].topk(1)[1][0]
            w = ix2word[top_index.item()]
            txt.append(w)
            input = (input.data.new([top_index])).view(1, 1)
        if w == '<EOP>':
            break
    return ''.join(txt)
if __name__=="__main__":
    fire.Fire()

5epoch,10batch,普通pc,GTX1050,2GB顯存,訓(xùn)練時間30分鐘。
50epoch 128batch colab免費gpu 16GB顯存,訓(xùn)練時間1小時

測試
def test():
    datasets = PoetryDataset(data_root)
    data, ix2word, word2ix = datasets.getData()
    modle = Net(len(word2ix), 128, 256)  # 模型定義:vocab_size, embedding_dim, hidden_dim —— 8293 * 128 * 256
    if t.cuda.is_available() == True:
        modle.cuda()
        modle.load_state_dict(t.load('./checkpoints/model_poet_2.pth'))
        modle.eval()
        name = input("請輸入您的開頭:")
        txt = generate(modle, name, ix2word, word2ix)
        print(txt)

由于才訓(xùn)練了5epoch效果不是太好,可視化loss后可多次epoch看看效果,還有個問題,如果輸入不變,生成的結(jié)果就是相同的,所以這個可能需要一個噪聲干擾。
5epoch版本效果

(env380) D:\code\deeplearn\learn_rnn\pytorch\4.nn模塊\案例\生成古詩\tang>python main.py test
請輸入您的開頭:唧唧復(fù)唧唧
唧唧復(fù)唧唧,不知何所如?君不見此地,不如此中生。一朝一杯酒,一日相追尋。一朝一杯酒,一醉一相逢。

(env380) D:\code\deeplearn\learn_rnn\pytorch\4.nn模塊\案例\生成古詩\tang>python main.py test
請輸入您的開頭:我兒小謙謙
我兒小謙謙,不是天地間。有時有所用,不是無為名。有時有所用,不是無生源。有時有所用,不是無生源。

50epoch版本效果

(env380) D:\code\deeplearn\learn_rnn\pytorch\4.nn模塊\案例\生成古詩\tang>python main.py test
請輸入您的開頭:我家小謙謙
我家小謙謙,今古何為郎。我生不相識,我心不可忘。我來不我見,我亦不得嘗。君今不我見,我亦不足傷。

(env380) D:\code\deeplearn\learn_rnn\pytorch\4.nn模塊\案例\生成古詩\tang>python main.py test
請輸入您的開頭:床前明月光
床前明月光,上客不可見。玉樓金閣深,玉瑟風(fēng)光緊。玉指滴芭蕉,飄飄出羅幕。玉堂無塵埃,玉節(jié)凌風(fēng)雷。
(env380) D:\code\deeplearn\learn_rnn\pytorch\4.nn模塊\案例\生成古詩\tang>python main.py test
請輸入您的開頭:唧唧復(fù)唧唧
唧唧復(fù)唧唧,胡兒女卿侯。妾本邯鄲道,相逢兩不游。妾心不可再,妾意不能休。妾本不相見,妾心如有鉤。

GRU

Gated Recurrent Unit – GRU 是 LSTM 的一個變體。他保留了 LSTM 劃重點,遺忘不重要信息的特點,在long-term 傳播的時候也不會被丟失。

LSTM 的參數(shù)太多,計算需要很長時間。因此,最近業(yè)界又提出了 GRU(Gated RecurrentUnit,門控循環(huán)單元)。GRU 保留了 LSTM使用門的理念,但是減少了參數(shù),縮短了計算時間。

相對于 LSTM 使用隱藏狀態(tài)和記憶單元兩條線,GRU只使用隱藏狀態(tài)。異同點如下:
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
GRU的計算圖
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
GRU計算圖,σ節(jié)點和tanh節(jié)點有專用的權(quán)重,節(jié)點內(nèi)部進行仿射變換(“1?”節(jié)點輸入x,輸出1 ? x)
深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)
GRU 中進行的計算由上述 4 個式子表示(這里 xt和 ht?1 都是行向量),如圖所示,GRU 沒有記憶單元,只有一個隱藏狀態(tài)h在時間方向上傳播。這里使用r和z共兩個門(LSTM 使用 3 個門),r稱為 reset 門,z稱為 update 門。

r(reset門)**決定在多大程度上“忽略”過去的隱藏狀態(tài)。根據(jù)公式2.3,如果r是 0,則新的隱藏狀態(tài)h~僅取決于輸入 x t x_t xt?。也就是說,此時過去的隱藏狀態(tài)將完全被忽略。

z(update門)**是更新隱藏狀態(tài)的門,它扮演了 LSTM 的 forget 門和input 門兩個角色。公式2.4 的(1?z)⊙ h t ? 1 h_{t?1} ht?1?部分充當(dāng) forget 門的功能,從過去的隱藏狀態(tài)中刪除應(yīng)該被遺忘的信息。z⊙ h ? h^~ h?的部分充當(dāng) input 門的功能,對新增的信息進行加權(quán)。文章來源地址http://www.zghlxwxcb.cn/news/detail-501819.html

到了這里,關(guān)于深度學(xué)習(xí)05-CNN循環(huán)神經(jīng)網(wǎng)絡(luò)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 深度學(xué)習(xí)03-卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    深度學(xué)習(xí)03-卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    CNN,即卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network),是一種常用于圖像和視頻處理的深度學(xué)習(xí)模型。與傳統(tǒng)神經(jīng)網(wǎng)絡(luò)相比,CNN 有著更好的處理圖像和序列數(shù)據(jù)的能力,因為它能夠自動學(xué)習(xí)圖像中的特征,并提取出最有用的信息。 CNN 的一個核心特點是卷積操作,它可以在圖像上進

    2024年02月05日
    瀏覽(25)
  • 深度學(xué)習(xí)1.卷積神經(jīng)網(wǎng)絡(luò)-CNN

    深度學(xué)習(xí)1.卷積神經(jīng)網(wǎng)絡(luò)-CNN

    目錄 卷積神經(jīng)網(wǎng)絡(luò) – CNN CNN 解決了什么問題? 需要處理的數(shù)據(jù)量太大 保留圖像特征 人類的視覺原理 卷積神經(jīng)網(wǎng)絡(luò)-CNN 的基本原理 卷積——提取特征 池化層(下采樣)——數(shù)據(jù)降維,避免過擬合 全連接層——輸出結(jié)果 CNN 有哪些實際應(yīng)用? 總結(jié) 百度百科+維基百科 卷積層

    2024年02月11日
    瀏覽(28)
  • 深度學(xué)習(xí)入門(三):卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    深度學(xué)習(xí)入門(三):卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    給定一張圖片,計算機需要模型判斷圖里的東西是什么? (car、truck、airplane、ship、horse) CONV:卷積計算層,線性乘積求和 RELU:激勵層,激活函數(shù) POOL:池化層,取區(qū)域平均或最大(MAX POOL) PC:全連接層 對CNN來說,它是一塊一塊進行對比的,“小塊”稱之為Features特征。

    2024年02月11日
    瀏覽(37)
  • 深度學(xué)習(xí)入門教學(xué)——卷積神經(jīng)網(wǎng)絡(luò)CNN

    深度學(xué)習(xí)入門教學(xué)——卷積神經(jīng)網(wǎng)絡(luò)CNN

    1、應(yīng)用領(lǐng)域 檢測任務(wù) 分類與檢索 超分辨率重構(gòu) 2、卷積網(wǎng)絡(luò)與傳統(tǒng)網(wǎng)咯的區(qū)別 傳統(tǒng)神經(jīng)網(wǎng)絡(luò)和卷積神經(jīng)網(wǎng)絡(luò)都是用來 提取特征 的。 神經(jīng)網(wǎng)絡(luò): 可以將其看作是一個二維的。 卷積神經(jīng)網(wǎng)絡(luò): 可以將其看作是一個三維的。 ?3、整體框架 該層主要是對原始圖像數(shù)據(jù)進行預(yù)處

    2024年02月10日
    瀏覽(25)
  • 【深度學(xué)習(xí)】實驗05 構(gòu)造神經(jīng)網(wǎng)絡(luò)示例

    神經(jīng)網(wǎng)絡(luò)是一種仿生學(xué)原理的機器學(xué)習(xí)算法,靈感來源于人腦的神經(jīng)系統(tǒng)。它由多個神經(jīng)元(或稱為節(jié)點)組成,這些神經(jīng)元通過連接權(quán)重形成復(fù)雜的網(wǎng)絡(luò)結(jié)構(gòu),用來學(xué)習(xí)和提取輸入數(shù)據(jù)的特征,并用于分類、回歸、聚類等任務(wù)。 注明:該代碼用來訓(xùn)練一個神經(jīng)網(wǎng)絡(luò),網(wǎng)絡(luò)擬

    2024年02月10日
    瀏覽(24)
  • 【深度學(xué)習(xí)_TensorFlow】卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    【深度學(xué)習(xí)_TensorFlow】卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    這篇文章的行文思路如下: 先根據(jù)視頻了解卷積和卷積神經(jīng)網(wǎng)絡(luò)的整體框架 接著了解卷積神經(jīng)網(wǎng)絡(luò)構(gòu)建過程中的一些重要操作,包括內(nèi)積、填充、池化。 然后介紹卷積層如何實現(xiàn)。 最后用卷積神經(jīng)網(wǎng)絡(luò)的開山之作(LeNet-5)來進行上手練習(xí)。 最近學(xué)習(xí)信號與系統(tǒng)的時候,了

    2024年02月07日
    瀏覽(97)
  • 【深度學(xué)習(xí)】最強算法之:卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    【深度學(xué)習(xí)】最強算法之:卷積神經(jīng)網(wǎng)絡(luò)(CNN)

    小屌絲 :魚哥, 看下這個流程圖,我沒看明白 小魚 :啥流程圖。 小屌絲 :你看,就是這個。 小魚 :嗯,不錯,不錯。 小屌絲 :能不能給我講一講這個? 小魚 :你要了解CNN ? 小屌絲 :CNN 是? 小魚 :…你這… 深度學(xué)習(xí)知道嗎? 小屌絲 :知道啊 小魚 :你都知道深度

    2024年04月09日
    瀏覽(28)
  • 學(xué)習(xí)筆記:深度學(xué)習(xí)(3)——卷積神經(jīng)網(wǎng)絡(luò)(CNN)理論篇

    學(xué)習(xí)筆記:深度學(xué)習(xí)(3)——卷積神經(jīng)網(wǎng)絡(luò)(CNN)理論篇

    學(xué)習(xí)時間:2022.04.10~2022.04.12 CNN(Convolutional Neural Networks, ConvNets, 卷積神經(jīng)網(wǎng)絡(luò))是神經(jīng)網(wǎng)絡(luò)的一種,是理解圖像內(nèi)容的最佳學(xué)習(xí)算法之一,并且在圖像分割、分類、檢測和檢索相關(guān)任務(wù)中表現(xiàn)出色。 3.1.1 什么是CNN? CNN是一種帶有卷積結(jié)構(gòu)的前饋神經(jīng)網(wǎng)絡(luò), 卷積結(jié)構(gòu) 可以減少

    2024年02月03日
    瀏覽(31)
  • 深度學(xué)習(xí)循環(huán)神經(jīng)網(wǎng)絡(luò)

    循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,RNN)是一種廣泛應(yīng)用于序列數(shù)據(jù)、自然語言處理等領(lǐng)域的神經(jīng)網(wǎng)絡(luò)。與傳統(tǒng)的前饋神經(jīng)網(wǎng)絡(luò)不同,循環(huán)神經(jīng)網(wǎng)絡(luò)的輸入不僅取決于當(dāng)前輸入,還取決于之前的狀態(tài)。這使得循環(huán)神經(jīng)網(wǎng)絡(luò)可以對序列數(shù)據(jù)進行建模,具有記憶和遞歸的能力。

    2024年02月13日
    瀏覽(19)
  • 深度學(xué)習(xí)入門——卷積神經(jīng)網(wǎng)絡(luò)CNN基本原理+實戰(zhàn)

    深度學(xué)習(xí)入門——卷積神經(jīng)網(wǎng)絡(luò)CNN基本原理+實戰(zhàn)

    ? 卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network,CNN)是深度學(xué)習(xí)技術(shù)中最基礎(chǔ)的網(wǎng)絡(luò)結(jié)構(gòu),模擬人腦工作,具備強大的特征學(xué)習(xí)能力。CNN結(jié)構(gòu)主要由兩部分組成:特征提取部分和分類部分color{blue}{特征提取部分和分類部分}特征提取部分和分類部分。特征提取部分網(wǎng)絡(luò)將執(zhí)行一系列

    2024年01月21日
    瀏覽(37)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包