<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 6.3 語言模型數據集(周杰倫專輯歌詞) 本節將介紹如何預處理一個語言模型數據集,并將其轉換成字符級循環神經網絡所需要的輸入格式。為此,我們收集了周杰倫從第一張專輯《Jay》到第十張專輯《跨時代》中的歌詞,并在后面幾節里應用循環神經網絡來訓練一個語言模型。當模型訓練好后,我們就可以用這個模型來創作歌詞。 ## 6.3.1 讀取數據集 首先讀取這個數據集,看看前40個字符是什么樣的。 ``` python import torch import random import zipfile with zipfile.ZipFile('../../data/jaychou_lyrics.txt.zip') as zin: with zin.open('jaychou_lyrics.txt') as f: corpus_chars = f.read().decode('utf-8') corpus_chars[:40] ``` 輸出: ``` '想要有直升機\n想要和你飛到宇宙去\n想要和你融化在一起\n融化在宇宙里\n我每天每天每' ``` 這個數據集有6萬多個字符。為了打印方便,我們把換行符替換成空格,然后僅使用前1萬個字符來訓練模型。 ``` python corpus_chars = corpus_chars.replace('\n', ' ').replace('\r', ' ') corpus_chars = corpus_chars[0:10000] ``` ## 6.3.2 建立字符索引 我們將每個字符映射成一個從0開始的連續整數,又稱索引,來方便之后的數據處理。為了得到索引,我們將數據集里所有不同字符取出來,然后將其逐一映射到索引來構造詞典。接著,打印`vocab_size`,即詞典中不同字符的個數,又稱詞典大小。 ``` python idx_to_char = list(set(corpus_chars)) char_to_idx = dict([(char, i) for i, char in enumerate(idx_to_char)]) vocab_size = len(char_to_idx) vocab_size # 1027 ``` 之后,將訓練數據集中每個字符轉化為索引,并打印前20個字符及其對應的索引。 ``` python corpus_indices = [char_to_idx[char] for char in corpus_chars] sample = corpus_indices[:20] print('chars:', ''.join([idx_to_char[idx] for idx in sample])) print('indices:', sample) ``` 輸出: ``` chars: 想要有直升機 想要和你飛到宇宙去 想要和 indices: [250, 164, 576, 421, 674, 653, 357, 250, 164, 850, 217, 910, 1012, 261, 275, 366, 357, 250, 164, 850] ``` 我們將以上代碼封裝在`d2lzh_pytorch`包里的`load_data_jay_lyrics`函數中,以方便后面章節調用。調用該函數后會依次得到`corpus_indices`、`char_to_idx`、`idx_to_char`和`vocab_size`這4個變量。 ## 6.3.3 時序數據的采樣 在訓練中我們需要每次隨機讀取小批量樣本和標簽。與之前章節的實驗數據不同的是,時序數據的一個樣本通常包含連續的字符。假設時間步數為5,樣本序列為5個字符,即“想”“要”“有”“直”“升”。該樣本的標簽序列為這些字符分別在訓練集中的下一個字符,即“要”“有”“直”“升”“機”。我們有兩種方式對時序數據進行采樣,分別是隨機采樣和相鄰采樣。 ### 6.3.3.1 隨機采樣 下面的代碼每次從數據里隨機采樣一個小批量。其中批量大小`batch_size`指每個小批量的樣本數,`num_steps`為每個樣本所包含的時間步數。 在隨機采樣中,每個樣本是原始序列上任意截取的一段序列。相鄰的兩個隨機小批量在原始序列上的位置不一定相毗鄰。因此,我們無法用一個小批量最終時間步的隱藏狀態來初始化下一個小批量的隱藏狀態。在訓練模型時,每次隨機采樣前都需要重新初始化隱藏狀態。 ``` python # 本函數已保存在d2lzh_pytorch包中方便以后使用 def data_iter_random(corpus_indices, batch_size, num_steps, device=None): # 減1是因為輸出的索引x是相應輸入的索引y加1 num_examples = (len(corpus_indices) - 1) // num_steps epoch_size = num_examples // batch_size example_indices = list(range(num_examples)) random.shuffle(example_indices) # 返回從pos開始的長為num_steps的序列 def _data(pos): return corpus_indices[pos: pos + num_steps] if device is None: device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') for i in range(epoch_size): # 每次讀取batch_size個隨機樣本 i = i * batch_size batch_indices = example_indices[i: i + batch_size] X = [_data(j * num_steps) for j in batch_indices] Y = [_data(j * num_steps + 1) for j in batch_indices] yield torch.tensor(X, dtype=torch.float32, device=device), torch.tensor(Y, dtype=torch.float32, device=device) ``` 讓我們輸入一個從0到29的連續整數的人工序列。設批量大小和時間步數分別為2和6。打印隨機采樣每次讀取的小批量樣本的輸入`X`和標簽`Y`。可見,相鄰的兩個隨機小批量在原始序列上的位置不一定相毗鄰。 ``` python my_seq = list(range(30)) for X, Y in data_iter_random(my_seq, batch_size=2, num_steps=6): print('X: ', X, '\nY:', Y, '\n') ``` 輸出: ``` X: tensor([[18., 19., 20., 21., 22., 23.], [12., 13., 14., 15., 16., 17.]]) Y: tensor([[19., 20., 21., 22., 23., 24.], [13., 14., 15., 16., 17., 18.]]) X: tensor([[ 0., 1., 2., 3., 4., 5.], [ 6., 7., 8., 9., 10., 11.]]) Y: tensor([[ 1., 2., 3., 4., 5., 6.], [ 7., 8., 9., 10., 11., 12.]]) ``` ### 6.3.3.2 相鄰采樣 除對原始序列做隨機采樣之外,我們還可以令相鄰的兩個隨機小批量在原始序列上的位置相毗鄰。這時候,我們就可以用一個小批量最終時間步的隱藏狀態來初始化下一個小批量的隱藏狀態,從而使下一個小批量的輸出也取決于當前小批量的輸入,并如此循環下去。這對實現循環神經網絡造成了兩方面影響:一方面, 在訓練模型時,我們只需在每一個迭代周期開始時初始化隱藏狀態;另一方面,當多個相鄰小批量通過傳遞隱藏狀態串聯起來時,模型參數的梯度計算將依賴所有串聯起來的小批量序列。同一迭代周期中,隨著迭代次數的增加,梯度的計算開銷會越來越大。 為了使模型參數的梯度計算只依賴一次迭代讀取的小批量序列,我們可以在每次讀取小批量前將隱藏狀態從計算圖中分離出來。我們將在下一節(循環神經網絡的從零開始實現)的實現中了解這種處理方式。 ``` python # 本函數已保存在d2lzh_pytorch包中方便以后使用 def data_iter_consecutive(corpus_indices, batch_size, num_steps, device=None): if device is None: device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') corpus_indices = torch.tensor(corpus_indices, dtype=torch.float32, device=device) data_len = len(corpus_indices) batch_len = data_len // batch_size indices = corpus_indices[0: batch_size*batch_len].view(batch_size, batch_len) epoch_size = (batch_len - 1) // num_steps for i in range(epoch_size): i = i * num_steps X = indices[:, i: i + num_steps] Y = indices[:, i + 1: i + num_steps + 1] yield X, Y ``` 同樣的設置下,打印相鄰采樣每次讀取的小批量樣本的輸入`X`和標簽`Y`。相鄰的兩個隨機小批量在原始序列上的位置相毗鄰。 ``` python for X, Y in data_iter_consecutive(my_seq, batch_size=2, num_steps=6): print('X: ', X, '\nY:', Y, '\n') ``` 輸出: ``` X: tensor([[ 0., 1., 2., 3., 4., 5.], [15., 16., 17., 18., 19., 20.]]) Y: tensor([[ 1., 2., 3., 4., 5., 6.], [16., 17., 18., 19., 20., 21.]]) X: tensor([[ 6., 7., 8., 9., 10., 11.], [21., 22., 23., 24., 25., 26.]]) Y: tensor([[ 7., 8., 9., 10., 11., 12.], [22., 23., 24., 25., 26., 27.]]) ``` ## 小結 * 時序數據采樣方式包括隨機采樣和相鄰采樣。使用這兩種方式的循環神經網絡訓練在實現上略有不同。 ----------- > 注:除代碼外本節與原書此節基本相同,[原書傳送門](https://zh.d2l.ai/chapter_recurrent-neural-networks/lang-model-dataset.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>

                              哎呀哎呀视频在线观看