現在讓我們構建一個進行這種分類的神經網絡。我們需要決定輸入/輸出的解釋。我們的輸入已經是數字,因此我們可以直接將它們輸入到網絡中。我們的輸出是兩個對象,葉子和花朵,神經網絡無法輸出這些對象。讓我們看看這里可以使用的一些方案:

這兩種方案都允許網絡輸出可以解釋為葉子或花朵的數字。我們在這里選擇第二種方案,因為它可以很好地推廣到我們稍后將要看到的其他內容。這是一個使用該方案進行分類的神經網絡。讓我們來看看它的工作原理:

藍色圓圈的計算方式如下:(32 * 0.10) + (107 * -0.29) + (56 * -0.07) + (11.2 * 0.46) = — 26.6

一些術語:

神經元/節(jié)點: 圓圈中的數字

權重: 線上的彩色數字

: 神經元的集合稱為層。你可以認為這個網絡有 3 層:具有 4 個神經元的輸入層,具有 3 個神經元的中間層和具有 2 個神經元的輸出層。

要計算此網絡的預測/輸出(稱為“前向傳播”),你需要從左側開始。我們擁有輸入層中神經元的數據。要“向前”移動到下一層,你需要將圓圈中的數字與相應神經元對的權重相乘,然后將它們全部相加。我們在上面演示了藍色和橙色圓圈的數學運算。運行整個網絡,我們看到輸出層中的第一個數字更大,因此我們將其解釋為“網絡將這些 (RGB,Vol) 值分類為葉子”。一個訓練有素的網絡可以接受各種 (RGB,Vol) 輸入并正確地對物體進行分類。

該模型不知道葉子或花朵是什么,也不知道 (RGB,Vol) 是什么。它的工作是只接受 4 個數字并給出 2 個數字。我們將其解釋為 4 個輸入數字是 (RGB,Vol),并且我們決定查看輸出數字并推斷如果第一個數字更大,則它是葉子,依此類推。最后,我們還需要選擇正確的權重,以便模型能夠接受我們的輸入數字并給出正確的兩個數字,這樣當我們解釋它們時,就能得到我們想要的解釋。

一個有趣的副作用是,你可以使用相同的網絡,而不是輸入 RGB、Vol,而是輸入其他 4 個數字,例如云量、濕度等,并將這兩個數字解釋為“一小時內晴天”或“一小時內下雨”,然后如果你對權重進行了很好的校準,則可以讓完全相同的網絡同時完成兩件事——對葉子/花朵進行分類并預測一小時內的降雨!網絡只給你兩個數字,你是否將其解釋為分類或預測或其他什么完全取決于你。

為簡化而省略的內容(可以忽略而不影響理解):

這些模型是如何訓練的?

在上面的例子中,我們神奇地獲得了權重,這些權重允許我們將數據輸入模型并得到一個好的輸出。但這些權重是如何確定的呢?設置這些權重(或“參數”)的過程被稱為“訓練模型”,我們需要一些訓練數據來訓練模型。

假設我們有一些數據,其中我們有輸入,并且我們已經知道每個輸入對應的是葉子還是花,這是我們的“訓練數據”,并且由于我們有每組 (R,G,B,Vol) 數字對應的葉子/花標簽,這就是“標記數據”。

以下是它的工作原理:

幾點說明:

在實踐中,訓練深度網絡是一個艱難而復雜的過程,因為梯度很容易失控,在訓練過程中變?yōu)榱慊驘o窮大(稱為“梯度消失”和“梯度爆炸”問題)。我們在這里討論的損失的簡單定義是完全有效的,但很少使用,因為有更好的函數形式可以很好地用于特定目的。對于包含數十億參數的現代模型,訓練一個模型需要大量的計算資源,這本身就存在問題(內存限制、并行化等)。

所有這些是如何幫助生成語言的?

記住,神經網絡接收一些數字,根據訓練的參數進行一些數學運算,并輸出一些其他的數字。一切都與解釋和訓練參數(即將它們設置為某些數字)有關。如果我們可以將這兩個數字解釋為“葉子/花”或“一小時內下雨或晴天”,我們也可以將它們解釋為“句子中的下一個字符”。

但是英語中的字母不止 2 個,因此我們必須將輸出層中的神經元數量擴展到,比如說,英語中的 26 個字母(我們還添加一些符號,如空格、句點等)。每個神經元可以對應一個字符,我們查看輸出層中的(大約 26 個)神經元,并說輸出層中編號最高的神經元對應的字符是輸出字符。現在我們有一個可以接收一些輸入并輸出一個字符的網絡。

如果我們將網絡中的輸入替換為這些字符:“Humpty Dumpt”,并要求它輸出一個字符,并將其解釋為“網絡對我們剛剛輸入的序列中下一個字符的建議”。我們或許可以很好地設置權重,使其輸出“y”——從而完成“Humpty Dumpty”。除了一個問題,我們如何將這些字符列表輸入到網絡中?我們的網絡只接受數字!

一個簡單的解決方案是給每個字符分配一個數字。假設 a=1,b=2,以此類推?,F在我們可以輸入“humpty dumpt”并訓練它給我們“y”。我們的網絡看起來像這樣:

好的,現在我們可以通過向網絡提供一個字符列表來預測下一個字符。我們可以利用這個事實來構建一個完整的句子。例如,一旦我們預測了“y”,我們可以將“y”添加到我們擁有的字符列表中,并將其輸入到網絡中,并要求它預測下一個字符。如果訓練得當,它應該給我們一個空格,以此類推。到最后,我們應該能夠遞歸地生成“Humpty Dumpty sat on a wall”。我們有了生成式人工智能。此外,我們現在有了一個能夠生成語言的網絡!_ _現在,沒有人真正輸入隨機分配的數字,我們將在后面看到更合理的方案。如果你等不及了,請隨意查看附錄中關于獨熱編碼的部分。

敏銳的讀者會注意到,我們實際上不能將“Humpty Dumpty”輸入到網絡中,因為根據圖示,它在輸入層中只有 12 個神經元,每個神經元對應“humpty dumpt”中的一個字符(包括空格)。那么我們如何在下一次傳遞中輸入“y”呢?在那里放置第 13 個神經元需要我們修改整個網絡,這是不可行的。解決方案很簡單,讓我們去掉“h”,并發(fā)送最近的 12 個字符。所以我們將發(fā)送“umpty dumpty”,網絡將預測一個空格。然后我們將輸入“mpty dumpty ”,它將產生一個“s”,以此類推。它看起來像這樣:

在最后一行,通過只向模型提供“ sat on the wal”,我們丟棄了很多信息。那么今天最新最好的網絡是如何做的呢?或多或少就是這樣。我們可以輸入到網絡中的輸入長度是固定的(由輸入層的大小決定)。這被稱為“上下文長度”——提供給網絡進行未來預測的上下文。現代網絡可以有非常大的上下文長度(幾千個單詞),這很有幫助。有一些方法可以輸入無限長度的序列,但這些方法的性能雖然令人印象深刻,但已經被其他具有較大(但固定)上下文長度的模型所超越。

細心的讀者還會注意到,我們對相同字母的輸入和輸出有不同的解釋!例如,當輸入“h”時,我們只是用數字 8 來表示它,但在輸出層,我們不是要求模型輸出一個數字(“h”為 8,“i”為 9,以此類推……),而是要求模型輸出 26 個數字,然后我們看看哪個數字最大,如果第 8 個數字最大,我們就將輸出解釋為“h”。為什么我們不在兩端使用相同的、一致的解釋呢?我們可以這樣做,只是在語言的情況下,讓自己能夠在不同的解釋之間進行選擇,可以讓你有更好的機會構建更好的模型。事實證明,目前已知的對輸入和輸出最有效的解釋是不同的。事實上,我們在這個模型中輸入數字的方式并不是最好的方法,我們很快就會看到更好的方法。

是什么讓大型語言模型如此出色?

逐個字符地生成“Humpty Dumpty sat on a wall”與現代大型語言模型所能做的相去甚遠。從我們上面討論的簡單生成式人工智能到像人類一樣的機器人,有很多不同之處和創(chuàng)新。讓我們來看看它們:

嵌入(Embeddings)

回想一下,我們說過將字符輸入模型的方式并非最佳方法。我們只是任意地為每個字符選擇了一個數字。如果我們能分配更好的數字,使我們能夠訓練更好的網絡,那會怎么樣呢?我們如何找到這些更好的數字呢?這里有一個巧妙的技巧:

當我們訓練上面的模型時,我們的做法是四處移動權重,看看最終能否得到更小的損失。然后緩慢地、遞歸地改變權重。在每次迭代中,我們會:

在這個過程中,輸入是固定的。當輸入是(RGB,Vol)時,這是合理的。但是我們現在為 a、b、c 等輸入的數字是我們任意選擇的。如果在每次迭代中,除了稍微移動權重之外,我們也移動輸入,看看是否可以通過使用不同的數字來表示“a”等來獲得更低的損失?我們肯定是在減少損失并使模型變得更好(這是我們移動 ‘a’ 的輸入的方向,通過設計)?;旧?,不僅對權重應用梯度下降,也對輸入的數字表示應用梯度下降,因為它們反正也是任意選擇的數字。這被稱為“嵌入”。它是輸入到數字的映射,正如你剛才看到的,它需要被訓練。訓練嵌入的過程與訓練參數的過程非常相似。然而,這樣做的一大優(yōu)勢是,一旦你訓練了一個嵌入,你就可以在另一個模型中使用它。請記住,你將始終使用相同的嵌入來表示單個標記/字符/詞。

我們討論了每個字符只有一個數字的嵌入。然而,實際上嵌入有多個數字。這是因為很難用單個數字來捕捉概念的豐富性。如果我們看看我們的葉子和花的例子,每個對象有四個數字(輸入層的維度)。這四個數字中的每一個都傳達了一個屬性,模型能夠使用所有這些屬性來有效地猜測對象。如果我們只有一個數字,比如顏色的紅色通道,那么模型可能會更難。我們在這里試圖捕捉人類語言——我們需要不止一個數字。

因此,與其用單個數字表示每個字符,不如用多個數字表示它來捕捉其豐富性?讓我們?yōu)槊總€字符分配一組數字。讓我們將一個有序的數字集合稱為“向量”(有序是指每個數字都有一個位置,如果我們交換兩個數字的位置,它會給我們一個不同的向量。我們的葉子/花數據就是這種情況,如果我們交換了葉子的 R 和 G 數字,我們會得到不同的顏色,它將不再是相同的向量)。向量的長度就是它包含的數字個數。我們將為每個字符分配一個向量。出現兩個問題:

當然,所有嵌入向量必須具有相同的長度,否則我們將無法將所有字符組合輸入到網絡中。例如,“humpty dumpt”和下一次迭代“umpty dumpty”——在這兩種情況下,我們都在網絡中輸入 12 個字符,如果 12 個字符中的每一個都不是由長度為 10 的向量表示,我們將無法可靠地將它們全部輸入到長度為 120 的輸入層中。讓我們可視化這些嵌入向量:

讓我們將相同大小的向量的有序集合稱為矩陣。上面的這個矩陣被稱為嵌入矩陣。你告訴它一個與你的字母對應的列號,查看矩陣中的該列將為你提供用于表示該字母的向量。這可以更普遍地應用于嵌入任何任意的事物集合——你只需要在這個矩陣中擁有與你要嵌入的事物一樣多的列。

子詞分詞器(Subword Tokenizers)

到目前為止,我們一直使用字符作為語言的基本構建塊。這有其局限性。神經網絡權重必須承擔大量的繁重工作,它們必須理解某些字符序列(即單詞)彼此相鄰出現,然后與其他單詞相鄰出現。如果我們直接將嵌入分配給單詞,并讓網絡預測下一個單詞,那會怎么樣?網絡除了數字之外什么都不懂,所以我們可以為“humpty”、“dumpty”、“sat”、“on”等每個單詞分配一個長度為 10 的向量,然后我們只需輸入兩個單詞,它就可以給我們下一個單詞。“標記”是指我們嵌入然后輸入到模型中的單個單元。到目前為止,我們的模型使用字符作為標記,現在我們建議使用整個單詞作為標記(當然,如果你愿意,也可以使用整個句子或短語作為標記)。

使用單詞標記化對我們的模型有一個深遠的影響。英語中有超過 18 萬個單詞。使用我們?yōu)槊總€可能的輸出設置一個神經元的輸出解釋方案,我們需要在輸出層中有數十萬個神經元,而不是 26 個左右。對于現代網絡實現有意義結果所需的隱藏層大小,這個問題變得不那么緊迫了。然而,值得注意的是,由于我們分別處理每個單詞,并且我們從每個單詞的隨機數字嵌入開始——非常相似的單詞(例如“cat”和“cats”)將以沒有關系的狀態(tài)開始。你會期望這兩個單詞的嵌入應該彼此接近——這無疑是模型將要學習的。但是,我們能否以某種方式利用這種明顯的相似性來搶占先機并簡化問題?

是的,我們可以。如今,語言模型中最常見的嵌入方案是將單詞分解成子詞,然后嵌入它們。在 cat 的例子中,我們將 cats 分解成兩個標記“cat”和“s”。現在,模型更容易理解“s”后跟其他熟悉單詞的概念,等等。這也減少了我們需要的標記數量(sentencpiece是一種常見的標記器,詞匯量選項有數萬個,而英語中有數十萬個單詞)。標記器是一種接收你的輸入文本(例如“Humpty Dumpt”),將其拆分為標記,并為你提供需要在嵌入矩陣中查找該標記的嵌入向量的相應數字的東西。例如,在“humpty dumpty”的情況下,如果我們使用字符級標記器,并且我們像上圖那樣排列嵌入矩陣,那么標記器將首先將 humpty dumpt 拆分為字符 [‘h’,’u’,…’t’],然后返回數字 [8,21,…20],因為你需要查找嵌入矩陣的第 8 列才能獲得 ‘h’ 的嵌入向量(嵌入向量是你將輸入到模型中的內容,而不是數字 8,不像以前)。矩陣中列的排列完全無關緊要,我們可以將任何列分配給 ‘h’,只要每次輸入 ‘h’ 時我們都查找相同的向量,我們就可以了。標記器只是給我們一個任意的(但固定的)數字,以便于查找。我們真正需要它們完成的主要任務是將句子拆分成標記。

使用嵌入和子詞標記化,模型可能如下所示:

接下來的幾節(jié)將討論語言建模方面的最新進展,以及使大型語言模型像今天這樣強大的進展。然而,要理解這些,你需要了解一些基本的數學概念。以下是這些概念:

我在附錄中添加了這些概念的摘要。

自注意力機制

到目前為止,我們只見過一種簡單的神經網絡結構(稱為前饋網絡),它包含若干層,每一層都與下一層全連接(即,連續(xù)層中的任意兩個神經元之間都有一條連接線),并且它只連接到下一層(例如,第 1 層和第 3 層之間沒有連接線,等等)。然而,可以想象,沒有什么能阻止我們移除或建立其他連接,甚至構建更復雜的結構。讓我們來探討一個特別重要的結構:自注意力機制。

如果你觀察人類語言的結構,我們想要預測的下一個詞將取決于之前的所有詞。然而,它們對某些詞的依賴程度可能比其他詞更大。例如,如果我們試圖預測“Damian 有一個秘密的孩子,一個女孩,他在遺囑中寫道,他所有的財產,連同魔法球,都將屬于____”這句話中的下一個詞。這里的詞可能是“她”或“他”,它特別取決于句子中前面出現的詞:女孩/男孩

好消息是,我們簡單的前饋模型連接到上下文中的所有單詞,因此它可以學習重要單詞的適當權重。但問題是,通過前饋層連接模型中特定位置的權重是固定的(對于每個位置)。如果重要的詞總是在同一個位置,它會適當地學習權重,我們就沒事了。然而,與下一個預測相關的詞可能出現在系統(tǒng)中的任何位置。我們可以改寫上面的句子,當猜測“她 vs 他”時,無論“男孩/女孩”出現在句子的哪個位置,它都是一個非常重要的預測詞。因此,我們需要權重不僅取決于位置,還取決于該位置的內容。我們如何實現這一點?

自注意力機制的作用類似于將每個單詞的嵌入向量相加,但它不是直接相加,而是對每個向量應用一些權重。因此,如果 ‘humpty’、’dumpty’、’sat’ 的嵌入向量分別是 x1、x2、x3,那么它會在將它們相加之前將每個向量乘以一個權重(一個數字)。類似于 output = 0.5 x1 + 0.25 x2 + 0.25 x3,其中 output 是自注意力機制的輸出。如果我們將權重寫為 u1、u2、u3,使得 output = u1x1+u2x2+u3x3,那么我們如何找到這些權重 u1、u2、u3 呢?

理想情況下,我們希望這些權重取決于我們正在添加的向量——正如我們所看到的,有些向量可能比其他向量更重要。但對誰重要呢?對我們要預測的詞來說重要。所以我們也希望權重取決于我們要預測的詞?,F在有一個問題,我們當然不知道我們要預測的詞是什么,在我們預測它之前。因此,自注意力機制使用緊接在我們即將預測的詞之前的詞,即句子中最后一個可用的詞(我真的不知道為什么這樣,為什么不是其他東西,但深度學習中的很多東西都是反復試驗的,我懷疑這樣做效果很好)。

很好,所以我們需要這些向量的權重,并且我們希望每個權重都取決于我們正在聚合的詞和緊接在我們即將預測的詞之前的詞?;旧希覀兿胍粋€函數 u1 = F(x1, x3),其中 x1 是我們將要加權的詞,x3 是序列中的最后一個詞(假設我們只有 3 個詞)?,F在,實現這一點的一個直接方法是為 x1 設置一個向量(我們稱之為 k1),為 x3 設置一個單獨的向量(我們稱之為 q3),然后簡單地取它們的點積。這將給我們一個數字,它將取決于 x1 和 x3。我們如何得到這些向量 k1 和 q3 呢?我們構建一個微小的單層神經網絡,從 x1 到 k1(或 x2 到 k2,x3 到 k3,等等)。我們構建另一個網絡,從 x3 到 q3 等等……使用我們的矩陣表示法,我們基本上得到了權重矩陣 Wk 和 Wq,使得 k1 = Wkx1,q1 =Wqx1,等等?,F在我們可以取 k1 和 q3 的點積得到一個標量,所以 u1 = F(x1,x3) = Wkx1 · Wqx3。

自注意力機制中發(fā)生的另一件事是,我們不直接取嵌入向量本身的加權和。相反,我們取該嵌入向量的某個“值”的加權和,該值是通過另一個小的單層網絡獲得的。這意味著類似于 k1 和 q1,我們現在也有單詞 x1 的 v1,我們通過矩陣 Wv 獲得它,使得 v1=Wvx1。然后將這個 v1 聚合。因此,如果我們只有 3 個單詞并且我們試圖預測第 4 個單詞,那么它看起來像這樣:

加號表示向量的簡單加法,這意味著它們必須具有相同的長度。這里沒有顯示的最后一個修改是標量 u1、u2、u3 等…不一定加起來等于 1。如果我們需要它們作為權重,我們應該讓它們加起來等于 1。所以我們將在這里應用一個熟悉的技巧,并使用 softmax 函數。

這就是自注意力機制。還有交叉注意力機制,其中你可以讓 q3 來自最后一個詞,但 k 和 v 可以完全來自另一個句子。例如,這在翻譯任務中很有價值。現在我們知道了什么是注意力機制。

現在可以把整個東西放在一個盒子里,稱之為“自注意力塊”?;旧希@個自注意力塊接收嵌入向量并輸出一個用戶選擇的任意長度的輸出向量。這個塊有三個參數,Wk、Wq、Wv——它不需要比這更復雜。機器學習文獻中有許多這樣的塊,它們通常在圖中用帶有名稱的框表示。類似于這樣:

你會注意到,到目前為止,自注意力機制中事物的位置似乎并不重要。我們一直在使用相同的 W,因此切換 ‘Humpty’ 和 ‘Dumpty’ 并不會真正改變結果——所有數字最終都會相同。這意味著雖然注意力機制可以找出需要注意什么,但這并不取決于單詞的位置。然而,我們確實知道單詞位置在英語中很重要,我們可能可以通過讓模型感知單詞的位置來提高性能。

因此,當使用注意力機制時,我們通常不會將嵌入向量直接饋送到自注意力塊。我們稍后將看到如何在將嵌入向量饋送到注意力塊之前添加“位置編碼”。

給預先了解者的注釋: 對于那些不是第一次閱讀自注意力機制的人來說,請注意我們沒有引用任何 K 和 Q 矩陣,或者應用掩碼等等。這是因為這些東西是實現細節(jié),源于這些模型通常是如何訓練的。輸入一批數據,同時訓練模型從 ‘humpty’ 預測 ‘dumpty’,從 ‘humpty dumpty’ 預測 ‘sat’,等等。這是一個提高效率的問題,不會影響解釋,甚至不會影響模型輸出,我們選擇在這里省略訓練效率技巧。

Softmax

我們在第一篇筆記中簡要地談到了 softmax。以下是 softmax 試圖解決的問題:在我們的輸出解釋中,我們擁有的神經元數量與我們希望網絡從中選擇一個的選項數量相同。我們說過,我們將把網絡的選擇解釋為值最高的神經元。然后我們說,我們要計算損失,即網絡提供的值與我們想要的理想值之間的差值。但我們想要的理想值是多少?在葉子/花的例子中,我們將其設置為 ‘0.8’。但為什么是 ‘0.8’?為什么不是 ‘5’、’10’ 或 ‘1000 萬’?對于該訓練示例,越高越好。理想情況下,我們希望它是無窮大!現在,這將使問題難以處理——所有損失都將是無限的,而我們通過調整參數來最小化損失的計劃(記住“梯度下降”)將會失敗。我們如何處理這個問題?

我們可以做的一件簡單的事情是限制我們想要的值。比如說在 ‘0’ 和 ‘1’ 之間?這將使所有損失都是有限的,但現在我們面臨的問題是當網絡超出范圍時會發(fā)生什么。假設它在一個案例中為(葉子,花)輸出 ‘(5,1)’,在另一個案例中輸出 ‘(0,1)’。第一種情況做出了正確的選擇,但損失更糟糕!好的,所以現在我們需要一種方法來將最后一層也轉換成 ‘(0,1)’ 范圍內的輸出,以便它保持順序。我們可以使用任何函數(數學中的“函數”僅僅是將一個數字映射到另一個數字——輸入一個數字,輸出另一個數字——它根據給定輸入的輸出進行規(guī)則化)來完成這項工作。一種可能的選擇是邏輯函數(見下圖),它將所有數字映射到 ‘(0,1)’ 之間的數字并保持順序:

現在,對于最后一層中的每個神經元,我們都有一個 ‘0’ 到 ‘1’ 之間的數字,我們可以通過將正確的神經元設置為 ‘1’,將其他神經元設置為 ‘0’,并取其與網絡提供給我們的值的差值來計算損失。這將起作用,但我們能做得更好嗎?

回到我們的“矮胖子”示例,假設我們正在嘗試逐個字符地生成矮胖子字符,并且我們的模型在預測矮胖子中的“m”時出錯。它沒有給我們最后一層以“m”作為最高值,而是給了我們“u”作為最高值,但“m”緊隨其后。

現在我們可以繼續(xù)“duu”并嘗試預測下一個字符等等,但模型的置信度會很低,因為從“humpty duu..”開始沒有那么多好的延續(xù)。另一方面,“m”緊隨其后,所以我們也可以試一下“m”,預測接下來的幾個字符,看看會發(fā)生什么?也許它會給我們一個更好的整體單詞?

所以我們在這里談論的不僅僅是盲目地選擇最大值,而是嘗試幾個值。有什么好方法呢?好吧,我們必須為每一個分配一個機會——比如說我們將以 ‘50%’ 的概率選擇第一個,以 ‘25%’ 的概率選擇第二個,以此類推。這是一個好方法。但也許我們希望這個機會取決于底層的模型預測。如果模型預測這里 m 和 u 的值彼此非常接近(與其他值相比)——那么也許接近 ’50-50′ 的機會來探索這兩個值是一個好主意?

所以我們需要一個好的規(guī)則來獲取所有這些數字并將它們轉換為機會。這就是 softmax 的作用。它是上述邏輯函數的推廣,但具有附加功能。如果你給它 ’10’ 個任意數字——它會給你 ’10’ 個輸出,每個都在 ‘0’ 和 ‘1’ 之間,重要的是,所有 ’10’ 個輸出加起來等于 ‘1’,這樣我們就可以把它們解釋為機會。你幾乎會在每個語言模型中發(fā)現 softmax 作為最后一層。

殘差連接(Residual connections)

隨著章節(jié)的進展,我們逐漸改變了網絡的可視化方式。我們現在使用方框/塊來表示某些概念。這種表示法對于表示殘差連接這一特別有用的概念非常有用。讓我們看一下殘差連接與自注意力塊的組合:

請注意,我們把“Input”和“Output”放在方框中是為了簡化事情,但它們基本上仍然只是一組神經元/數字,與上面顯示的相同。

那么這里發(fā)生了什么?我們基本上是在獲取自注意力塊的輸出,在將其傳遞到下一個塊之前,我們將原始輸入添加到其中。首先要注意的是,這將要求自注意力塊輸出的維度必須與輸入的維度相同。這不是問題,因為正如我們所指出的,自注意力輸出是由用戶決定的。但為什么要這樣做呢?我們在這里不會深入討論所有細節(jié),但關鍵是隨著網絡變得更深(輸入和輸出之間的層數更多),訓練它們變得越來越困難。殘差連接已被證明有助于應對這些訓練挑戰(zhàn)。

層歸一化(Layer Normalization)

層歸一化是一個相當簡單的層,它獲取進入該層的數據,并通過減去均值并除以標準差來對其進行歸一化(可能還會多一點,如下所示)。例如,如果我們要在輸入之后立即應用層歸一化,它將獲取輸入層中的所有神經元,然后計算兩個統(tǒng)計數據:它們的均值和標準差。假設均值為 M,標準差為 S,那么層歸一化的作用是獲取每個神經元,并將其替換為 (x-M)/S,其中 x 表示任何給定神經元的原始值。

那么這有什么幫助呢?它基本上穩(wěn)定了輸入向量,并有助于訓練深度網絡。一個擔憂是,通過歸一化輸入,我們是否從中刪除了一些可能有用的信息,這些信息可能有助于學習有關我們目標的有價值的東西?為了解決這個問題,層歸一化層有一個縮放參數和一個偏置參數。基本上,對于每個神經元,你只需將其乘以一個標量,然后加上一個偏置即可。這些標量和偏置值是可以訓練的參數。這允許網絡學習一些可能對預測有價值的變化。由于這些是唯一的參數,因此 LayerNorm 塊沒有很多參數需要訓練。整個過程如下所示:

Scale 和 Bias 是可訓練的參數。你可以看到,層歸一化是一個相對簡單的塊,其中每個數字只進行逐點運算(在初始均值和標準差計算之后)。這讓我們想起了激活層(例如 RELU),主要區(qū)別在于這里我們有一些可訓練的參數(盡管由于簡單的逐點運算,參數比其他層少得多)。

標準差是衡量值分散程度的統(tǒng)計量,例如,如果所有值都相同,則標準差為零。一般來說,如果每個值都與其均值相差很遠,則標準差會很高。一組數字 a1、a2、a3……(假設有 N 個數字)的標準差計算公式如下:從每個數字中減去均值(這些數字的均值),然后對每個 N 個數字的答案進行平方。將所有這些數字相加,然后除以 N。現在取答案的平方根。

給預先了解情況的人的說明:經驗豐富的機器學習專業(yè)人員會注意到這里沒有討論批量歸一化。事實上,我們在這篇文章中根本沒有介紹批量的概念。在大多數情況下,我認為批量是另一種訓練加速器,與理解核心概念無關(除了批量歸一化,我們這里不需要)。

Dropout

Dropout 是一種簡單但有效的避免模型過擬合的方法。過擬合是指你在訓練數據上訓練模型,它在該數據集上表現良好,但對模型未見過的示例泛化能力較差。幫助我們避免過擬合的技術被稱為“正則化技術”,而 Dropout 就是其中之一。

如果你訓練一個模型,它可能會在數據上犯錯誤和/或以特定方式過擬合。如果你訓練另一個模型,它可能會做同樣的事情,但方式不同。如果你訓練多個這樣的模型并平均它們的輸出會怎樣?這些通常被稱為“集成模型”,因為它們通過組合來自多個模型的輸出來預測輸出,并且集成模型的性能通常優(yōu)于任何單個模型。

在神經網絡中,你可以做同樣的事情。你可以構建多個(略有不同)的模型,然后組合它們的輸出來獲得一個更好的模型。然而,這在計算上可能非常昂貴。Dropout 是一種并非完全構建集成模型但確實捕捉了該概念某些精髓的技術。

這個概念很簡單,通過在訓練期間插入一個 Dropout 層,你所做的就是在插入 Dropout 的層之間隨機刪除一定百分比的直接神經元連接??紤]到我們的初始網絡并在輸入層和中間層之間插入一個 Dropout 率為 50% 的 Dropout 層,它看起來像這樣:

現在,這迫使網絡進行大量的冗余訓練。本質上,你是在同時訓練多個不同的模型——但它們共享權重。

現在進行推理,我們可以遵循與集成模型相同的方法。我們可以使用 Dropout 進行多次預測,然后將它們組合起來。然而,由于這在計算上非常密集——而且由于我們的模型共享共同的權重——為什么我們不直接使用所有權重進行預測(因此,我們不一次使用 50% 的權重,而是一次使用所有權重)。這應該能讓我們大致了解集成模型的效果。

不過有一個問題:使用 50% 權重訓練的模型在中間神經元中的數值與使用所有權重訓練的模型非常不同。我們想要的是更多集成風格的平均。我們如何做到這一點?好吧,一個簡單的方法是簡單地將所有權重乘以 0.5,因為我們現在使用的權重是原來的兩倍。這就是 Dropout 在推理過程中所做的。它將使用具有所有權重的完整網絡,并簡單地將權重乘以 (1- p),其中 p 是刪除概率。這已被證明作為一種正則化技術效果相當好。

多頭注意力

這是 Transformer 架構中的關鍵模塊。我們已經看到了注意力模塊是什么。記住,注意力模塊的輸出是由用戶確定的,它是 v 的長度。多頭注意力基本上就是并行運行多個注意力頭(它們都接受相同的輸入)。然后我們獲取它們的所有輸出并簡單地將它們連接起來。它看起來像這樣:

請記住,從 v1 -> v1h1 的箭頭是線性層——每個箭頭上都有一個進行轉換的矩陣。我只是為了避免混亂沒有顯示它們。

這里發(fā)生的事情是,我們?yōu)槊總€頭生成相同的鍵、查詢和值。但在我們使用這些 k、q、v 值之前,我們基本上在其上應用了線性變換(分別應用于每個 k、q、v,并且分別應用于每個頭)。這個額外的層在自注意力中并不存在。

順便提一句,對我來說,這是一種創(chuàng)建多頭注意力的略微令人驚訝的方式。例如,為什么不為每個頭創(chuàng)建單獨的 Wk、Wq、Wv 矩陣,而不是添加一個新層并共享這些權重。如果你知道,請告訴我——我真的不知道。

位置編碼和嵌入

我們在自注意力部分簡要討論了使用位置編碼的動機。這些是什么?雖然圖片顯示的是位置編碼,但使用位置嵌入比使用編碼更常見。因此,我們在這里討論一個常見的位置嵌入,但附錄也涵蓋了原始論文中使用的位置編碼。位置嵌入與任何其他嵌入沒有什么不同,只是我們嵌入的是數字 1、2、3 等,而不是嵌入單詞詞匯。因此,這個嵌入是一個與單詞嵌入長度相同的矩陣,每一列對應一個數字。就是這樣。

GPT 架構

我們來談談 GPT 架構。這是大多數 GPT 模型中使用的架構(存在一些差異)。如果你一直關注這篇文章,這應該很容易理解。使用框圖表示法,這就是該架構在高級別的外觀:

此時,除了“GPT Transformer 模塊”之外,所有其他模塊都已進行了詳細討論。這里的 + 號只是表示兩個向量相加(這意味著兩個嵌入必須大小相同)。我們來看看這個 GPT Transformer 模塊:

就是這樣。它在這里被稱為“Transformer”,因為它源自并且是 Transformer 的一種——這是一種我們將在下一節(jié)中看到的架構。這并不影響理解,因為我們之前已經涵蓋了這里顯示的所有構建模塊。讓我們回顧一下到目前為止我們?yōu)闃嫿ㄟ@個 GPT 架構所涵蓋的所有內容:

隨著公司構建強大的現代 LLM,隨著時間的推移,對此進行了修改,但基本原理保持不變。

現在,這個 GPT Transformer 實際上就是原始 Transformer 論文中引入 Transformer 架構的所謂的“解碼器”。讓我們來看看它。

Transformer 架構

這是近年來推動語言模型能力快速提升的關鍵創(chuàng)新之一。Transformer 不僅提高了預測精度,而且比以前的模型更容易/更高效(訓練),從而允許更大的模型尺寸。上面提到的 GPT 架構就是基于此。

如果你看一下 GPT 架構,你會發(fā)現它非常適合生成序列中的下一個單詞。它從根本上遵循我們在第 1 部分中討論的相同邏輯。從幾個單詞開始,然后一次繼續(xù)生成一個。但是,如果你想進行翻譯怎么辦?如果你有一個德語句子(例如 “Wo wohnst du?” = “Where do you live?”),你想把它翻譯成英語,我們該如何訓練模型來做這件事?

好吧,我們要做的第一件事就是找到一種輸入德語單詞的方法。這意味著我們必須擴展我們的嵌入以包含德語和英語?,F在,我想這里有一個簡單的輸入信息的方法。我們?yōu)槭裁床缓唵蔚貙⒌抡Z句子連接到目前為止生成的英語的開頭,并將其饋送到上下文中呢?為了方便模型處理,我們可以添加一個分隔符。在每一步中,它看起來像這樣:

這將起作用,但還有改進的空間:

Transformer 最初就是為此任務而創(chuàng)建的,它由一個“編碼器”和一個“解碼器”組成——它們基本上是兩個獨立的塊。一個塊簡單地獲取德語句子并給出一個中間表示(同樣,基本上是一堆數字)——這被稱為編碼器。

第二個塊生成單詞(到目前為止我們已經看到了很多)。唯一的區(qū)別是,除了向它提供到目前為止生成的單詞之外,我們還向它提供編碼的德語(來自編碼器塊)句子。因此,當它生成語言時,它的上下文基本上是到目前為止生成的所有單詞,加上德語。這個塊被稱為解碼器。

這些編碼器和解碼器中的每一個都由幾個塊組成,特別是夾在其他層之間的注意力塊。讓我們看一下論文“Attention is all you need”中的 Transformer 插圖,并嘗試理解它:

左側的垂直塊組稱為“編碼器”,右側的稱為“解碼器”。讓我們回顧并理解我們之前還沒有講過的任何內容:

_回顧如何閱讀圖表:_這里的每個方框都是一個塊,它以神經元的形式接收一些輸入,并輸出一組神經元作為輸出,然后可以由下一個塊處理或由我們解釋。箭頭顯示了塊的輸出流向。如您所見,我們經常將一個塊的輸出作為輸入饋送到多個塊中。讓我們在這里逐一介紹:

前饋:前饋網絡是不包含循環(huán)的網絡。我們在第 1 節(jié)中的原始網絡是一個前饋網絡。事實上,這個塊使用了非常相似的結構。它包含兩個線性層,每個線性層后面跟著一個 RELU(參見第一節(jié)中關于 RELU 的注釋)和一個 dropout 層。請記住,這個前饋網絡獨立地應用于每個位置。這意味著位置 0 上的信息有一個前饋網絡,位置 1 上有一個,依此類推。但是位置 x 的神經元與位置 y 的前饋網絡沒有鏈接。這一點很重要,因為如果我們不這樣做,它將允許網絡在訓練期間通過向前看作弊。

_交叉注意力:_你會注意到解碼器有一個多頭注意力,箭頭來自編碼器。這里發(fā)生了什么?還記得自注意力和多頭注意力中的值、鍵、查詢嗎?它們都來自相同的序列。事實上,查詢只是來自序列的最后一個單詞。那么,如果我們保留查詢,但從完全不同的序列中獲取值和鍵呢?這就是這里發(fā)生的事情。值和鍵來自編碼器的輸出。除了鍵和值的輸入來源之外,在數學上沒有任何變化。

Nx: 這里的 Nx 只是表示這個塊被鏈式重復了 N 次。所以基本上你是將塊一個接一個地堆疊起來,并將前一個塊的輸入傳遞給下一個塊。這是一種使神經網絡更深的方法?,F在,查看圖表,關于編碼器輸出如何饋送到解碼器,存在一些混淆之處。假設 N=5。我們是否將每個編碼器層的輸出饋送到相應的解碼器層?不。基本上,你只運行一次編碼器。然后你只需獲取該表示并將相同的內容饋送到 5 個解碼器層中的每一個。

Add & Norm 塊: 這與下面基本相同(猜想作者只是想節(jié)省空間)

其他一切都已討論過?,F在,你已經有了 Transformer 架構的完整解釋,它是從簡單的加法和乘法運算開始構建的,并且完全自包含!你知道每一行、每一個和、每一個框和每一個詞在如何從頭構建它們方面的含義。從理論上講,這些筆記包含了你從頭開始編寫 Transformer 代碼所需的內容。事實上,如果你感興趣,這個倉庫為上面的 GPT 架構做了這件事。

附錄

矩陣乘法

我們在上面嵌入的上下文中介紹了向量和矩陣。矩陣有兩個維度(行數和列數)。向量也可以被認為是一個維度等于 1 的矩陣。兩個矩陣的乘積定義為:

點代表乘法?,F在讓我們再看一下第一張圖中藍色和有機神經元的計算。如果我們將權重寫成矩陣,將輸入寫成向量,我們可以用以下方式寫出整個操作:

如果權重矩陣稱為“W”,輸入稱為“x”,則 Wx 是結果(在本例中為中間層)。我們也可以將兩者轉置并將其寫為 xW——這是一個偏好問題。

標準差

我們在層歸一化部分使用了標準差的概念。標準差是衡量數值(在一組數字中)分散程度的統(tǒng)計指標,例如,如果所有值都相同,則標準差為零。一般來說,如果每個值都與這些相同值的平均值相差很遠,那么你將擁有一個高標準差。計算一組數字 a1、a2、a3…(假設為 N 個數字)的標準差的公式如下:從每個數字中減去平均值(這些數字的平均值),然后對每個 N 個數字的答案進行平方。將所有這些數字相加,然后除以 N。現在取答案的平方根。

位置編碼

上面我們討論了位置嵌入。位置編碼只是一個與詞嵌入向量長度相同的向量,但它不是一種嵌入,因為它沒有被訓練。我們只是簡單地給每個位置分配一個唯一的向量,例如,位置 1 一個向量,位置 2 另一個向量,以此類推。一個簡單的方法是將該位置的向量填充為位置編號。因此,位置 1 的向量將是 [1,1,1…1],位置 2 的向量將是 [2,2,2…2],以此類推(記住每個向量的長度必須與嵌入長度匹配才能進行加法運算)。這是有問題的,因為我們最終可能會在向量中得到很大的數字,這會在訓練過程中造成挑戰(zhàn)。當然,我們可以通過將每個數字除以位置的最大值來歸一化這些向量,因此如果總共有 3 個單詞,則位置 1 為 [.33,.33,..,.33],位置 2 為 [.67, .67, ..,.67],以此類推?,F在的問題是,我們不斷地改變位置 1 的編碼(當我們輸入 4 個單詞的句子時,這些數字會有所不同),這給網絡學習帶來了挑戰(zhàn)。因此,我們想要一種方案,為每個位置分配一個唯一的向量,并且數字不會爆炸?;旧?,如果上下文長度為 d(即,我們可以輸入到網絡中用于預測下一個標記/單詞的最大標記/單詞數量,請參閱“它是如何生成語言的?”部分中的討論),并且如果嵌入向量的長度為 10(假設),那么我們需要一個 10 行 d 列的矩陣,其中所有列都是唯一的,并且所有數字都在 0 和 1 之間。鑒于零和一之間有無限多的數字,而矩陣的大小是有限的,這可以通過多種方式實現。

“Attention is all you need”論文中使用的方法如下:

為什么選擇這種方法?通過改變 10k 的冪,你就是在改變在 p 軸上觀察時正弦函數的振幅。如果你有 10 個不同的正弦函數,具有 10 個不同的振幅,那么對于 p 的變化值,需要很長時間才會出現重復(即所有 10 個值都相同)。這有助于我們獲得唯一值?,F在,實際的論文同時使用了正弦和余弦函數,編碼的形式是:如果 i 為偶數,則 si(p) = sin (p/10000^(i/d));如果 i 為奇數,則 si(p) = cos(p/10000^(i/d))。

文章轉自微信公眾號@知覺之門

上一篇:

使用LlamaParse、Langchain和Groq在復雜PDF上進行RAG

下一篇:

高級 RAG 技術——圖解概覽
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費