詞向量嵌入的深入研究

2021-10-01 05:08:22 字數 3882 閱讀 7514

最近做專案想把bert的詞向量提出來用,好好研究了一下詞向量的嵌入。傳統詞向量嵌入主要就是word2vec和keras.layers.embedding層了,除此之外還打算講一下bert的詞向量應用:

不管是用word2vec、embedding層還是bert,每個詞都會被先編碼為乙個數字,你的資料集/batch會先被轉化為乙個[batch_size,seq_length]的矩陣,然後再使用詞向量嵌入把他做成乙個[batch_size,seq_length,z_dim]的三維矩陣,其中seq_length是句長,z_dim就是詞向量長度。對於變長的句子,一般是採取padding處理,就是用[unk]識別符號把句子不夠長的部分補齊。最後投進神經網路的就是這個[batch_size,seq_length,z_dim]的三維矩陣。

keras.layers.embedding(input_dim,output_dim):

input_dim是字典長度(總詞量),output_dim就是嵌入維度。

embedding層在編碼的時候就和就是乙個矩陣,矩陣就是一種變換嗎,矩陣的值通過結果的反向傳播來更新。所以他本身對於每個詞的編碼是結合了語句和整個資料集的上下文學習經驗的。

word2vec本身是訓練乙個矩陣,這個矩陣和embedding層的神經網路基本上是一樣的,所以我們在用word2vec的時候是先訓練word2vec模型,然後把word2vec的矩陣按行提出來放進embedding層裡,當然一般是要把這層凍結掉的,因為word2vec是在進入模型之前就訓練好的:

#word2vec的訓練:

# 設定詞語向量維度

num_featrues = char_size

# 保證被考慮詞語的最低頻度

min_word_count = min_count

# 設定並行化訓練使用cpu計算核心數量

num_workers =4

# 設定詞語上下文視窗大小

context = 5

w2v_model = word2vec.word2vec(word2veccut, workers=num_workers, size=num_featrues, min_count=min_word_count, window=context)

w2v_model.init_sims(replace=true)

#利用訓練後的word2vec自定義embedding的訓練矩陣,每行代表乙個詞(結合獨熱碼和矩陣乘法理解)

embedding_matrix = np.zeros((len(chars)+4, char_size))

for word, i in char2id.items():

try:

embedding_vector = w2v_model[str(word)]

embedding_matrix[i] = embedding_vector

except keyerror:

continue

然後神經網路embedding層載入權重矩陣並凍結:

embedding = embedding(len(chars)+4, char_size,weights=[embedding_matrix], trainable=false)
那麼word2vec和embedding層哪個好呢?

我個人是傾向word2vec的,因為word2vec的訓練是無監督的,特別是對於文字摘要任務,詞向量本身應該表示詞義,和他的結果應該是沒關係的,embedding層作為有監督訓練出來的詞的權重必然會受到結果的影響,但是在文字摘要任務中詞義是不應該受到結果影響的。

bert的提取詞向量(tensorflow):

token=tokenization.chartokenizer(bert_vocab_file)

split_tokens = token.tokenize('鋤禾日當午')

print(split_tokens)

word_ids = token.convert_tokens_to_ids(split_tokens)

print(word_ids,len(word_ids))

test_ids=[100,101,102,103]

ret_words=token.convert_ids_to_tokens(test_ids)

print(ret_words)

word_mask = [1] * len(word_ids)

word_segment_ids = [0] * len(word_ids)

# graph

input_ids = tf.placeholder(tf.int32, shape=[none, none], name='input_ids')

input_mask = tf.placeholder(tf.int32, shape=[none, none], name='input_masks')

segment_ids = tf.placeholder(tf.int32, shape=[none, none], name='segment_ids')

model=modeling.bertmodel(

config=bert_config,

is_training=false,

input_ids=input_ids,

input_mask=input_mask,

token_type_ids=segment_ids,

use_one_hot_embeddings=false,

)# 載入bert模型

tvars=tf.trainable_variables()

(assignment, initialized_variable_names) = modeling.get_assignment_map_from_checkpoint(tvars, init_checkpoint)

tf.train.init_from_checkpoint(init_checkpoint, assignment)

# 獲取最後一層和倒數第二層。

encoder_last_layer = model.get_sequence_output()

encoder_last2_layer = model.all_encoder_layers[-2]

querylist=['鋤禾日當午','汗滴禾下土']

veclist=

with tf.session() as sess:

sess.run(tf.global_variables_initializer())

token = tokenization.chartokenizer(vocab_file=bert_vocab_file)

for query in querylist:

split_tokens = token.tokenize(query)

word_ids=token.convert_tokens_to_ids(split_tokens)

word_mask=[1] * len(word_ids)

word_segment_ids=[0] * len(word_ids)

fd =

last = sess.run(encoder_last_layer, feed_dict=fd)

print(last)

其中token是呼叫的谷歌開源的bert**裡的tokenization,對句子進行分詞和編碼,**裡出現的[100,101,102,103]是[cls][sep][unk][mask]四個識別符號(具體順序我記不太清了,可以看bert模型目錄下面的vocab.txt)。token.convert_ids_to_tokens需要自己翻一下tokenization.py改一下原始碼,很簡單的,bert的詞與編碼(不是詞向量)的對應是用dict實現的。

當然你要投不等長的資料集進去你要先mask,把短句子補齊到同一長度。

flex Bindable深入研究

bindable 元資料標籤,它在 中的作用就是向編譯器提供如何編譯程式的資訊。它的最大作用是使程式元件間的資料同步變得容易。在開發中通常用上bindable作用在檢視控制項上,如給它繫結乙個物件,則以後只需要在邏輯層更改這個物件的值,則檢視層的控制項資料會自動更新 同步 而不再需要手動去更新檢視。...

URLRequest深入研究

urlrequest 的乙個例項 html view plain copy create the request.所構建的nsurlrequest具有乙個依賴於快取響應的特定策略,cachepolicy取得策略,timeoutinterval取得超時值 nsurlrequest therequest...

深入研究AsyncTask

asynctask提供了一種在後台執行操作而在ui執行緒顯示結果的方式,而且開發者不必操作執行緒或者handler.乙個asynctask定義了三種泛型分別是params,progress,result,還有四個函式分別是onpreexecute doinbackground onprogressu...