word2vec閱讀筆記

 

1一個輸入層 ; 1 個隱含層; 1個輸出層

 

syn0       input -> hidden 的 weights     在code中是一個1維數組,但是應該按照二維數組來理解。

                訪問時實際上可以看成  syn0[i, j]   i爲第i個單詞,j爲第j個隱含單元。

               大小:  詞典大小 * 隱含層大小

syn1       hidden->output 的 weights

                

 

neu1      浮點型數組,  隱含層神經的值
               大小: 隱含層大小

neu1e     隱含層誤差量

               大小: 隱含層大小

 

vocab_size  不同單詞個數,也就是詞典大小。

layer1_size  向量長度,實際上就是隱含層的大小。

 

分析完其實就是一個BP網絡,不過還是不知道爲啥要將前後幾個詞和當前詞聯繫起來,要完全理解此場景的模型思想,看來還是得看論文了。

 

 

  1. TrainModelThread
    while (1)
    1. 打印訓練的進度情況
    2. (while)從輸入文件中讀入1000個單詞組成一個句子,存入sen, sen[i] = word_index, 也就是sen數組裏的順序與單詞在原文中的順序一致,而sen存放的值爲詞典中該單詞的位置。
      sentence_length  - 該sen數組的長度
      sentence_position - 爲最外層while循環遍歷該句子時,對記錄當前單詞在此句子中的位置。
    3. 如果 處理的單詞個數超出了分配給當前線程的個數,則結束。 
    4. 獲取當前單詞。  從句子sen中取出 word_index = sen[sentence_position]; 
    5. 初始化 隱含層神經neu1 、隱含層誤差 neu1e 爲0
    6. b  產生隨機數b, 取值目前爲0~4之間。      窗口值window默認爲5
    7. cbow
      1. in -> hidden  (正向傳播,  得到隱含層)
        for (遍歷左右窗口詞,c從 sentence_position - (window -b)   到  sentence_position + (window -b)   , 且 c != sentence_position 
        1. 得到c處存放的單詞索引 last_word = sen[c];
        2. 將該詞對應到的每一個in->hidden的網絡權重係數syn0 累加到  隱含層單元neu1中
           for (c = 0; c < layer1_size; c++) neu1[c] += syn0[c + last_word * layer1_size];
      2. HIERARCHICAL SOFTMAX   目前默認hs爲1的。
        for (遍歷該詞的huffman編碼串)
        1. f = 0
        2. 計算出該詞在hidden-output 網絡中的權重存儲位置 l2 = vocab_[word_index].point[d] * layer1_size;
          這裏的point[d]有疑問?? 是否有可能超出vocab_size呢?
          >> 不會,這個是哈夫曼樹中的非葉子節點路徑上的點,也就是多個二分類的決策點
        3. hidden -> output    (正向傳播,得到該編碼單元對應的output 值f)
          for (c = 0; c < layer1_size; c++) f += neu1[c] * syn1[c + l2];
        4. 對 f 進行Sigmoid變換  (這裏是預先存放在了expTable表中)
        5. 計算下降的梯度g     (乘了學習率alpha)
           g = (1 - vocab_[word_index].code[d] - f) * alpha;
        6. output - > hidden (反向傳播 得到隱含層誤差)
          for (c = 0; c < layer1_size; c++) neu1e[c] += g * syn1[c + l2];
        7. 學習權重 hidden-output 
          for (c = 0; c < layer1_size; c++) syn1[c + l2] += g * neu1[c];
      3. NEGATIVE SAMPLING   目前運行時默認未走此步
      4. hidden -> in (反向傳遞, 更新in-hidden網絡權重)
        for (遍歷左右窗口詞,c從 sentence_position - (window -b)   到  sentence_position + (window -b)   , 且 c != sentence_position 
        1. 得到c處存放的單詞索引 last_word = sen[c];
        2. 學習權重input-hidden   將隱含層單元誤差量neu1e 加到  該詞對應到的每一個in->hidden的網絡權重係數syn0上
           for (c = 0; c < layer1_size; c++) syn0[c + last_word * layer1_size] += neu1e[c];
    8. skip-gram
      這裏居然沒有隱含神經元的概念,其實也是neu1,只是這裏的neu1[c] = syn0[c + last_word * layer1_size] ,所以省去了用neu1[c]去計算;因此計算輸出值f的時候,直接用的是兩層網絡的權重syn0與syn1相乘;
      第1層網絡權重用的是窗口詞的, 第2層網絡權重用的是當前詞的;
      其餘部分和cbow模型類似。 
  2. 保存結果
    將input-hidden網絡權重(syn0)作爲了詞向量保存,其實是保存的爲neu1,隱含層的值,隱含層的值爲n-1個詞爲0,一個詞A爲1時候的詞典向量的特徵表示,相當於詞A的特徵表示,所以將其作爲詞A的特徵向量。

 

 

負採樣: https://www.cnblogs.com/pinard/p/7249903.html 

發佈了95 篇原創文章 · 獲贊 12 · 訪問量 46萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章