簡體   English   中英

在keras模型中使用預先訓練的單詞嵌入?

[英]Using pre-trained word embeddings in a keras model?

我正在關注如何使用預先訓練過的單詞嵌入來自keras團隊的這個github代碼。 我能夠理解其中的大部分,但我對矢量大小有疑問。 我希望有人可以幫助我。

首先我們定義Tokenizer(num_words=MAX_NUM_WORDS)

Tokenizer() num_words參數編寫 keras文檔只考慮MAX_NUM_WORDS - 1因此如果MAX_NUM_WORDS=20000我將有大約19999字。

num_words :基於字頻率保留的最大字數。 只保留最常見的num_words-1個單詞。

接下來在代碼中我們准備了一個基於手套矢量的Embedding Matrix 當我們這樣做時,我們正在考慮一個大小( np.zeros((MAX_NUM_WORDS+1, 100))np.zeros((MAX_NUM_WORDS+1, 100))的矩陣。 如果我們的詞匯中只有19999單詞,我無法理解為什么我們考慮20001的矩陣。

然后我們將num_words傳遞給嵌入層。 根據input_dim參數的嵌入層文檔,它說,

input_dim :int> 0.詞匯表的大小,即最大整數索引+ 1。

embedding_layer = Embedding(input_dim=num_words,
                            output_dim=EMBEDDING_DIM,
                            embeddings_initializer=Constant(embedding_matrix),
                            input_length=MAX_SEQUENCE_LENGTH,
trainable=False)

根據Tokenizer()函數,我們的詞匯量大1999919999嗎? 那么我們為什么input_dim 20001作為input_dim傳遞

這是從github鏈接中獲取的一小段代碼。

MAX_NUM_WORDS = 20000
MAX_SEQUENCE_LENGTH = 1000
EMBEDDING_DIR = 100

tokenizer = Tokenizer(num_words=MAX_NUM_WORDS)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)

data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)

# prepare embedding matrix
num_words = MAX_NUM_WORDS + 1
embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
for word, i in word_index.items():
    if i > MAX_NUM_WORDS:
        continue
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        embedding_matrix[i] = embedding_vector

embedding_layer = Embedding(num_words,
                            EMBEDDING_DIM,
                            embeddings_initializer=Constant(embedding_matrix),
                            input_length=MAX_SEQUENCE_LENGTH,
                            trainable=False)

對於嵌入,輸入dim(下面代碼中的num_words)是詞匯表的大小。 例如,如果您的數據是整數編碼為0-10之間的值,那么詞匯表的大小將是11個單詞。 這就是將1添加到len(word_index)和MAX_NUM_WORDS的最小值的原因。

嵌入矩陣將具有詞匯量大小和向量長度的維度

embedding_layer = Embedding(num_words,
                            EMBEDDING_DIM,
                            embeddings_initializer=Constant(embedding_matrix),
                            input_length=MAX_SEQUENCE_LENGTH,
                            trainable=False)

num_words = min(MAX_NUM_WORDS, len(word_index)) + 1

創建了一個簡單的tokenizer來解釋這一點。

t  = Tokenizer(num_words=5)
fit_text = ["The earth is an awesome place live"]
t.fit_on_texts(fit_text)
word_index = t.word_index
​
print('word_index : ',word_index)
print('len word_index : ',len(t.word_index))
word_index :  {'the': 1, 'earth': 2, 'is': 3, 'an': 4, 'awesome': 5, 'place': 6, 'live': 7}
len word_index :  7

在下面的例子中,您只覆蓋大小為4的詞匯表,因為tokenizer索引從1開始。

embedding_matrix = np.zeros((5, 10))
embedding_matrix
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

for word, i in word_index.items():
    if i < 5:       
        embedding_matrix[i] = [0,1,0,0,0,0,0,0,0,0]

print (embedding_matrix)
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]

在下面的情況中,您需要添加1(5 + 1)來覆蓋大小為5的詞匯表以覆蓋索引0

embedding_matrix = np.zeros((6, 10))
for word, i in word_index.items():
    if i < 6:       
        embedding_matrix[i] = [0,1,0,0,0,0,0,0,0,0]

print (embedding_matrix)

[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]

我認為你的疑問是有效的。 在代碼的提交中進行了更改,以保持單詞的index = MAX_NUM_WORDS 在此之前, Tokenizer上有一個提交 ,使其保留num_words字而不是num_words - 1字。 但后來這個Tokenizer變化恢復了。 所以我猜測示例更新的作者可能假設Tokenizernum_words更新時保留了num_words字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM