
21,976 文字

こんにちは、皆さん。本日はご参加いただきありがとうございます。私はアレクサンダー・アミニと申します。イーバと共に、今年のコースで皆さんの講師を務めます。これはMIT深層学習入門、正式なコース名は6.S191です。このクラスへの皆さんをお迎えできることを大変嬉しく思います。まずは「MIT深層学習入門とは何か」という問いから始めるのが良いでしょう。これは深層学習の全てを学ぶ1週間のブートキャンプです。非常に楽しいけれども、同時に非常に集中的な1週間になります。なぜなら、これから5日間で膨大な量の内容をカバーするからです。
これは私たちがこのクラスを教える8年目になりますが、特にここ数年の分野の進歩は本当に驚くべきものです。毎年このクラスを教えるたびに、この講義の紹介方法がますます面白くなり、長年にわたって適応し進化してきました。会場の皆さんの多くは、深層学習の進歩がこれほど急速に起こっているため、ここ数年の進歩に少し鈍感になっているかもしれません。そのため、数年前の状況を忘れないことも重要だと思います。
まずはこの画像をお見せしましょう。皆さん自身の目で進歩を確認するのが一番です。ちょうど10年前、これが最先端の深層学習ベースの顔生成システムでした。これは実際の顔ではなく、顔を生成できる最先端モデルであり、当時できる最高のものでした。その数年後には、画像生成の進歩は tremendously に進んでおり、より写真のようなリアルな画像が生成されるようになりました。さらに数年後には、これらの画像が生き生きとし始め、時間的な情報や動画、動きが加わるようになりました。
実際、右側に表示されているこの動画は、数年前に私たちがこのクラスで作成したものです。まだ見ていない方のために、全部ではなく最初の10秒だけ再生しますね。「皆さん、こんにちは。MITで教えている深層学習の公式入門コース、MIT 6.S191へようこそ。」
全部は再生しませんが、要点はわかると思います。この動画は5年前、2020年に私たちがこのクラスの一部として作成し、当時このクラスを紹介するために使用しました。2020年にこれを行ったとき、当時としては大きな話題になりました。深層学習モデルの写真リアリズム能力において大きな飛躍であり、クリップはすぐにバイラルになり、そのリアリズムについて多くのコメントがありました。
しかし興味深いことに、人々が見なかったのは、最終結果だけでなく、その2分間のクリップ(最初の10秒だけ見せましたが、全体で2分間)を生成するために、約2時間分のプロフェッショナルな音声データの録音(私たちではない話者の)、約50時間分の高精細ビデオデータによる顔モデルの構築、そして約15万5000米ドルの計算コストがかかったことです。そのすべてが、事前に定義されたスクリプトを生成するためだけに使われました。対話することはできず、インタラクティブではなく、事前に定義された静的なスクリプトにすぎませんでしたが、それでも膨大な時間、データ、エネルギー、そして財源が必要でした。
このクラスを始めるにあたり、「今日ではどのようになっているのか」という質問をしたいと思います。その動画は2020年に作成されましたが、今は2025年です。2020年のあらゆる制限を考えると、今日の世界ではクローニングや生成AIはどのようになっているでしょうか。これを説明する最良の方法は、実際にお見せすることだと思います。2020年に費やした計算リソースの代わりに、今日はリアルタイムで編集なしで皆さんの前で行ってみましょう。
実は、秘密があります。別の画面を共有しますね。これは、私が話している間にバックグラウンドで音声を録音しているターミナルウィンドウです。私たちが作成したこのプログラムが私の音声を聞き、録音しています。録音を一時停止し、以前の時間のかかるリソースと比べて、いかに速く私の声を瞬時にクローンできるか見てみましょう。
今停止します。瞬時にクローンが作成されるのがわかりますね。声がクローンされました。これを使って、以前のような事前定義されたスクリプトではなく、このボイスとリアルタイムで編集なしの会話をしてみます。今日の世界でこれらの生成AIモデルがどれだけ動的で柔軟になったかを見てみましょう。
「こんにちは、聞こえますか?」
「はい、はっきり聞こえます。お元気ですか?」
「ちょっと待って、あなたは私にとても似た声をしていますね?」
「そうですね、私たちは思っていた以上に似ていますね。何をしているんですか?」
「実は、今年のMIT深層学習クラスを開始したところで、今まさに聴衆の前に立っています。」
「MIT深層学習入門は素晴らしいクラスですね。クラスはどうですか?」
「今始まったばかりです。私はちょうど深層学習とは何かを紹介しようとしていました。その部分をあなたに代わってもらえませんか?」
「深層学習は、人工ニューラルネットワークを使用してデータから学習する機械学習の一種です。これらのネットワークは人間の脳の構造に着想を得ており、大量のデータから複雑なパターンを学習できます。深層学習は、画像認識、自然言語処理、自動運転車など、幅広い応用分野で使用されています。」
「それはなかなか良いですね。観客に伝えていた驚くべきことは、今日の深層学習がとても柔軟で動的だということです。どう思いますか?」
「その通りです。深層学習は非常に動的で、新しいアーキテクチャ、アルゴリズム、アプリケーションが常に開発されている進化し続ける分野です。」
「ちょっと待ってください、あなたがどれだけ動的か示すために、あなたを中断します。深層学習の話はもう十分です。代わりに、カメについての物語を教えてください。面白いものにしてください。」
「カメですか?面白いカメの話ですね。こんな感じです。シェルという名前のカメがいました。彼は普通のカメではありません。シェルには夢があります。飛ぶことを夢見て、小さなヒレをパタパタさせて地面から離れる練習をしています。ある日、彼はドクター・シェルドンという狂気の発明家カメに出会います。彼はロケット推進のシェルを作りました。シェリーはそれに飛び乗り、バーンと宇宙に飛び出します。彼らは惑星を通り過ぎ、エイリアンに会います…」
「中断しますね、カメ最高ですね!ここで終わりにしましょう。」
「ありがとうございます、クラスを紹介する素晴らしい方法でした。」
「お役に立ててよかったです。さようなら。」
「さようなら。」
素晴らしいですね。これは、数年前には非常に静的なコンテンツを生成していた状態から、今日ではリアルタイムで編集なしの非常に動的なコンテンツまで、この分野がどれほど進歩したかを示す楽しい方法です。
今のデモで深層学習とは何かについての簡単な紹介を聞いたばかりですが、このデモや過去数年で皆さんが目にしてきた進歩、そしてこれから1週間のクラスで見るものは、その進歩を推進する基本的な技術です。
まずは基礎を築き、この分野の本質について説明します。そのためには、まず「知能とは何か」を紹介する必要があります。私にとって、知能とは「将来の決断や行動を知らせるために情報を処理する能力」を意味します。これが知能の意味です。私たち全員が毎日この能力を発揮しています。人工知能とは、まさにそれと同じプロセスを行う人工的なアルゴリズムを構築する実践です。情報やデータを使用して将来の決定を知らせるのです。
機械学習とは何でしょうか?機械学習は人工知能のサブセットで、コンピュータにデータの使い方や情報処理の方法を明示的にプログラムするのではなく、データ内のパターンを学習して決定を行うことに焦点を当てています。そして深層学習は、ニューラルネットワーク、深層ニューラルネットワークを使ってそのプロセスを行う機械学習のサブセットです。このクラスを通じて深層ニューラルネットワークとは何かを学びますが、ハイレベルでは、このコース全体はこの核心的なアイデアに関するものです。つまり、コンピュータに観察やデータから直接タスクの学習方法を教える方法を学ぶことです。講義を通じて堅固な基盤を提供し、同時にソフトウェアラボを通じて実践的な理解も得られるようになっています。
これはコース全体についてハイレベルでお話しするきっかけになります。この講座は技術的な講義とソフトウェアラボの組み合わせになります。分野が急速に進化しているため、今年は特に多くの新しい更新があり、特に深層学習のよりモダンな側面の重要なポイントを強調します。その目的で、業界のリーダーによる最先端の深層学習法やAI手法に関するゲストレクチャーで締めくくります。
また、今夜4時30分からレセプションがありますので、皆さんをご招待します。深層学習についてもっと学ぶために皆さんと話し合える機会です。食事も用意されています。
今年はソフトウェアラボにも多くの素晴らしい更新があります。TensorFlowとPyTorchのソフトウェアラボを導入します。これらは皆さんにとって講義で学んだことを実践するための素晴らしい学習経験になるだけでなく、コンテストの賞金に応募し、多くの賞金を獲得する資格を得る手段にもなります。
具体的にはどのように機能するのでしょうか?毎日専用の講義があり、その講義を反映した専用のソフトウェアラボがあります。ソフトウェアラボは、その日の講義で教えられた内容を強化するものです。今日からラボ1が始まり、言語モデルの一形態、非常に小さな言語モデルですが、次のトークンを予測する言語モデルを構築します。これは音楽を生成し、音楽の次のトークンを予測することで、新しい民謡を生成できるようになります。
明日はラボ2で顔検出システムに進み、ゼロからコンピュータビジョンシステムを構築する実践経験を得ることができます。また、これらのシステムでアンバランスなデータを修正する自動技術についても理解します。最後にラボ3は、今年初めて公開される大規模言語モデルに関する新しいラボです。このラボでは、20億パラメータの大規模言語モデルを微調整し、ミステリースタイルであなたが制御するコンピュートで行い、また言語モデルの品質を評価するAIジャッジを構築します。
これら3つのラボはとても楽しいものになるでしょう。最後に、クラスの最終日には最終プロジェクトのピッチコンペティションがあります。各グループは3〜5人からなり、シャークタンクスタイルのピッチコンペティションで3〜5分のプレゼンテーションを行います。これによって、さらに多くの賞を獲得する資格が得られます。
このクラスの一部として利用できる多くの素晴らしいリソースがあります。このスライドとすべての講義はオンラインで公開されており、ウェブサイトで既に確認できるはずです。何かヘルプが必要な場合は、Piazzaに投稿してください。質問や問題があれば、いつでも連絡できる優れたTAと講師のチームがあります。私とイーバがコースの主要な講師を務めますが、コース中に多くのゲスト講師からも話を聞くことになります。
この講座は、長年にわたる素晴らしいスポンサーの支援なしには実現しませんでした。彼らの支援に大きな感謝を表します。
では、楽しい内容に入っていきましょう。このコースは8年間教えられており、これまでに約1300万人を教えてきました。MIT単独では約3000人、毎年オンラインでは約10万人がこのクラスを受講しています。素晴らしい仲間の一員であり、今日ここにいる皆さんを歓迎できて本当に嬉しいです。
このクラスの技術的な部分に入るにあたり、「なぜ深層学習か、なぜ今なのか」という根本的な問いから始めたいと思います。これは皆さんが今日ここに来る前に考えた質問だと思います。深層学習の基礎を理解することは、この分野を推進するさらに良いアルゴリズムを構築するために非常に重要です。
従来の機械学習は、「特徴量」と呼ばれるセットを定義します。これらの特徴量は基本的にタスクを段階的に実行するための規則です。問題は、私たち人間が特徴量を定義する場合、通常は非常に堅牢な特徴量を構築することがあまり得意ではないことです。例えば、顔を検出できるAIモデルを構築するとしたら、どのようにしますか?画像で顔を検出するためにどのような特徴量を構築しますか?
まず、画像内の線、つまりエッジを検出することから始めることができます。次に、それらの線を組み合わせて、曲線やエッジなどを検出します。そして、それらを組み合わせてより複合的なオブジェクト、例えば目、鼻、耳などを形成し始めることができます。そこから顔の構造を構築し始めることができます。なぜこのようにするのでしょうか?実際、これは皆さんも自然に考えるであろう方法です。なぜなら、顔を一度に検出することは非常に難しいからです。実際には、まず低レベルの特徴から処理し始め、それらを組み合わせて顔に関する直感を形成します。
深層学習の鍵となるアイデアはこのプロセスと何ら変わりません。鍵となるアイデアは、私や皆さんが正確にそれらの特徴量を明示的に定義するのではなく、特徴量を学習することです。深層学習の鍵となるアイデアは、多くの顔を観察した後、階層的な方法で段階的に検出すべきことを学習できるかどうかということです。まず線を検出し、次に曲線を検出し、次に目、鼻、耳などの複合物を検出し、そして顔の構造を構築するという具合です。これがまさに深層学習が行うことであり、今日の講義を通してその仕組みを見ていきます。
ここ数年で深層学習の驚くべき進歩を目にしていますが、特に今日の講義で学ぶことはほとんど何十年も前に発明または開発されたものであることを理解することが重要です。これは新しいものではありません。なぜ今日これらすべてを目にしているのでしょうか?その理由は、何十年も前の技術であっても、3つの重要な要素によって爆発的に普及したからです。
第一にデータです。データは世界中でますます豊富になり、これが深層学習の進歩を推進しています。第二に計算能力です。計算能力はますます強力になり、より一般化されています。特にGPUアーキテクチャが学習の進歩を推進しており、GPUは最近になって一般化され始めました。最後に、TensorFlow、PyTorch、Kerasなどのオープンソースツールボックスが、わずか1週間のコースで皆さんがこれらのアーキテクチャに直接取り組み始めることを非常に効率的かつ容易にしています。
では、すべてのニューラルネットワークの基本的な構成要素、単一のニューロンまたはパーセプトロンから始めましょう。パーセプトロンとは何でしょうか?パーセプトロンまたは単一のニューロンのアイデアは非常にシンプルです。情報の順伝播によってパーセプトロンを定義しましょう。入力が与えられたとき、パーセプトロンはどのように出力を計算するのでしょうか。
X1からXMの入力セットを定義し、これらの各入力は対応する重みW1からWMで乗算されます。乗算後、これらの数値をすべて加算し、得られた単一の数値を非線形活性化関数に通します。これは単一の数値に適用される非線形一次元関数で、ここではGと表記されています。
ひとつ細部を修正します。すべての重みを入力に掛けた後、バイアス項と呼ばれる1つの数値も追加します。バイアス項は、方程式を見ると、活性化関数G上で左右にシフトする方法と考えることができます。これは方程式内の設計されたシフトスカラーです。
このスライドの右側では、左側の図が数学的に式として表現されているのがわかります。今度は、明瞭さのために線形代数のベクトルとドット積を使ってこれを書き直します。
X1からXMの代わりに、大文字のXというベクトルを書きます。大文字のXはすべての入力の集まりであり、大文字のWはすべての重みの集まりまたはベクトルになります。出力Yは、XとWのドット積にバイアスを加え、G(非線形性)を通すことで得られます。
「非線形性」について何度か言及しましたが、これは何でしょうか?非線形関数だと言いましたが、具体的には何ですか?よく使われる例のひとつはシグモイド関数です。シグモイド関数はx軸上の任意の実数に対して作用しますが、出力は0から1の間に限られます。シグモイド関数は、パーセプトロンやニューロンの出力を確率に変換したい場合に非常に適しています。
実際には、多くの種類の非線形関数があり、これはニューラルネットワークでよく使用される関数のひとつにすぎません。このプレゼンテーションでは、様々な非線形関数の例をいくつか見ていきます。また、このスライドの下部にTensorFlowとPyTorchの両方のコードスニペットがあり、数学で見ているものと後のソフトウェアラボで関連するコードを関連付けるのに役立ちます。
先ほど見たシグモイド関数は確率に適していますが、右側にある整流線形ユニット(ReLU)も見られます。これは厳密に正の値を出力し、区分的に線形です。ゼロより前は線形、ゼロより後も線形ですが、x=0で単一の非線形性があります。
なぜ活性化関数が必要なのでしょうか?これは皆さんが疑問に思った質問だと思います。一見不要に思えるかもしれません。活性化関数の要点は実はシンプルで、モデルに非線形性を導入することです。非線形活性化関数がなければ、線形モデルになってしまいます。では、なぜ非線形性が欲しいのでしょうか?それは、現実世界の実際のデータが非常に非線形だからです。
これを示す良い例を挙げましょう。この画像を見て、赤い点と緑の点を分離する分類器、つまり単一の線を引くとしたら、その線を引くことはできますか?一見すると引けそうですが、それがまっすぐな線でなければならないとしたら?まっすぐな線だと、このタスクを適切に行うことは本当に難しくなります。これが線形モデルの問題です。
非線形性を持つ利点は、モデルの深さが十分であれば、任意に複雑な関数を近似できることです。これがニューラルネットワーク、非線形ニューラルネットワークを非常に強力にしている理由です。
簡単な例で理解を助けましょう。ここに訓練済みのニューラルネットワークがあると想像してください。これには1つのパーセプトロンがありますが、X1とX2の2つの入力、W1とW2の2つの重み、そして上部にバイアス項もあります。
どのようにこの情報を処理するでしょうか?前と同じようにドット積を計算し、バイアスを加え、非線形性Gを通します。データを入力すると、入力はX1が+3、X2が-2です。これらを重みと一緒に方程式に代入すると、このニューロンの全関数空間をパラメータ化する2次元の線が得られます。2次元なので、この線を実際にプロットできます。つまり、この全空間がどのように見えるかを正確に言うことができ、このモデルが見る新しい入力がこの線に対してどこに落ちるかがわかります。
例えば、この新しい点がX1X2空間にあるとすると、点(-1, 2)にあり、この線に対してグラフィカルに正確にどこに落ちるかを視覚的に確認できます。また、方程式に代入することもできます。X1に-1、X2に2を入力し、左下の方程式に代入し、非線形性(ここではシグモイド関数)を通すと、0と1の間の値に圧縮され、最終的な答えは0.2になります。これは0.5未満で、0.5が分割線になります。これはすべての出力が0と1の間に分離されるためです。
これをグラフィカルに表現することもできます。線の上に直接落ちると、非線形性後の出力は0.5になります。青い側に落ちるほど0.5未満の値になり、緑の側に落ちるほど0.5を超える値になります。つまり、線は空間の両側の分離点を表し、入力がどちら側に落ちるかによって、その点を正の点または負の点として分類できます。
今、単一のニューロンと2つの入力に対してこれを行いましたが、2つ以上の入力を持つモデルがあると、このプロットを描くことはもはや不可能になります。これは理解と直感の構築において対処する必要があることですが、この小さなスケールでもこのプロットからある程度の直感を構築できることを願っています。
では、単に1つのニューロンを超えて、ネットワークを構築する方法を見ていきましょう。ここで本当に強力なシステムを構築するのは、1つのニューロンだけではなく、完全なネットワークからです。そのために、もう一度図を見直しましょう。
このクラスから何かを持ち帰るとすれば、これがそのスライドです。既に何度も言いましたが、もう一度言います。ニューロンを通して情報を渡す方法は、ドット積を取り、バイアスを適用し、非線形性を適用するという3つのステップです。これらのステップが何度も繰り返されます。
図をシンプルにするために、希望通り定着し始めたと思われるので、図からすべての重みとバイアス項を削除します。今後は図を整理するために、これらの2つのものがあると常に想定してください。
ここでZは、ドット積とバイアスの結果、つまり非線形性Gの前の結果です。ZをGに通すとYが得られ、これがここに表現されています。
では、1つの出力ではなく、2つの出力を持つマルチ出力ニューラルネットワークが欲しい場合はどうでしょうか?
実は簡単で、2つ目のパーセプトロンを作成するだけです。今は1つではなく2つのニューロンを持ち、両方のニューロンは同じ入力を持ちますが、重みが異なるため、2つの異なる出力が生成されます。両方が同じ情報を入力として取り、自分自身の重みで処理し、2つの異なる出力を一から作成します。
このような層は、通常「密結合層」と呼ばれます。なぜなら、入力のすべてが出力のすべてに接続されているからです。また、非線形性を除外すれば、これも線形層です。すべての入力Xを取り、重みWで線形に操作し、バイアスを加えるだけであり、これも線形操作だからです。
これをPythonでゼロから実装してみましょう。まず、2つの重みを定義します。self.wは重みベクトル、self.bはバイアススカラー(1つの数値)です。ここでは、n次元の出力全体なので、出力にもn個のニューロンがあります。
この層を通して順伝播を行いたい場合、どうすれば良いでしょうか?前と同じように、ドット積(これはドット積でここではmultiplyとして表現されています)を取り、バイアスを加え、非線形性を適用します。ここではシグモイド関数ですが、任意の非線形性に変更できます。PyTorchでは、左側と右側はほぼ完全に一致していることがわかります。2つの重み(重みとバイアス)を作成し、行列乗算を適用し、バイアスを加え、非線形性を適用します。前と全く同じです。
幸いなことに、TensorFlowとPyTorchはこのタイプの密結合層または線形層を既に実装しているため、自分で実装する必要はありません。これは良い学習演習でしたが、ここでは関数を呼び出すだけで済みます。
次に単一層のニューラルネットワーク、つまり出力が単一のパーセプトロンから直接来るのではなく、2つの層を通過しなければならない単一の隠れ層を持つネットワークを見てみましょう。これはどのようなものでしょうか?
これは、単一の隠れ層が出力層と入力層の間に配置されているものです。なぜ「隠れ」と呼ぶのでしょうか?それは、この層内で起こるデータを直接観察しないからです。入力層はモデルに提供するデータであり、出力層は通常、監視するものです。隠れ層は観測可能なデータの過程で学習されるものです。
入力から隠れ層、そして隠れ層から出力への変換があるため、2つの層があることになります。これはまた、2つの重み行列Wが必要であることを意味し、左側にW1、右側にW2があります。
隠れ層内の単一のユニット、単一のパーセプトロン、単一のニューロン(例えばZ2)を見ると、それは以前見たパーセプトロンと同じです。同じようにドット積を取り、バイアスを加え、非線形性を通して答えを計算します。別のノード、別のニューロン(例えばその下のZ3)を見ると、同様にドット積、バイアス、非線形性で計算されますが、Z2と同じ入力を取りつつ、異なる重みを持ちます。そのためドット積とバイアスは異なります。
この画像も少し複雑に見えるので、もっとシンプルにします。すべての矢印を、2つのコンポーネント間で起こるこの密結合層、この線形接続層を表す単一のアイコンに置き換えます。
TensorFlowやPyTorchでこのようなネットワークを構築するには、これらの便利な関数が本当に役立ちます。ゼロから多くを実装する必要がないからです。
深層ニューラルネットワークを作成したい場合、どうすれば良いでしょうか?深層ニューラルネットワークとは何でしょうか?それは単に線形層を順番に積み重ね、その後に非線形性、さらに線形層、さらに非線形性を階層的に何度も何度も繰り返すだけのものです。これは最終的な出力が、これらの線形操作と非線形操作を深く深く通り抜けていく階層的な組み合わせとして作成されるモデルです。
[質問への回答:なぜ異なる層(深さ軸と出力軸)があるのか]
深さ軸の異なる層は、ネットワークのより多くの深さ、より多くの複雑さに対応します。より複雑なタスクにはより多くの深さが必要です。なぜなら、より多くの階層的な非線形性を導入するからです。1つの層の後には、単一の非線形性からの表現力に限界があります。より複雑なタスクになるほど、より深い表現力のある関数が必要になります。
もう一方の軸、より多くの出力というのは単に問題定義です。より多くのものを予測したい場合、より多くの出力が必要になります。良い例は、画像生成です。画像を生成するためには、その画像内のすべてのピクセルの値を生成する必要があります。これは多くの出力です。対して、明日の天気を予測するだけであれば、それは温度値、つまり1つの出力です。問題定義によって、これら2つのことが変わります。
ニューラルネットワークを構成するものについて理解したので、この理論を実践に応用する例を見ていきましょう。先ほどの質問に関連して、非常に現実的な問題にニューラルネットワークを応用する方法を理解してみましょう。
おそらく皆さんが自問している質問の一つが「このクラスに合格するだろうか?」というものでしょう。この答えを推測または予測できるニューラルネットワークを構築してみましょう。
非常にシンプルなモデルを構築します。2つの入力と1つの出力があります。出力はこのクラスに合格するかどうか(はいかいいえ)の単一の数値、合格する確率です。2つの入力は、1週間のうちに出席する講義の数と最終プロジェクトに費やす時間数で定義されます。
このクラスを何年も教えてきたので、この操作に関する過去の学生からのデータがあります。緑の点はクラスに合格した人、赤の点は合格しなかった人を示しています。また、あなたがこのクラスに費やす時間、最終プロジェクトに費やす時間を推測することもできます。私たちは、これらの学生の過去のデータからあなたが合格する確率対合格しない確率のどこに位置するかを判断するニューラルネットワークを構築したいと思います。
実際にやってみましょう。これまでクラスで学んだことをすべて使って、ステップバイステップで進めていきます。2つの入力があります。これはあなた、新しい人です。4つの講義に出席し、最終プロジェクトに5時間費やしました。これら2つの数字をモデルの左側に入力として供給できます。
また、単一層のニューラルネットワーク、非常に基本的なニューラルネットワークがあり、隠れ層には3つの隠れユニットがあり、出力はクラスに合格するかどうかのバイナリ出力の1つだけです。
このモデルが答えを大きく間違えたことがわかります。クラスに合格する確率が0.1または10%と予測しましたが、実際にはあなたはとても良くやって、確実に合格しました。なぜこのネットワークがここで非常に失敗したと思いますか?
[質問への回答:訓練されていないから]
その通りです!モデルはここで前のスライドで示したデータを見ていません。基本的に、現実世界について何も知識を持たないまっさらな状態のようなものです。この問題についても何も知らないので、まずこの問題について学ぶ必要があります。
これは今まで話していなかったことですが、モデルを訓練するためには、モデルが悪い予測を行ったときに、それがどれだけ悪いかを理解する必要があります。悪い予測とは何を意味するのでしょうか?それは、予測が良い予測と比べてどれだけ悪いかを定量化できる必要があるということです。
これをニューラルネットワークの損失と呼びます。ニューラルネットワークの損失は、その予測と真の答え、またはデータの真の観測値がどれだけ離れているかの測定値です。損失が小さいほど、これら2つのものが近いことを意味します。つまり、予測が本当に真の値と一致していることを示します。これにより小さな損失が生まれます。
データが1人の学生からだけではなく、多くの過去の学生からのものだと仮定しましょう。モデルがこの1人の学生だけではなく、過去のクラス全体にわたって集計的にどのように機能しているかを気にしたいと思います。
ニューラルネットワークを訓練するとき、単一のデータポイントだけでなく、データセット全体で損失を最小化する(または精度を最大化する)ニューラルネットワークを見つけたいと思います。これを経験的損失と呼び、単にデータセット内の各データポイントの損失の平均です。
今まで、バイナリ分類(はい・いいえの答え)の問題に焦点を当ててきましたが、このような損失には、ソフトマックスクロスエントロピー損失と呼ばれるものを使用できます。これについては後で詳しく学びますが、これは2つの確率分布、2つのバイナリ確率分布間の差または距離を測定しています。
ただ、バイナリ出力ではなく、連続的な値、例えば「クラスに合格するかしないか」ではなく、どれだけ良い成績を取るかというパーセンテージのような実数の最終出力を予測したいとしましょう。
そのような場合、バイナリ損失を使用することはできなくなるので、損失を変更する必要があります。例えば、平均二乗誤差損失に変更できます。予測された成績と真の成績を取り、それらを引いて二乗することで距離測定を作成します。
これらは大まかに言って、カテゴリカルな離散的な損失(バイナリ損失など)と連続的な損失(MSE損失など)という2種類の損失です。もちろん、クラスで触れる他の多くの損失もありますが、これら2つは分野で広くカバーされています。
これらすべての情報をまとめて、ネットワークの重みを見つける問題について話し始めましょう。ネットワークの定義について話し、ネットワークが何かを間違えたときにペナルティを与えることについて話しましたが、ネットワークを実際に改善する方法、または訓練する方法については話していませんでした。
次の部分でそれについて話しましょう。ここでの目的は何でしょうか?結局のところ、このクラス全体を通して何をしようとしているのでしょうか?それは、データセット上で損失を最小化するネットワークまたはモデルを見つけて構築しようとしていることです。損失は予測と真の値の間のこの差を測定し、私たちはデータセット上で損失を最小化するネットワークを見つけたいのです。
これは数学的に、この方程式を通じて、1からnまでの全データセットに渡る損失Lを最小化する重みWを見つけたいということを意味します。Wの重みは、ネットワーク全体のすべての層からのすべての重みの集まりであることを覚えておいてください。これらをすべて1つにまとめて、これらが最適化しようとする重みです。
この最適化手順をどのように行うのでしょうか?損失関数は重みの関数にすぎないことを覚えておいてください。一連の重みが与えられると、損失関数は単一の値を返します。それは予測された答えと真の答えがどれだけ離れているかを示します。
ネットワークに重みが2つしかなければ、このような画像のように損失の景観をプロットできるでしょう。重み1と重み2のグリッド上にプロットし、重みの各構成について、その構成がどれだけのエラーまたは損失を得ているかを見ることができます。
私たちが望むのは、この景観の最も低い点を見つけることです。最小の損失を与える重み1と重み2の組み合わせを見つけたいのです。どうすれば良いでしょうか?
ランダムな点から始めることができます。景観内のランダムな点、任意の点を選び、そこから始めます。勾配と呼ばれるものを計算します。勾配は、この点からどの方向が上かを教えてくれます。それは局所的な測定で、「私がちょうどここに立っている場所から、どの方向が上か」と言うだけです。
そして、その反対方向に小さなステップを踏みます。損失を下がる方向に小さなステップを踏み、最終的に丘の底に到達し、局所最小値と呼ばれるところに収束するまで、このプロセスを何度も何度も繰り返します。
この手順、このアルゴリズムを勾配降下法と呼び、擬似コードとして要約できます。もう一度簡単に見直しましょう。まず、重みをランダムに初期化します。これは景観内のランダムな場所を選ぶことを意味します。
次に、勾配(ここではDJ/DWと呼ばれる)を計算します。これは、重みの小さな変化が損失をどれだけ変えるかを示します。つまり、損失を増加させるために重みを変えるべき方向を教えてくれます。
その方向とは反対方向に小さなステップを踏みます。ここで勾配を取り、-1を掛けて、その方向とは反対方向に進みます。そして、その方向にどれだけ移動するかの小さなステップサイズ(ここではEtaと呼ぶ)を掛けます。そして、このループを何度も何度も繰り返します。
TensorFlowでも、同じように表現されているのが見られますが、ここで注目したいのはこの項です。これは方向の項で、勾配を教えてくれます。勾配は、どの方向が上かを教えてくれます(あるいは、その負の値を取れば、どの方向が下かを教えてくれます)。しかし、これを計算する方法については説明していませんでした。
ニューラルネットワークにおける勾配の計算プロセスは、バックプロパゲーション(逆伝播)と呼ばれます。バックプロパゲーションがどのように機能し、特定のニューラルネットワークの勾配をどのように計算するかについて、ステップバイステップの例を見ていきましょう。
デモンストレーションのために、最もシンプルなニューラルネットワークから始めましょう。1つの入力、1つの出力、そして中間に1つの隠れニューロンがあります。これ以上シンプルなネットワークはありません。
最終的な損失Lに対する勾配を計算したいとします。まずはW2に関して計算しましょう。W2の小さな変化が損失にどれだけ影響するかを知りたいのです。
この導関数を数学的に書き出し、連鎖律を使って分解できます。なぜ分解したいのでしょうか?まず、この勾配DJ/DW2を2つの項DJ/DYとDY/DW2に分解します。これは連鎖律の基本的な拡張であり、何も魔法はありません。なぜこれが可能なのでしょうか?それは、Yが前の層にのみ依存しているからです。
次に、W2の前の重みW1の勾配を計算したいとします。この方程式でW2をW1に置き換え、再び連鎖律を適用する必要があります。なぜなら、最後の項の計算が明確に定義されていないからです。実際にもう一度展開する必要があります。
これがバックプロパゲーションと呼ばれる理由です。実際に出力から始めて、これらの反復的な連鎖律をネットワーク全体を通して、出力から入力まで、ステップバイステップで計算する必要があるからです。
重みにわたって出力から入力までこれらの勾配を伝播するこのプロセスを繰り返し、このプロセス全体の最後には、ネットワーク内のすべての重みについて、「この重みを少し増やすと、損失は上がるのか下がるのか」という方向が得られます。もし損失が下がるなら、その重みを少し増やすべきですね(または反対方向に進む)。
これがバックプロパゲーションアルゴリズムです。理論的には、微分計算の連鎖律の応用にすぎませんが、実際には非常に複雑で面倒なものになる可能性があります。モデル内のすべての重みに対してステップバイステップでこれを行う必要があるため、非常に計算集約的な作業です。
実際には、今日の深層学習フレームワーク(TensorFlow、PyTorchなど)はこれを自動的に行うため、自分で実装する必要はありませんが、これらの動作の理論的な側面とフード下で何が起こっているかを理解することは重要です。
これを機会として、ニューラルネットワークの訓練の実用的な意味について議論したいと思います。以前に見せた非常に美しく滑らかな損失景観の写真を見せましたが、実際にはニューラルネットワークの最適化は非常に難しいです。
これは深層ニューラルネットワークの損失景観の投影で、2017年頃に出た論文からのものです。いくつかの損失景観がどれほど複雑に見えるかを視覚化できるようになり、このようなバックプロパゲーションと最適化技術を適用することは非常に難しいことがわかります。
バックプロパゲーションと特に勾配項に深く入る前に、ここに表示されている方程式について話し始めたことを思い出してください。どのように重みを更新するのでしょうか?反対方向に小さな増分のステップを踏むことで更新します。
ここで重要な項は「小さなステップ」です。これはモデルの学習率と呼ばれます。これは基本的に、どれだけ速くステップを踏み、バックプロパゲーションの計算中に勾配にどれだけ速く耳を傾けるかを決定します。
実際には、学習率の設定は非常に難しい場合があります。学習率を遅すぎるように設定すると、基本的に点から始まりますが、いくつかの局所最小値にはまってしまい、到達できる最良の最小値ではない可能性があります。大きすぎると、不安定な挙動が発生し、正しい方向にステップを踏み始めても、ステップが大きすぎて学習の安定した場所から爆発してしまいます。
理想的には、局所最小値をいくつか飛ばせるほど小さすぎず、また発散しないほど大きすぎない学習率を設定したいですね。では、実際に学習率をどうやって設定するのでしょうか?
一つの選択肢、そして実際に非常に一般的な選択肢は、いくつかの学習率を試して、最も良いものを見つけることです。これよりも良い方法はありますか?
アイデアは、検索空間で最適化している方法に応じて学習率を適応させることができる適応的なアルゴリズムを設計できるかどうかです。これは基本的に、実際の学習率が勾配とデータの関数として増減することを意味します。どれだけ速く学習しているか、景観がどれだけ急かなど、これらのさまざまな要素によって、学習率のこれらの適応的な特性がすべて決まります。
実際、これらは広く研究されており、多くの異なるタイプの適応学習率スケジューラが作成されています。ここではいくつかの例を見ることができます:Adam など、多くは「Ada」(適応的という意味)で始まります。これらは適応特性のさまざまなバリエーションです。
特にAdamは、非常によく使用される最適化手順の一つであり、多くのラボで使用することになりますが、これらのさまざまな学習率スケジューラをすべて試して実験し、何が最も効果的かを確認することをお勧めします。多くの場合、異なる問題に対して異なるタイプの学習率スケジューラが効果的です。
これらを試すのは、多くの場合、学習ループに対する1行の変更くらい簡単です。SGD(確率的勾配降下法)は、以前に見た基本的な勾配降下アルゴリズムですが、実際に私が紹介したのは勾配降下アルゴリズムであり、確率的勾配降下アルゴリズムではありませんでした。これら2つのアルゴリズムの違いについて少し掘り下げたいと思います。
そのためには、まず勾配降下アルゴリズムをもう一度見直す必要があります。ここでの勾配は、バックプロパゲーションで計算されたその部分ですが、計算量が多いのは、データセット内のすべてのデータポイントにわたる合計または平均として計算されるからです。つまり、1つのデータポイントだけでなく、データセット内のすべてのデータポイントに対して勾配を計算するのです。
ほとんどの現実の問題では、このステップの毎回の反復でデータセット全体に対して勾配を計算することは実現可能ではありません。なぜなら、勾配を1回だけ計算するのではなく、この最適化プロセス全体でそれぞれのポイントで計算し、ネットワークを何百万回、あるいはそれ以上のステップで最適化します。そして、それらのステップの一つ一つでデータセット全体をループしたくはないでしょう。
そこで、確率的勾配降下法と呼ばれる新しいタイプの勾配降下法を定義しましょう。データセット全体に対して勾配を計算する代わりに、非常にノイジーな勾配を計算します。これはデータセット内の1つのデータポイントに対してのみ計算された勾配です。データポイントをランダムに選び、データセット全体ではなく、その1つのデータポイントに関して勾配を計算します。これは明らかにはるかにノイジーになりますが、はるかに速く答えを得ることができるので、より多くのステップを進むことができます。
ここにも自然なトレードオフがあります。速く進みたいが、あまりにもノイジーになりたくはありません。明らかに中間の方法があります。1つの例でノイジーな勾配を計算する代わりに、ミニバッチ勾配降下法と呼ばれるものを使用できます。
ミニバッチ勾配降下法では、バッチサイズを設定し、各反復で1つのデータポイントだけではなく、例えば32や128のようなK個のデータポイントに関して勾配を計算します。これらの例えば32のデータポイントに関する勾配を見て、その勾配を平均します。これにより、測定においてより信頼性と堅牢性を得ることができ、同時に速度も得られます。データセット全体には行きません。32は通常、データセット全体よりもはるかに小さいです。
これは何を意味するのでしょうか?これは、確率的勾配降下法と比較して勾配の精度が向上することを意味します。一度に1つのデータポイントを追いかけるような非常にノイジーになることはなく、より滑らかに収束できます。また、データセット全体に対する完全な勾配降下法と比較してはるかに高速になれることも意味します。
これは、一方で私たちがより安定しているため、学習率を上げることもできることを意味します。これら2つのことは非常に密接に関連しています。勾配と学習率の関係は、非常に良い直感を持つべきものです。勾配がより安定しているため(単一のサンプルではなくミニバッチ上で平均しているため)、より大きなステップを踏み始めることができます。最適化の過程で勾配をもっと信頼できるようになります。
また、訓練の並列化も可能になります。32のデータポイントに対して勾配を計算したい場合、GPUの32のプロセスに並列化できます。一度に1つではなく、並列に計算するのです。これにより、GPU高速化をさらに活用できるようになります。
講義2の前に短い休憩を取る前の最後のトピックは、ニューラルネットワークの過学習と正則化についてです。これは深層学習だけでなく、機械学習全体の最も基本的なトピックの一つであり、特に今日のラボで触れることになるので、カバーしたいと思います。
理想的には、機械学習ではトレーニングセットだけでうまく機能するモデルを構築したくありません。モデルをトレーニングセットで訓練しますが、トレーニングセットだけでうまく機能することを望んでいるわけではありません。実は、多くの場合、トレーニングセットでの実際の性能についてはあまり気にしません。それを代用として使用しますが、本当に気にしているのは、モデルが野生に展開されたときの、全く新しいテストデータに対してどれだけうまく機能するかです。
別の言い方をすれば、モデルを構築するときにトレーニングデータから表現を学習したいと思いますが、それでも未見のテストデータにも一般化してほしいのです。
例えばこの画像を見てください。X軸とY軸の間の関係を記述する線を引きたいとします。左側では、非常にシンプルなモデル、線形モデルがあります。トレーニングポイントを記述でき、おそらくテストポイントもある程度の忠実さで記述できますが、トレーニングセットとテストセットの両方でデータセットの豊かさと複雑さを完全に捉えていません。モデルの表現力を十分に活用していません。
右側に移ると、トレーニングサイドのデータポイントを暗記し始めていることがわかります。その結果、まったく新しいテストデータのパフォーマンスを損なっています。トレーニング中に見たものに過度に依存しているからです。
常に望むのは、中間に位置することです。トレーニングポイントを活用したいですが、あまりにも依存したりそれらを暗記したりはしたくありません。
[過学習の問題の実例に関する質問への回答]
過学習の実例としては、非常に小さなデータセットがあるが非常に大きなネットワークがある場合です。データセット内のすべてのデータを単に暗記するモデルを学習することになります。モデルは悪いことをしているわけではありません。トレーニングセットを完全に暗記する能力があるからです。モデルはテストセットを見ることはなく、未知のデータなので、見ることができるのはあなたが与えるトレーニングセットだけです。非常に小さなトレーニングセットと非常に大きなモデルを与えると、モデルは期待通りに動作し、トレーニングセットを完全に学習します。しかし、より多くのテストデータを見せると、それはトレーニングデータに忠実ではなくなります。なぜなら、完全に同じ分布からのものではないからです。
[確率的勾配降下法の「確率的」の意味に関する質問への回答]
確率性は純粋に選択演算子から来ています。確率的勾配降下法を呼ぶ理由は、選択プロセスのためです。データセット全体に対してこれを行うのではなく、データのサブセットを確率的に選択し、その選択は確率的です。確率的選択を取り、その確率的なデータ選択に関して勾配を計算します。勾配は無制限かもしれませんが、それらのデータポイント(何であれ)に関して勾配を計算します。確率性は勾配計算からではなく、選択部分から来ています。
[より適応的なデータ選択方法に関する質問への回答]
本当に確率的にデータを見る代わりに、より適応的な方法があるのかという質問ですが、答えは確かにはいです。実際、純粋に確率的なデータの見方も現実的ではありません。私たち人間はこのように動作しません。ランダムにデータを見るのではなく、時間の経過とともに順次データを見て、意味と目的を持ってデータを見ます。明日の講義では、このタイプの適応的選択プロセスをどのように行うか、そしてその利点の例を見ることになります。
では、正則化について簡単にまとめましょう。正則化は、これらの複雑な暗記プロトコルを抑制する技術です。非常に小さなデータセットと大きなモデルがある場合、モデルがそのデータセットを単に暗記することを抑制したいと思います。どうすればモデルがそのようなことを学ぶのを抑制できるでしょうか?
先に見たように、これはモデルの全体的なパフォーマンスにとって本当に重要です。なぜなら、トレーニング結果は気にせず、最終的にはテスト結果を気にするからです。
最も人気のある正則化技術は実際には非常にシンプルなアイデアで、このコースのほとんどのラボで使用することになります。それはドロップアウトのアイデアです。
ドロップアウトとは何でしょうか?深層ニューラルネットワークの画像を再訪しましょう。ドロップアウトでは、トレーニング中にある確率で隠れニューロンのいくつかの活性化をランダムにゼロに設定します。
例えば、ドロップアウトを50%に設定すると、ニューロンの50%の活性化をドロップアウト(またはゼロに設定)します。これにより、ネットワークはどのニューロンの出力にも過度に依存しないようになります。ニューロンがドロップアウトした後の次の層への入力は、前の入力について多くを暗記することができません。なぜなら、データセットの選択だけでなく、モデルの順伝播自体にもある程度の確率性が導入されているからです。
同じデータを選んで、同じデータを2回モデルに通したとしても、ドロップアウトのために、モデルは同じ正確なデータを2回覚えることさえできません。これは非常に強力なアイデアで、基本的にモデルの容量を下げ、モデルが単一の経路を学習する能力を抑制し、単一の決定をするための複数の経路を学習することを強制しています。そして、毎回の反復でこのプロセスを繰り返し、新しいデータを見るたび、または順伝播を行うたびに、データがモデルを通過するためのランダムな経路を常に作成します。
最後の技術として紹介するのは、早期停止のアイデアについてです。早期停止は基本的に、トレーニング損失とテスト損失の間の偏差をモニタリングすることを意味します。
テスト損失の代用として、保留セットを持つことができます。それは真のテスト損失ではないかもしれませんが、トレーニングしない別の代用です。モデルがトレーニングセットと保留セット(検証セットと呼びましょう)の両方でどれだけうまく機能しているかをモニタリングできます。
始めは、トレーニングするにつれて、これらの線の両方が下がり始めます。これは素晴らしいことで、理にかなっています。モデルが学習しているからです。トレーニングの過程でより強くなっています。
やがて、モデルが損失をプラトーに達させ始め、テストでは増加し始めるのが見られるでしょう。トレーニング精度は、モデルに十分な容量があれば、常に下がり続け、トレーニングセットでより良くなり続けるはずです。しかしある時点で、テスト損失がデータを暗記し始め、トレーニング損失内のデータを暗記し始め、その結果テスト損失が少し上がり始めます。
このパターンはトレーニングの残りの間続き、ここが本当に注目すべき点です。この曲線をプロットした場合、各段階でモデルを保存しますが、この点で起こったモデルのチェックポイントだけを取ります。なぜなら、トレーニング損失がこの点の後でさらに良くなったとしても、トレーニングセットを見ると、より良いモデルがあるように見えますが、テストセットでは実際にトレーニングセットの一部を暗記し始めたことがわかります。だから、右側のモデルは取らず、中間のモデルを取ります。
[早期停止とテストの頻度に関する質問への回答]
トレーニングの各イテレーションでテストを行うのではなく、不必要な計算を避けるために、一般的にはある程度のイテレーション毎に一度テスト実行を行います。例えば、1000イテレーション毎に、テストセットの一部(例えば100データポイント)のバッチでテストを行い、おおよその評価を得ることができます。
[ドロップアウトされたノードの勾配に関する質問への回答]
ドロップアウトされたノードには勾配はありませんが、他のすべてのノードについては更新を得ます。
[早期停止のためのデータ分割に関する質問への回答]
早期停止が機能するためには、データを分割する必要があります。一般的な方法としては、トレーニングデータの70%を実際のトレーニングに使用し、残りの30%をテストと検証に使用します。
[トレーニングデータとテストデータの損失の理想的な差に関する質問への回答]
理想的には差がないことが望ましいですが、実際にはさまざまです。例えば、トレーニングセットが非常に大きく、モデルが全容量を学習することが不可能な場合、トレーニングとテストの差は非常に小さくなります。言語モデリングの例では、巨大な言語モデルでさえ、言語が非常に大きなデータセットであるため、データセット全体を暗記するのに苦労します。そのような場合、トレーニングとテストの曲線は非常に似ています。しかし、そのため他のタイプの検証を行う必要があります。言語モデルには、他の深層学習モデルが持つ古典的な過学習の問題はないですが、他の問題があります。
この講義のまとめとして、次の講義に進む前に3つのポイントをまとめます。
まず、ニューラルネットワークの構築、ニューラルネットワークのアーキテクチャについて話しました。基本的な操作、基本的なアーキテクチャはパーセプトロンと呼ばれる単一のニューロンです。これらの単一ニューロンを積み重ねて複雑な階層的ネットワークを形成し、データを使用してこれらのネットワークを数学的に最適化する方法を学びました。
最後に、バッチ勾配降下法から過学習と正則化、これらのモデルの最適化まで、多くの実用的な意味について取り上げました。
次の講義では、イーバから深層シーケンスモデリングについて聞きます。これは大規模言語モデルのバックボーンであり、非常に興味深い講義になるでしょう。
おそらく5分間の休憩を取って、イーバと私がノートパソコンを交換し、それから講義を続け、その後ソフトウェアラボがあり、リンクでのレセプションと食事があります。
ありがとうございました。


コメント