WEBVTT

00:00.180 --> 00:02.250
こんにちは､ このチュートリアルにようこそ｡ 

00:02.280 --> 00:08.400
今回の特別チュートリアルは､ a3cアルゴリズムに迫るということで､ 超エキサイティングな内容になっています｡ 

00:08.430 --> 00:13.890
これから実装するもの､ それは適格性トレースやソースと呼ばれるものですが､ 実は非同期の能動的批評､

00:14.280 --> 00:19.830
エージェント､ アルゴリズムのアルゴリズムです｡ しかし､ まだエージェントは1つなのでA3

00:19.830 --> 00:24.900
Cとは考えられません｡ それでも､ これから実装するものは実は次の論文から取ったもので､

00:24.900 --> 00:33.690
それは深い強化学習に対する同期的手法としてこの論文であることが分かるでしょう｡

00:33.690 --> 00:40.770
そして､ この講座の最終特典として実装する3つの重要なアルゴリズムが､ この論文に書かれています｡

00:40.770 --> 00:47.760
でも､ 今言ったように､ 今実装するのは実はこのモデル､ 非同期とステップだから､

00:48.210 --> 00:50.850
それに近づいているんです｡

00:50.850 --> 00:51.600
Q学習について｡ 

00:51.600 --> 00:52.620
それです｡ 

00:52.620 --> 00:57.930
ということは､ ほぼそのあとの3つのキーですが､ エージェントが1人ということですね｡ 

00:57.930 --> 01:04.020
そして､ これとステップQの学習で強力なのは､ 以前のような1ステップではなく､

01:04.020 --> 01:09.420
エンドステップで累積報酬と累積目標を学習していくことです｡

01:09.420 --> 01:14.940
そうすることで､ 学習のパフォーマンスが向上し､ AIがより強力になります｡ 

01:15.000 --> 01:18.750
そこで､ 実際にこのアルゴリズムの疑似コードを作ってみました｡ 

01:18.750 --> 01:20.970
それは､ このアルゴリズムです｡ 

01:20.970 --> 01:23.130
では､ クリックしてみましょう｡ 

01:23.130 --> 01:25.680
それが､ これから実装するアルゴリズムです｡ 

01:25.680 --> 01:32.310
しかし､ エージェントが1人しかいない場合､ ここでは､ 現在の状態とプレイした行動のQ値に基づいて､ イプシロン貪欲政策に従って行動a

01:32.310 --> 01:37.950
tを取るという違いがあることを覚えておいてください｡

01:37.950 --> 01:41.820
しかし､ いずれの場合も､ ε-greedyのポリシーは導入していません｡ 

01:41.820 --> 01:45.030
ソフトマックスを実装しましたが､ その他は同じです｡ 

01:45.030 --> 01:50.700
ご覧のように､ エンドステップ､ 実際には10ステップで累積報酬を計算することになりますが､ 覚えておいてください｡

01:50.700 --> 01:52.170
そして､ 段数は10に等しい｡ 

01:52.170 --> 01:57.930
そして､ 今から実装するアルゴリズムに､ このコード行を実装することになります｡ 

01:57.930 --> 02:01.920
これを手に入れ､ ほとんどがこれも実装することになります｡ 

02:01.920 --> 02:07.530
現在の状態と現在のアクションのQ値の最大値を取得することがわかると思います｡ 

02:07.530 --> 02:10.950
そして､ このシータがちょうどターゲットパラメータになります｡ 

02:11.160 --> 02:15.180
では､ こうしましょう､ このアルゴリズムを攻略しましょう｡ 

02:15.180 --> 02:21.420
こちらは非同期とステップの色分けということですが､ エージェントは1つしかないので､ 私たちとしては非同期と言う権利はありませんが､

02:21.420 --> 02:29.220
それゆえNステップQの学習資格､ トレース､ あるいはソースと呼ぶことができます｡

02:30.090 --> 02:31.620
よし､ じゃあやってみようか｡ 

02:31.620 --> 02:32.880
かなり楽しくなりそうです｡ 

02:32.880 --> 02:37.230
私たちは基本的に､ ここにある疑似コードに従えばいいのです｡ 

02:37.230 --> 02:43.980
ご覧のように､ 必要なパラメータはガンマです｡ ガンマパラメータは減衰パラメータです｡

02:43.980 --> 02:50.190
というわけで､ まずはこのガンマパラメータの変数を導入し､ 値を決めていくことにします｡ 

02:50.550 --> 02:51.690
では､ こうしてみましょう｡ 

02:51.690 --> 02:53.910
実はこれを実装するためのクラスは必要ないのです｡ 

02:53.910 --> 02:58.740
この適格性追跡モデルのためにオブジェクトを作成する必要がないため､

02:58.740 --> 03:00.720
単純に関数で実装できます｡

03:00.720 --> 03:06.690
基本的にやりたいことは入力とターゲットを返すことなので､ 関数で十分です｡ 後でAIを学習させるときに､

03:06.690 --> 03:13.170
予測とターゲットの間の距離を最小化する準備ができます｡

03:13.170 --> 03:19.530
そして､ 予測を得るためには入力が必要です｡ なぜなら､ 出力信号を得るために､ 入力に対して脳を働かせるからです｡

03:19.530 --> 03:21.060
それが私たちの予測になります｡ 

03:21.060 --> 03:30.420
そして､ 予測とターゲットが決まったら､ 予測とターゲットの二乗距離を最小化するようにAIを学習させる準備が整います｡

03:30.420 --> 03:32.070
だから､ これをやる意味があるんです｡ 

03:32.070 --> 03:32.610
今すぐ

03:32.610 --> 03:42.600
この関数は､ これらのターゲットでこれらの入力を返すことができるように実装されており､ 二乗距離予測マイナスターゲットを最小化するためのトレーニングの準備ができるようになっています｡

03:42.840 --> 03:44.100
よし､ じゃあやってみようか｡ 

03:44.100 --> 03:46.320
先程も言いましたが､ 機能を実装したいのです｡ 

03:46.320 --> 03:47.430
まずはデフから｡ 

03:47.430 --> 03:52.680
この機能､ ここでは読みやすいアンダースコアのトレースと呼ぶことにします｡ 

03:52.680 --> 03:54.000
また､ ソースと呼ぶこともできます｡ 

03:54.150 --> 03:59.670
呼び方やタイプカラーリングも自由ですが､ ここでは適格性トレースと呼ぶことにしましょう｡ 

03:59.670 --> 04:06.030
この関数は､ バッチを引数として受け取ります｡ 

04:06.060 --> 04:13.320
AIをバッチで学習させるので､ いくつかのインプットとターゲットを得ることになるからです｡

04:13.320 --> 04:17.190
そして､ 入力とターゲットは､ いくつかのバッチの中に入ることになります｡ 

04:17.190 --> 04:24.840
したがって､ この入力引数は､ いくつかの入力と､ それから計算するいくつかのターゲットを含むこのバッチである｡

04:25.260 --> 04:26.670
そうそう､ そうなんです｡ 

04:26.670 --> 04:28.230
それだけが､ 私たちに必要な主張です｡ 

04:28.260 --> 04:31.860
では､ この関数の内部で､ 必要なことを定義してみましょう｡ 

04:32.130 --> 04:37.350
そこで､ 論文の疑似コードで見たように､ ガンマパラメータが必要です｡ 

04:37.350 --> 04:48.150
そこで､ ガンマパラメータを導入することから始めます｡ ガンマは等しいので､ すでに値を決めることができ､ 今回は4を選ぶことにします｡

04:48.150 --> 04:48.150
99.

04:48.180 --> 04:50.370
ガンマの値としては､ 古典的な良い値ですね｡ 

04:50.370 --> 04:54.930
そして､ 心配ないのは､ これが我々のAIにとってお得なものであることを確認したことです｡ 

04:55.500 --> 04:56.970
よし､ じゃあ次のステップだ｡ 

04:56.970 --> 04:59.670
次は､ 入力の準備です｡ 

05:00.740 --> 05:04.950
そして､ 私たちの目標は､ それこそ私たちが返したいものだからです｡ 

05:04.970 --> 05:08.300
インプットとターゲットを返して､ トレーニングを準備したい｡ 

05:08.750 --> 05:12.860
それで､ もう空リストで初期化すればいいんです｡ 

05:12.860 --> 05:18.320
なぜなら､ バッチ内のこれらの入力では､ もちろん､ いくつかの入力をすべてリストにするつもりだからです｡

05:18.320 --> 05:23.660
そのため､ ターゲットだけでなく､ 入力もリストとして初期化しているんだ｡ 

05:24.080 --> 05:24.830
これでよしとしよう｡ 

05:24.830 --> 05:27.320
そこで､ ターゲットで入力を初期化しました｡ 

05:27.320 --> 05:31.430
そして最後には､ この適格性追跡機能が戻ってきます｡ 

05:31.430 --> 05:32.240
その通りです｡ 

05:32.240 --> 05:35.480
これらのインプットとターゲットは､ もちろん記入された｡ 

05:36.110 --> 05:41.360
関数が返すものには､ いくつかの入力と､ それに関連するいくつかのターゲットがあります｡ 

05:42.140 --> 05:42.470
わかりました｡ 

05:42.470 --> 05:43.130
次のステップへ

05:43.130 --> 05:45.650
次は､ forループの格納です｡ 

05:45.650 --> 05:51.320
それはまさに､ 論文の疑似コード､ この一連のコードに従っているからです｡ 

05:51.320 --> 05:57.290
そして､ ご覧のように､ このリピートコードの部分があり､ それを正確にフルループで繰り返すのです｡ 

05:57.440 --> 06:03.710
そこで､ このコードでは､ 10回のステップの累積報酬を計算することにします｡ 

06:03.710 --> 06:05.090
また､ どのように計算されているのでしょうか？

06:05.090 --> 06:07.880
まあ､ 各ステップにおいて､ それは最後のステップではないのですが｡ 

06:07.880 --> 06:12.980
この､ ステップ実行中にいる現在の状態のQ値の最大値を取得するんです｡ 

06:12.980 --> 06:17.720
そして､ 10段階のうち最後のセットまで到達すれば､ まあ､ これはゼロに等しくなるわけです｡ 

06:17.720 --> 06:19.490
つまり､ もう更新したくないのです｡ 

06:19.820 --> 06:23.210
そして､ このforループは､ もう一つのforループになります｡ 

06:23.210 --> 06:25.490
ここではリピートとは言いませんが､ それと同じです｡ 

06:25.490 --> 06:28.310
これは､ アルゴリズムの2番目のforループになります｡ 

06:28.310 --> 06:35.480
さて､ このように報酬を更新するには､ 減衰パラメータγを掛けて報酬を加算することになります｡

06:35.720 --> 06:36.830
では､ こうしてみましょう｡ 

06:36.830 --> 06:40.250
Pythonに戻り､ forループを開始しましょう｡ 

06:40.490 --> 06:44.840
では､ 4つ､ そして反復変数には何が入るのでしょうか？

06:44.840 --> 06:50.180
さて､ これが私たちの10ステップシリーズ､ 10の変遷のシリーズになります｡ 

06:50.180 --> 06:58.610
そこで､ 10回の遷移の連続のようなものを表すこの変数を系列と呼ぶことにします｡

06:58.610 --> 07:00.830
それで4シリーズ｡ 

07:00.920 --> 07:02.330
それから､ どうでしょう？

07:02.330 --> 07:07.970
さて､ 私たちのシリーズは､ 私たちのバッチ､ つまり､ AIを訓練するバッチに属します｡ 

07:08.000 --> 07:14.390
そして､ series in batchは､ 入力バッチに含まれる10個のトランジションのすべてのシリーズを対象としています｡ 

07:14.570 --> 07:16.460
さて......どうするかな｡ 

07:16.940 --> 07:21.890
さて､ 累積報酬を得るためには､ 一連の遷移の最初の遷移の状態と､ 最後の遷移の状態が必要であることは､

07:21.890 --> 07:26.480
疑似コードでおわかりでしょう｡

07:26.480 --> 07:29.840
だから､ 今やらなければならないのは､ これらの入力状態を把握することです｡ 

07:29.840 --> 07:36.590
そして､ この2つの入力状態をinputと呼ぶ変数に入れ､ この2つの入力状態､

07:36.590 --> 07:45.260
シリーズの最初のものと最後のものを取得し､ 非生物的な配列に入れることになります｡

07:45.590 --> 07:48.310
しかし､ 心配はご無用｡ この数字の配列に留まることはない｡ 

07:48.320 --> 07:50.900
もちろん､ それを総量変数に変換します｡ 

07:50.900 --> 07:56.660
しかし､ 最初のステップは､ これらを入力状態にすることで､ 最後の1つの配列に最初の1つを入れます｡ 

07:57.050 --> 08:03.260
そして､ このnumpy配列のここに､ 最初の入力､ つまり系列の最初の遷移の入力状態を追加し､

08:03.260 --> 08:06.380
それがseriesとなるわけです｡

08:07.780 --> 08:11.340
そして､ 最初の遷移を取るために､ 系列のインデックス・ゼロを取るのです｡ 

08:11.350 --> 08:12.820
それが最初の移行です｡ 

08:13.090 --> 08:17.830
そして､ その属性であるstateを取ることでアクセスすることができる｡ 

08:18.040 --> 08:24.220
これは､ 経験リプレイファイルの中で､ 各遷移に対して特別な構造を定義しているからです｡

08:24.220 --> 08:29.350
その構造は､ 各遷移が､ 状態､ 行動､ 報酬で構成されています｡

08:29.350 --> 08:31.840
しかし､ その後に行われる最後の要素｡ 

08:31.840 --> 08:38.830
この特殊な構造は､ エクスペリエンス・リプレイにおけるトランジションの定義に由来しています｡

08:39.160 --> 08:39.490
わかりました｡ 

08:39.490 --> 08:48.490
これで､ 最初のトランジションの入力状態が得られたので､ 今度はシリーズの最後のトランジションの入力状態も得てみましょう｡

08:48.490 --> 08:49.930
そして､ それを実行すること､ それは同じことです｡ 

08:49.930 --> 08:51.910
これをコピーすればいいんです｡ 

08:53.320 --> 09:00.310
これをベースに､ ゼロを直列の最後のインデックスで置き換えると､ 直列の最後の遷移の入力状態を得ることができる､

09:00.310 --> 09:07.420
マイナス1直列､ マイナス1というトリックでアクセスできます｡

09:08.140 --> 09:14.410
それでは､ この2つの要素を角括弧の中に入れてみましょう｡ 

09:15.130 --> 09:18.310
それがアンパイヤ機能で期待されているからです｡ 

09:18.700 --> 09:26.020
そして､ それをトーチテンソルとトーチ変数に変換するのですから､ 重要なことがあるのです｡

09:26.020 --> 09:31.680
さて､ トーチテンソルは定義上､ 1つの単一型を含む特殊な配列であることを思い出してください｡ 

09:31.690 --> 09:34.510
だから､ 無理やり一つの型を持たせる必要があるんです｡ 

09:34.510 --> 09:37.540
そして､ いつものようにfloat型を選択します｡ 

09:37.540 --> 09:52.300
そして､ ここにD型のequalsとP型のfloat32というパラメータを追加して､ これをトーチテンソルとトーチ変数に変換できるようにしました｡

09:52.300 --> 09:57.340
では､ これをうまくやるために､ まず､ トーチセンサーに変換してみましょう｡ 

09:57.340 --> 10:02.590
そして､ NumPyからtorchが使えることを忘れないでください｡ 

10:03.700 --> 10:12.220
次に､ 2つの入力状態のすべての配列をこのトーチテンソルの中に入れ､ 関数によってそれらからトーチを得るようにします｡

10:12.340 --> 10:13.120
完璧です｡ 

10:13.120 --> 10:18.060
つまり､ この配列の入力状態をトーチセンサーに変換することになります｡ 

10:18.070 --> 10:24.250
そして､ 今度はこのトーチテンソルを変数クラスを使ってトーチ変数に入れる｡ 

10:25.350 --> 10:28.220
つまり､ inputは変数クラスのオブジェクトになります｡ 

10:28.230 --> 10:35.970
そして実際､ あなたが理解したように､ この変数クラスはこれらすべてを引数として受け取り､ それがオブジェクトを作成するのです｡

10:36.510 --> 10:38.270
よし､ これで大丈夫だろう｡ 

10:38.280 --> 10:40.770
必要なのは2つの入力です｡ 

10:40.770 --> 10:45.120
つまり､ 最初の遷移の入力状態と最後の遷移の入力状態です｡ 

10:45.580 --> 10:48.840
そして今､ 私たちはインプットを得たわけですが､ さて､ 何が得られるのでしょうか？

10:48.870 --> 10:52.440
目の脳の出力信号を得ることができる｡ 

10:52.470 --> 10:53.790
それが予測です｡ 

10:53.790 --> 10:55.710
しかし､ 私たちはそれを出力と呼ぶことにしています｡ 

10:56.520 --> 10:59.120
それが出力信号であり､ 出力を得るためです｡ 

10:59.130 --> 11:05.280
というのも､ 私たちはすでに畳み込みニューラルネットワークという脳を作り上げているからです｡

11:05.280 --> 11:16.590
そして､ 脳スキャンを入力に適用すると､ 予測値が出力されるという単純なものです｡

11:16.590 --> 11:19.500
そして今､ 私たちはすでに次のステップに進む準備ができています｡ 

11:20.510 --> 11:24.810
そして次は､ この累積報酬の計算を開始する｡ 

11:24.830 --> 11:31.040
では､ SE2のアルゴリズムと全く同じように､ ソースと呼ぶべきか､ ステップと呼ぶべきかを考えてみます｡

11:31.040 --> 11:31.820
Q学習について｡ 

11:32.000 --> 11:38.670
今回は､ 累積報酬の変数を紹介します｡ 

11:38.690 --> 11:41.000
そして､ 紙面に戻ろう｡ 

11:41.030 --> 11:45.860
今お見せしたように､ この累積報酬を得るためにしなければならないこと､ それは私たちのここなのです｡ 

11:45.860 --> 11:53.640
さて､ 10ステップの実行の各ステップで､ この累積報酬にゼロを加えて更新する必要があります｡

11:53.660 --> 12:00.020
シリーズの最後の日付に達したか､ Q値の最大値に達したか､ シリーズの最後の状態に達していなければ､ 最後のステップを除いたすべてのステップについて､

12:00.020 --> 12:03.290
です｡

12:03.530 --> 12:05.720
では､ これをシンプルに実装してみましょう｡ 

12:05.910 --> 12:07.130
Pythonに戻ろう｡ 

12:07.370 --> 12:13.580
つまり､ この累積報酬は､ 先ほど見たように､ 0に等しくなるわけです｡  0.

12:13.970 --> 12:14.660
もしや｡ 

12:15.020 --> 12:18.920
最終日を迎え､ このコンディションをこのように乗りこなすことができるのです｡ 

12:19.250 --> 12:28.460
インデックスから1を引いたシリーズが最後の送信であれば､ doneを追加します｡ doneは､

12:28.460 --> 12:35.510
経験済みリプレイファイルを定義したこの遷移構造の属性だからです｡

12:35.510 --> 12:42.140
これはオープンエアーの構造からきているもので､ オープンジムのウェブサイトを見ると､ 実はここにあるのですが､

12:42.320 --> 12:44.990
私が用意したものです｡

12:44.990 --> 12:47.050
つまり､ ゼロの平方根ですね｡ 

12:47.060 --> 12:53.090
そして､ もし私たちがドキュメントに行き､ そしてもし私たちがそうなら､ それはチュートリアルです｡ 

12:53.090 --> 12:55.070
ぜひ一度､ ご覧になってみてください｡ 

12:55.190 --> 13:01.730
環境を走らせることもできますが､ たいていの場合､ 我々の観測､ つまり我々のトランジションは､

13:01.730 --> 13:05.390
観測､ 報酬によって定義されていることがわかります｡

13:05.390 --> 13:11.780
そして､ ここが終わった､ ここが終わったというのは､ まさに移行やステップが終わったということです｡ 

13:11.840 --> 13:15.380
そして､ ここで行われたものをifの条件として使用します｡ 

13:15.380 --> 13:23.120
したがって､ シリーズマイナス1ドット完了とは､ シリーズの最後の遷移が終われば､ 完了ということになる｡ 

13:23.540 --> 13:32.810
そして､ この累積報酬は､ シリーズの最後の遷移が終わった場合は0になり､ そうでない場合は最後の遷移に到達していないことになるのです｡

13:32.810 --> 13:40.910
さて､ 累積報酬は､ 先ほど言ったように､ Q値の最大値で更新されることになります｡ 

13:40.910 --> 13:47.330
そして､ ここの出力が脳の出力なので､ それがニューラルネットワークの予測になるのです｡ 

13:47.330 --> 13:51.350
そして､ ご存知の通り､ ニューラルネットワークの予測値は､ キューの予測値です｡ 

13:51.350 --> 13:54.830
さて､ この出力にはQ値が含まれています｡ 

13:54.830 --> 14:01.100
そして､ Q値の最大値を取る必要があるので､ まあ､ 構造体はインデックス1にQ値を含むので､

14:01.110 --> 14:09.320
まずこのインデックスを追加し､ 次に､ この出力構造体のデータにアクセスするためのデータを追加する必要があります｡

14:09.320 --> 14:11.930
トーチ変数という特殊な構造を持っているんですよね｡ 

14:12.020 --> 14:16.940
これでQ値が求まり､ Q値の最大値を取りたい｡ 

14:16.940 --> 14:29.990
そうすると､ 論文にあるように､ 非終端状態のQ値の最大値をTパーフェクトとして得ることができるのです｡

14:29.990 --> 14:36.020
そして､ これから行うのは､ この10ステップのシリーズに対応する2番目のforループを作ることです｡ 

14:36.020 --> 14:43.340
この方法で累積報酬を更新するつもりです｡ まず､ すでに持っている減衰パラメータのガンマを掛け､

14:43.340 --> 14:46.130
それから報酬を加えます｡

14:46.130 --> 14:47.360
では､ こうしてみましょう｡ 

14:47.360 --> 14:50.840
実際には､ 疑似コードと全く同じことをするつもりです｡ 

14:50.840 --> 14:56.510
お気づきのように､ 右から始まっているので､ 最初のステップから始まって､ 最後のステップまで行っているわけではありません｡

14:56.510 --> 15:02.150
最後のステップから始めて､ 最初のステップまでtマイナス1してスタートする｡ 

15:02.150 --> 15:06.110
それは､ 最終的に､ 累積報酬は､ Rゼロ＋ガンマr1＋ガンマの2乗､

15:06.110 --> 15:24.980
または2＋ドット点＋ガンマの10乗に等しく､ ここで､ 1､ 2､ 10はシリーズの各終了ステップで得られる報酬です｡

15:25.370 --> 15:29.810
では､ 2つ目のループを撮る前にちょっと休憩して､ 次のチュートリアルでお会いしましょう｡ 

15:29.810 --> 15:31.070
それまではお楽しみに｡ 

15:31.070 --> 15:31.610
I.
