web-dev-qa-db-ja.com

埋め込みレイヤーと高密度レイヤーの違いは何ですか?

Kerasの Embedding Layer のドキュメント:

正の整数(インデックス)を固定サイズの密なベクトルに変換します。例えば。 [[4], [20]]-> [[0.25, 0.1], [0.6, -0.2]]

これは、長さvocabulary_sizeのワンホットベクトルとして入力をエンコードし、それらを 高密度レイヤー に入力することでも達成できると考えています。

埋め込みレイヤーは、この2段階のプロセスの利便性にすぎないのでしょうか?

18
Imran

数学的には、違いは次のとおりです。

  • 埋め込み層はselect操作を実行します。ケラでは、このレイヤーは次と同等です:

    K.gather(self.embeddings, inputs)      # just one matrix
    
  • 密なレイヤーはdot-product操作とオプションのアクティベーションを実行します:

    outputs = matmul(inputs, self.kernel)  # a kernel matrix
    outputs = bias_add(outputs, self.bias) # a bias vector
    return self.activation(outputs)        # an activation function
    

エミュレートワンホットエンコーディングを介して完全に接続されたレイヤーを持つ埋め込みレイヤーを使用できますが、高密度埋め込みのポイントはavoidワンホット表現です。 NLPでは、Wordの語彙サイズは100k(場合によっては100万)程度です。それに加えて、多くの場合、単語のシーケンスをバッチで処理する必要があります。 Wordインデックスのシーケンスのバッチの処理は、ワンホットベクトルのシーケンスのバッチよりもはるかに効率的です。さらに、gather操作自体は、フォワードパスとバックワードパスの両方で、行列の内積よりも高速です。

25
Maxim

埋め込みレイヤーのほうが速い。これは、仮定を単純化する高密度レイヤーと本質的に同等であるためです。

これらの重みを持つWord-to-embeddingレイヤーを想像してください。

w = [[0.1, 0.2, 0.3, 0.4],
     [0.5, 0.6, 0.7, 0.8],
     [0.9, 0.0, 0.1, 0.2]]

Denseレイヤーは、これらを行列乗算を実行する実際の重みのように扱います。埋め込みレイヤーは、これらの重みをベクトルのリスト、各ベクトルは1つのWordを表します;として単純に扱います。語彙の0番目の単語はw[0]、1番目はw[1]など.


例として、上記の重みと次の文を使用します。

[0, 2, 1, 2]

単純なDenseベースのネットは、その文を1ホットエンコードに変換する必要があります

[[1, 0, 0],
 [0, 0, 1],
 [0, 1, 0],
 [0, 0, 1]]

その後、行列乗算を行います

[[1 * 0.1 + 0 * 0.5 + 0 * 0.9, 1 * 0.2 + 0 * 0.6 + 0 * 0.0, 1 * 0.3 + 0 * 0.7 + 0 * 0.1, 1 * 0.4 + 0 * 0.8 + 0 * 0.2],
 [0 * 0.1 + 0 * 0.5 + 1 * 0.9, 0 * 0.2 + 0 * 0.6 + 1 * 0.0, 0 * 0.3 + 0 * 0.7 + 1 * 0.1, 0 * 0.4 + 0 * 0.8 + 1 * 0.2],
 [0 * 0.1 + 1 * 0.5 + 0 * 0.9, 0 * 0.2 + 1 * 0.6 + 0 * 0.0, 0 * 0.3 + 1 * 0.7 + 0 * 0.1, 0 * 0.4 + 1 * 0.8 + 0 * 0.2],
 [0 * 0.1 + 0 * 0.5 + 1 * 0.9, 0 * 0.2 + 0 * 0.6 + 1 * 0.0, 0 * 0.3 + 0 * 0.7 + 1 * 0.1, 0 * 0.4 + 0 * 0.8 + 1 * 0.2]]

=

[[0.1, 0.2, 0.3, 0.4],
 [0.9, 0.0, 0.1, 0.2],
 [0.5, 0.6, 0.7, 0.8],
 [0.9, 0.0, 0.1, 0.2]]

ただし、Embeddingレイヤーは単に[0, 2, 1, 2]インデックス0、2、1、2でレイヤーの重みを取り、すぐに取得します

[w[0],
 w[2],
 w[1],
 w[2]]

=

[[0.1, 0.2, 0.3, 0.4],
 [0.9, 0.0, 0.1, 0.2],
 [0.5, 0.6, 0.7, 0.8],
 [0.9, 0.0, 0.1, 0.2]]

したがって、同じ結果になりますが、うまくいけばより高速に取得できます。


Embeddingレイヤーには制限があります:

  • 入力は[0、vocab_length)の整数である必要があります。
  • バイアスなし。
  • アクティベーションなし。

ただし、整数エンコードされたWordを埋め込みに変換するだけであれば、これらの制限は問題になりません。