CS224D Deep Learning for NLP lecture2

斯坦福深度學習與自然語言處理課程是Richard Socher今年開的課程。他是德國人,本來學習的是機器視覺。在斯坦福大學博士畢業,師從Andrew Ng和Chris Channing學習機器學習和NLP,畢業後也成爲一個大牛。本人小白一枚,花了好長時間才消化了課程的視頻和課件,爲了防止以後忘記,在這裏紀錄一下。

先放上該課程的官網鎮樓:http://cs224d.stanford.edu/syllabus.html
還有一個專門提供NLP資料的網站:http://www.52nlp.cn
課程的官網課件和筆記我會在每次看完後上傳到CSDN,可以免費下載(lecture2的課件後來發現要一個積分才能下載,想改成免費但是CSDN貌似改不了)

Lecture1 沒有什麼乾貨,不寫了。

Lecture2 詞矢量

計算機如何表示單詞的含義呢?普遍的做法是像WordNet(這究竟是個什麼,調研之後再補上)一樣用分類的方法表示從屬關係和同義關係。但是這樣的做法有很多侷限,例如生詞和新詞就無法表示,並且需要大量的人力去建造和維護,最關鍵的是無法準確度量詞語之間的相似度,於是詞語的離散表示(discrete representation)應運而生。

在向量空間裏,一個向量通常有1個1和很多0(剩下的應該都是0),維度從20K(語音)到13M(Google1T)不等,這種表示方式我們稱爲”one-hot”表示。但是這種表示方法有個問題,假設
motel=[0000001000000]
hotel=[0000100000000],則VmotelVhotel=0 無法表示他們的相似度

You shall know a word by the company it keeps
——J.R.Firth 1957:11

詞矢量的基本假設: 假設相似的詞總是有相似的上下文

於是我們使用上下文來表示一個單詞。用上下文表示詞語有兩種方法:用整個文檔的詞表示當前單詞,和使用有限長窗口內的詞表示當前單詞,究竟應該選用哪種方案呢?

整個文檔VS窗口

  • 使用文檔的話,詞-文檔的共現矩陣會使得大衆話題有相似的輸入,導致進一步的隱藏語義分析
  • 使用窗口的話可以讓我們同時保留句法(POS)和語法信息

所以此後我們使用基於窗口的方法用上下文表示詞矢量。窗的長度通常爲5-10。
在這裏,我們令窗長爲1,計算對稱的共現矩陣。
Example corpus:
- I like learning.
- I like NLP.
- I enjoy flying.

得到的共現矩陣見pdf第8頁

共現矩陣的問題是隨着字典的變大而變大,需要很高維的存儲,並且在後續的分類模型中會有稀疏問題,所以需要進行降維。如何用最重要的若干信息來生成密集的向量呢?

SVD分解

SVD分解就是把一個nm 的矩陣分解爲特徵向量U,對角陣S和向量V的乘積。其中U的每一列表示各個特徵分量,S的每個元素可以看作是能量(或者是比重),每個元素從左上到右下從大到小排列。所以共現矩陣X可以分解爲以U爲基底的向量的和,因此只要提取U中前K列作爲基底,用前K列表示即可以將原來的U中的m維降到K維。
簡單的python編程在pdf第12頁中有。我自己寫了一個python小程序,自帶求共現矩陣功能。完整代碼:

import numpy as np
import matplotlib.pyplot as plt
la=np.linalg
sentence=[[],[],[]]
sentence[0]=["I","like","deep","learning","."]
sentence[1]=["I","like","NLP","."]
sentence[2]=["I","enjoy","flying","."]
wordset=sentence[0]+sentence[1]+sentence[2]
vocabulary=sentence[0]
def count(x,y):
    count=0
    for i in range(0,3):
        if x in sentence[i] and y in sentence[i]:
            if np.fabs(sentence[i].index(y)-sentence[i].index(x))==1:
                    count+=1
    return count

for i in wordset:
    if not i in vocabulary:
        vocabulary.append(i)
lenth=len(vocabulary)

X=np.zeros((lenth,lenth))
for i in range(0,lenth):
    for j in range(0,lenth):
        X[i][j]=count(vocabulary[i],vocabulary[j])
print X
U,s,Vh=la.svd(X,full_matrices=False)
print U,s,Vh
fig=plt.figure()
for i in xrange(lenth):
    plt.text(U[i,0],U[i,1],vocabulary[i])
plt.xlim(-0.8,0.3)
plt.ylim(-0.6,0.6)
plt.show()

圖1
上圖爲程序運行的結果,可以看到詞的座標位置和課件上的並不一樣。說明了結果與詞的排列順序有關,不同順序共現矩陣不同,效果不同。爲了效果起見,應該將詞的順序按照在文檔中出現的頻率降序排列。

Hacks to X(共現矩陣):
對於像(the,he,she)這樣的功能詞,出現頻率太高,解決方法:

  • 使用min(X,t),t~100的方法限制最高頻率
  • 直接忽略
  • 用pearson correction 而不是直接統計次數,將負值設爲0
  • 使用有斜坡的窗使靠近的詞更高比重(感覺就像DSP裏的漢寧窗和漢命窗等)
    。。。

SVD分解的問題:

對於一個n*m的矩陣,計算複雜度是O(mn2) ,並且難以處理新詞和新文檔,與DL的體制不同。
所以有了新的思路:直接學習低維詞矢量

word2vec

word2vec主要思想

  • 並非直接計算共現次數,而是預測每個詞周圍的詞
  • 與Golve很相似
  • 更快更容易適應新文檔和在單詞里加入新詞

具體細節

目標函數:給定當前中心詞,最大化上下文中所有的詞的log概率

J(θ)=1Tt=1Tcjc,j0logp(wt+j|wt)

對於p(wt+j|wt) ,最簡單的等式如下(我一點都不覺得softmax簡單,然而歪過人貌似都信手拈來):
p(wO|wI)=exp(vTwovwI)Ww=1exp(vTwvwI))

其中,v和v’分別是一個單詞的”輸入”和”輸出”詞矢量,即每個詞有兩個向量。輸入向量很好理解,就是作爲中心詞時的詞矢量。一開始我並不懂“輸出”詞矢量是什麼鬼,看到Lecture3才明白,原來就是該詞在變成非中心詞時更新後的矢量。
例如 I like to run, 當like作爲中心詞時,它當前的詞矢量爲”輸入”詞矢量vlike ,而當to是中心詞時,like就成爲周圍詞(就是輸出詞),這時更新to的詞矢量vto 的同時,like的詞矢量也會更新,這個新的詞矢量就是like的輸出詞矢量vlike .

梯度的推導

基礎知識:

  • xTax=aTxx=a
  • Chain rule! dydx=dydududx

推導開始:

vclogP(O|C)=vclog(exp(uTovc)Ww=1exp(uTowvc))=vc[uTovclog(w=1Wexp(uTowvc))]

=uo1Ww=1exp(uTwvc)x=1Wexp(uTxvc)vc=uo1Ww=1exp(uTwvc)x=1Wexp(uTxvc)uTxvcvc

=uo1Ww=1exp(uTwvc)x=1Wexp(uTxvc)ux=uox=1Wexp(uTxvc)Ww=1exp(uTwvc)ux

=uox=1WP(X|C)ux

有木有很神奇!在當前中心詞C下週圍詞O的log概率的梯度爲,周圍詞O的”輸出“詞矢量減去,在中心詞C下所有詞X的概率乘X的”輸出“詞矢量之和(即所有”輸出“詞矢量的期望)。

雖然化成這種形式之後很方便計算,可以使用梯度下降法(SGD)求解,但是因爲每次更新都需要計算所有詞的概率和詞矢量,這個目標函數在大詞彙的字典並不適用,因爲尺度太大訓練太慢!

解決思路:

  • 進行近似
  • 定義負預測(negative prediction)(對於在上下文中不出現的單詞,只採樣幾個,從而把注意力集中在大多數的正預測上)目前不是很懂這個負預測是什麼,有什麼作用,之後搞懂裏再補上

在word2vec裏發現的線性關係:

-句法上
xapplexapplesxcarxcarsxfamilyxfamilies

-語義上
xshirtxclothingxchairxfurniture
xkingxmanxqueenxwoman

講義裏還有很多圖片,這裏不貼了

Lecture3 預告

  • details to implement word2vec
  • word embedding matrix
  • advantages of low dimensional word vectors
發佈了39 篇原創文章 · 獲贊 58 · 訪問量 44萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章