web-dev-qa-db-ja.com

例で説明:ケラスにレイヤーを埋め込む方法

KerasのEmbeddingレイヤーがわかりません。それを説明する記事はたくさんありますが、私はまだ混乱しています。たとえば、次のコードはimdb感情分析からのものです。

top_words = 5000
max_review_length = 500
embedding_vecor_length = 32    

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(X_train, y_train, nb_Epoch=3, batch_size=64)

このコードでは、埋め込みレイヤーは正確に何をしていますか?埋め込みレイヤーの出力は何ですか?誰かがいくつかの例を使って説明できるといいですね!

18
user1670773

埋め込みレイヤーは、Word2vecや事前計算された手袋と同じように、入力語から埋め込みベクトルを作成します(私自身はまだ数学を理解していません)。

コードに入る前に、簡単な例を作ってみましょう。

texts = ['This is a text','This is not a text']

最初に、これらの文を整数のベクトルに変換します。各単語は、辞書内の単語に割り当てられた番号であり、ベクトルの順序によって単語のシーケンスが作成されます。

from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences 
from keras.utils import to_categorical

max_review_length = 6 #maximum length of the sentence
embedding_vecor_length = 3
top_words = 10

#num_words is tne number of unique words in the sequence, if there's more top count words are taken
tokenizer = Tokenizer(top_words)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
Word_index = tokenizer.Word_index
input_dim = len(Word_index) + 1
print('Found %s unique tokens.' % len(Word_index))

#max_review_length is the maximum length of the input text so that we can create vector [... 0,0,1,3,50] where 1,3,50 are individual words
data = pad_sequences(sequences, max_review_length)

print('Shape of data tensor:', data.shape)
print(data)

[Out:] 
'This is a text' --> [0 0 1 2 3 4]
'This is not a text' --> [0 1 2 5 3 4]

これらを埋め込みレイヤーに入力できます

from keras.models import Sequential
from keras.layers import Embedding

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length,mask_zero=True))
model.compile(optimizer='adam', loss='categorical_crossentropy')
output_array = model.predict(data)

output_arrayにはサイズの配列(2、6、3)が含まれます。私の場合、2つの入力レビューまたは文、6は各レビューの最大単語数(max_review_length)、3はembedding_vecor_lengthです。例えば。

array([[[-0.01494285, -0.007915  ,  0.01764857],
    [-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827]],

   [[-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [-0.01736645, -0.03719328,  0.02757809],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827]]], dtype=float32)

あなたのケースでは、5000ワードのリストがあり、最大500ワードのレビューを作成でき(さらにトリミングされます)、これらの500ワードのそれぞれをサイズ32のベクトルに変換できます。

次のコマンドを実行すると、Wordインデックスと埋め込みベクトル間のマッピングを取得できます。

model.layers[0].get_weights()

以下の例では、top_wordsが10であったため、10ワードのマッピングがあり、0、1、2、3、4、および5のマッピングは上記のoutput_arrayに等しいことがわかります。

[array([[-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827],
    [-0.01736645, -0.03719328,  0.02757809],
    [ 0.0100757 , -0.03956784,  0.03794377],
    [-0.02672029, -0.00879055, -0.039394  ],
    [-0.00949502, -0.02805768, -0.04179233],
    [ 0.0180716 ,  0.03622523,  0.02232374]], dtype=float32)]

https://stats.stackexchange.com/questions/270546/how-does-keras-embedding-layer-work で述べたように、これらのベクトルはランダムに開始され、ネットワードオプティマイザによって他と同様に最適化されますネットワークの他のパラメータ。

9
Vaasha

上記の詳細な回答には同意しますが、より直感的な説明を心がけたいと思います。

埋め込みレイヤーがどのように機能するかを理解するには、一歩下がって、そもそもなぜ埋め込みが必要なのかを理解するのが良いでしょう。

通常、MLモデルはベクター(数値の配列)を入力として受け取り、テキストを処理するときに文字列を数値に変換します。これを行う最も簡単な方法の1つは、各文字列をカテゴリ変数として扱うワンホットエンコーディングです。しかし、最初の問題は、10000語の辞書(語彙)を使用する場合、ワンホットエンコーディングはスペース(メモリ)をかなり浪費することです。

また、個別のエンティティは0または1にマッピングされて特定のカテゴリを通知するため、ワンホットエンコーディングでは単語間の関係をキャプチャできません。したがって、 IMDB movie data-set に精通している場合は、ワンホットエンコーディングは感情分析には役に立ちません。なぜなら、コサイン距離を使用して類似性を測定する場合、異なるインデックス間の比較ごとに類似性は常にゼロになるためです。

これにより、次のような方法を見つけることができます-

  • 同様の単語は同様のエンコーディングを持つことができ、
  • カテゴリー変数を表すために、一意のカテゴリーの数よりも数を少なくします。

埋め込みに入ります。

埋め込みは浮動小数点値の密なベクトルであり、これらの数値はランダムに生成され、トレーニング中にこれらの値はトレーニング中に密なレイヤーの重みが更新されるのと同じように、バックプロップを介して更新されます。
TensorFlow docs で定義されているとおり

埋め込みレイヤーは、整数インデックス(特定の単語を表す)から密なベクトル(埋め込み)にマップするルックアップテーブルとして理解できます。

シーケンシャルでモデルを構築する前に、すでに Keras Tokenizer API を使用しており、入力データはすでに整数コード化されています。ここで、埋め込みディメンションの数(16、32、64など)に言及すると、ルックアップテーブルの列数はそれによって決まります。

埋め込みレイヤーの出力は常に2D配列です。そのため、通常、密なレイヤーに接続する前にフラット化されます。前の回答でも、0番目のレイヤーの重みの2D配列と列数=埋め込みベクトルの長さがわかります。

それが、Kerasの埋め込みレイヤーの考え方です。うまくいけば、これはもう少し光を放ち、私はこれが @ Vaasha によって投稿された回答の良い伴奏になるかもしれないと思いました。

参照:TensorFlow Word埋め込みチュートリアル

0
Suvo