所有的語言模型的發展都離不開最基礎的模型,統計語言模型是最重要的一環,word2vec也是如此,統計語言模型是用來計算一個句子的概率的概率模型,通常是基於一個語料庫來構建,那什麼叫一個句子的概率呢?
1、softmax
softmax 函數通常處理機器學習分類問題的輸出層的激活函數,它的輸入是一個實數向量,輸出向量的長度是與輸入向量相同,但所有的取值範圍是(0,1),且所有元素的和爲1,輸出向量的各個元素值表示某個分類的可能性。
softmax函數的數學表達式:
由於輸入x是實數向量,e的x次方的計算結果可能非常大甚至溢出,不利於計算的穩定性。所以通常將x減去一個常數c再輸入到softmax。下面證明了x的常數加減是不會影響softmax結果的(softmax的常數不變性):
2、神經網絡基礎
sigmoid
爲什麼要在隱藏層使用激活函數呢?
非線性的激活函數,因爲如果不用激活函數,每一層輸出都是上層輸入的線性函數,無論神經網絡有多少層,輸出都是輸入的線性組合。如果使用的話,激活函數給神經元引入了非線性因素,使得神經網絡可以任意逼近任何非線性函數,這樣神經網絡就可以應用到衆多的非線性模型中。
由於反向傳播計算過程需要用到導數,所以需要對sigmoid函數求導,sigmoid函數的數學表達式爲:
對sigmoid函數求導,得到的是導數就是s*(1-s)。
淺層的網絡的樣子
前向傳播
A0=x
z1=A0*w1+b1
A1=sigmoid(z1)
z2=A1*w2+b2
A2=sifmoid(z2)
損失函數cost
反向傳播:
dz2=A2-Y
dw2=A1T*dz2
dz1=dz2*w2T
dw1=A0T*dz1
實現淺層的神經網絡
'''
w1 #shape=(節點,) (10,5)
b1 #shape=(1,節點) (1,5)
w2 #shape=(節點,特徵) (5,10)
b2 #shape=(1,類別) (1,10)
'''
N=data.shape[0]
#forward prpagation
A0=data
Z1=np.dot(A0,W1)+b1
A1=sigmoid(Z1)
Z2=np.dot(A1,w2)+b2
A2=softmax(Z2)
#compute cost
target=np.argmax(label,axis=1)
cost_each=-np.log(A2[range(N),target]).reshape(-1,-1) #target是索引,one-hot的索引#值,reshape(-1,1)轉成列向量
cost=np.mean(cost_each,axis=0)
#反向傳播
dz2=(A2-labels)/N
dw2=np.dot(A1.T,dz2)
db2=np.sum(dz2,axis=0,keepdims=True)
dz1=np.dot(dz2,w2.T)*sigmoid_grad(A1)
dw1=np.dot(A0.T,dz1)
db1=np.sum(dz1,axis=0,keepdims=True)
實現skip-gram
#標準化處理,橫向量歸一化,目的是梯度下降的時候,下降速度會更快,不存在某一個值變化太大。
x=np.arrange(12).reshape(2,6)
x/=np.linalg.norm(x,axis=1)
def softmaxCostAndGradient(predicted, target, outputVectors, dataset):
""" Softmax cost function for word2vec models
### YOUR CODE HERE
w1=predicted.reshape(-1,-1)#
#forward
A0=outputVectors
z1=np.dot(A0,W1)
A1=softmax(z1)
#計算損失
cost=-np.log(A1[target])
#反向傳播求梯度
A1[target]-=1.0
dw1=np.outer(A1.T,A0)
dz1=np.dot(A,w1.T)
gradPred=dw1
grad=dz1
### END YOUR CODE
return cost, gradPred, grad
負採樣
負採樣 :引入不正確的樣本,從語料庫中抽取出的,都是0,也就是都是負樣本,負採樣K次,
K值選擇:語料庫很大,K=5,語料庫很小,K=20
負採樣推導:
def negSamplingCostAndGradient(predicted, target, outputVectors, dataset,
K=10):
indices = [target]
indices.extend(getNegativeSamples(target, dataset, K))
### YOUR CODE HERE
grad=np.zeros(outputVectors.shape)
gradPred=np.zeros(predicted.shape)
#正樣本的損失值
cost=0
z=sigmoid(np.dot(outputVectors[target],predicted))
cost-=np.log(z)
grad[target]+=predicted*(z-1.0)
gradPred+=outputVectors[target]*(z-1.0)#更新預測
#計算K個負樣本的損失值
for k in xrange(K):
samp=dataset.sampleTokenIdx()
z=sigmoid(np.dot(outputVectors[samp],predicted))
cost-=np.log(1.0-z)
grad[samp]+=predicted*z
gradPred+=outputVectors[samp]*z
### END YOUR CODE
4、情感分類
1、什麼是情感分類
情感分類的任務就是看一段文本,然後分辨是否喜歡他們討論的東西
2、如何簡單的實現情感分類
詞向量的平均值進行預測
3、簡單的情感分類缺點是多少
“這道紅燒排骨做得好喫,美觀,吸引人,健康不沾邊”
可能這句話會是正向情感,但是因爲語序的原因,健康不沾邊是更加重要,所以越在後面的越重要,語序很重要,這應該是負向的情感。