WEBVTT

00:00.270 --> 00:02.910
こんにちは､ このPythonチュートリアルへようこそ｡ 

00:02.940 --> 00:09.120
さて､ 前節で eligibility trace を使ったおかげで､ 出力とターゲット間の二乗距離を最小化するようにネットワークを訓練する準備ができました｡

00:09.120 --> 00:28.260
基本的には､ 入力､ ターゲット､ 予測を得て､ 予測とターゲットの間の最後の誤差を計算し､ 確率的勾配降下を用いた後方伝搬で重みを更新して､ 全体の訓練を始める準備ができたわけです｡

00:28.260 --> 00:35.220
しかし､ 100ステップの移動平均を計算したいので､ トレーニング中の平均を記録するために､

00:35.220 --> 00:47.250
このトレーニング全体を行う前に､ 100ステップの移動平均を取得するクラスを作ります｡

00:47.250 --> 00:48.180
だから心配ない｡ 

00:48.180 --> 00:49.350
早くやります｡ 

00:49.350 --> 00:53.580
3つの関数を持つクラスを作りますが､ このチュートリアル1回で全て行います｡ 

00:53.580 --> 00:54.810
だから､ 早くやります｡ 

00:54.810 --> 00:55.770
もう､ やりましたよ｡ 

00:55.770 --> 01:00.630
それに､ 今はトレーニングに集中したいのです｡ それが一番大切ですから｡ 

01:00.630 --> 01:03.990
では､ このクラスを今すぐこのチュートリアル1回で作ってみましょう｡ 

01:04.350 --> 01:04.740
わかりました｡ 

01:04.740 --> 01:10.800
そこで､ 新しいクラス､ 4移動平均と呼ぶことにします｡ 

01:10.950 --> 01:13.230
そして､ 最初の関数を紹介します｡ 

01:13.230 --> 01:18.720
それはもちろん､ その中で変わることのないinit関数なんですね｡ 

01:18.720 --> 01:21.900
そして､ このinit関数は2つの引数を取ることになる｡ 

01:21.900 --> 01:34.440
最初のものは､ 移動平均の未来オブジェクトとサイズのための自己であり､ これは平均を計算することになる報酬のリストのサイズに対応することになります｡

01:34.440 --> 01:36.240
これが100になるわけです｡ 

01:36.720 --> 01:37.080
わかりました｡ 

01:37.080 --> 01:41.880
init関数の引数ができたので､ 次はその関数の中に入ってみましょう｡ 

01:41.890 --> 01:43.050
これで､ 何をすればいいのかがわかったと思います｡ 

01:43.080 --> 01:47.220
オブジェクトに固有の変数を初期化する必要があります｡ 

01:47.220 --> 01:54.120
そして､ これらはまあ最初に､ 報酬のリストになるわけです｡ 

01:54.120 --> 01:59.130
つまり､ これが平均を計算する100の報酬を含むリストになります｡ 

01:59.130 --> 02:05.220
ここでは､ 単にこのリストを空のリストで初期化しているだけです｡ 

02:05.640 --> 02:06.720
だから､ 報酬のリスト｡ 

02:06.720 --> 02:14.040
そして､ 未来のオブジェクトの2番目の変数は､ もちろん､

02:14.040 --> 02:21.000
サイズになります｡ サイズは､ 未来の移動平均オブジェクトを作成するときに入力する引数と同じになりますから､

02:21.000 --> 02:32.100
ここにサイズがあります｡

02:32.100 --> 02:35.430
気をつけることは､ 単純な報酬ではなく､ 積み重ねの報酬です｡ 

02:35.430 --> 02:40.560
それはですね､ 適格トレースをしているので､ 10ステップごとに学習するため､ 単純な報酬ではなく､

02:40.560 --> 02:44.430
累積的な報酬で学習しているからです｡

02:44.430 --> 02:52.440
つまり､ これから作るこのadd関数は､ 累積報酬を報酬のリストに追加するのです｡ 

02:52.590 --> 02:59.220
で､ defは､ もちろんADDと呼ぶことにして､ このADD関数は2つの引数を取ることにしています｡ 

02:59.220 --> 03:08.250
最初のものは自己です｡ なぜなら､ ここでこの報酬のリストを使うのは､ 単純にこの報酬のリストに累積報酬を追加するためです｡

03:08.250 --> 03:11.550
だから､ このソの自己が必要なんです｡ 

03:11.550 --> 03:17.760
そして2つ目が報酬で､ これは累積報酬を表します｡ 

03:18.420 --> 03:18.810
わかりました｡ 

03:18.810 --> 03:21.620
これがADD関数の2つの引数です｡ 

03:21.750 --> 03:25.230
では､ この関数の内部で､ 何をしなければならないかを定義してみましょう｡ 

03:25.590 --> 03:25.850
なるほど｡ 

03:25.890 --> 03:32.190
非常に単純なことですが､ まず､ 累積的な報酬､ 新しい報酬を得るたびに､ つまり､ 新しい10ステップを進めたときに､

03:32.190 --> 03:39.060
この累積的な報酬をリストに追加しなければならないのです｡

03:39.060 --> 03:40.410
そして､ それこそが私たちの目指すところです｡ 

03:40.410 --> 03:48.840
これから､ 10ステップ進んだ後に得られる新しい累積報酬を､ この報酬リストに追加するコード行を書きます｡

03:49.050 --> 03:55.920
なぜなら､ バッチを扱うので､ 報酬はリストになることもありますが､ 他のケースでは､

03:55.920 --> 04:02.040
報酬は単一の要素になることもあるからです｡

04:02.040 --> 04:09.480
また､ リストに要素を追加する構文､ つまりここでの報酬のリストは､ リストを追加するのか､ 単一の要素を追加するのか､

04:09.480 --> 04:13.080
同じではありません｡

04:13.080 --> 04:16.860
だから､ この2つのケースを分けるための条件を作ればいいんです｡ 

04:16.860 --> 04:23.430
そして､ まず最初のケース､ つまり､ この報酬のリストに追加するものがリストの場合について説明します｡

04:23.430 --> 04:29.700
そして､ そのために､ isインスタンスを追加し､ 括弧の中に2つの引数を入力するのです｡ 

04:29.700 --> 04:34.080
まず1つ目は､ 私たちが追加しているリワードなので､ 報酬です｡ 

04:34.440 --> 04:37.170
そして2つ目がリストです｡ 

04:37.410 --> 04:47.340
例えば､ 報酬リストというのは､ 報酬がリストになっている場合です｡ 報酬がリストになっている場合､

04:47.340 --> 04:54.870
私たちが行うことは､ 非常に単純に､ 私たちがリストを取ることです｡

04:55.680 --> 04:56.520
報奨金

04:57.450 --> 05:08.250
これはリストなので､ 単純な足し算の操作で2つのリストを合計することができます｡

05:08.580 --> 05:09.180
報酬のことです｡ 

05:09.180 --> 05:11.670
これはtrueと同じになるので､ ここにリストがあります｡ 

05:11.700 --> 05:13.110
つまり､ 今回のケースであれば

05:13.110 --> 05:23.970
そして､ このリストを報酬のリストに単純に合計することができます｡ したがって､ ここにある報酬のリストと等しい報酬を単純に追加すればよいのです｡

05:24.660 --> 05:30.300
そして､ こうすることで､ この2つのリストを合計してリストを拡張しているに過ぎないのです｡ 

05:30.930 --> 05:31.440
わかりました｡ 

05:31.440 --> 05:33.390
そして､ 2つ目の条件｡ 

05:33.660 --> 05:35.910
だから､ 単純にelseを追加すればいいんです｡ 

05:36.030 --> 05:41.640
つまり､ 報酬がリストでない場合､ したがって単一の要素である場合です｡ 

05:41.880 --> 05:44.180
その他､ その場合はどうなるのでしょうか？

05:44.190 --> 05:45.210
まあ､ それは同じなんですけどね｡ 

05:45.210 --> 05:53.690
rewardsをリストに追加したいのですが､ rewardsはもはやリストではないので､ この構文は使えません｡

05:53.700 --> 05:55.250
単一要素になります｡ 

05:55.260 --> 05:59.850
そこで､ もう一つの構文として､ append関数を使う必要があります｡ 

05:59.850 --> 06:05.670
リストに1つの要素を追加したい場合､ append関数を使用する必要がありますいくつかの2を追加することができます｡

06:05.670 --> 06:07.770
そして､ これこそが､ これからやろうとしていることなのです｡ 

06:07.770 --> 06:18.110
オブジェクトの報酬のリストをここに貼り付けて､ ドットアペンドを追加するのです｡ 

06:18.120 --> 06:18.930
これでよしとしよう｡ 

06:18.930 --> 06:24.540
まず1つ目ですが､ もちろん括弧の中に追加したい要素を入力します｡ 

06:24.540 --> 06:26.220
そして､ これはもちろん報酬です｡ 

06:26.220 --> 06:29.280
しかし､ その場合の報酬はリストにはならない｡ 

06:29.280 --> 06:34.110
リストにではなく､ 1つの累積報酬のような単一の要素になります｡ 

06:34.740 --> 06:35.160
わかりました｡ 

06:35.160 --> 06:39.300
そして､ こうしたいが､ 今度は何かを追加しなければならない｡ 

06:39.300 --> 06:45.180
この報酬のリストが100以上の要素になると､ どうなるかというと､ そうなります｡ 

06:45.270 --> 06:51.210
さて､ その場合､ やらなければならないことは､ この報酬のリストの最初の要素を削除して､

06:51.210 --> 06:56.160
この報酬のリストが常に100以上の要素を含まないようにすることです｡

06:56.160 --> 07:00.330
つまり､ 自動運転車のスコアウィンドウを作るときにやったことと全く同じです｡ 

07:00.330 --> 07:08.640
そして､ これを確実にするために､ 報酬のリストの長さ､ つまり､ この数がselfより大きいときはいつでも､

07:08.910 --> 07:25.350
報酬のリストの要素の数､ つまり､ ここで設定したサイズ､ 後でオブジェクトを作成するときに100に等しくなることを指定するウェル条件を追加するつもりです｡

07:25.350 --> 07:30.180
まあ､ この報酬のリストの要素数が100より大きくなると､ すぐに

07:30.180 --> 07:40.320
さて､ 私たちがしたいことは､ インデックスを0にすることで得られる報酬リストの最初の要素を削除することです｡

07:40.320 --> 07:43.110
それが､ 報酬一覧の最初のインデックスです｡ 

07:43.350 --> 07:50.730
これは､ 報酬のリストの最初の要素で､ 報酬のリストに100以上の要素が含まれるたびに､

07:50.730 --> 07:52.890
これを削除したい｡

07:53.340 --> 08:01.620
この条件によって､ 報酬のリストには100以上の要素が含まれないようにすることができます｡

08:01.950 --> 08:17.280
したがって､ 今私たちができることは､ 100個の要素を含む報酬リストの平均を計算する新しい関数を作ることです｡

08:17.880 --> 08:19.590
では､ この新しい関数を作ってみましょう｡ 

08:19.590 --> 08:24.600
Pythonにはリストの平均を計算するNumPyのmain関数があるので､

08:24.630 --> 08:27.180
とても簡単でしょう｡

08:27.480 --> 08:31.710
では､ 最後の関数を紹介しましょう｡ ここでは､ 平均と呼ぶことにします｡ 

08:31.980 --> 08:37.050
この関数は1つの引数を取ることになりますが､ それはselfになります｡

08:37.050 --> 08:41.430
なぜなら､ もちろん､ まだ報酬のリストを使うからです｡

08:41.430 --> 08:44.220
だからセルフとコロン｡ 

08:44.490 --> 08:51.630
そして､ 平均を計算してみましょう｡ もちろん､ 平均関数を適用して平均を得ることができますので､

08:51.630 --> 08:55.500
直接､ 平均を返します｡

08:55.590 --> 09:00.000
さて､ 私たちが計算したいのは､ その平均値が報酬のリストであるということです｡ 

09:00.000 --> 09:01.770
まだコピーしていたようです｡ 

09:01.770 --> 09:02.100
はい｡ 

09:02.100 --> 09:02.910
これでよしとしよう｡ 

09:02.910 --> 09:07.050
そこで､ 単純に報酬のリストの平均値を返すことにした｡ 

09:07.050 --> 09:11.210
そして､ 平均は､ 先ほども言ったように､ 円周率以外の関数である｡ 

09:11.220 --> 09:16.500
そこで､ ここでは､ ショートカットと､ 報酬の自己リストを意味するpを追加しています｡ 

09:16.500 --> 09:17.460
そして､ そこに行く｡ 

09:17.460 --> 09:20.370
100歩譲って平均は取れている｡ 

09:20.850 --> 09:21.540
完璧です｡ 

09:21.540 --> 09:23.970
だから､ その授業はとても効率よく作りました｡ 

09:23.970 --> 09:28.980
では､ 100歩譲って移動平均を求める方法を説明します｡ 

09:28.980 --> 09:38.490
そして､ トレーニングを行う際には1つの移動平均オブジェクトを使用することになるので､ まあ､ もうこの移動平均オブジェクトを作りましょうよ｡

09:38.490 --> 09:46.260
そして､ これをAと呼ぶことにして､ 単純にMarはAクラスのオブジェクトとすることにします｡ 

09:46.260 --> 09:54.810
そして､ 先ほども言ったように､ 100ステップで移動平均を計算したいので､ サイズは100にしたいのです｡ 

09:54.900 --> 09:55.920
とても完璧です｡ 

09:55.920 --> 09:56.670
これでよしとしよう｡ 

09:56.890 --> 10:01.600
これでようやくAIに知能を持たせるための訓練ができるようになりました｡ 

10:01.630 --> 10:02.780
そろそろ潮時かな｡ 

10:02.800 --> 10:05.960
ここからが､ 私たちのAIが賢くなるポイントです｡ 

10:05.980 --> 10:07.660
だから､ 早くトレーニングしたいんです｡ 

10:07.690 --> 10:11.190
これはすでにやっていたことなので､ かなり楽になりそうです｡ 

10:11.200 --> 10:12.580
でも､ これは楽しいことになりそうです｡ 

10:12.580 --> 10:18.640
しかも､ そのあとは､ 基本的に目の準備が完全に整っているので､ さらに楽しい時間になるはずです｡

10:18.640 --> 10:24.850
それが構築され､ またインテリジェントであるため､ コードを実行し､ そしてAIがドゥームをプレイし､

10:24.850 --> 10:33.240
最終的にはAIがドゥームをプレイしているビデオを見て､ ベストに到達することに成功するかどうかを確認することになるのです｡

10:33.250 --> 10:34.340
だから､ 待ち遠しいんです｡ 

10:34.360 --> 10:35.650
そのトレーニングをしよう｡ 

10:35.650 --> 10:36.460
そして､ それまでは

10:36.460 --> 10:37.360
そして､ 私｡ 
