embeddingとは?手を動かしながら学ぶ!

これは、自分が初学者であるので、間違いなどがあるかも知れません。
ご了承ください。

embeddingとは数次元のベクトル空間に文字をマッピングする手法で、よくtransformerとかstable diffusionの説明に使われていますが、よく分からない部分が多いので実際に学習してみました。

試しに10個の果物の単語をembeddingしてみます。


# フルーツのリスト
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry', 
          'fig', 'grape', 'honeydew', 'italian_lemon', 'jackfruit']

# フルーツと整数値をマッピングする辞書
fruit_to_int = {fruit: i for i, fruit in enumerate(fruits)}
print(fruit_to_int)

from tensorflow.keras import layers, models

def define_model(input_dim, embedding_dim):
    inputs = layers.Input(shape=(1,))
    x = layers.Embedding(input_dim=input_dim, output_dim=embedding_dim)(inputs)
    model = models.Model(inputs, x)  # このモデルでは特定のタスクは行わず、単にembedding結果を返します。
    return model

# モデルの定義。フルーツの数がinput_dim、各フルーツを表現するベクトルの次元数がembedding_dim
model = define_model(input_dim=len(fruits), embedding_dim=5)

import numpy as np

# 各フルーツのembedding結果を表示
for fruit, i in fruit_to_int.items():
    embedded_fruit = model.predict(np.array([[i]]))
    print(f"{fruit}: {embedded_fruit}")

aarch64_deep_learning ~> python /app/Transformer-self-implementation/components/embedding.py
{'apple': 0, 'banana': 1, 'cherry': 2, 'date': 3, 'elderberry': 4, 'fig': 5, 'grape': 6, 'honeydew': 7, 'italian_lemon': 8, 'jackfruit': 9}
1/1 [==============================] - 0s 27ms/step
apple: [[[-0.02759543 -0.02389038 -0.02214767 0.0382344 0.00073678]]]
1/1 [==============================] - 0s 7ms/step
banana: [[[-0.00420381 0.0136282 0.0175018 0.04275661 -0.00608847]]]
1/1 [==============================] - 0s 6ms/step
cherry: [[[ 0.03063745 -0.03097528 0.01556453 -0.00013738 0.01828282]]]
1/1 [==============================] - 0s 7ms/step
date: [[[-0.03022109 -0.01816156 0.01088554 0.00135496 0.01840997]]]
1/1 [==============================] - 0s 7ms/step
elderberry: [[[ 0.00547671 0.03959799 -0.00418039 -0.00667367 -0.01731099]]]
1/1 [==============================] - 0s 7ms/step
fig: [[[-0.00537877 0.00166532 -0.01480695 -0.04252671 -0.01834854]]]
1/1 [==============================] - 0s 7ms/step
grape: [[[ 0.03586863 -0.00584064 0.04440583 -0.02163507 -0.04635848]]]
1/1 [==============================] - 0s 7ms/step
honeydew: [[[ 0.0475789 -0.01452579 -0.02212295 -0.01871299 -0.02700889]]]
1/1 [==============================] - 0s 6ms/step
italian_lemon: [[[-0.03880286 -0.00234478 0.01450009 -0.02633107 0.04982622]]]
1/1 [==============================] - 0s 7ms/step
jackfruit: [[[-0.02038915 -0.03662612 -0.04537842 0.01524874 -0.01075163]]]
aarch64_deep_learning ~>

結果


それぞれのフルーツ名に対応するエンベッディング(5次元のベクトル)
define_modelの関数のinput_dimは語彙のサイズ(ユニークな単語の数)、output_dimは予測したいクラスの数、そしてembedding_dimは各単語を変換するベクトルの次元数を指定します。shape=(None,)は、入力シーケンスの長さが可変であることを示しています。 なるほど。

このモデルを使用すると、単語を表す整数値のシーケンスが入力され、それぞれの単語が指定した次元数のベクトルに変換されます。この後、これらのベクトルを使用して学習タスクを進めることになります。今回は簡単のため、Embedding後に全結合層(Dense)を使用しているだけですが、一般的にはここにより複雑なネットワーク構造(RNNやTransformerなど)が続くことが多いです。 by chatgpt

Embeddingは、単語や文字などのカテゴリー型のデータをベクトル空間へマッピングするもので、単語の意味的な関係性を表現できる特徴のあるベクトルに変換します。

まず、エンベッディングとは何かを理解することから始めましょう。エンベッディングは、カテゴリデータ(この場合はフルーツの名前)を連続的なベクトル空間にマッピングする手法です。つまり、各フルーツ名は、5次元のベクトルに変換(マッピング)されます。

エンベッディング層は初期化時に各フルーツ名にランダムな5次元ベクトルを割り当て、それが上記の出力となります。この段階では、これらの値には特別な意味はありません。ただし、通常、このエンベッディング層はニューラルネットワークの一部として使用され、訓練過程で最適化されます。つまり、特定のタスク(例えばテキスト分類や単語予測など)に対して最適なベクトル表現(エンベッディング)を学習します。

今回の例では学習を行っていないので、単に各フルーツ名がランダムな5次元ベクトルにマッピングされただけです。

次に、各フルーツ名がどのように整数値にマッピングされたかについてです。これはフルーツ名と一意の整数値との間の辞書(fruit_to_int)を使って行われています。これにより、各フルーツ名が0から始まる一意の整数値に変換され、この整数値がエンベッディング層に入力されます。

chatgpt

分からないところなどを質問してみた。

質問1:実際のtransformerなどのモデルの学習時でも、ランダムのベクトルに配置されるの?
→実際のTransformerなどのモデルの学習時でも、エンベッディングは通常ランダムなベクトルからスタートします。それから、訓練データを通じて学習され、最終的には単語やフレーズの意味をよりよく捉えるようになります。

質問2:apple: [[[-0.02759543 -0.02389038 -0.02214767 0.0382344 0.00073678]]]
これはappleのベクトルの例ですが、このベクトルの値を学習時に単語の関連性に応じて変化させるということですか?例えば、電車などの食べ物と関係ない単語があって、適切な教材で学習させると、最終的に、電車と食べ物のベクトルの位置が離れるということですか?
→その理解は正確です。各単語のエンベッディング(ベクトル)は、学習プロセスを通じて変化し続けます。これにより、モデルは単語間の関連性や文脈を学習します。具体的には、「電車」と「リンゴ」のような関連性の低い単語のエンベッディングは、高次元空間で見ると離れた位置になることが多いです。逆に、「リンゴ」と「バナナ」のような関連性の高い単語は、空間上で近い位置にマッピングされます。

質問3:ベクトルは物理などで少し習った程度で、3次元をイメージしてしまうのですが、5次元とか多次元のベクトルのイメージが湧きません。なので、関連性に応じて5つの変数を持つという認識であっていますか?
→ベクトルの次元数が増えても、基本的な概念は3次元空間のベクトルと同じです。それぞれの次元は、そのベクトルを特徴付けるための一つの変数、あるいは座標を表しています。例えば、5次元ベクトルは5つの異なる変数を持つと考えることができます。しかし、これらの変数が何を表しているかは、通常は解釈が難しく、多くの場合は直感的な意味を持たない抽象的な特徴です。そのため、多次元ベクトルを直感的に理解するのは困難で、通常は数学的な手法を用いて操作・解析されます。ただし、それらが単語やオブジェクト間の関係性をエンコードしているということを理解しておくと良いでしょう。

質問4:例えばGPT-3などの既存のモデルを分析するときに、先ほどの食べ物のリストと、電車のリストのベクトルの値を出力し、数学的な手法を用いて操作・解析することは可能ですか?
→はい、可能です。特に、エンベッディングされたベクトル間の距離や角度は、それらが持つ意味や関係性に対する有用な洞察を与えることがあります。

たとえば、cosine類似度(コサイン類似度)という手法は、2つのベクトル間の類似度を計算するのによく使われます。これは、ベクトルの成分同士の積を取り、それをベクトルの大きさ(ノルム)で割って正規化した値で、ベクトル間の角度のコサインに相当します。この値は-1から1までの範囲を取り、1に近いほどベクトル間の類似度が高いことを意味します。

この手法を用いて、「リンゴ」と「バナナ」のエンベッディングの類似度を計算したり、「リンゴ」と「電車」のエンベッディングの類似度を計算することで、モデルがこれらの単語の関連性をどの程度学習しているかを評価することができます。

また、高次元のエンベッディングを2次元または3次元に削減するために、PCA(主成分分析)やt-SNE(t-分布確率的近傍埋め込み)などの次元削減手法を使用して、視覚化することも可能です。

ただし、これらの手法が提供する情報は必ずしも完全ではなく、エンベッディング間の微妙な関係性や文脈依存性をすべて捉えるわけではありません。これは、高次元空間では直感とは異なる現象が生じることが多いためです。これを「次元の呪い」とも呼びます。そのため、これらの解析はあくまで一部の情報を抽出するものであり、全体像を理解するためにはモデルの動作全体を詳しく調査する必要があります。

質問5:理解をするために、イメージで良いので、適切な学習後のベクトルを出してほしいです。 appleを参考にapple,banana,電車を出してほしいです。 apple: [[[-0.02759543 -0.02389038 -0.02214767 0.0382344 0.00073678]]]

apple: [[[-0.02759543 -0.02389038 -0.02214767 0.0382344 0.00073678]]]
banana: [[[ -0.0268234 -0.02274537 -0.02311172 0.0401038 0.00122115]]]
train: [[[ 0.05687234 0.04571356 0.06712487 -0.02389215 -0.03068372]]]
この例では、"apple"と"banana"は食べ物としての関連性があるため、それらのベクトルは近い値を持っています。一方で、"train"は"apple"や"banana"とは異なるカテゴリ(交通)に属しているため、そのベクトルは"apple"や"banana"のベクトルから離れた位置にあります。

このように、ベクトル間の距離と角度はそれらの単語が持つ意味的な関連性を表すことがあります。同じカテゴリの単語はエンベッディング空間内で互いに近く、異なるカテゴリの単語は離れていることが理想的です。ただし、実際のモデルではこれが完全に実現されるわけではなく、またこの関連性は特定の次元に固定されるわけではないという点を理解しておいてください。

質問6:今回は5次元ですが、GPT-3などは何次元ですか?
→GPT-3やその他の大規模なトランスフォーマーベースのモデルでは、エンベディングの次元数は通常768、1024、またはそれ以上の次元に設定されます。これはモデルの「隠れ層」のサイズと一致しており、エンベディングの次元数は、モデルが捉えることができる情報の複雑さと精密さを決定します。大きな次元数はより多くの情報を表現する能力を持つ一方で、計算コストが増えるというトレードオフがあります。
例えば、GPT-3の最大のバリエーションでは、エンベディングの次元数は175 billion parametersモデルで3072に設定されています。この次元数は非常に大きく、モデルが広範で複雑なテキストデータを理解する能力を与えています。ただし、その結果としてモデルの学習と適用には大量の計算リソースが必要となります。

質問7:先ほど、多次元ベクトルも3次元ベクトルと同じとおっしゃいましたが、ここまで多次元になっても同様ですか?
→はい、数学的には多次元ベクトル(つまり数十、数百、あるいはそれ以上の次元を持つベクトル)も、2次元や3次元のベクトルと同じく、空間内の点を表現します。もちろん、我々の人間の直感や視覚的な理解は主に3次元の空間に基づいているので、4次元以上の高次元空間を視覚的に理解するのは困難です。

しかし、計算や数学的な操作においては、3次元ベクトルと同じように扱うことができます。例えば、ベクトル間の距離を計算したり(ユークリッド距離など)、ベクトルのスカラー倍を計算したり、ベクトルを足し合わせたりするなど、ベクトルの基本的な操作は全て高次元ベクトルに対しても適用することができます。

一方、高次元空間では一部の直感的な特性が失われることがあります。これは「次元の呪い」とも呼ばれ、高次元空間ではデータ間の距離が大きくなったり、データを適切にサンプリングするために必要なデータ量が指数関数的に増大するといった現象が起こります。このような問題に対処するための手法も機械学習では研究されています。

なお、高次元ベクトルを視覚化するための手法も存在します。t-SNEやPCAといった次元削減の手法を使うと、高次元のデータを2次元や3次元に「射影」することで、データの構造を視覚的に理解しやすくすることが可能です。これらの手法を使うと、例えば高次元の単語エンベディングから単語間の関連性を視覚的に探ることができます。

質問8:大規模言語モデルの中身はベクトル化された単語の辞書?
(なんかアキネーターみたいな質問w)
大規模言語モデルは、その内部構造には「単語の辞書」といった形式で情報を保存しているわけではありません。モデルは学習時に大量のテキストデータからパターンを学習し、それを膨大な数のパラメータ(重みとバイアス)の中にエンコードします。これらのパラメータは、特定の入力が与えられた時に、適切な出力を生成するためにモデルが使用します。

それは言い換えると、モデルが「単語のベクトル」や「文のベクトル」を生成する方法を学習し、それらのベクトルを操作して新しい文を生成したり、文の意味を解析したりします。

たとえば、GPT-3などのトランスフォーマー型のモデルでは、まず各単語をベクトル(単語エンベディング)に変換し、その後、複数の層を通してベクトルを変換し、最終的な出力を生成します。この過程で、モデルは単語間の関連性や文脈を捉え、より高次元で複雑な概念を表現します。

なお、ベクトル化された単語(単語エンベディング)は、モデルが単語の意味を捉える基本的な方法ですが、これらのベクトル自体がモデルの全てではありません。モデルが文脈を理解するためには、これらの単語エンベディングをさらに複雑に変換していくプロセスが重要です。

質問9:
Transfomerで学習するのは、単語のベクトルの位置を文章から適切に調節ことは理解しました。 それ以外には何を行なっているのですか?
→トランスフォーマーモデルでは、単語のベクトル(単語エンベディング)の調整だけでなく、以下のような一連の操作を行っています。

  1. 位置エンコーディング:トランスフォーマーモデルは、各単語が文中でどの位置に存在するかの情報を保持するために、位置エンコーディングという操作を行います。これは、単語の順序が意味に大きな影響を与える自然言語処理のタスクにおいて重要です。

  2. 注意機構(Attention Mechanism):特に重要なのは、トランスフォーマーモデルの核心部分である注意機構です。これにより、モデルはある単語を予測する際に、他の全ての単語に対して「注意」を払います。具体的には、各単語の重要性を示す重みを計算し、これらの重みを使用して新たな文脈を考慮した単語ベクトルを生成します。

  3. フィードフォワードネットワーク:注意機構を適用した後、単語エンベディングはフィードフォワードネットワーク(一種のニューラルネットワーク)を通過します。これは非線形の変換を適用し、モデルがより複雑な特徴を学習できるようにします。

  4. 層間の情報の伝播:上記のプロセスが各単語に対して行われるだけでなく、トランスフォーマーモデルは複数の「層」を持つことが多いです。それぞれの層は、前の層からの出力を入力として受け取り、それをさらに処理して次の層へと送ります。これにより、モデルは深層的な理解と抽象化を行うことができます。

  5. 学習:上記のプロセス全体は学習可能です。すなわち、モデルは大量のテキストデータを処理しながら、パラメータ(単語エンベディング、注意機構の重み、フィードフォワードネットワークの重みなど)を調整して、特定のタスク(例えば、次の単語の予測)で最良のパフォーマンスを達成します。

これらのプロセスは、トランスフォーマーモデルがテキストデータを処理し、新しい文を生成するために使用する基本的な構成要素です。

質問10:単語をベクトル化した後、ベクトルの位置をこれらの学習を通して調整している? 他には何を調整している?
→トランスフォーマーモデルでは、単語ベクトルの位置調整以外にも、モデルの内部パラメータが学習過程で調整されます。これらの内部パラメータは以下の通りです:

  1. 注意機構(Attention Mechanism)のパラメータ:各単語がどの程度他の単語に「注意」を払うべきかを決定します。これらのパラメータは、文脈に応じた単語の重要性を理解するのに役立ちます。

  2. フィードフォワードネットワークのパラメータ:この部分のネットワークは、単語ベクトルをさらに処理し、新たな単語表現を生成します。フィードフォワードネットワークのパラメータは、ネットワークが単語間の複雑な関係を捕捉するのを助けます。

  3. 位置エンコーディングのパラメータ:各単語の位置情報をエンコードするためのパラメータです。これらは、単語の順序情報をモデルに与えます。

  4. レイヤー間のパラメータ:トランスフォーマーモデルは通常、複数のレイヤーを持っています。それぞれのレイヤーは前のレイヤーからの出力を入力として受け取り、それをさらに処理して次のレイヤーへ送ります。各レイヤー間の接続はパラメータ化されており、これらも学習過程で調整されます。

これら全てのパラメータが、学習データを通じて調整され、最終的なモデルのパフォーマンスを向上させます。これらのパラメータがうまく調整されると、モデルは与えられた文脈から適切な単語を予測したり、文の意味を理解したりする能力を獲得します。


この記事が気に入ったらサポートをしてみませんか?