<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 6.8 長短期記憶(LSTM) 本節將介紹另一種常用的門控循環神經網絡:長短期記憶(long short-term memory,LSTM)[1]。它比門控循環單元的結構稍微復雜一點。 ## 6.8.1 長短期記憶 LSTM 中引入了3個門,即輸入門(input gate)、遺忘門(forget gate)和輸出門(output gate),以及與隱藏狀態形狀相同的記憶細胞(某些文獻把記憶細胞當成一種特殊的隱藏狀態),從而記錄額外的信息。 ### 6.8.1.1 輸入門、遺忘門和輸出門 與門控循環單元中的重置門和更新門一樣,如圖6.7所示,長短期記憶的門的輸入均為當前時間步輸入`$ \boldsymbol{X}_t $` 與上一時間步隱藏狀態`$ \boldsymbol{H}_{t-1} $`,輸出由激活函數為sigmoid函數的全連接層計算得到。如此一來,這3個門元素的值域均為`$ [0,1] $`。 :-: ![](https://img.kancloud.cn/b2/3a/b23aa494adaef98d43193604556a3895.svg) <div align=center>圖6.7 長短期記憶中輸入門、遺忘門和輸出門的計算</div> 具體來說,假設隱藏單元個數為`$ h $`,給定時間步`$ t $`的小批量輸入`$ \boldsymbol{X}_t \in \mathbb{R}^{n \times d} $`(樣本數為`$ n $`,輸入個數為`$ d $`)和上一時間步隱藏狀態`$ \boldsymbol{H}_{t-1} \in \mathbb{R}^{n \times h} $` 。 時間步`$ t $`的輸入門`$ \boldsymbol{I}_t \in \mathbb{R}^{n \times h} $`、遺忘門`$ \boldsymbol{F}_t \in \mathbb{R}^{n \times h} $`和輸出門`$ \boldsymbol{O}_t \in \mathbb{R}^{n \times h} $`分別計算如下: ```[tex] \begin{aligned} \boldsymbol{I}_t &= \sigma(\boldsymbol{X}_t \boldsymbol{W}_{xi} + \boldsymbol{H}_{t-1} \boldsymbol{W}_{hi} + \boldsymbol{b}_i),\\ \boldsymbol{F}_t &= \sigma(\boldsymbol{X}_t \boldsymbol{W}_{xf} + \boldsymbol{H}_{t-1} \boldsymbol{W}_{hf} + \boldsymbol{b}_f),\\ \boldsymbol{O}_t &= \sigma(\boldsymbol{X}_t \boldsymbol{W}_{xo} + \boldsymbol{H}_{t-1} \boldsymbol{W}_{ho} + \boldsymbol{b}_o), \end{aligned} ``` 其中的`$ \boldsymbol{W}_{xi}, \boldsymbol{W}_{xf}, \boldsymbol{W}_{xo} \in \mathbb{R}^{d \times h} $`和`$ \boldsymbol{W}_{hi}, \boldsymbol{W}_{hf}, \boldsymbol{W}_{ho} \in \mathbb{R}^{h \times h} $`是權重參數,`$ \boldsymbol{b}_i, \boldsymbol{b}_f, \boldsymbol{b}_o \in \mathbb{R}^{1 \times h} $`是偏差參數。 ### 6.8.1.2 候選記憶細胞 接下來,長短期記憶需要計算候選記憶細胞`$ \tilde{\boldsymbol{C}}_t $` 。它的計算與上面介紹的3個門類似,但使用了值域在`$ [-1, 1] $`的tanh函數作為激活函數,如圖6.8所示。 :-: ![](https://img.kancloud.cn/34/a2/34a2709ff8454e37125d899f064c9ebf.svg) <div align=center>圖6.8 長短期記憶中候選記憶細胞的計算</div> 具體來說,時間步`$ t $`的候選記憶細胞`$ \tilde{\boldsymbol{C}}_t \in \mathbb{R}^{n \times h} $` 的計算為 ```[tex] \tilde{\boldsymbol{C}}_t = \text{tanh}(\boldsymbol{X}_t \boldsymbol{W}_{xc} + \boldsymbol{H}_{t-1} \boldsymbol{W}_{hc} + \boldsymbol{b}_c), ``` 其中`$ \boldsymbol{W}_{xc} \in \mathbb{R}^{d \times h} $`和`$ \boldsymbol{W}_{hc} \in \mathbb{R}^{h \times h} $`是權重參數,`$ \boldsymbol{b}_c \in \mathbb{R}^{1 \times h} $`是偏差參數。 ### 6.8.1.3 記憶細胞 我們可以通過元素值域在`$ [0, 1] $`的輸入門、遺忘門和輸出門來控制隱藏狀態中信息的流動,這一般也是通過使用按元素乘法(符號為`$ \odot $`)來實現的。當前時間步記憶細胞`$ \boldsymbol{C}_t \in \mathbb{R}^{n \times h} $`的計算組合了上一時間步記憶細胞和當前時間步候選記憶細胞的信息,并通過遺忘門和輸入門來控制信息的流動: ```[tex] \boldsymbol{C}_t = \boldsymbol{F}_t \odot \boldsymbol{C}_{t-1} + \boldsymbol{I}_t \odot \tilde{\boldsymbol{C}}_t. ``` 如圖6.9所示,遺忘門控制上一時間步的記憶細胞`$ \boldsymbol{C}_{t-1} $`中的信息是否傳遞到當前時間步,而輸入門則控制當前時間步的輸入`$ \boldsymbol{X}_t $`通過候選記憶細胞`$ \tilde{\boldsymbol{C}}_t $`如何流入當前時間步的記憶細胞。如果遺忘門一直近似1且輸入門一直近似0,過去的記憶細胞將一直通過時間保存并傳遞至當前時間步。這個設計可以應對循環神經網絡中的梯度衰減問題,并更好地捕捉時間序列中時間步距離較大的依賴關系。 :-: ![](https://img.kancloud.cn/e3/a6/e3a628fdc218b5fc5aaec8bad594735f.svg) <div align=center>圖6.9 長短期記憶中記憶細胞的計算</div> ### 6.8.1.4 隱藏狀態 有了記憶細胞以后,接下來我們還可以通過輸出門來控制從記憶細胞到隱藏狀態`$ \boldsymbol{H}_t \in \mathbb{R}^{n \times h} $`的信息的流動: ```[tex] \boldsymbol{H}_t = \boldsymbol{O}_t \odot \text{tanh}(\boldsymbol{C}_t). ``` 這里的tanh函數確保隱藏狀態元素值在-1到1之間。需要注意的是,當輸出門近似1時,記憶細胞信息將傳遞到隱藏狀態供輸出層使用;當輸出門近似0時,記憶細胞信息只自己保留。圖6.10展示了長短期記憶中隱藏狀態的計算。 :-: ![](https://img.kancloud.cn/0a/f6/0af67fda8a6253a7e307c41a53f70f94.svg) <div align=center>圖6.10 長短期記憶中隱藏狀態的計算</div> ## 6.8.2 讀取數據集 下面我們開始實現并展示長短期記憶。和前幾節中的實驗一樣,這里依然使用周杰倫歌詞數據集來訓練模型作詞。 ``` python import numpy as np import torch from torch import nn, optim import torch.nn.functional as F import sys sys.path.append("..") import d2lzh_pytorch as d2l device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') (corpus_indices, char_to_idx, idx_to_char, vocab_size) = d2l.load_data_jay_lyrics() ``` ## 6.8.3 從零開始實現 我們先介紹如何從零開始實現長短期記憶。 ### 6.8.3.1 初始化模型參數 下面的代碼對模型參數進行初始化。超參數`num_hiddens`定義了隱藏單元的個數。 ``` python num_inputs, num_hiddens, num_outputs = vocab_size, 256, vocab_size print('will use', device) def get_params(): def _one(shape): ts = torch.tensor(np.random.normal(0, 0.01, size=shape), device=device, dtype=torch.float32) return torch.nn.Parameter(ts, requires_grad=True) def _three(): return (_one((num_inputs, num_hiddens)), _one((num_hiddens, num_hiddens)), torch.nn.Parameter(torch.zeros(num_hiddens, device=device, dtype=torch.float32), requires_grad=True)) W_xi, W_hi, b_i = _three() # 輸入門參數 W_xf, W_hf, b_f = _three() # 遺忘門參數 W_xo, W_ho, b_o = _three() # 輸出門參數 W_xc, W_hc, b_c = _three() # 候選記憶細胞參數 # 輸出層參數 W_hq = _one((num_hiddens, num_outputs)) b_q = torch.nn.Parameter(torch.zeros(num_outputs, device=device, dtype=torch.float32), requires_grad=True) return nn.ParameterList([W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc, b_c, W_hq, b_q]) ``` ## 6.8.4 定義模型 在初始化函數中,長短期記憶的隱藏狀態需要返回額外的形狀為(批量大小, 隱藏單元個數)的值為0的記憶細胞。 ``` python def init_lstm_state(batch_size, num_hiddens, device): return (torch.zeros((batch_size, num_hiddens), device=device), torch.zeros((batch_size, num_hiddens), device=device)) ``` 下面根據長短期記憶的計算表達式定義模型。需要注意的是,只有隱藏狀態會傳遞到輸出層,而記憶細胞不參與輸出層的計算。 ``` python def lstm(inputs, state, params): [W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc, b_c, W_hq, b_q] = params (H, C) = state outputs = [] for X in inputs: I = torch.sigmoid(torch.matmul(X, W_xi) + torch.matmul(H, W_hi) + b_i) F = torch.sigmoid(torch.matmul(X, W_xf) + torch.matmul(H, W_hf) + b_f) O = torch.sigmoid(torch.matmul(X, W_xo) + torch.matmul(H, W_ho) + b_o) C_tilda = torch.tanh(torch.matmul(X, W_xc) + torch.matmul(H, W_hc) + b_c) C = F * C + I * C_tilda H = O * C.tanh() Y = torch.matmul(H, W_hq) + b_q outputs.append(Y) return outputs, (H, C) ``` ### 6.8.4.1 訓練模型并創作歌詞 同上一節一樣,我們在訓練模型時只使用相鄰采樣。設置好超參數后,我們將訓練模型并根據前綴“分開”和“不分開”分別創作長度為50個字符的一段歌詞。 ``` python num_epochs, num_steps, batch_size, lr, clipping_theta = 160, 35, 32, 1e2, 1e-2 pred_period, pred_len, prefixes = 40, 50, ['分開', '不分開'] ``` 我們每過40個迭代周期便根據當前訓練的模型創作一段歌詞。 ``` python d2l.train_and_predict_rnn(lstm, get_params, init_lstm_state, num_hiddens, vocab_size, device, corpus_indices, idx_to_char, char_to_idx, False, num_epochs, num_steps, lr, clipping_theta, batch_size, pred_period, pred_len, prefixes) ``` 輸出: ``` epoch 40, perplexity 211.416571, time 1.37 sec - 分開 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 - 不分開 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 我不的我 epoch 80, perplexity 67.048346, time 1.35 sec - 分開 我想你你 我不要再想 我不要這我 我不要這我 我不要這我 我不要這我 我不要這我 我不要這我 我不 - 不分開 我想你你想你 我不要這不樣 我不要這我 我不要這我 我不要這我 我不要這我 我不要這我 我不要這我 epoch 120, perplexity 15.552743, time 1.36 sec - 分開 我想帶你的微笑 像這在 你想我 我想你 說你我 說你了 說給怎么么 有你在空 你在在空 在你的空 - 不分開 我想要你已經堡 一樣樣 說你了 我想就這樣著你 不知不覺 你已了離開活 后知后覺 我該了這生活 我 epoch 160, perplexity 4.274031, time 1.35 sec - 分開 我想帶你 你不一外在半空 我只能夠遠遠著她 這些我 你想我難難頭 一話看人對落我一望望我 我不那這 - 不分開 我想你這生堡 我知好煩 你不的節我 后知后覺 我該了這節奏 后知后覺 又過了一個秋 后知后覺 我該 ``` ## 6.8.5 簡潔實現 在Gluon中我們可以直接調用`rnn`模塊中的`LSTM`類。 ``` python lr = 1e-2 # 注意調整學習率 lstm_layer = nn.LSTM(input_size=vocab_size, hidden_size=num_hiddens) model = d2l.RNNModel(lstm_layer, vocab_size) d2l.train_and_predict_rnn_pytorch(model, num_hiddens, vocab_size, device, corpus_indices, idx_to_char, char_to_idx, num_epochs, num_steps, lr, clipping_theta, batch_size, pred_period, pred_len, prefixes) ``` 輸出: ``` epoch 40, perplexity 1.020401, time 1.54 sec - 分開始想擔 媽跟我 一定是我媽在 因為分手前那句抱歉 在感動 穿梭時間的畫面的鐘 從反方向開始移動 回到 - 不分開始想像 媽跟我 我將我的寂寞封閉 然后在這里 不限日期 然后將過去 慢慢溫習 讓我愛上你 那場悲劇 epoch 80, perplexity 1.011164, time 1.34 sec - 分開始想擔 你的 從前的可愛女人 溫柔的讓我心疼的可愛女人 透明的讓我感動的可愛女人 壞壞的讓我瘋狂的可 - 不分開 我滿了 讓我瘋狂的可愛女人 漂亮的讓我面紅的可愛女人 溫柔的讓我心疼的可愛女人 透明的讓我感動的可 epoch 120, perplexity 1.025348, time 1.39 sec - 分開始共渡每一天 手牽手 一步兩步三步四步望著天 看星星 一顆兩顆三顆四顆 連成線背著背默默許下心愿 看 - 不分開 我不懂 說了沒用 他的笑容 有何不同 在你心中 我不再受寵 我的天空 是雨是風 還是彩虹 你在操縱 epoch 160, perplexity 1.017492, time 1.42 sec - 分開始鄉相信命運 感謝地心引力 讓我碰到你 漂亮的讓我面紅的可愛女人 溫柔的讓我心疼的可愛女人 透明的讓 - 不分開 我不能再想 我不 我不 我不能 愛情走的太快就像龍卷風 不能承受我已無處可躲 我不要再想 我不要再 ``` ## 小結 * 長短期記憶的隱藏層輸出包括隱藏狀態和記憶細胞。只有隱藏狀態會傳遞到輸出層。 * 長短期記憶的輸入門、遺忘門和輸出門可以控制信息的流動。 * 長短期記憶可以應對循環神經網絡中的梯度衰減問題,并更好地捕捉時間序列中時間步距離較大的依賴關系。 ## 參考文獻 [1] Hochreiter, S., & Schmidhuber, J. (1997). Long short-term memory. Neural computation, 9(8), 1735-1780. ----------- > 注:除代碼外本節與原書此節基本相同,[原書傳送門](https://zh.d2l.ai/chapter_recurrent-neural-networks/lstm.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看