「X」Embedding in NLP アドバンスト シリーズでは、自然言語処理の基本知識、つまり自然言語のトークン、N グラム、バッグオブワード言語モデルを紹介しました。今日も皆さんと一緒に「練習」を続け、ニューラル ネットワーク言語モデル、特にリカレント ニューラル ネットワークを詳しく掘り下げ、埋め込みベクトルを生成する方法を簡単に理解します。
01. ニューラルネットワークを深く理解する
まず、ニューラル ネットワークのコンポーネント、つまりニューロン、多層ネットワーク、バックプロパゲーション アルゴリズムを簡単に確認しましょう。これらの基本概念についてさらに詳しく知りたい場合は、CS231n コース ノートなどの他のリソースを参照してください。
機械学習において、ニューロンはすべてのニューラル ネットワークを構成する基本単位です。基本的に、ニューロンは、すべての入力とオプションのバイアス項の重み付き合計を取るニューラル ネットワーク内のユニットです。方程式表現は次のとおりです。
ここで、 は前の層のニューロンの出力を表し、このニューロンが出力値を合成するために使用する重みを表します。
多層ニューラル ネットワークが上記の方程式の加重和のみで構成されている場合、すべての項を 1 つの線形層に結合できますが、これはトークン間の関係のモデル化や複雑なテキストのエンコードにはあまり理想的ではありません。これが、すべてのニューロンが加重和の後に非線形活性化関数を含む理由です。その最もよく知られた例は、修正線形単位 (ReLU) 関数です。
最新のニューラル ネットワーク言語モデルのほとんどでは、Gaussian Error Linear Unit (GELU) アクティベーション関数がより一般的です。
ここで、はガウス累積分布関数を表し、これを使用して。この活性化関数は、上で説明した加重合計の後に適用されます。全体として、単一のニューロンは次のようになります。
より複雑な機能を学習するには、ニューロンを積み重ねて層を形成します。同じ層内のすべてのニューロンは同じ入力を受け取ります。それらの唯一の違いは重み W とバイアス b です。上の方程式は、単一レイヤーの行列表記で表すことができます。
ここで、w は入力xに適用されるすべての重みを含む 2 次元行列であり、行列の各行はニューロンの重みに対応します。このタイプの層は、すべての入力x がすべての出力yに接続されているため、密層または完全接続層と呼ばれることがよくあります。
これら 2 つの層を連結して、基本的なフィードフォワード ネットワークを作成できます。
ここでは、入力xにも出力yにも直接接続されていない新しい隠れ層h1を導入します。この層はネットワークの深さを効果的に増加させ、パラメーター (複数の重み行列w )の総数を増加させます。このとき、より多くの隠れ層が追加されるにつれて、入力層に近い隠れ値 (アクティベーション値) はxに「似ている」のに対し、出力に近いアクティベーション値は x に「似ている」ことに注意することが重要です。よりyに似ています。
この原則に基づいたベクトルの埋め込みについては、後続の記事で説明します。隠れ層の概念は、ベクトル検索を理解する上で非常に重要です。
フィードフォワード ネットワーク内の個々のニューロンのパラメーターは、バックプロパゲーションと呼ばれるプロセスを通じて更新できます。バックプロパゲーションとは、基本的に微積分の連鎖則を繰り返し適用することです。バックプロパゲーションを具体的に説明するコースを検索すると、バックプロパゲーションがニューラル ネットワークのトレーニングに非常に効果的である理由が紹介されます。ここでは詳細は説明しませんが、基本的なプロセスは次のとおりです。
-
ニューラル ネットワークを通じてデータのバッチをフィードします。
-
損失を計算します。これは通常、回帰の場合は L2 損失 (二乗差)、分類の場合はクロスエントロピー損失です。
-
この損失を使用して、最後の隠れ層の重みによる損失勾配を計算します。
-
最後の隠れ層、すなわち を通した損失を計算します。
-
この損失を最後から 2 番目の隠れ層の重みに逆伝播します。
-
すべての重みの偏導関数が計算されるまで、ステップ 4 と 5 を繰り返します。
ネットワーク内のすべての重みに関連する損失の偏導関数を計算した後、オプティマイザーと学習率に基づいて大規模な重み更新を実行できます。このプロセスは、モデルが収束に達するか、すべてのエポックが完了するまで繰り返されます。
02.リカレントニューラルネットワーク
すべての形式のテキストと自然言語は本質的に逐次的であり、単語/トークンが次々に処理されることを意味します。単語の追加、連続する 2 つのトークンの反転、句読点の追加など、一見単純な変更が、解釈に大きな違いをもたらす可能性があります。たとえば、「チャールズ、食べましょう」というフレーズと「チャールズを食べましょう」というフレーズはまったく別のものです。自然言語の逐次的な性質により、リカレント ニューラル ネットワーク (RNN) は当然のことながら言語モデリングに最適な選択肢となっています。
再帰は、関数がコードではなくニューラル ネットワークである独自の形式の再帰です。RNN には生物学的な起源もあります。人間の脳は (人工) ニューラル ネットワークに例えることができ、私たちが入力した言葉や話す言葉は生物学的な処理の結果です。
RNN は、1) 標準フィードフォワード ネットワークと 2) 再帰コンポーネントの 2 つのコンポーネントで構成されます。フィードフォワード ネットワークは、前のセクションで説明したものと同じです。再帰コンポーネントの場合、ネットワークが以前のコンテキストを維持できるように、最後の隠れ状態が入力にフィードバックされます。したがって、以前の知識 (前のタイム ステップからの隠れ層の形式) が、新しいタイム ステップごとにネットワークに注入されます。
RNN の上記のマクロ定義と説明に基づいて、RNN がどのように実装されているか、および RNN がセマンティック モデリングで優れたパフォーマンスを発揮する理由を大まかに理解できます。
まず、RNN の再帰構造により、人間が話したり読み書きしたりするのと同じように、データを順番にキャプチャして処理できるようになります。さらに、RNN は、初期の「情報」に効果的にアクセスでき、n グラム モデルや純粋なフィードフォワード ネットワークよりも自然言語を理解できます。
PyTorch を使用して RNN を実装してみることができます。これには PyTorch の基本を深く理解する必要があることに注意してください。PyTorch に詳しくない場合は、最初にこのリンクを読むことをお勧めします。
まず単純なフィードフォワード ネットワークを定義し、次にそれを単純な RNN に拡張し、最初に層を定義します。
from torch import Tensor
import torch.nn as nn
class BasicNN(nn.Module):
def __init__(self, in_dims: int, hidden_dims: int, out_dims: int):
super(BasicNN, self).__init__()
self.w0 = nn.Linear(in_dims, hidden_dims)
self.w1 = nn.Linear(hidden_dims, out_dims)
生の論理値のみを出力しているため、損失のスタイルは定義されていないことに注意してください。トレーニング中に、実際の状況に基づいて、 などのいくつかの基準を追加できますnn.CrossEntropyLoss
。
これで、フォワード パスを実装できます。
def forward(self, x: Tensor):
h = self.w0(x)
y = self.w1(h)
return y
これら 2 つのコード スニペットを組み合わせると、非常に基本的なフィードフォワード ニューラル ネットワークが形成されます。これを RNN に変えるには、最後の隠れ状態から入力に戻るフィードバック ループを追加する必要があります。
def forward(self, x: Tensor, h_p: Tensor):
h = self.w0(torch.cat(x, h_p))
y = self.w1(h)
return (y, h)
基本的には上記がすべての手順です。w0
で定義されたニューロン層への入力の数を増やしたので、__init__
でその定義を更新する必要があります。それでは、これを実行して、すべてをコード スニペットに結合しましょう。
import torch.nn as nn
from torch import Tensor
class SimpleRNN(nn.Module):
def __init__(self, in_dims: int, hidden_dims: int, out_dims: int):
super(RNN, self).__init__()
self.w0 = nn.Linear(in_dims + hidden_dims, hidden_dims)
self.w1 = nn.Linear(hidden_dims, out_dims)
def forward(self, x: Tensor, h_p: Tensor):
h = self.w0(torch.cat(x, h_p))
y = self.w1(h)
return (y, h)
各フォワードパスでは、h
出力とともに隠れ層のアクティベーション値が返されます。これらのアクティベーション値は、シーケンス内の新しいトークンごとに再びモデルに渡すことができます。このようなプロセスは次のとおりです (次のコードは説明のみを目的としています)。
model = SimpleRNN(n_in, n_hidden, n_out)
...
h = torch.zeros(1, n_hidden)
for token in range(seq):
(out, h) = model(token, )
この時点で、単純なフィードフォワード ネットワークを定義し、それを単純な RNN に拡張することに成功しました。
03.言語モデルの埋め込み
上の例で見た隠れ層は、RNN に入力されたすべて (すべてのトークン) を効果的にエンコードします。より具体的には、RNN が見たテキストを解析するために必要なすべての情報がアクティベーション値 h に含まれている必要があります。言い換えれば、h は入力シーケンスのセマンティクスをエンコードし、h によって定義される浮動小数点値の順序付けされたセットは、埋め込みベクトル (埋め込みと呼ばれます) です。
これらのベクトル表現は、ベクトル検索およびベクトル データベースの基礎を広く形成しています。今日の自然言語埋め込みは、RNN ではなく、トランスフォーマーと呼ばれる別のクラスの機械学習モデルによって生成されますが、基礎となる概念は基本的に同じで、テキスト コンテンツをコンピューターが理解できる埋め込みベクトルにエンコードします。埋め込みベクトルの使用については、次回のブログ投稿で詳しく説明します。
04. 概要
PyTorch に単純なリカレント ニューラル ネットワークを実装し、言語モデルの埋め込みを簡単に紹介しました。リカレント ニューラル ネットワークは言語を理解するための強力なツールであり、さまざまなアプリケーション (機械翻訳、分類、質問応答など) で使用できますが、それでも、埋め込みベクトルの生成に使用される ML モデルの種類ではありません。
次のチュートリアルでは、オープン ソースの Transformer モデルを使用して埋め込みベクトルを生成し、ベクトルの検索と操作を実行してベクトルの威力を実証します。さらに、バッグ オブ ワード モデルの概念にも戻り、この 2 つをどのように組み合わせて語彙と意味をエンコードできるかを見ていきます。乞うご期待!
SenseTime創設者Tang Xiaoou氏死去、55歳 2023年、PHP停滞 紅蒙システム独立間近、多くの大学が「紅蒙授業」開設 Quark BrowserのPC版が内部テスト開始. ByteDanceはOpenAIによって「禁止」された. Zhihuijunの新興企業は借り換え、金額は6億元以上、事前評価額は35億元. AIコードアシスタントは非常に人気があるため、プログラミングで競争することさえできません言語ランキング. Mate 60 Proの5Gモデムと無線周波数技術ははるかに先を行っている No Star, No Fix MariaDBがSkySQLをスピンオフし、独立した会社として設立