skip gram原始碼解析的一些文章和見解

2021-08-01 22:16:43 字數 3114 閱讀 8071

word2vec入門篇應該是這個:

第一種是帶隱藏層的,其啟用函式為tanh,然而由於隱藏層到output_layer的引數太多,畢竟output_layer的引數為vocabulary_size,動輒成千上萬,所以第一種被去掉了;

第二種是採用huffuman tree和hierarchical softmax;

第三種是負樣本取樣 nagetive sampling,相比第二種的計算速度更快。

cbow和skip-gram的區別在於:乙個是通過上下文**中心詞,乙個是通過中心詞**上下文,這點非常重要,輸入和輸出是不一樣的,但是中間過程十分相似。

這裡主要講負樣本取樣的skip-gram模型,目標是通過中心詞**上下文,參考這篇文章:

負樣本取樣的思想為:增大取到上下文詞的概率,減小取到其他詞(除了中心詞和上下文)的概率,其損失函式是在此基礎上進行取對數,之後進行引數和詞向量的更新。負樣本的取樣方法是按照詞頻排序之後選取和中心詞接近詞頻的一部分詞,如果取到正樣本則捨棄。

一般將其理解為:

我自己理解為:

完整**來自udacity:

過程解釋:

定義:count::高頻詞以及對應詞頻,低頻詞為unk(unkown)以及對應詞頻;dictionary:詞以及其對應編碼;reserve_dictionary:編碼以及其對應詞;data:原文本中所有單詞組成的編碼;

執行一下就會發現:

data: ['anarchism', 'originated', 'as', 'a', 'term', 'of', 'abuse', 'first']

with num_skips = 2 and skip_window = 1:

batch: ['originated', 'originated', 'as', 'as', 'a', 'a', 'term', 'term']

labels: ['as', 'anarchism', 'originated', 'a', 'as', 'term', 'a', 'of']

with num_skips = 4 and skip_window = 2:

batch: ['as', 'as', 'as', 'as', 'a', 'a', 'a', 'a']

labels: ['originated', 'a', 'anarchism', 'term', 'of', 'originated', 'term', 'as']

當skip_window=1,它跳過了開頭第乙個單詞,而當=2,則跳過了開頭前兩個單詞。

batch_size:每次批量輸入的詞的個數,embedding_size:詞向量的大小;但是最終輸入的是embed:注意這個函式:tf.nn.embedding_lookup(embeddings, train_dataset),是在embeddings中尋找train_dataset對應的行和列,這裡有個參考:此時在最終的loss計算當中:

loss = tf.reduce_mean(

tf.nn.sampled_softmax_loss(weights=softmax_weights, biases=softmax_biases, inputs=embed,

labels=train_labels, num_sampled=num_sampled, num_classes=vocabulary_size))

weights的大小為50000*128,biases的大小為50000*1,embed的大小為128*128,num_sampled為負樣本的個數,num_classes為總的類別,即vocabulary_size。valid_size = 16,表示求相似度的16個目標向量。接下來可以試著計算這些詞向量與其他詞向量的相似度,採用餘弦定理如下,先對兩個矩陣進行標準化,再求矩陣相乘,取top_k即為相似度最大的前k個值,:

norm = tf.sqrt(tf.reduce_sum(tf.square(embeddings), 1, keep_dims=true))#50000,對第二維度求和

normalized_embeddings = embeddings / norm#標準化,50000*128

valid_embeddings = tf.nn.embedding_lookup(

normalized_embeddings, valid_dataset)#16*128

similarity = tf.matmul(valid_embeddings, tf.transpose(normalized_embeddings))#16*50000

取法如下,此時中心詞為valid_word,接近詞的編碼為nearest,之後按照reserve_dictionary找回原來的單詞即可:

sim = similarity.eval()#16*50000

#sim是乙個大小為[valid_size,vocabulary]的陣列。sim[i,:]是valid_dataset[i]和其它元素的相似程度。

for i in range(valid_size):

valid_word = reverse_dictionary[valid_examples[i]]

top_k = 8 # number of nearest neighbors

nearest = (-sim[i, :]).argsort()[1:top_k+1]#第i行所有列排序後原來的編碼,從1開始是因為第0個是詞向量與本身的相似度

關於cbow的負樣本取樣**:

其中注意的是,train_dataset是乙個128*4的矩陣,經過tf.nn.emdedding_lookup之後變成乙個128*4*128,即128個詞的4個128維詞向量,之後經過tf.reduce_sum()將第二維求和,即將4個編碼求和,與第乙個鏈結所述的上下文的詞向量相加一致。

另:關於word2vec中使用到的技巧演算法:

TFS原始碼解析一

tfs是乙個 分布式檔案系統,集群中主要涉及名字伺服器nameserver,以及資料伺服器dataserver,nameserver提供索引管理,dataserver提供資料儲存及管理。客戶端通過nameserver請求,獲取到dataserver中的資料路徑,然後通過dataserver獲取資料操...

caffe原始碼解析 一

用si載入 後 首先從caffe layer的實現看起,不同框架下最大的差異就在於層的實現也決定了層的靈活性 layer可以看成是乙個基類,下面存在data layer,activation neuron layers,vision layer,common layers,loss layer,各個...

OkHttp原始碼解析 一

執行請求的地方.client.newcall request enqueue new callback override public void onresponse call call,response response throws ioexception okhttpclient的newcal...