神經網絡語言模型
- 什么是神經網絡?
- 神經網絡的基本結構是什么?
- 輸入層
- 隱藏層
- 輸出層
- 神經網絡為什么能解決問題?
- 通用近似定理
- 為什么需要權重和偏置?為什么需要激活函數?
- 權重是如何確定的?
- 1. 窮舉
- 2. 反向傳播
- 主要步驟:
- 能使用梯度來優化參數的原因
- 卷積神經網絡跟經典的神經網絡有什么差異?
- 神經網絡怎么在語言模型層面進行應用?
- 輸入層的不同
- 如何將詞拼接成語句作為輸入?
- 如何確定詞要轉化的向量值是多少?
- 嵌入矩陣
- 輸出層的不同
- softmax
- 為什么會想到用神經網絡來構件語言模型?
本文一共回答了六個問題,這六個問題可以分為兩個部分:
- 神經網絡基本原理
- 神經網絡+語言模型 = 神經網絡語言模型
第一部分:
- 一、什么是神經網絡?
- 二、神經網絡的基本結構是什么?
- 三、神經網絡為什么能解決問題?
- 四、卷積神經網絡跟經典的神經網絡有什么差異?
第二部分:
- 五、神經網絡怎么在語言模型層面進行應用?
- 六、為什么會想到用神經網絡來構件語言模型?
什么是神經網絡?
神經網絡是一種模擬人腦神經元連接結構的機器學習模型。
如果之前聽過什么輸入層、隱藏層、輸出層,那這些概念就是來自神經網絡。
如果沒聽過,那就簡單理解神經網絡就是用一堆矩陣來模擬某一個連續函數,我們可能不知道這個函數是長什么樣的,但是我們猜有這么一個函數F(X),當我們給定輸入X,F(X)有一個輸出G,G就是神經網絡根據輸入預測的輸出。
神經網絡的基本結構是什么?
神經網絡的結構包括:
- 層數(幾層隱藏層)
- 每層的神經元數目
- 相鄰層之間神經元相連的權重
- 每層使用的激活函數
輸入層
接受原始數據(如圖像像素、音頻、文本向量)
所謂的輸入層,就是將輸入數據用離散的數據表示,為什么需要離散,因為現實世界是連續的,有些概念是抽象的,例如文字的“你”、“我”,我們告訴計算機說輸入一個“你”、“我”,實際上也是將“你”、“我”變成一堆010101010…,我理解這就是離散的過程,也就是輸入層的作用:將現實中的數據以向量/矩陣等計算機可以進行運算的格式進行表示。
隱藏層
通過加權和+激活函數提取特征
隱藏層很"簡單",就是外界數據通過輸入層之后,變成了一堆計算機可以運算的數據,隱藏層對數據刷刷一堆操作,最后輸出到輸出層。
輸出層
輸出預測結果
輸出層可以簡單理解為函數的輸出值,只不過輸出值可以用輸出層的節點來組合表示。最簡單的是如果F(X)的結果只可能是0~9十個數,那么輸出層的節點個數就可以設為10。
神經網絡為什么能解決問題?
通用近似定理
依據理論為“通用近似定理”,經典論述為:
一個具有足夠數量隱藏單元、非線性激活函數 的前饋神經網絡,可以以任意精度逼近定義在緊致空間上的任意連續函數。
換句話說,只要網絡足夠大,它就能學會從輸入到輸出的任意連續映射。
所以有時候我們會聽到類似“算的不夠準?再加節點!再加一層!”的說法。
【一些思考】我個人理解這個過程有點像多項式擬合一個連續函數,我只要把多項式的項數加的夠多,總能擬合出來的,不夠準確?那就再加一項!
為什么需要權重和偏置?為什么需要激活函數?
首先是權重和偏置,他們兩是線性的,是根據上一層的數據簡單的線性組合。例如輸入是In0、In1、In2,想要知道他們對P0結果的貢獻,
r e s 0 = I n 0 ? W 00 + I n 1 ? W 10 + I n 2 ? W 20 + B 0 res0 = In0 * W00 + In1 * W10 + In2 * W20 + B0 res0=In0?W00+In1?W10+In2?W20+B0
這里使用res0代表他不是最終值,而只是一個中間值,Wxx代表權重,B0代表偏置,這里只是想要表達一個大概的計算流程
可以看出來,都是線性組合,如果只有權重和偏置,沒有激活函數,神經網絡是一個線性變換堆疊(即矩陣乘法),只能擬合線性關系。為了求得可以擬合的更多結果,需要加入激活函數。
加入非線性激活函數(如 ReLU、Sigmoid、Tanh)后,網絡就可以表達更復雜、非線性的函數。
激活函數有很多種,這里隨便放一張圖來表示激活函數的樣式
A c t F u n c ( r e s 0 ) 【 A c t F u n c 代表激活函數】 ActFunc(res0) 【ActFunc代表激活函數】 ActFunc(res0)【ActFunc代表激活函數】
【一些思考】我對權重、偏置和激活函數的理解就是:線性+非線性=非線性。
通過激活函數引入非線性,使得神經網絡可以表達非線性的函數,因為生活中需要用到神經網絡來解決的問題基本都是非線性的。
而神經網絡不同層之間節點的權重連接,以及在節點上的偏置,其實就是加入了更多排列組合后引入了更多的可能變化,通過引入變化來使得神經網絡更能描述復雜的事物。
權重是如何確定的?
一個神經網絡想要算得準,那就需要進行調整,但是對于神經網絡來說,網絡結構一旦確定下來,可以調整的空間就局限在權重和偏置了。
為什么不調整節點數量和激活函數?也有,這樣相當于重新確定一個神經網絡算法,我們從控制變量法的思想出發,先考慮權重和偏置的改變。
下邊為了方便說明,我就統一用權重來表示權重+偏置
既然要確定權重的值,那么就需要考慮一個問題:
我為什么要選擇這個值作為權重具體的參數值,而不是那個值?
也就是需要一個評價標準來評價權重的選擇,這個標準就是:
最小化損失函數輸出,即網絡預測值和真實值之間的誤差。
說人話就是,我選擇這一批權重值能猜的準。
借用3blue1brown的比喻:
想象一個“有很多旋鈕的機器”,你要不斷調整這些旋鈕(即權重),直到輸出結果最接近你想要的答案。
下邊有兩種選擇權重的方法:
1. 窮舉
對應的權重是要調高,還是要調低,最簡單的辦法就是窮舉!
畢竟只要給足夠長的時間,一只猴子也能在打字機上打出一本《哈姆雷特》(狗頭)。
不過這種方法用的比較少,因為在參數比較多的情況下,我們很難說運氣好剛好找到一組合適的參數,加上人類的生命目前還是有限的,我們比較期望能夠有一個方法來指導我們進行,盡快找到合適的權重。
2. 反向傳播
反向傳播是一種使用鏈式法則(Chain Rule)計算誤差梯度的方法。
主要步驟:
假定神經網絡很簡單:
【輸入x】—w1(權重)----【隱藏層】----w2(權重)—【輸出】
- 前向傳播:
- 將輸入數據通過神經網絡,得到預測輸出。
這個正向的過程可以是:
- x*w1 = z1,作為隱藏層的中間結果
- σ ( z 1 ) = a 1 \sigma(z1) = a1 σ(z1)=a1,表示進行激活
- a1 * w2 = z2,作為輸出層的中間結果
- σ ( z 2 ) = a 2 \sigma(z2) = a2 σ(z2)=a2,a2表示激活后輸出層的最終結果,也被稱為預測值 y pred y_{\text{pred}} ypred?
- 計算損失:
- 使用損失函數 L ( y true , y pred ) L(y_{\text{true}}, y_{\text{pred}}) L(ytrue?,ypred?) 評估預測的好壞。
- 反向傳播計算梯度:
- 對每一層的參數求偏導(鏈式法則)。
L是a2的函數,a2是z2的函數,z2是a1的函數,a1是z1的函數,z1是w1的函數,但是只要每一層都有表達式關系,我們就可以通過鏈式法則求得偏導數:
? L / ? w 1 = ? L / ? a 2 ? ? a 2 / ? z 2 ? ? z 2 / ? a 1 ? ? a 1 / ? z 1 ? ? z 1 / ? w 1 ?L/?w1 = ?L/?a2 ? ?a2/?z2 ? ?z2/?a1 ? ?a1/?z1 ? ?z1/?w1 ?L/?w1=?L/?a2??a2/?z2??z2/?a1??a1/?z1??z1/?w1
- 參數更新:
- 使用梯度下降等優化器來更新參數。
能使用梯度來優化參數的原因
- 誤差L跟神經網絡中可以調節的權重W有關,L可以表示為W和輸入X的函數。
- 因此 ? L ? W \frac{?L}{?W} ?W?L?就能得到L對參數W的梯度,按照梯度的定義,梯度是函數值增長最快的方向,因此梯度的反方向,就是誤差L降低最快的方向。
- 函數是復雜的,我們得到的方向只是在當前這個局部點的最快下降方向,因此為了避免“走過頭”,我們還需要選擇“步長” : η \eta η, η \eta η同時也被稱為“學習率”。
- 最終更新后的權重就是: W n e w = W o l d ? ? L ? W ? η W_{new} = W_{old} - \frac{?L}{?W} * \eta Wnew?=Wold???W?L??η
【一些思考】 反向傳播為什么叫反向傳播?因為他是通過向前傳播計算之后,欸,發現算出來的值跟真實值(這里的真實值指的是訓練材料給的值)有誤差,就通過這個誤差,把誤差當成一個輸入,反著來更新權重。
問題是我要怎么用這個誤差,讓誤差來指導我更新參數,使得下一次算的時候能更貼近真實值?
就想到了L可以表示為w的函數,那么我通過求梯度,梯度的反向是函數值降低最快的方向,通過疊加梯度和步長,更新權重w,來力求讓L趨于0。
這樣通過反復迭代,也就能得到一個比較好的權重參數了。
卷積神經網絡跟經典的神經網絡有什么差異?
卷積神經網絡采用了“滑動窗口”和參數共用的概念,專業點的話為
使用一個小窗口(卷積核)在圖像上滑動,對局部區域執行加權求和(即卷積運算),并使用相同的權重(權重共享)。
挖個坑,后續再用一個獨立的章節單獨說明。
神經網絡怎么在語言模型層面進行應用?
本質上,神經網絡語言模型和N-Gram一樣,都是預測下一個詞的概率,因為神經網絡是用來擬合函數的,這句話也可以表述為:
用神經網絡擬合一個“下一個詞的概率函數”
輸入層的不同
神經網絡的輸入層接受的是數字,有些的場景下可以直接提供離散的數值,例如圖像/音頻等,可以直接用像素點的值或者頻率。
但是神經網絡能接受的其實是離散的數字,所以需要將輸入的詞轉化為向量,便于后續操作,這一步稱之為嵌入。
如何將詞拼接成語句作為輸入?
通過嵌入我們只能獲取單個詞的詞向量,但是作為神經網絡語言模型的輸入,當個詞肯定是不夠的,起碼一定量的詞組成的語句才能很好的預測下一個詞,畢竟“我打你”和“你打我”是不一樣的,雖然他們組成的詞是一樣的。
參照 N-Gram 的建模方式,為了將語句中的順序信息傳入神經網絡語言模型,前饋神經網絡語言模型(Feedforward Neural Network Language Model) 對輸入層的處理采用了嵌入+向量拼接的方式:
每個詞先通過詞嵌入層(Embedding Layer)轉化為嵌入向量,例如:
“我” → v_我 = [0.2, 0.1, -0.3, 0.7]
“打” → v_打 = [-0.1, 0.3, 0.8, 0.2]
然后將這些向量按詞語順序拼接成一個大向量:
[v_我 ; v_打] = [0.2, 0.1, -0.3, 0.7, -0.1, 0.3, 0.8, 0.2]
這個拼接后的向量作為輸入層的輸入傳入神經網絡。因此,必須先確定上下文窗口大小 N(例如使用 N-1 個詞預測下一個詞),才能確定輸入層的維度,即 N-1 個詞 × 每個詞的嵌入維度。
不過,這種方式也存在缺陷:
- 輸入的上下文長度是固定的,不能適應變長句子;
- 難以建模長距離依賴;
- 對于超出窗口的上下文信息無法捕捉。
可以發現這些限制和N-Gram是很像的,因為前饋神經網絡語言模型輸入層的節點數量跟N-Gram依據前N-1個詞預測下一個詞的N-1數量是成比例的。(假設是依靠前兩個詞預測下一個詞,嵌入向量的長度是4,前饋神經網絡語言模型輸入層的節點數量就是4*2 = 8)
這些限制正是后續引入循環神經網絡(RNN)和 Transformer 架構的動因。
如何確定詞要轉化的向量值是多少?
- 第一步:生成隨機的向量值
- 第二步:正向傳播
- 第三步:計算損失函數
- 第四步:反向傳播更新參數
不過在反向傳播更新參數的時候,神經網絡一般不會更新到入參,因為入參本來就是確定的。
但是!“嵌入”流程一開始生成的向量值是隨機的,所以他也是可以進行更新的!
【一些思考】輸入層的入參也是損失函數參數的一部分,因此也是能計算隨時函數L與輸入層參數x的偏導數,進行通過梯度進行更新。只是通常神經網絡的輸入都是確定的,總不能更新確定的東西吧(狗頭)。但是神經網絡語言模型不一樣!可以認為確定的是“詞”,但是“詞”到神經網絡中間的一層“嵌入”,也可以認為是一個函數變換的過程,因此也是能夠進行更新的,更新“詞”到對應“嵌入向量值”的過程,就相當于更新神經網絡權重的過程。
這里有一個比較好的比喻:“嵌入向量”是”“詞”在高維空間中的坐標點,因為我們一開始不知道這個坐標在哪,只能隨便猜,但是通過反向轉播,我們讓這個坐標更加的準確。
嵌入矩陣
嵌入矩陣的概念是從嵌入向量引入的,在做神經網絡語言模型的時候,首先需要確認詞匯表的大小,也就是我需要認識多少個“詞”,這樣我可以給每一個詞一個單獨的嵌入向量,也可以在輸出的時候,給出每一個詞的概率,而這都需要知道“詞匯表的大小”。
嵌入矩陣說白了就是一個向量的向量,
e m b e d d i n g ( w i ) = E [ i ] embedding(w_i) = E[i] embedding(wi?)=E[i]
其中 E E E是嵌入矩陣, i i i是詞匯表中第 i i i個詞, E [ i ] E[i] E[i]也就是詞匯表中第 i i i個詞的嵌入向量。
輸出層的不同
正如一開始所言,神經網絡語言模型希望得到的結果是預測下一個詞是什么, 如何表示這個結果呢?我們可以將輸出層的大小設置為詞匯表的大小,這樣才能輸出所有詞的概率。
softmax
因為輸出層的結果不一定是0~1之間的值,所以需要有一個辦法將結果轉化為概率。
softmax ( z i ) = e z i ∑ j = 1 K e z j \text{softmax}(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}} softmax(zi?)=∑j=1K?ezj?ezi??
其中, z i , z j z_i,z_j zi?,zj?代表輸出第i, j個的值。
反向傳播就可以通過這個概率來計算。
【一些思考】可以將softmax計算出概率的過程看作在輸出層節點上的“激活函數”,雖然不太像哈,激活函數只需要這個節點的信息,但是softmax需要所有節點的信息參與計算。
所以,通過神經網絡搭建語言模型的過程中,神經網絡語言模型多了嵌入計算詞向量的過程和softmax計算概率的過程,而計算詞向量的過程是一個可以學習的過程,詞向量或者說嵌入向量更像是詞在高位空間的一個映射,因此這種映射關系是可以學習的;而softmax計算出的概率,又可以跟訓練材料的實際輸出進行對比,計算損失函數,從而通過反向傳播來更新神經網絡模型的參數。
為什么會想到用神經網絡來構件語言模型?
使用神經網絡搭建語言模型的核心動機在于:我們認為語言可以被表示為一種連續的分布式表示,而神經網絡恰好擅長擬合這類復雜的函數關系。
換句話說,我們希望構建一個預測函數,能夠根據已有的上下文來預測下一個詞。這個函數本質上是非線性、高維、難以顯式表達的,但神經網絡正好能夠在數據驅動下自動學習到這種“看不見摸不著”的映射。
用ai的話來總結,就是
- 語言的本質可以用連續空間來建模
各個詞之間不是孤立的,是有聯系的。通過詞嵌入(Word Embedding),我們將詞映射到一個連續的高維向量空間,從而可以使用向量運算表達語義關系;
例如:king - man + woman ≈ queen 這樣的類比關系。 - 語言可以被看作是“序列”的建模問題
也就是下一詞的出現和前面的上下文息息相關 - 神經網絡具有強大的表示與泛化能力
能構建“預測函數”,這個比N-Gram強多了,N-Gram只能計算已經出現過的組合,但是神經網絡語言模型訓練好之后就算是沒出現過的組合,也能夠進行預測,因為他不是通過簡單的概率計算來做的。
【一些思考】我們使用神經網絡搭建語言模型,是因為我們認為語言可以嵌入到一個連續空間中,并通過可學習的函數來預測詞的分布。