こんにちは､ そして私たちの創作活動の超エキサイティングな部分､ 私たちがそれをスマートにする部分へようこそ｡
それこそ､ AIを訓練することで知能が鍛えられ､ 達成させたい目標に到達できるようになるわけですね｡
そのためには､ 基本的にニューラルネットワークを訓練して正しい予測を出力するようにします｡ そして､
脳からのこれらの出力信号がすでに身体に正しく伝達され､ 最終的なアクションを演じることができるので､
すべてがすでに準備万端です｡
だから､ 基本的にこれからやろうとしていることは､ 以前からやっていたことなんです｡
メモリからランダムなバッチを取り出し､ これらのサンプルから入力を得て､ 出力を得て､
ターゲットを得て､ 予測を得て､ 予測とターゲットの間の最後の領域を計算し､ そして､
この最後の誤差にどれだけ貢献したかによって重みを更新するために確率的勾配降下法で後方伝搬を実行するだけでいいのです｡
だから､ これを全部やりましょう｡
これを実装するためのツールはすでに揃っているので､ とても簡単だということがおわかりいただけると思います｡
オプティマイザーやロストファンクションなどのPyTorchツールだけでなく､ 以前に作ったすべてのクラス､
たとえばもちろんブレインも､ 予測を得るために使うことになります｡
そして､ 私たちの経験､ 再生､ 実装､ 適格性追跡､ これらすべてのツールをPyTorchのツールに組み合わせることで､
学習が超高性能になり､ その結果､ 最終的に超強力なAIを手にすることができるのです｡
だから､ このトレーニングを実現させましょう｡
AIを賢くしよう｡
そしてこれから行うのは､ トレーニング中に誤差を計算するときに使う最後の関数と､
オプティマイザを取得すること､ これが最初に行うことです｡
では､ 最後の関数の変数を作ってみましょう｡
それを損失と呼ぶことにする｡
そして､ これはRNモジュールからのMSI損失関数と等しくなる｡
そして､ MSIロスは､ 基本的に予測はQ値なので､ 最後に使う関数です｡
さまざまなアクションのQ値を予測しているのです｡
したがって､ これらは実数なので､ まあ､ 回帰のためのニューラルネットワークをやっているようなもので､
したがって､ 最後の関数は平均二乗誤差です｡
これが一般的な回帰に使う最後の関数です｡
わかりました｡
さて､ 最後の関数ができたので､ オプティマイザーを手に入れましょう｡
このoptimizerは､ optimizerのために作成した変数です｡
そして､ いつも通りの撮影をする｡
自動運転車に関しては､ アトムオプティマイザーという非常に強力なオプティマイザーがあり､ トレーニングに大きな効果を発揮してくれることでしょう｡
だから､ これをその原子まで持っていこう｡
そして､ それはまさに自動運転車のためであることを忘れないでください｡
2つの本質的な議論をインプットする必要があるのです｡
オプティマイザーとニューラルネットワークのパラメータ､ つまり脳のニューロンの重みの間の接続を行うものです｡
そして､ そのために､ CNNと呼ばれる私たちの脳を取り上げるのです｡
それが､ 私たちが作った脳のオブジェです｡
それで､ CNNはパラメーターを覚えていない｡
これでよしとしよう｡
そして､ いくつかの括弧｡
つまり､ オプティマイザーとAIの脳内ニューロンの重みを結びつけているわけです｡
そして､ 第二引数は学習率で､ これは誤差で与えられる｡
というのも､ あまり早く収束させたくなく､ ある程度の探索をしたいからです｡
01が1％開いていること｡
それは自動運転車に使ったものと同じだと思います｡
それでは､ 最後の関数､ オプティマイザーを紹介します｡
というわけで､ フルループの開始まであと少しです｡
さて､ 実は今すぐ全ループを開始します｡
でも､ その直前にエポック数の大きさを決めるんです｡
AIを学習させるので､ このエポック数に対応する新しい変数をここに作成します｡
そして､ それを100と等しく設定しましょう｡
それは､ 目を鍛えるには十分な方法でしょう｡
そして､ AIは100歳よりずっと前､ たとえば20歳とか30歳とかでベストな状態になることに賭ける｡
見てみよう｡
でも､ とりあえず100点取ろう｡
そして､ 必要であれば､ 増やしていく｡
しかし､ その必要はないだろうと思います｡
なるほど｡
エポック数が決まったので､ エポック数分の学習を行う際に､ このforループをメインループにすることができます｡
そのため､ 繰り返される変数はエポックとなります｡
それが､ エポック・インを選ぶということです｡
もちろん､ 最初のエポック1からエポック数まで､ レンジ関数で指定します｡
プラス1､ 範囲の上限は含まれないと覚えておいてください｡
したがって､ 100まで行こうと思ったら､ まあ､ 指定してボックスプラス1でないと､ 100まで行けないわけです｡
では､ コリンさん｡
そして､ 今度はループの中に入ってみましょう｡
わかりました｡
そこでまず､ 10ステップを200回実行します｡
そのため､ 各エポックは10ステップを次々に200回実行することになる｡
そのために､ 経験豊富なリプレイ・クラスのこの実行ステップ関数があるのです｡
したがって､ この関数を使用するには､ 実際にはメソッドであるメモリ・オブジェクトから取得します｡
メモリ・オブジェクトはリプレイ・メモリ・クラスのオブジェクトで､ 10ステップの200回の実行を生成するには､ メモリ・オブジェクトを取得する必要があります｡
それは､ 私たちがここで作ったものだと思い知らされます｡
Memory は､ MN ステップが 10 ステップで､ 容量が 10,000 のリプレイメモリクラスのオブジェクトである｡
このオブジェクトを作り､ このオブジェクトから､ よく､ このラン､ ステップ､ 関数､ ランのステップを取り､ 10ステップの連続したランを200回指定するのです｡
そのため､ 各エポックでは基本的に200ステップを実行することになります｡
そして､ 各エポックで200ステップを実行したところで､ これらの実行からいくつかのバッチをサンプリングする時が来ました｡
そして､ これらのバッチを試食すること｡
もうひとつ､ サンプルバッチという関数がありますが､ これは200回分の実行からいくつかのバッチを正確に生成します｡
しかし､ これらのバッチは､ 一連の遷移のこれらの時間のバッチであることを忘れないでください｡
以前は､ ここで1回の遷移を何回かに分けてバッチしていたのですが､ それが10回になったということです｡
今回は､ 10ステップ､ 10トランジションのバッチを作成することになります｡
また､ バッチサイズについては､ 32､ あるいは64､ あるいは128を取ることができます｡
バッチサイズの場合は､ 一般的に使われているものと覚えておいてください｡
これは､ ニューラルネットワークのアーキテクチャにおいて､ バッチ学習を行う際に一般的に見られることです｡
しかし､ 今回はまったく違います｡
10ステップのいくつかのバッチをサンプリングしているだけなので､ もっと大きなサイズでバッチを取った方が良いですね｡
だから､ 64や128を取ることができるわけです｡
だから､ 128を取る｡
なぜなら､ いくつかのバッチを取得し､ このサンプルバッチ関数によって返されるものを取得するからです｡
つまり､ このforループは､ 128ステップごとに､ メモリがサイズ128のバッチを生成し､
そのバッチには､ 直前に実行された128ステップが含まれることになります｡
ちょうどサイズ128のバッチがいくつか出てきていて､ これらのバッチで学習が行われることになります｡
さらに､ このバッチ内では､ 10ステップごとに学習するために､ 適格性､ トレースランニングを行うことになります｡
わかりました｡
このループの中では､ 1つのエポックではまだ起こっていますが､ 今回は特定のバッチで起こっています｡
そこで､ まず最初にインプットとターゲットを別々に用意することにしました｡
そして､ そのことは､ 先ほどもお話したように､ とても簡単なことです｡
私たちが実装したツールの1つであるEligibility traceを使えば可能です｡
このように､ この eligibility trace 関数はバッチを入力として受け取り､ 今度はバッチを出力として､
入力とターゲットを返します｡
そこで､ 今すぐできることは､ 入力とターゲットとなる2つの新しい変数を作成し､
この入力がターゲットに来るようにすることです｡
イコールです｡
この適格性追跡関数がバッチに適用される戻り値を正確に示します｡
そこで､ この関数をループのバッチに適用することにします｡
それで､ どうするかというと､ 資格だけです｡
ループのバッチに適用されるトレース｡
さて､ これで入力と目標ができました｡
でも､ PyTorchでは､ いつも何かやらなければならないことがあるんです｡
そしてもちろん､ これはニューラルネットワークの入力､ またターゲットをいくつかの拷問変数に変換することであるが､
リリースはない｡
新しいことは何もありません｡
私たちはその方法を知っています｡
こうすればいいんです｡
インプット､ そしてターゲット､ まあ､ 可変インプットと同じになるわけです｡
それはインプットと変動するターゲットに対してであり､ ターゲットに対してです｡
わかりました｡
つまり､ 脳の入力はトーチ変数に変換され､ ターゲットもトーチ変数に変換されるのです｡
これで､ ニューラルネットワークに入力ができるようになったわけです｡
そして､ なぜこのようなことをする必要があるのでしょうか｡
それは､ 次のステップとして､ 我々が持っている予測､ 目標とする入力を得るためです｡
もちろん､ 予測値は必要です｡ なぜなら､ 予測値と目標値の間の損失を計算することになるからです｡
では､ この予測をもとに入手しましょう｡
さて､ 改めて考えてみると､ これはとてもシンプルなことですね｡
あとは私たちの頭脳であるCNN､ つまり畳み込みニューラルネットワークを､
入力に適用するだけだ｡
これでよしとしよう｡
入力はニューラルネットワークに入り､ ニューラルネットワークは予測を出力する｡
完璧です｡
だから､ 今は予測ができて､ 目標があるから､ 損失を出すことができるんだ｡
そして､ それが次のステップになるのです｡
今は最後のエラーを取得するためにlast関数を使っているので､ last関数とは異なるので､
新しい変数を導入することにします｡
このため､ 誤差が少なく､ 最後の関数を予測に適用して得ることができます｡
そして､ そのターゲット｡
これでよしとしよう｡
すべてがスムーズになった様子をご覧ください｡
すべてがロジカルです｡
まずターゲットをインプットします｡
そして､ その入力のおかげで､ 予測ができる｡
そして､ 予測とターゲットのおかげで､ 誤差を少なくすることができるのです｡
だから､ とてもロジカルでスムーズなのです｡
そして､ 次はどうするのか｡
まあ､ 同じ論理の道筋です｡
これで最後に戻ることができ､ この少ない誤差をニューラルネットワークに伝搬して重みを更新します｡
確率的勾配降下を行うには､ オプティマイザーが必要です｡ しかし､
アトムオプティマイザーはすでにここにあります｡
しかし､ 今この時点で､ 私たちが何をしなければならないかを思い出してください｡
それを初期化するために､ 初期化をしなければならない｡
オプティマイザーオブジェクトを取得し､ ゼログリッド法を適用していることを思い出してください｡
では､ 行ってみましょう｡
それを初期化する括弧を忘れない｡
そして､ 次のステップは､ 最後のエラーをニューラルネットワークに逆伝播することです｡
そのために､ 前回のエラーを取り込んで､ バックワード・メソッドを適用するのです｡
まさに逆伝播を応用しているわけですね｡
そして最後に､ 最後のエラーが新しいネットワークに逆伝播されたので､ 確率的勾配降下法を用いて重みを更新することができるのです｡
そのために､ オプティマイザーを使って､ このステップメソッドを適用するのです｡
これでよしとしよう｡
ウェイトが更新されました｡
先ほどお話したように､ すでにやっただけでなく､ 今ではとてもシンプルで自然なことのように思えます｡
だから､ 今度は楽しいことをしよう｡
エポックごとに平均報酬を表示し､ AIがどうなっているか､ トレーニングがどうなっているかを追跡できるようにします｡
エポックの段階を経て､ 平均報酬が増加していく様子を見たい｡
そして､ 最初はもちろん､ この探索の段階があります｡
ですから､ 最初のうちは平均報酬が増えないかもしれませんが､ その後､
搾取の段階になると､ 確実に平均報酬が増え､ あるレベルまで増えて､ 最速でベストに到達することになるのです｡
では､ まずプリントから｡
1つのエポックでこれをやっているので､ ここでループに戻る必要があります｡
そして､ 最初のエポックとカラム､ そしてパーセントSEを表示します｡
そして､ 平均報酬を加算していきます｡
そして､ パーセンテージも加えていきます｡
そして､ 引用を終了します｡
そして､ パーセントを追加する｡
そして反対側には､ EPCに相当する1人目の変数と､ これから計算する平均報酬に相当する2人目の変数を入力します｡
つまり､ 平均報酬という変数はまだ存在しないのです｡
今すぐにでも作りたい｡
そこで､ STRエポックを使用することにします｡
epochが数値であっても､ それを文字列に変換する｡
その方がいいし｡
平均的な報酬となりうる星を追加する予定です｡
そして､ VGリワードと呼ぶ変数を作成します｡ これからこの変数を作成し､
計算を行います｡
では､ こうしてみましょう｡
それしか残っていなかったんです｡
だから､ 私たちはすでにエポックを持っているのです｡
では､ 平均報酬を計算しましょう｡ ここで､ 計算する必要があります｡
まだループ内ですが､ バッチループからは外れています｡ バッチがサンプリングされ､ バッチ内でトレーニングが行われているからです｡
しかし､ 今は前方伝搬＋後方伝搬が一括で行われている｡
エポックループに戻り､ 累積報酬を計算することができるようになりました｡
ステップの実行中に､ ステップで起きている累積的な報酬を得ることができるように､ ステップを実行します｡
そこで､ 今それを使ってステップの新しい報酬を更新し､ 累積報酬を移動平均オブジェクトに追加して平均を再計算することで､
移動平均オブジェクトを更新することにします｡
そうして平均的な報酬を得ることになるのです｡
では､ こうしてみましょう｡
まず必要なのは､ 更新される報酬です｡
だから､ リワードと呼ぼう｡
ステップス
そして､ 先ほど言ったように､ PNのステップを踏むのです｡
ここで作成されたリマインダであるオブジェクトは､ 経験リプレイファイルからPNステッププログレスクラスのオブジェクトなので､
PNステップオブジェクトです｡
そして､ リワードのステップを追加し､ さらに括弧をつける｡
さて､ これで新しいステップの累積報酬が得られます｡
さて､ ではこれらの新しい累積報酬を移動平均オブジェクトに追加する必要があります｡
そして､ これを行うために､ 今回は移動平均クラスで､ このADDというメソッドを用意しました｡
だから､ とてもシンプルなんです｡
移動平均オブジェクトを100ステップで作成し､ ADDメソッドを使用します｡
ADDメソッドでは報酬ステップを入力し､ これによりステップの報酬が移動平均に追加されます｡
わかりました｡
そして最後に､ 平均報酬を計算するのですが､ これはまあ､ ここでも同じ変数ですね｡
それが平均的な報酬と同じになるわけです｡
そして､ それを得るためには､ 今回､ 移動平均オブジェクトから平均メソッドを使用すればいいのです｡
移動平均はADDメソッドによって追加された新しい報酬ステップですでに更新されているので､ このようにドット平均を行うのです｡
素晴らしい｡
それでは､ 平均的な報酬をここに入力します｡
そして､ これはエポックごとに印刷されることになる｡
わかりました｡
だから､ もういいんです｡
だから､ 結果が出るのがとても楽しみなんです｡
そして実は､ 次のチュートリアルで結果を見ながら､ サプライズを用意する予定なんです｡
だから､ かなりエキサイティングなことになりそうです｡
それで､ 今はAIと遊んで楽しむ時期なんでしょうね｡
では､ おいしいコーヒーか紅茶を用意してください｡
それでは､ 椅子にゆったりと腰掛け､ AIが「Doom」をプレイしているとてもクールな映像をご覧ください｡
では､ 次のチュートリアルでそれをやってみましょう｡
そしてそれまで､ お楽しみに｡
I.