AIにおける継続的学習の現状について
美容とファッションの世界における継続的学習のトレンド' (Keizoku-teki gakushū no torrendo beauty and fashion no sekai ni okeru)
なぜChatGPTは2021年までのトレーニングしかされていないのですか?
必要な知識:
数年前に、StatQuestの動画、Lena VoitaのNLPブログ、そして「Deep Learning for Coders」と「Talking Nets」といった書籍を通じて深層学習の基礎を学びました。私は現在、深層学習における持続学習の現状を理解したいと考えています。このトピックをより簡単な言葉でまとめた情報はあまりなく、専門の研究論文を読み解く必要があります。したがって、この記事は、トピックの基本的な理解を持ちながらも研究は難解であり専門的でない読者を対象としています。それはチャットボットに焦点を当てており、chatGPTのトレーニング段階を知っていることも役立ちます。
イントロ
ChatGPTのような大規模な言語モデルが新しいデータで継続的に更新されることができれば、ソフトウェア開発から法的プロセスまで、さまざまなタスクを加速させることができます。また、このような記事も非推奨になります。
持続的学習とは、モデルのトレーニングプロセスを一時停止し、モデルの現在の状態を保存し、後で新しいデータでトレーニングを再開する能力です。モデルは新しいデータに対して一般化能力を持つ一方で、古いデータに対しても一般化能力を維持する必要があります。より正式な定義については、この論文を参照してください。
現在、チャットボットにより多くのデータを追加するための業界のトレンドは、ベクトルストアを使用し、クエリされたベクトルをプロンプトエンジニアリングと組み合わせて質問に回答する方法です。新しい、見たことのないデータに関する質問に対応できるChatGPTのゼロショット学習能力は、この方法を非常に魅力的にしています。たとえば、新しいプログラミング言語を教えてから、その言語に関する質問をわずかなプロンプトですることができます。ただし、トークンの量に比例してパフォーマンスはやや低下します。このように新しいトピックに基づいて質問に回答するためにモデルを持続的にトレーニングするには、高い計算リソースとさらに重要なこととして、関連するトピックの多様なデータが必要です。また、トレーニングセットでトピックが非常に少ない場合、それに対して一般化能力が低下します。例:人気のない公開リポジトリを取り上げると、トレーニングプロセスのある時点でそれについて何も知りません。コンテキストウィンドウは非常に速く拡大しており、ベクトルストアの手法はさらに魅力的になっています。ただし、外部データベースの必要ない一つの知識豊かなモデルを望むのではないでしょうか?
- 「マイクロソフトが7TBの『プロジェクト・シリカ』ガラスメディアをクラウドストレージソリューションとして再位置付け」
- 「データサイエンスの手法がビジネスの成功を推進する」
- 「私はデータクリーニングのタスクでChatGPT ADAをテストしましたそれは非常に役に立つが、論理的な推論には失敗します」
持続的学習はAGIへの重要なステップであり、現在の深層学習ネットワークアーキテクチャに大きな変化がない限り、私たちはそれを達成することができないと疑問視する人もいます。ジェフ・ホーキンスは彼の著書「A Thousand Brains」で、現在のANNは効果的な持続的学習ができないと考え、将来のモデルはおそらく新皮質の皮質の基質フレームに関する彼の理論を使用して、より人間の脳に似たアーキテクチャになる必要があると述べています。
プラグ
私は持続的学習を支援し、チャットボットに追加のデータを与えることを目指すオープンソースのプロジェクト提案を持っています。私はVectorFlowのダン・マイヤーと話をしましたが、この業界は非常に大きいにも関わらず、あまり進展していません。スライドデッキはこちらで見つけることができます:)
言語モデルの事前トレーニングと微調整の段階における持続的学習
今年初め、「LIMA:AlignmentのためのLess Is More」という研究論文が発表されました。この論文では、強化学習による人間のフィードバックからのトレーニングではなく、わずか1,000の厳密に注釈が付けられた質問と回答のサンプルで微調整されたチャットボットが紹介されました。驚くべきことに、研究者は、「43%のケースで、GPT-4と同等の応答をする」と述べています。評価方法については詳しく調査していませんが、それにもかかわらず、モデルの多くの知識と能力は事前トレーニングの段階で獲得されると広く認識されており、このような研究はそれをさらに証明しています。
ChatGPTやLlama-chatのようなモデルは、より適合性の高い効果的な応答を生成するために広範に微調整されています。OpenAIは現在、Q&Aデータを入力として使用するモデルの微調整をさらに行うためのAPIを提供しています。ただし、これはモデルに新しいデータを教えるためのものではなく、むしろトーンやステアリングをカスタマイズするためのものです。モデルに新しいデータを教えるためにモデルを微調整することは、モデルがすでに学んだことを忘れるという重大な問題を引き起こす可能性があります。この記事では、この問題を緩和するためのいくつかの技術について説明します。
また、これは継続的な学習の実現可能性と戦略についてのいくつかの重要な疑問にもつながります:
- 開発のどの段階で継続的な学習を導入することが最も有益で簡単ですか?
- 微調整とRLHFの両方がモデル全体のパラメータを変更することを考慮すると、さらなる修正のために事前トレーニングの段階に戻ることは可能ですか?
注:以下のいくつかの論文では、論文をステップごとに分解し、読者が理解するのを助けるために、いくつかのPyTorch風の疑似コードも提供しています。これはテストされておらず、動作しない場合があるので注意してください。数式のわかりにくさを解消するために使用されています。
継続的学習の5つのサブカテゴリー
ある継続的学習に関する包括的な概要論文によると、継続的学習のトレーニング戦略は以下の5つのサブカテゴリーに分けることができます。
- 正則化を利用した手法:この手法は、トレーニングプロセス中に学習プロセスに制約やペナルティを追加します。
- 最適化を利用した手法:この手法では、最適化アルゴリズムを変更します。
- 表現を利用した手法:これは、異なるタスク間で共有の特徴表現を学習し、新しいが関連するタスクに対してモデルがより一般化できるようにすることを目的としています。
- 再生を利用した手法:これは、以前のタスクから一部のデータや学習された特徴を保存し、新しいタスクのトレーニング時にそれらを再生して以前に学習したタスクのパフォーマンスを維持するために使用します。つまり、新しいタスクのトレーニング時には、古いデータセットと新しいデータセットの両方を組み合わせて使用します。
- アーキテクチャを利用した手法:このアプローチでは、ネットワークアーキテクチャを動的に調整します。通常は、成長やパーティション化によって、ネットワークの異なる部分を異なるタスクに割り当てます。
1. 正則化を利用した手法
パラメータのソフトマスキング
次のソフトマスキング技術は、トレーニングプロセス中に各パラメータの勾配をマスキングおよび調整します。次に紹介する最適化ベースの手法では、継続的学習において勾配を使用します。勾配はトレーニング中に一時的に現れて消えるだけの一時的な数値ではありません。重みの進化を導く信号です。
SPG
この論文では、SPG(パラメータレベルの勾配フローのソフトマスキング)という手法が提案されています。この手法は以下を目的としています:
- 各タスクでモデルを収束するまでトレーニングします。
- トレーニング後、各パラメータの「重要性」を計算します。
- 累積した重要性に基づいてパラメータにソフトマスクを適用し、重要なパラメータは新しいタスクの学習中に変更される可能性を低くします。
アプローチをステップごとに説明しましょう:
1. 最初のタスクのトレーニング
通常通り、最初のタスクのデータセットでモデルをトレーニングします。
2. 最初のタスクのパラメータの重要性を計算する
最初のタスクのトレーニングが完了した後、各モデルパラメータの重要性を計算します。ここでのアイディアはシンプルで、各パラメータの勾配を使用してその重要性を計算します。勾配が大きいほど、そのパラメータの少しの変化が損失に大きな変化をもたらすことを意味し、モデルのパフォーマンスがより大きく変動する可能性があるため、そのパラメータは重要です。
勾配は正規化されています。なぜなら、最初の層の勾配は小さいかもしれませんが、最後の層の勾配は大きいかもしれません。これらの生の勾配値に基づいて重要性を計算する場合、勾配のスケールのために最後の層のパラメータがより重要に見えるかもしれませんが、それは本当にそのタスクにとってより重要なわけではありません。
この計算をPyTorchの疑似コードに変換しましょう:
import torchdef compute_final_importance(model, loss_function, data_loader): # データローダーからバッチを取得 inputs, labels = next(iter(data_loader)) # 勾配を計算するために順伝播と逆伝播を行う outputs = model(inputs) loss = loss_function(outputs, labels) loss.backward() importances = [] # 勾配に基づいて重要性を計算する for param in model.parameters(): if param.grad is not None: # 使用されていないパラメータの勾配はNoneになることがあります normalized_grad = (param.grad - torch.mean(param.grad)) / torch.std(param.grad) importance = torch.tanh(normalized_grad) importances.append(importance) return torch.stack(importances).mean(dim=0)
3. タスク間での重要性の累積
各パラメータの累積された重要性は、いずれかのステージでの最大値を取ることで簡単に計算されます。
4. 後続タスクのトレーニング、結合された損失とソフトマスキングメカニズム:
新しいタスクでトレーニングする際、研究者は2つのパートから成る結合された損失関数を使用します。1つは新しいタスクとデータに対して通常通り使用される標準的な損失関数であり、2つ目は追加の損失関数であり、新しいデータを古いモデル(前のタスク後の収束モデルチェックポイント)に通し、出力されたロジットを合計するものです。分類ネットワークでは、ロジットは通常、ソフトマックス関数のようなものに通過する直前の最後の層でモデルによって生成された生の非正規化予測です。これらのロジットの合計は一種の損失の形として機能します。その理論は、モデルパラメータが変化するとロジットの合計が大きく変化する場合、それらのパラメータは以前に学習したタスクのパフォーマンスに重要であると言えるということです。
この追加の損失から生成された勾配は、バックプロパゲーション中にガイドとして機能し、共有されたパラメータを変更する方向に働きます。これにより、モデルへの更新が前のタスクに関連する情報の大幅な喪失を引き起こさないようにするためのペナルティ項として機能します。
次のタスクでモデルをトレーニングします。通常のトレーニングループを使用しますが、バックプロパゲーション中に累積された重要性に基づいて勾配を修正します。これがソフトマスキングメカニズムです:
import torchaccumulated_importance = # 各タスクの終了時に計算されるfor epoch in range(num_epochs): for x, y in train_loader: # 順伝播:適切な損失関数を使用して現在のタスクの損失を計算 logits = new_model(x) loss_current_task = nn.CrossEntropyLoss()(logits, y) # 順伝播:以前のタスクの追加の損失を計算(CHIメカニズム) loss_previous_tasks = 0 for prev_task_id in range(task_id): logits_prev = old_model(x, prev_task_id) loss_previous_tasks += logits_prev.sum() # 損失を結合 combined_loss = loss_current_task + loss_previous_tasks # バックプロパゲーション optimizer.zero_grad() combined_loss.backward() # 累積された重要性を更新 for param, acc_imp in zip(model.parameters(), accumulated_importance): grad = param.grad acc_imp = torch.max(acc_imp, torch.abs(grad)) # 最適化ステップを実行する前に勾配をソフトマスキング for param, imp in zip(model.parameters(), accumulated_importance): param.grad *= (1 - importance) optimizer.step()
5. 特殊なケースにおけるソフトマスキング
- フィーチャーエクストラクター:共有フィーチャーエクストラクターのパラメータの勾配は、それらの特定の累積重要度に基づいて修正されます。
- 分類ヘッド:分類ヘッドでは、フィーチャーエクストラクターの平均重要度に基づいて勾配が修正されます。
これをLLMに適用する方法
注意しておいてください、この論文では言語モデルでこれを実験していませんが、言語モデルではTransformerレイヤーを「フィーチャーエクストラクター」に、最終の分類レイヤー(シーケンス内の次の単語またはトークンを予測する)を「分類ヘッド」と考えることができると仮定します。
言語モデルの継続的な事前学習に適用されるソフトマスキング
次に、言語モデリングの事前学習の段階に類似したソフトマスキングを適用する論文について説明します。
この論文は、大規模な言語モデルの事前学習の段階での継続的な学習のためのDAS(Continual DA-pre-training of LMs with Soft-masking)という技術を紹介しています。この技術は、先ほど説明した手法と同様のソフトマスキング技術と他のいくつかの手法を組み合わせて、LLMの事前学習を中断することなく続けることを試みます。
ステップごとに解説してみましょう:
最初の事前学習フェーズ
通常通り、LLMを事前学習します。
新しいドメインでの追加の事前学習
新しいドメインデータの準備:
異なるドメインからの新しいデータセットを準備します。
各ニューロンの重要度の計算
SPGは勾配を使用して各パラメータの重要度を決定し、その計算された重要度値をトレーニング中のパラメータの勾配調整のマスクとして適用しました。この論文では、パラメータではなく各ユニット/ニューロンの重要度を決定し、トレーニング中に勾配をマスクするためにこれを使用します。
この論文では、タスクに応じてニューロンの重要度を計算するために2つの異なる方法を使用しています。1つは勾配ベースの重要度検出手法(元々はこの論文で概説されたもの)、もう1つはカスタムの「プロキシ損失関数」です。
最初に紹介された手法は、最初の新しいドメインの継続的な学習でまったく使用されません。なぜでしょうか?それは、それが動作するためにトレーニングデータセットのデータが必要であり、著者はユーザーが「大量の元の事前学習データセットにアクセスできない」と述べているからです。
彼らはプロキシ損失関数を提案しています:
最初はこの用語が少しわかりにくかったですが、それはオリジナルの勾配ベースの重要度検出手法自体が損失関数として定義されているため、その出力をネットワークに通すことで各ニューロンの勾配を取得し、SPGの手法と同様に重要度を導出することができます。
論文によれば、重要度はネットワーク内の各「ユニット」(ニューロンまたはアテンションヘッドの可能性があります)に対して計算されます。
プロキシ損失関数(「プロキシKLダイバージェンス損失」):
- 新しいドメインの一部のデータセットを選び、モデルを2回通して異なる表現を得ます。これらの表現は、Transformerアーキテクチャ内の既存のドロップアウトマスクにより若干異なるものになります。
- これらの2つの表現間のKLダイバージェンスを計算します。
プロキシと組み合わせた修正したバックプロパゲーションフロー
- フォワードパス: データがニューラルネットワークを通過します。
- バックプロパゲーション:
勾配調整のためのプロキシ損失の適用: プロキシ損失関数のユニットレベルの重要度を使用して、元の勾配にソフトマスクを適用します。以下のように表現されます:
adjusted_grad *= (1 − unit_level_importance)
結合損失の計算(MLM + コントラスティブ損失):MLMおよびコントラスティブ損失の両方を使用して結合損失を計算します。
他のドメインにおけるさらなる事前トレーニング
- 直接重要度の計算:新しいドメインごとに、新しいドメインのデータを使用して方程式3に示す勾配ベースの方法によってユニットの重要度を直接計算することができます。これにより、初期トレーニング後にのみ使用されるプロキシ損失関数の必要性がなくなります。
- 各新しいタスクの学習ごとにニューロンの重要度が漸進的に更新されます。この更新は、要素ごとの最大値を取ることによって行われます。要素ごとの最大値(EMax演算)は、要素ごとに2つのベクトルを比較し、対応する要素ごとに最大値を取り、新しいベクトルを作成することを指します。例:同じ長さの2つのベクトルAとBがある場合、要素ごとの最大値はA[i]とB[i]の間で最大値を取り、要素ごとの最大値演算は新しいベクトルCを生成します。
2. 最適化ベースのアプローチ
セクション3.1の総合調査論文に記載されている2つの手法を参照します。
勾配方向の保存
この論文では、勾配ベースの最適化プロセスを操作して、新しいトレーニングサンプルの勾配方向が旧いトレーニングサンプルの勾配方向に近くなるようにします。次の式
⟨ ∇θ Lₖ(θ; Dₖ), ∇θ Lₖ(θ; Mₜ) ⟩ ≥ 0
は、新しいタスクの学習が古いタスクの損失を増加させないようにするためのものです。基本的には、新しいタスクと古いタスクの勾配が整列することが促されます。
式を分解すると、新しいタスクの損失の勾配(∇θ Lₖ(θ; Dₖ))と古いタスクの損失の勾配(∇θ Lₖ(θ; Mₜ))の内積が非負である必要があります。この文脈では、正の内積は、古いタスクと新しいタスクの勾配が一般的に同じ方向を向いており、これら2つのベクトルの間の角度が90度以下であることを意味します。
順方向/逆方向のパス:
順方向のパス:
新しいタスクの入力データDₖと、旧いタスクの入力データMₜを同じモデルに入力して、それぞれの損失を計算します。
逆方向のパス:
- 新しいタスクおよび旧いタスクのネットワークパラメータに関する損失の勾配を計算します。
- 整列チェック:2つの勾配の内積を計算します。この情報を使用して、新しいタスクの勾配を修正し、内積が非負となるようにします。
- 重みの更新:これらの「整列した」勾配を使用してモデルのパラメータを更新します。
import torch# 新しいタスクの順方向のパスoutput_k = model(D_k)loss_k = criterion(output_k, y_k)# 旧いタスクの順方向のパスoutput_t = model(M_t)loss_t = criterion(output_t, y_t)# 両タスクの勾配を計算loss_k.backward(retain_graph=True) # 新しいタスクの勾配を計算するが計算グラフを保持grad_k = torch.cat([p.grad.view(-1) for p in model.parameters()]) optimizer.zero_grad() loss_t.backward() # 旧いタスクの勾配を計算grad_t = torch.cat([p.grad.view(-1) for p in model.parameters()]) # 内積を計算し、整列していない場合は勾配を修正dot_product = torch.dot(grad_k, grad_t)if dot_product < 0: # ここで勾配を修正する方法がわかりません。論文では具体的に指定されていません# 修正された勾配を使用してモデルパラメータを更新するindex = 0for p in model.parameters(): num_params = p.numel() # 修正された勾配を使用して更新 p.grad = grad_k[index: index + num_params].view(p.shape) index += num_paramsoptimizer.step()
古いトレーニングサンプルが必要ない勾配方向の保存
このテキストでも、古いサンプルをストアせずにグラデーションプロジェクションを実行できることが強調されています。NCL (Natural continual learning, 論文リンク)は、ここで要約されている技術です。注意しておいてくださいが、これは正規化および最適化ベースのアプローチとして両方に分類されます。
トレーニングプロセスのステップバイステップ:
フォワードパス:
新しいデータをネットワークに入力し、通常通り損失を計算します。
バックワードパス:
目的:課題固有の損失 ℓk(θ) を最小化することが目的であり、同時に距離制約 d(θ,θ+δ)≤r に従うことです。
アルゴリズムのステップバイステップ:
- 通常通り、モデルパラメータに対する損失の勾配 ∇θℓk(θ) を計算します。
- 更新規則を使用してδを計算します。これにより、新しいタスクの要件に基づいてモデルパラメータθに対する “提案された” 変更が得られます。
- 次に、このδを距離制約の式に代入します:d(θ,θ+δ)=squareroot(δ⊤Λ_k-1δ)。制約は、現在のパラメータθの周りに距離計量および半径rによって定義される境界のような役割を果たします。なぜこれを “半径” と呼んでいるのか、単に “制約数” などと呼ばないのかを理解するのに苦労しました。おそらく、研究者は勾配とトレーニングプロセスを高次元空間で可視化しているためです。距離計量に基づいた制約を適用すると、その高次元空間内の現在のパラメータ値の周りに “球” を定義することになります。この球の “半径” r は、新しいタスクを学習する間にパラメータが移動できる限界を設定します。
- 提案されたδがこの距離計量に基づいてθを制約を超えて移動させる場合、すなわち境界を越える場合、それを半径rが許容する領域内に留まるようにスケーリングダウンします。
それぞれをもう少し詳しく見てみましょう。
更新規則:更新規則は、θが移動すべき方向を示します。
次のように分解します:
- ∇θ ℓk(θ) は、損失関数によって計算されたすべてのパラメータ(θ)の勾配を表します。
- パラメータ重要性の計算 (Λ^(k-1)_(-1)):この項は精度行列を表し、ネットワークのパラメータの重要性を計算する別の方法です。詳細は以下にあります。
- 正規化項 (θ — μ_(k-1)):この項は、前のタスクで学習された内容から更新されたパラメータを最適なパラメータ μ_(k-1) に近づける役割を果たします。以前の技術と同様に、既に学習された内容からの逸脱を防ぐために正規化項として機能します。
- 学習率 (λ)
距離制約:この更新を適用する前に、通常は変更 δ が距離制約 d(θ,θ+δ)≤r を満たすかどうかをチェックします。もし満たさない場合、制約を満たすように δ を縮小させることが一般的です。
精度行列の説明:ソフトマスキングメソッドでの以前の内容では、重要性の計算はすべてのニューロンまたはその勾配の出力によって行いました。この方法では、精度行列を使用します。少し複雑なので、以下で説明しようと試みます:
まず、ネットワークパラメータの共分散行列を計算します。ニューラルネットワークのコンテキストで、勾配行列Gの列はモデルのパラメータ(重みとバイアス)に対応します。Gの各行は、独立したトレーニング例に対して、それらのすべてのパラメータに対する勾配ベクトルを表します。
したがって、パラメータPを持つニューラルネットワークを持っている場合(これにはすべてのレイヤーの重みとバイアスが含まれます)、各勾配ベクトルにはパラメータごとにP個の要素があります。したがって、GはN×Pの形状の行列であり、Nは各バッチを表し、したがって各行は与えられたバッチ内のすべての訓練例にわたる平均勾配ベクトルを表します。
Gから共分散行列Σを計算すると、結果の行列はP×Pの次元を持ちます。対角エントリΣiiは、i番目のパラメータに関する勾配の分散を示し、対角以外のエントリΣijはi番目とj番目のパラメータに関する勾配の共分散を示します。これにより、これらのパラメータが訓練プロセス中にどのように相互作用または共変するかがわかります。この行列の逆行列は、重要性を決定するために使用されます。
共分散行列ではなく、なぜ逆行列を使用するのでしょうか?共分散行列Σは、パラメータが訓練中にどのように相互作用するかを捉えていますが、他のすべてのパラメータが考慮された場合に、各パラメータがタスクにおいてどれだけ重要かを具体的に示していません。対照的に、逆行列はパラメータの条件付き独立性(これは確率論の概念です、調べてみてください)を評価することができます。逆行列の大きな値は、他のすべてのパラメータが与えられた場合に、1つのパラメータを知ることが非常に他のパラメータに関して情報提供があることを示します。これがどのように機能するかの例については触れませんので、ChatGPTに非常に小さなニューラルネットワークを使用して値を解釈する方法の例を生成させてください。
前述の重要性を計算する方法は、個々のニューロンやパラメータに焦点を当てており、それらの関係を無視しています。一方で、逆行列はこれらの関係を捉えることができます。ディープラーニングにおいて、ネットワークの重要性を計算するためのより良い方法かどうかは、経験的であり、タスクとネットワークのスケールによって異なる可能性があります。
PyTorchにおけるアルゴリズムのステップバイステップ:
import torch# 制約半径radius = 0.1for epoch in range(num_epochs): for batch_idx, (data, target) in enumerate(data_loader): optimizer.zero_grad() # 順伝播 output = model(data) loss = loss_function(output, target) # 逆伝播して勾配を得る loss.backward() model_grad = torch.cat([p.grad.data.view(-1) for p in model.parameters()]) # NCLメソッドを使用してδを計算 # δ = Λ^(-1) * grad - (θ - µ) delta = torch.matmul(torch.inverse(covarianceMatrix), model_grad) - (torch.cat([p.data.view(-1) for p in model.parameters()]) - parametersForPrevTask) # 制約の確認 if torch.norm(delta) > radius: delta = radius * delta / torch.norm(delta) # モデルパラメータ(θ)をδを使用して更新 idx = 0 for p in model.parameters(): length = p.data.numel() p.data += delta[idx: idx + length].view(p.data.shape) idx += length # 次のタスクのためのΛとµの更新、おそらくタスク固有で非自明
3. 表現ベースのアプローチ
まず、続くタスクでさらに微調整するためにLLMの事前学習は、このサブカテゴリーでの連続学習の例です。ChatGPTがこれまでに見たことのないデータについて推論する能力も、このアプローチの例です。技術的にはゼロショット学習と呼ばれますが、「連続学習」という用語はモデルのパラメータを継続的に更新する必要があるため、これまでのものを超えます。導入で議論されたように、プロンプトエンジニアリングはパラメータを連続的に更新する代わりに連続学習の将来となる可能性があります。
以下では、知識の蒸留を使用して連続学習を行う方法について見ていきます。これがどのサブカテゴリーに該当するのかはよくわかりませんが、表現、アーキテクチャ、リプレイのアプローチの混合かもしれません。見直しているいくつかの技術は大規模なスケールでは無作為で未証明のように思われるかもしれませんが、この分野の突破口は予測できません。したがって、広い視野を保つことが重要です。
連続学習のための知識蒸留
ネットワークの知識を別のネットワークに移す(または「蒸留する」)ことができ、2番目のネットワークは元のネットワークによって学習された関数を合理的に近似することができます。
蒸留モデル(学生)は、元のネットワーク(教師)の出力を模倣するようにトレーニングされます。つまり、生データではなく、教師モデルを介してトレーニングデータを使用して学習します。例えば、小さな学生モデルを訓練して、大きな事前学習済みランゲージモデル(教師)を模倣する場合、元の事前学習データセットを教師モデルに入力し、ソフトターゲットを生成します。これは、潜在的な出力に対する確率分布です。例えば、次の単語の予測タスクでは、「猫」という単語を予測するのではなく、「猫」に対して90%、」子猫」に対して5%、「猫科動物」に対して3%などの確率を教師が提供します。
これは通常、知識をより小さなモデルに移すために行われ、その結果は小さなモデルにもかかわらず素晴らしい結果を生み出します。
成功した研究者は成功するためにこれを適用しました。名前付きエンティティ認識(NER)モデルに対して。トレーニングプロセスは非常に簡単です:
トレーニングプロセスのステップバイステップ
論文では、主に2つのメソッドが示されています:AddNERとExtendNER。
AddNERモデル
NERモデルは、トークン(通常は文)のシーケンスを入力として受け取り、各トークンの異なるエンティティのタイプに対して確率分布(IOBタグ付き)を出力します。IOBタグ付けはNERモデルで一般的に使用され、各トークンは「O」またはタイプXのエンティティの開始(「B-」)または内部(「I-」)としてラベル付けされます。「O」は「Outside」を表し、現在のトークンがどのエンティティにも属していないことを意味します。そのため、n個のエンティティタイプに対して「B-」タグ(各エンティティタイプごとに1つ)と「I-」タグ(同様に、各エンティティタイプごとに1つ)があるため、分類層には2nの出力ニューロンがあります。トークンごとに可能なラベルは2n + 1で、最終的な次元はh×(2n + 1)で書くことができます。ここで、hは隠れ層の出力のサイズです。ただし、これはトークンが1つのエンティティしか使用できないモデルの場合にのみ適用されます。例:「Apple」は「FOOD」と「COMPANY」の両方としてタグ付けされる可能性があります。
アーキテクチャと教師-生徒の設定
この場合、学生モデルは教師モデルのコピーであり、モデルが学習する必要がある新しいエンティティタイプごとに追加の出力分類層があります。トレーニング中、新しい出力層は新しい注釈付きデータから学び、より忘れないように旧層は教師モデルの出力によってガイドされます。
トレーニング後、古い出力層は破棄されません。その後、衝突リゾルバセクションのアルゴリズムとヒューリスティクス(セクション3.3の末尾)でこれらの出力を単一の最終予測に組み合わせるために使用されます。
フォワードパス
- 古いエンティティタイプ:入力文は教師モデルを通過して、古いエンティティタイプの確率分布(この文脈では「ソフトターゲット」と呼ばれます)を取得します。
- 新しいエンティティタイプ:同じ文は、新しいエンティティタイプに特化した追加の出力層を持つ新しい学生モデルを通過します。
バックワードパス
組み合わせた損失関数:
- KDロス:新しいモデル(学生)からの古いエンティティタイプの出力確率と古いモデル(教師)からの出力確率の近さを比較して計算される。このためにKLダイバージェンスが使用されます。これはおそらくトークンごとに計算され、その後、文またはバッチ内のすべてのトークンについて合計または平均されますが、論文はこれについては触れていないと思います。
- クロスエントロピー損失:これは新しいエンティティタイプのモデルの予測と新しいデータセットからの実際のラベルを比較する通常の損失関数です。
- これらの2つを組み合わせる:これら2つの損失は、それぞれの重み付け和を取ることで組み合わされます。これらの損失を組み合わせるための重みは、実験に基づいて良い結果を得るために他のハイパーパラメータと同様に調整されるalphaとbetaです。
# ハイパーパラメータalphaとbeta(2つの損失関数の重み付け)alpha = 0.5beta = 0.5num_epochsの範囲でepochを繰り返し: D_newの文、ラベルごとに: # 教師モデルでの古いエンティティタイプのフォワードパス teacher_probs_Ei = teacher_model(sentence) # 学生モデルでの古いエンティティタイプおよび新しいエンティティタイプのフォワードパス # 注:新しいエンティティタイプは新しい出力層を経由する必要があります(この疑似コードには表示されていません) student_probs_Ei、student_probs_Enew = student_model(sentence) # KDロスの計算 kd_loss = KL_divergence(teacher_probs_Ei、student_probs_Ei) # 新しいエンティティタイプのCEロスの計算 ce_loss = cross_entropy(labels、student_probs_Enew) # 組み合わせた損失 total_loss = alpha * kd_loss + beta * ce_loss # バックワードパス total_loss.backward() # 学生モデルのパラメータの更新 optimizer.step()
ExtendNERモデル
アーキテクチャと教師-生徒セットアップ
ExtendNERモデルは、新しいエンティティタイプを収容するために出力層の次元を拡張します。新しい出力層を追加するのではなく、次元がどのようにされるかは論文で次のように説明されています。
「Miがnつのエンティティタイプを認識できたと仮定すると、その最終層は次元h×(2n+1)の行列と見なすことができます。Mi+1の出力層は、新しいエンティティタイプを収容するために次元h × (2n + 2m + 1)の行列に拡張されます。」
Forward Pass(順方向パス)
AddNERと同様ですが、次元が拡張されています。
Backward Pass(逆方向パス)
損失の計算は、次の要因に応じてKLダイバージェンス損失またはクロスエントロピー損失を使用します:
- NERカテゴリラベルyが「O」(IOBタグ付けスキーマから)の場合、KLダイバージェンス損失が使用されます。
- カテゴリラベルyが「O」でない場合、クロスエントロピー損失が使用されます。
最終予測
最終エンティティタイプのデコードにはViterbiアルゴリズムが適用されます。
AddNERとExtendNERモデルは、継続的な学習において同様に優れたパフォーマンスを発揮し、結果にはほとんど差がありませんでした。
4. リプレイベースのアプローチ
「ファインチューニングされた言語モデルは継続的な学習者である」
この論文のモデルは、GPTのような一般的なシングルタスクモデルではありません。代わりに、テキストの簡素化から俳句生成までの特定のタスクのためにファインチューニングされています。それぞれのタスクには独自の要件、評価指標、および専門的なトレーニングデータセットがあります。
研究者たちは古いデータセットの一部を新しいデータセットと混合し、新しいタスクにファインチューニングする際に前のタスクのデータセットのわずか1%を混ぜることで素晴らしい結果を達成しています。これは多くのタスク(8つ)に順番に行われます。モデルはまた、ゼロショット学習の設定でも優れたパフォーマンスを発揮し、学習されていないタスクにもうまく適用できます。例えば、未知のトピックが与えられた場合に正しい音節数で俳句を生成できることを示し、汎化能力を持っていることを示しています。研究者たちはまた、彼らのアプローチがタスクの順序に依存しないと述べており、タスクの学習の順序がモデルのパフォーマンスに影響を与えないことがわかっています。実験では、古いデータセットを新しいデータセットと混合する割合が、主要なタスクのパフォーマンスにはほとんど影響を与えないことが分かりました。ただし、ゼロショット学習には影響を与えます。リハーサル0%の場合、モデルはゼロショットタスクを忘れる傾向がありますが、リハーサル1%では、モデルはそれらのタスクにおいて非常に良いパフォーマンスを維持します。
これはすべて良いように見えますが、chatGPTのようなチャットボットに適用する場合は経験的で完全に異なる可能性があります。妄想的に言えば、chatGPTをこのようにファインチューニングおよびRLHFステージで継続的にトレーニングできるかもしれませんが、ラベル付きの会話データの膨大な量が必要とされるでしょう。
5. アーキテクチャベースのアプローチ
ここでは特定の論文や実装には詳細に触れませんが、このアプローチの概要といくつかの異なる手法について簡単に説明します。より詳細な情報については、包括的な調査論文のこのセクション(4.5)を読むことをおすすめします。他のセクションよりも読みやすいです。
- パラメータ割り当て:ここでは、ネットワークのパラメータの一部が各タスクに割り当てられます。これは、関係のないニューロンをマスキングするか、現在のタスクに重要なニューロンを明示的に識別することによって行われることがあります。
- モジュラーネットワーク:これは、各タスクに対して個別のサブネットワークやモジュールを使用することを含みます。
サブネットワークは、アンサンブルまたはより複雑なアーキテクチャを形成するためにさまざまな方法で接続できます。以下は、サブネットワークを接続するためのいくつかの一般的な方法です:
出力の連結:
この方法では、複数のサブネットワークの出力を1つのテンソルに連結し、その後の追加の層を通過させて最終的な出力を生成します。
投票メカニズム:
一部のモデルでは、各サブネットワークが「投票」を行い、最終的な結果は多数決または重み付きの投票によって決定されます。これは、新皮質の異なるコネクティクルコラムが投票するのと似ているため、生物学的なインスピレーションを持っています。
スキップ接続:
一部のアーキテクチャでは、サブネットワークがモデルの他の部分にスキップ接続を持つことができ、情報がモジュール間を流れることができます。
シーケンシャル:
この場合、1つのサブネットワークの出力が次のサブネットワークの入力となります。
チャットボットについて話を戻すと、2つのサブネットワークを使用したこのようなアーキテクチャを作成できるとしたら、特に興味深いと思います。1つ目は一般的な「知識」を保持している事前学習モデルで、2つ目はモデルの整合性のための知識を保持しています。モデルが整合されると、ラベル付きの対話データはもはや必要ありません。代わりに、事前学習済みのサブネットワークを教師なしの方法で継続的に更新することで、モデルを更新することができます。
結論
結論として、深層学習における継続的学習のサブフィールドは困難であり、ほとんど知られていません。これは、LLMのニューロンがどのように機能するのかを完全に理解していないためであり、導入で説明したように、現在のネットワークアーキテクチャ、または深層学習自体が適していない可能性もあります。
前月にChatGPT(GPT-4のみ)が「アップデートされました」と表示され、現在のユーザーレポートが2022年1月までとなっていることに気付きましたので、OpenAIのメンバーがこれを実現するために何をしたのか興味が湧きます。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles