[論文筆記]Skip-Thought Vectors_將句子或片語(而非單詞)向量化
Skip-Thoughts 使用跳躍思維模型
與 word2vec 相當相似是一種自然語言處理模型,但不是一次將個別單詞轉換為向量。
取而代之,將整個句子作為單位轉換為向量。
主要理論是去取得一個自然語言語料庫,並找出哪些句子傾向於彼此相鄰出現,然後訓練一個神經網路,使其能預測哪些句子預期會出現在任何其他句子之前或之後。
研究問題
這項研究試圖解決的核心問題是:如何在這個缺乏標註數據的狀況下,學習出高品質、通用且分佈式的句子表示向量(Distributed Sentence Representations)?
在當時,雖然詞向量(Word Vectors)已經能透過非監督學習取得很好的效果,但句子向量的學習大多仍依賴「監督式任務」(Supervised tasks),例如情感分析或邏輯推理 。
這導致模型學習到的特徵往往只針對特定任務有效,缺乏通用性。雖然 Paragraph Vector 是一種非監督替代方案,但它在測試階段需要進行推論來計算新句子的向量,效率較低 。
作者希望創造一種「隨取隨用」(off-the-shelf)的編碼器,能將任何句子映射成向量,並直接應用於各種下游任務
Skip-Thought Vectors採用的encoder-decoder結構,會先將輸入句子的單詞序列進行編碼,並依序預測前後文句的單詞作為輸出。通過學習句子與其前後文句之間的共現關係,Skip-thought 能夠獲得句子編碼結果的數值向量(Skip-Thought Vector),可視為是對單詞向量合成方法本身的學習。
研究背景
Skip-thought 是由 Ryan Kiros 等人於 2015 年提出的一種深度學習演算法,用於將文檔中的句子表達轉換為數值向量。該演算法的特點在於採用無監督學習方式,因此在學習過程中無需標籤或註解過的文本。只要存在由有序句子組成的文檔,即可基於此進行學習並建立模型。
此篇論文研究的靈感主要來自於詞嵌入模型,但其演算法與 Word2vec 有很大的不同。
在 Word2vec(skip-gram)中,主要是透過對輸入詞彙預測其周邊位置的詞彙,來學習詞彙之間的共現關係。
- 從詞到句子: 既然 Skip-gram 可以透過預測上下文單字來學習詞義,那麼利用書籍中連貫的文本結構,一個句子應該也能透過預測「前一句」和「後一句」來學習句義 。
- 現有技術侷限: 當時主流的句子組合方法(Composition methods)如遞歸神經網絡(Recursive NN)或卷積網絡(CNN),通常需要依賴類別標籤進行倒傳遞更新,這限制了它們的推廣能力 。
- 目標設定: 作者決定不專注於設計新的組合運算符(composition operator),而是提出一個新的目標函數(objective function),讓任何編碼器都能透過此目標學習到通用的語義 。
此處 表示輸入句子的編碼結果,也就是 Skip-thought 向量。
當給定輸入句子的 Skip-thought 向量以及該句子前後文中出現的單詞時,會透過最大化輸出單詞機率的對數和來進行最佳化。
模型架構
Skip-Thought 模型採用了經典的 Encoder-Decoder架構
核心機制: 給定一個連續的句子三元組 ,模型將中間的句子 編碼,並試圖重構前一句 和後一句 。
編碼器 (Encoder): 使用帶有 GRU (Gated Recurrent Unit) 激活函數的 RNN。它將句子中的單字依序輸入,最後的隱藏狀態 (Hidden state) 即視為該句子的向量表示。
解碼器 (Decoder): 這是兩個獨立的神經語言模型 (Neural Language Model) —— 一個負責生成前一句,一個負責生成後一句。解碼器的運算會受到編碼器輸出的句子向量 所制約 (Conditioned on )。
詞彙擴展 (Vocabulary Expansion): 為了解決訓練資料中未見過單字 (OOV) 的問題,作者提出了一種線性映射方法。利用一個在大規模資料上預訓練好的 Word2Vec 模型,學習一個線性轉換矩陣 ,將 Word2Vec 空間中的詞向量映射到 Skip-Thought 的編碼器空間。這使得模型可涵蓋訓練時的 2 萬字,一口氣擴展到近 100 萬字。
實驗方法
作者的評估策略採取訓練完 Skip-Thought 模型後,將其凍結為特徵提取器,不再對編碼器進行Fine-tuning。
- 特徵提取: 對於下游任務的每個句子,直接計算其 Skip-Thought 向量。
- 線性分類器: 在這些凍結的向量特徵之上,僅訓練簡單的線性分類器(如 Logistic Regression),以此來嚴格檢驗向量本身的品質,而非依賴複雜的後端模型能力 。
評估任務: 涵蓋了 8 類任務
語義相關性 (Semantic Relatedness): SICK 數據集 。
釋義檢測 (Paraphrase Detection): Microsoft Research Paraphrase Corpus 。
圖像-句子排序 (Image-Sentence Ranking): Microsoft COCO 數據集 。
分類基準測試
情感分析: MR(Movie Review sentiment),CR(Customer Product Reviews)
主觀性分析(SUBJ)
意見極性(MPQA)
問題分類(TREC)
Skip-thought 的實作由論文作者在 GitHub 上公開
Ryan Kiros 原版的程式碼是用比較舊的 Theano 框架寫的
模型的訓練以及應用時使用的所有檔案皆存在於 training 目錄中。
- homogeneous_data.py : 用於建立mini-batch等任務
- layers.py: 定義各層(如 GRU)節點的行為
- model.py: 定義 Skip-thought 的網路
- vocab.py:計算詞彙出現次數,並建立出現詞彙的字典。
- train.py :用於執行模型的訓練
- tools.py :在模型套用時使用
先補下載安裝python2.7版本
https://www.python.org/downloads/release/python-2718/
在 Python 2.7 的年代,venv 還不是內建模組,所以必須手動安裝。
安裝 virtualenv 工具
C:\Python27\python.exe -m pip install virtualenv
安裝 virtualenv 工具
C:\Python27\python.exe -m pip install virtualenv
只能先手動敲指令創建好
進入 Project: [你的專案名] > Python Interpreter。
點擊右側的 Add Interpreter... -> Add Local Interpreter...。
在 Python 2.7 中,導入機制非常死板。請檢查左側目錄,確認以下每個層級都有 __init__.py
這邊補在sent2vec/training下新建一個空的python程式檔案命名為__init__.py
這邊補在sent2vec/training下新建一個空的python程式檔案命名為__init__.py
# -*- coding: utf-8 -*- import os import time from datetime import datetime os.environ['THEANO_FLAGS'] = 'device=cpu,floatX=float32,cxx=' # 關掉 C++ 編譯 from sent2vec.training import train, vocab, tools from nlp_utils import * #在 0.7.0 版本中,使用的是 device = gpu import theano print("Theano version: " + theano.__version__) print("Theano device: " + theano.config.device) # 檢查是否真的使用了 GPU if theano.config.device.startswith('gpu') or theano.config.device.startswith('cuda'): print("GPU is ENABLED!") else: print("GPU is NOT enabled. Current device: " + theano.config.device) # 1. 設定檔案路徑 source_file = 'training_data.txt' # 你的原始語料檔 model_name = 'my_skip_model.npz' # 模型存檔名稱 sentList = []#分詞後的句子列表 lines = getLinesFromTxt(source_file) print '句子數量 : '+str(len(lines)) for line in lines: line = line.strip() if not line: continue tokens = getTokenlistFromline_zh(line) # list of tokens sent = u' '.join(tokens) sentList.append(sent) print '分詞後的有效句子數 : '+str(len(sentList)) # 2. 建立詞彙表 (Vocabulary) # 這會統計詞頻並生成一個字典檔案,從輸入資料建立詞彙字典,並將其儲存。 #這裡的 worddict 是以單字為鍵、出現次數排名為值的字典。使用 loc 指定儲存目的地的路徑 print("Building vocabulary...") # build_dictionary 會回傳 (worddict, wordcount) worddict, _ = vocab.build_dictionary(sentList) vocab.save_dictionary(worddict, _, loc='dictionary.pkl') # 3. 執行訓練 train_start_dt = datetime.now() train_start_ts = time.time() print("Training start time: " + train_start_dt.strftime("%Y-%m-%d %H:%M:%S")) # 注意:skip-thoughts 訓練非常耗時且極度吃顯存(VRAM) # 如果沒有 GPU,這行可能會跑非常久 print("Starting training...") train.trainer( sentList, dictionary='dictionary.pkl', saveto=model_name, dim_word=128, # 300 -> 200 或更小 dim=300, # 1200 -> 600 或 300 n_words=6000, # 20000 -> 8000 / 5000 batch_size=8, # 64 -> 32 / 16 max_epochs=1, optimizer='adam', maxlen_w=60 ) train_end_dt = datetime.now() train_end_ts = time.time() elapsed_sec = train_end_ts - train_start_ts print("Training end time: " + train_end_dt.strftime("%Y-%m-%d %H:%M:%S")) print("Training elapsed: %.2f seconds (%.2f minutes)" % (elapsed_sec, elapsed_sec / 60.0)) print("Training complete!")
參考
Skip-thought vectors
Skip-Thought Vectors論文
Aligning Books and Movies:Towards Story-like Visual Explanations by Watching Movies and Reading Books
Neural storytelling: Skip thought vectors and Visual attention modelling
BookCorpus 是由未出版的作者撰寫的大量免費小說書籍,其中包含 16 種不同子流派(例如,浪漫、歷史、冒險等)的 11,038 本書(約 74m 句子和 1g 單詞)。
bookcorpus-datasheet
Kaggle BookCorpus
soskek/bookcorpus
ryankiros/skip-thoughts
Skip-thoughtを用いたテキストの数値ベクトル化
My Thoughts On Skip Thoughts
The first public PyTorch implementation of Skip-Thought Vectors
Skip-Thought Vector —— 跳跃思维句表示
留言
張貼留言