零基礎-動手學深度學習-8.3. 語言模型和數據集

很至關重要的一章:

8.3.1.?學習語言模型

8.3.2.?馬爾可夫模型與n元語法?

n元語法看的序列長度是固定的,?存儲的序列長是有限且可控的,使用統計方法的時候通常使用這個模型!!!統計方法!!!

8.3.3.?自然語言統計?

?我們看看在真實數據上如果進行自然語言統計。 根據?8.2節中介紹的時光機器數據集構建詞表, 并打印前10個最常用的(頻率最高的)單詞。

import random
import torch
from d2l import torch as d2ltokens = d2l.tokenize(d2l.read_time_machine())
# 因為每個文本行不一定是一個句子或一個段落,因此我們把所有文本行拼接到一起
corpus = [token for line in tokens for token in line]
vocab = d2l.Vocab(corpus)
vocab.token_freqs[:10]輸出:
[('the', 2261),('i', 1267),('and', 1245),('of', 1155),('a', 816),('to', 695),('was', 552),('in', 541),('that', 443),('my', 440)]

在自然語言處理(NLP)、文本分析和機器學習領域,"corpus"(語料庫)是指一個大規模的文本集合。

正如我們所看到的,最流行的詞看起來很無聊, 這些詞通常被稱為停用詞(stop words),因此可以被過濾掉。 盡管如此,它們本身仍然是有意義的,我們仍然會在模型中使用它們。 此外,還有個明顯的問題是詞頻衰減的速度相當地快。 例如,最常用單詞的詞頻對比,第10個還不到第1個的1/5。 為了更好地理解,我們可以畫出的詞頻圖:

freqs = [freq for token, freq in vocab.token_freqs]
d2l.plot(freqs, xlabel='token: x', ylabel='frequency: n(x)',xscale='log', yscale='log')
#token是已經排過序的,而且這里的token還用了log處理,代表的是80%出現都是20%的詞,因為這里log是線性關系。

?建模的意義在于說明單純平滑化的的不合理性:

bigram_tokens = [pair for pair in zip(corpus[:-1], corpus[1:])]
#這里是直接打包成一個zip,corpus[:-1]是把最后一個拿掉,corpus[1:]是從1才開始,每一次拿到就是元素和元素后面一個
bigram_vocab = d2l.Vocab(bigram_tokens)
bigram_vocab.token_freqs[:10]輸出:
[(('of', 'the'), 309),(('in', 'the'), 169),(('i', 'had'), 130),(('i', 'was'), 112),(('and', 'the'), 109),(('the', 'time'), 102),(('it', 'was'), 99),(('to', 'the'), 85),(('as', 'i'), 78),(('of', 'a'), 73)]

?這里值得注意:在十個最頻繁的詞對中,有九個是由兩個停用詞組成的, 只有一個與“the time”有關。 我們再進一步看看三元語法的頻率是否表現出相同的行為方式。

這里稍微提一下這個負數在list中的使用,一般表示的就是倒數,:-2就是一直到倒數第二個元素。

trigram_tokens = [triple for triple in zip(corpus[:-2], corpus[1:-1], corpus[2:])]
#這里就是三元了
trigram_vocab = d2l.Vocab(trigram_tokens)
trigram_vocab.token_freqs[:10]輸出:
[(('the', 'time', 'traveller'), 59),(('the', 'time', 'machine'), 30),(('the', 'medical', 'man'), 24),(('it', 'seemed', 'to'), 16),(('it', 'was', 'a'), 15),(('here', 'and', 'there'), 15),(('seemed', 'to', 'me'), 14),(('i', 'did', 'not'), 14),(('i', 'saw', 'the'), 13),(('i', 'began', 'to'), 13)]

?最后,我們直觀地對比三種模型中的詞元頻率:一元語法、二元語法和三元語法。

bigram_freqs = [freq for token, freq in bigram_vocab.token_freqs]
trigram_freqs = [freq for token, freq in trigram_vocab.token_freqs]
d2l.plot([freqs, bigram_freqs, trigram_freqs], xlabel='token: x',ylabel='frequency: n(x)', xscale='log', yscale='log',legend=['unigram', 'bigram', 'trigram'])

這張圖非常令人振奮!原因有很多:

  1. 除了一元語法詞,單詞序列似乎也遵循齊普夫定律, 盡管公式?(8.3.7)中的指數更小 (指數的大小受序列長度的影響);

  2. 詞表中元組的數量并沒有那么大,這說明語言中存在相當多的結構, 這些結構給了我們應用模型的希望;

  3. 很多元組很少出現,這使得拉普拉斯平滑非常不適合語言建模。 作為代替,我們將使用基于深度學習的模型。

?8.3.4.?讀取長序列數據

?8.3.4.1.?隨機采樣

在隨機采樣中,每個樣本都是在原始的長序列上任意捕獲的子序列。 在迭代過程中,來自兩個相鄰的、隨機的、小批量中的子序列不一定在原始序列上相鄰。 對于語言建模,目標是基于到目前為止我們看到的詞元來預測下一個詞元, 因此標簽是移位了一個詞元的原始序列

下面的代碼每次可以從數據中隨機生成一個小批量。 在這里,參數batch_size指定了每個小批量中子序列樣本的數目, 參數num_steps是每個子序列中預定義的時間步數

為了解決原本太多冗余的序列對的問題,深度學習的分割又有可能覆蓋不了所有序列對,因此核心思想在于隨機起始去取T長的序列,下面這個代碼挺刁的,可以看看寫的非常簡潔。

def seq_data_iter_random(corpus, batch_size, num_steps):  #@save ns類似于tao 每次取多長"""使用隨機抽樣生成一個小批量子序列"""# 從隨機偏移量開始對序列進行分區,隨機范圍包括num_steps-1corpus = corpus[random.randint(0, num_steps - 1):]# 減去1,是因為我們需要考慮標簽是后一位# random.randint(a, b):生成一個在 a 和 b 之間(包括 a 和 b)的隨機整數。num_subseqs = (len(corpus) - 1) // num_steps# 長度為num_steps的子序列的起始索引initial_indices = list(range(0, num_subseqs * num_steps, num_steps))# 在隨機抽樣的迭代過程中,# 來自兩個相鄰的、隨機的、小批量中的子序列不一定在原始序列上相鄰random.shuffle(initial_indices)#shuffle一下保證每次取的序列是隨機的def data(pos):# 返回從pos位置開始的長度為num_steps的序列return corpus[pos: pos + num_steps]num_batches = num_subseqs // batch_size #計算有多少次batchfor i in range(0, batch_size * num_batches, batch_size):# 在這里,initial_indices包含子序列的隨機起始索引 為了每次能把一個batch拿出來initial_indices_per_batch = initial_indices[i: i + batch_size]X = [data(j) for j in initial_indices_per_batch]Y = [data(j + 1) for j in initial_indices_per_batch]yield torch.tensor(X), torch.tensor(Y)

下面我們生成一個從0到34的序列。 假設批量大小為2,時間步數為5,這意味著可以生成35-1/5=6個“特征-標簽”子序列對。 如果設置小批量大小為2,我們只能得到3個小批量。

my_seq = list(range(35))
for X, Y in seq_data_iter_random(my_seq, batch_size=2, num_steps=5):print('X: ', X, '\nY:', Y)輸出:
X:  tensor([[13, 14, 15, 16, 17],[28, 29, 30, 31, 32]])
Y: tensor([[14, 15, 16, 17, 18],[29, 30, 31, 32, 33]])
X:  tensor([[ 3,  4,  5,  6,  7],[18, 19, 20, 21, 22]])
Y: tensor([[ 4,  5,  6,  7,  8],[19, 20, 21, 22, 23]])
X:  tensor([[ 8,  9, 10, 11, 12],[23, 24, 25, 26, 27]])
Y: tensor([[ 9, 10, 11, 12, 13],[24, 25, 26, 27, 28]])

?8.3.4.2.?順序分區

在迭代過程中,除了對原始序列可以隨機抽樣外, 我們還可以保證兩個相鄰的小批量中的子序列在原始序列上也是相鄰的。 這種策略在基于小批量的迭代過程中保留了拆分的子序列的順序,因此稱為順序分區。?

def seq_data_iter_sequential(corpus, batch_size, num_steps):  #@save"""使用順序分區生成一個小批量子序列"""# 從隨機偏移量開始劃分序列offset = random.randint(0, num_steps)num_tokens = ((len(corpus) - offset - 1) // batch_size) * batch_sizeXs = torch.tensor(corpus[offset: offset + num_tokens])Ys = torch.tensor(corpus[offset + 1: offset + 1 + num_tokens])Xs, Ys = Xs.reshape(batch_size, -1), Ys.reshape(batch_size, -1)num_batches = Xs.shape[1] // num_stepsfor i in range(0, num_steps * num_batches, num_steps):X = Xs[:, i: i + num_steps]Y = Ys[:, i: i + num_steps]yield X, Y

基于相同的設置,通過順序分區讀取每個小批量的子序列的特征X和標簽Y。 通過將它們打印出來可以發現: 迭代期間來自兩個相鄰的小批量中的子序列在原始序列中確實是相鄰的。

for X, Y in seq_data_iter_sequential(my_seq, batch_size=2, num_steps=5):print('X: ', X, '\nY:', Y)輸出:
X:  tensor([[ 0,  1,  2,  3,  4],[17, 18, 19, 20, 21]])
Y: tensor([[ 1,  2,  3,  4,  5],[18, 19, 20, 21, 22]])
X:  tensor([[ 5,  6,  7,  8,  9],[22, 23, 24, 25, 26]])
Y: tensor([[ 6,  7,  8,  9, 10],[23, 24, 25, 26, 27]])
X:  tensor([[10, 11, 12, 13, 14],[27, 28, 29, 30, 31]])
Y: tensor([[11, 12, 13, 14, 15],[28, 29, 30, 31, 32]])

?現在,我們將上面的兩個采樣函數包裝到一個類中, 以便稍后可以將其用作數據迭代器。

class SeqDataLoader:  #@save"""加載序列數據的迭代器"""def __init__(self, batch_size, num_steps, use_random_iter, max_tokens):if use_random_iter:self.data_iter_fn = d2l.seq_data_iter_randomelse:self.data_iter_fn = d2l.seq_data_iter_sequentialself.corpus, self.vocab = d2l.load_corpus_time_machine(max_tokens)self.batch_size, self.num_steps = batch_size, num_stepsdef __iter__(self):return self.data_iter_fn(self.corpus, self.batch_size, self.num_steps)

?最后,我們定義了一個函數load_data_time_machine, 它同時返回數據迭代器和詞表, 因此可以與其他帶有load_data前綴的函數 (如?3.5節中定義的?d2l.load_data_fashion_mnist)類似地使用。

def load_data_time_machine(batch_size, num_steps,  #@saveuse_random_iter=False, max_tokens=10000):"""返回時光機器數據集的迭代器和詞表"""data_iter = SeqDataLoader(batch_size, num_steps, use_random_iter, max_tokens)return data_iter, data_iter.vocab

8.3.5.?小結

  • 語言模型是自然語言處理的關鍵。

  • 元語法通過截斷相關性,為處理長序列提供了一種實用的模型。

  • 長序列存在一個問題:它們很少出現或者從不出現。

  • 齊普夫定律支配著單詞的分布,這個分布不僅適用于一元語法,還適用于其他元語法。

  • 通過拉普拉斯平滑法可以有效地處理結構豐富而頻率不足的低頻詞詞組。

  • 讀取長序列的主要方式是隨機采樣和順序分區。在迭代過程中,后者可以保證來自兩個相鄰的小批量中的子序列在原始序列上也是相鄰的。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94053.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94053.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94053.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++ 模板初階

什么是模板? 模板(Template)是 C 中實現泛型編程的核心工具。它允許我們編寫與具體數據類型無關的代碼,從而實現代碼復用和類型安全。為什么需要模板? 舉個生活中的例子:如果你要造一個能裝水的杯子&#x…

DockerFile文件執行docker bulid自動構建鏡像

文章目錄一、Dockerfile介紹二、Dockerfile鏡像制作和流程使用三、Dockerfile文件的制作鏡像的分層結構四、Dockerfile文件格式五、Dockerfile相關指令5.1 FROML:指定基礎鏡像5.2 LABEL:指定鏡像元數據5.3 RUN:執行shell指令5.4 ENV&#xff…

osloader!DoGlobalInitialization函數分析之HW_CURSOR--NTLDR源代碼分析之設置光標

第一部分: VOID DoGlobalInitialization(IN PBOOT_CONTEXT BootContextRecord){//// Turn the cursor off//HW_CURSOR(0,127);D:\srv03rtm\base\boot/inc/bldrx86.h:258:#define HW_CURSOR (*ExternalServicesTable->HardwareCursor)第二部分&#xff…

Elasticsearch 索引及節點級別增刪改查技術

以下是針對 Elasticsearch 索引及節點級別增刪改查技術做的簡短總結&#xff1a; 一、索引操作創建索引 功能&#xff1a;指定分片、副本數及映射規則[2][4]。示例&#xff1a;PUT /<index_name>?&#xff0c;可定義 settings&#xff08;如分片數&#xff09;和 mappin…

烽火HG680-KD_海思MV320處理器-安卓9-原廠系統升級包-針對解決燒錄不進系統的問題

烽火HG680-KD_海思MV320處理器-安卓9-原廠系統升級包&#xff08;注意是&#xff08;原機系統&#xff09;&#xff09;-主要是針對解決TTL燒錄后仍然不進系統使用。HG680-KD&#xff0f;HG680-KE&#xff0f;HG680-KF&#xff0f;HG680-KX 均通用。 說明&#xff1a; 前一個…

VS2019安裝HoloLens 沒有設備選項

第一步先檢查VS有沒有安裝C組件第二步把VS工程最后一個設置為啟動項

【云計算】云主機的親和性策略(二):集群節點組

《云主機的親和性策略》系列&#xff0c;共包含以下文章&#xff1a; 1?? 云主機的親和性策略&#xff08;一&#xff09;&#xff1a;快樂旅行團2?? 云主機的親和性策略&#xff08;二&#xff09;&#xff1a;集群節點組3?? 云主機的親和性策略&#xff08;三&#xf…

【人工智能】AI代理在零售業的崛起:從草莓訂購到全流程購物體驗

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 在零售業快速演變的格局中,AI代理正作為變革力量崛起,連接消費者需求與無縫履行。本文深入探討AI代理在零售中的興起,從通過對話界面訂購…

【讀論文】從Qwen3技術報告到Qwen3-30B-A3B 模型的深度解讀

引言:當大模型追求又小又好用 最近都是各種新大模型滿天飛,其中Qwen3-30B-A3B-Instruct-2507很是亮眼,這種參數尺寸是相對友好的,效果好而且模型不大。從這里就引發一下疑問,如何在保證強大能力的同時,兼顧模型的效率和可訪問性?毫無疑問,混合專家 (Mixture-of-Expert…

【番外篇15】中心極限定理:從數學原理到生活案例

一、什么是中心極限定理&#xff1f;中心極限定理(Central Limit Theorem, CLT)是概率論與統計學中最重要的定理之一&#xff0c;它揭示了為什么正態分布在自然界和統計學中如此普遍。?定理表述?&#xff1a;設X?, X?, ..., X? 是一組獨立同分布的隨機變量序列&#xff0c…

本地構建Docker鏡像并推送到GitHub Container Registry

一、本地構建并推送鏡像1. 登錄GitHub Container Registry首先&#xff0c;需要登錄到GitHub Container Registry (GHCR)&#xff1a;# 使用個人訪問令牌(PAT)登錄 docker login ghcr.io -u 你的GitHub用戶名 -p 你的個人訪問令牌注意&#xff1a;你需要在GitHub上創建一個具有…

DP-v2.1-mem-clean學習(3.6.8-3.6.8.1)

3.6.8 lttpr非透明模式下的鏈路訓練 3.6.8.1 支持8b/10b鏈路層訓練規范 ?默認透明模式? 若上游設備未啟用LTTPR非透明模式(Non-transparent),需在鏈路訓練前將DPCD F0003h寄存器寫入默認值55h38 ?非法中繼器計數值處理? 當DPCD F0002h(PHY_REPEATER_CNT)返回值非有…

kali安裝maven

kali安裝maven 下載maven的安裝包 wget https://dlcdn.apache.org/maven/maven-3/3.9.11/binaries/apache-maven-3.9.11-bin.tar.gz 注意可能返回404&#xff0c;這是因為官網已經更新了版本&#xff0c;這種情況可以自己訪問https://dlcdn.apache.org/maven/maven-3查看一下最…

GEO優化:品牌營銷新戰場的光明與荊棘

在AI重塑信息獲取方式的今天&#xff0c;一種名為GEO&#xff08;生成式引擎優化&#xff09;?的策略正悄然成為企業營銷版圖的新坐標。它不追求傳統搜索引擎中的鏈接排名&#xff0c;而是爭奪生成式AI&#xff08;如ChatGPT、DeepSeek等&#xff09;答案中的“話語權”——讓…

牛客 - 旋轉數組的最小數字

描述 有一個長度為 n 的非降序數組&#xff0c;比如[1,2,3,4,5]&#xff0c;將它進行旋轉&#xff0c;即把一個數組最開始的若干個元素搬到數組的末尾&#xff0c;變成一個旋轉數組&#xff0c;比如變成了[3,4,5,1,2]&#xff0c;或者[4,5,1,2,3]這樣的。請問&#xff0c;給定這…

1分鐘臨時共享空間在線小工具實現

運行效果&#xff1a;1分鐘臨時共享空間 - 免注冊即時文件文本共享工具 | 極速傳 直接上代碼&#xff1a; using Microsoft.AspNetCore.Mvc; using SaaS.OfficialWebSite.Web.Utils; using ZXing.QrCode; using ZXing; using SkiaSharp; using ZXing.SkiaSharp.Rendering; usin…

操作系統-lecture5(線程)

進程的缺點 在創建了子進程的時候&#xff0c;得到了可以并發執行的好處 但創建了進程資源會造成浪費 線程的引入 在同一個進程中有這樣兩個執行流&#xff0c;為并發執行的&#xff0c;稱之為線程 這里引用下《操作系統概念》中的線程概述 任務舉例 在復制的過程中&#xf…

FPGA kernel 仿真器調試環境搭建

參考:haps階段說明2:kernel運行和調試 1 仿真器加載FIT及調試步驟 由于使用仿真器,就要額外配置DS-5的軟件環境,有些步驟略復雜,請仔細按照說明操作。 1.1 導入kernel工程 不導入可以運行,但導入方便調試 file——-import 導入后的工程如圖 1.2 創建debug 使用attach方…

MySQL(173)MySQL中的存儲過程和函數有什么區別?

在MySQL中&#xff0c;存儲過程&#xff08;Stored Procedures&#xff09;和函數&#xff08;Functions&#xff09;是兩種用于封裝可重用SQL代碼的機制。盡管它們在很多方面類似&#xff0c;但仍有一些重要的區別。以下是對存儲過程和函數的詳細解釋&#xff0c;以及如何在My…

可計算存儲(Computational Storage)與DPU(Data Processing Unit)的技術特點對比及實際應用場景分析

以下是對可計算存儲&#xff08;Computational Storage&#xff09;與DPU&#xff08;Data Processing Unit&#xff09;的技術特點對比及實際應用場景分析&#xff0c;結合引用資料進行綜合說明&#xff1a;一、技術核心對比維度可計算存儲DPU核心差異定位存儲設備內置計算能力…