WEBVTT

00:00.480 --> 00:02.730
こんにちは､ このPythonチュートリアルへようこそ｡ 

00:02.910 --> 00:03.960
では､ こうしてみましょう｡ 

00:03.960 --> 00:08.370
このforループを､ 右から始まって左へ行くように作ってみましょう｡ 

00:08.430 --> 00:11.400
そして､ そのために4つを追加します｡ 

00:11.730 --> 00:17.580
今回は､ 最後のステップから一連の遷移の最初のステップに行くので､

00:17.580 --> 00:21.660
反復変数が私たちのステップになるわけです｡

00:21.660 --> 00:29.850
そして､ 今度は右から左へ行くコツは､ 4つのステップイン､ リバース､ リバーサルを使うことです｡ 

00:29.850 --> 00:31.920
そして､ あとはシーケンスを入力するだけです｡ 

00:31.920 --> 00:35.160
そして､ この一連の流れは､ もちろん､ 私たちのシリーズになります｡ 

00:35.160 --> 00:36.930
そこで､ 私たちのシリーズをインプットしました｡ 

00:37.020 --> 00:41.730
しかし､ 論文にあるように､ Tマイナス1からTスタートまで行っているのです｡ 

00:41.730 --> 00:43.890
だから､ 最後の最後のステップから行かないんです｡ 

00:43.890 --> 00:48.120
それが終局状態ですが､ その前の状態､ つまりtマイナス1です｡ 

00:48.120 --> 00:50.160
しかし､ それを始めるための2つが最初の一歩です｡ 

00:50.160 --> 00:58.980
そして､ 最後の状態ではなく､ その前の状態にするためには､ 括弧で囲んで､ 列のマイナス1を追加する必要があります｡

00:59.160 --> 01:03.630
機械やディープラーニングの講座について行った方はご存知だと思いますが､

01:03.630 --> 01:11.850
この仕掛け､ コリン､ マイナス1というのは､ 最後の要素の前の要素までは行くが､ 最後の要素までは行かないということです｡

01:11.850 --> 01:14.610
したがって､ 私たちが望む配列を得ることができるのです｡ 

01:14.610 --> 01:23.790
最後の要素の前の要素から最初の要素に行くというのがありますが､ それを逆にして､ 右から左に行くということをやっているということです｡

01:23.940 --> 01:24.330
わかりました｡ 

01:24.330 --> 01:26.850
そこで､ フルループに入る準備が整いました｡ 

01:26.850 --> 01:29.580
そして､ このforループの中で､ どこをどうするのか？

01:29.610 --> 01:32.670
まあ､ 論文通りにやるんですけどね｡ 

01:32.670 --> 01:42.120
累積報酬にガンマを掛けて更新し､ forループのステップにある現在のステップで得られた報酬を加算することになるのです｡

01:42.480 --> 01:45.330
よし､ じゃあPythonに戻ってやってみようか｡ 

01:45.330 --> 01:52.710
それで､ まず次のようにして累積報酬を更新したい｡ 

01:53.410 --> 01:54.790
掛け合わせること｡ 

01:55.520 --> 01:56.510
さようなら､ ジェマ｡ 

01:57.650 --> 01:58.430
これでよしとしよう｡ 

01:58.460 --> 02:00.140
ここではゲルマを掛けています｡ 

02:00.260 --> 02:03.830
という報酬を加えたい｡ 

02:04.490 --> 02:09.220
このように特殊な構造でアクセスすることができるステップ｡ 

02:09.230 --> 02:12.890
報酬は､ ステップオブジェクトの属性であることを忘れないでください｡ 

02:12.890 --> 02:15.710
そして､ ここではもちろんプラスアルファを加えるわけです｡ 

02:15.800 --> 02:16.190
わかりました｡ 

02:16.190 --> 02:25.490
つまり､ 累積報酬は､ 今いるステップの報酬､ ループに､ 更新前の累積報酬であるガンマタイムズを加えたものに等しいのです｡

02:25.970 --> 02:26.720
完璧です｡ 

02:26.720 --> 02:27.980
だから､ 今は大丈夫だと思っています｡ 

02:27.980 --> 02:30.050
アルゴリズムを徹底的に追及しています｡ 

02:30.260 --> 02:32.480
そして､ 次のステップへ｡ 

02:32.600 --> 02:34.850
まあ､ これからはかなり楽になりますよ｡ 

02:34.850 --> 02:40.890
最初のforループに戻ります｡ このforループは､ アルゴリズムに従ってこのように更新することで､

02:41.000 --> 02:45.140
右から左へ行く累積報酬を計算するだけだからです｡

02:45.680 --> 02:55.670
さて､ 覚えているように､ このようなことをする目的は､ 入力とターゲットを準備し､ トレーニングのために両者の二乗差を最小にすることです｡

02:55.670 --> 03:00.890
ですから､ 今､ 私たちがしなければならないことは､ このインプットとターゲットを準備することだけです｡ 

03:00.950 --> 03:03.170
では､ まずこれをやってみましょう｡ 

03:03.170 --> 03:08.330
必要なのは､ シリーズの最初の状態を入力リストに追加することです｡ 

03:08.330 --> 03:14.030
今までは､ この入力の状態がこの入力変数に入っているが､ それは出力を計算するためだけであった｡ 

03:14.030 --> 03:21.170
そこで､ この最初のステップの入力状態を別途取得し､ それこそ入力リストに追加する必要があるからです｡

03:21.170 --> 03:23.090
だから､ これは別にしよう｡ 

03:23.120 --> 03:25.520
よって､ ステートと呼ぶことにします｡ 

03:25.760 --> 03:28.100
というように､ ここと全く同じです｡ 

03:28.100 --> 03:34.370
この方法は､ 最初の遷移を含む系列の最初のインデックスを取り､ その状態を加算して､

03:34.370 --> 03:37.880
この最初の遷移の状態を得ることができる｡

03:38.120 --> 03:40.760
それなら､ 同じものが必要なんですね｡ 

03:40.760 --> 03:46.580
この最初の遷移の入力状態に関連するターゲットを別途取得することになる｡ 

03:46.580 --> 03:53.330
そして､ ここで新しい変数targetを導入し､ 最初のステップのQ値に等しくなるようにします｡ 

03:53.330 --> 03:58.670
そして､ Q値はニューラルネットワークが返すものなので､ 出力に含まれる｡ 

03:58.670 --> 04:05.660
そして､ outputは遷移の最初の要素を含むこの入力に関連する出力なので､ まあ､ ここでoutputを取ってインデックスを0にすれば､

04:05.660 --> 04:12.830
この最初の状態のQ値を得ることができます｡

04:12.830 --> 04:20.780
そして､ 最初の遷移の入力状態のQ値を単純に取得するドットデータを追加します｡ 

04:20.780 --> 04:22.850
そして､ それがまさに目標とするQ値なのです｡ 

04:22.850 --> 04:24.740
だから､ それを受けているわけです｡ 

04:25.100 --> 04:31.370
次に､ このターゲット変数を､ シリーズの最初のステップで選択されたアクションに対してのみ､

04:31.370 --> 04:32.900
更新するつもりです｡

04:32.900 --> 04:39.650
そして､ この系列の最初のステップにアクセスするために､ まあ､ 最初の系列のゼロを取る必要がありますこれは､

04:39.650 --> 04:42.680
まさに系列の最初のステップです シリーズゼロ｡

04:42.680 --> 04:47.270
そして､ このシリーズの最初のステップに対応するアクションにアクセスすることです｡ 

04:47.270 --> 04:48.950
さて､ ここで補足が必要です｡ 

04:49.730 --> 04:51.000
ドットアクション

04:51.030 --> 04:54.930
繰り返しになりますが､ これはこの属性構造を使っているのです｡ 

04:55.290 --> 04:58.740
アクションは､ シリーズの最初のステップの属性です｡ 

04:58.740 --> 05:04.590
なぜなら､ シリーズの各遷移は､ 状態アクション､ 報酬､ 行われたのでアクションここで､

05:04.590 --> 05:08.340
次の構造を持っているシリーズの最初の遷移です｡

05:08.340 --> 05:13.500
ここのactionという属性は､ 単純にこの最初のデートのアクションを取得するという意味です｡ 

05:14.170 --> 05:22.540
そして､ 最初のステップのその具体的な行動の目標が､ まさに累積報酬によって更新される必要があるわけです｡

05:22.570 --> 05:29.260
つまり､ ここでは基本的に､ シリーズの最初のステップで行われたアクションに関連するターゲットは､

05:29.260 --> 05:35.560
先ほど計算したこの累積報酬であると書くことにします｡

05:35.950 --> 05:36.670
わかりました｡ 

05:36.670 --> 05:45.730
そして､ この最初の入力状態をここに､ この最初のターゲットをここに追加することで､ ようやく入力を更新する準備が整ったのです｡

05:45.730 --> 05:51.130
最初のステップでは､ シリーズの最初のステップを更新するだけでよいのです｡ なぜなら､ 10ステップで目を訓練するので､

05:51.130 --> 05:55.930
入力は10ステップのうちの最初のステップになるからです｡

05:55.930 --> 06:01.000
また､ この最初のステップで目標を得ますが､ その後の10ステップでは入力や目標を得る必要はありません｡

06:01.000 --> 06:06.150
基本的に学習は10ステップ後に行われるからです｡

06:06.160 --> 06:11.110
だから今は､ シリーズの最初のステップの状態とターゲットしか出ていないわけです｡ 

06:11.620 --> 06:13.240
だから､ それを理解することが大切なんです｡ 

06:13.240 --> 06:20.170
ですから､ それを理解した上で､ インプットリストとターゲットリストにインプットしなければならないのです｡

06:20.500 --> 06:22.300
では､ まずこれをやってみましょう｡ 

06:22.300 --> 06:25.000
入力に状態を追記しよう｡ 

06:25.000 --> 06:35.950
そこで､ 入力リストを取り出し､ append関数を使って､ シリーズの最初のステップの入力状態を記憶しているstateを追加します｡

06:36.820 --> 06:42.260
そして､ 最初のステップのターゲットをターゲットのリストに追加することになります｡ 

06:42.280 --> 06:49.000
そのために､ ターゲットのリストを取り､ 同じようにappend関数を使って最初のターゲットを追加しています｡

06:49.330 --> 06:50.260
これでよしとしよう｡ 

06:50.290 --> 06:51.190
もう少しで完成です｡ 

06:51.190 --> 06:55.990
そして今､ 最後のものを返す必要があるのですが､ それはもちろん､ 必要なものです｡ 

06:55.990 --> 06:58.300
それは､ チュートリアルの冒頭で述べたとおりです｡ 

06:58.330 --> 07:01.600
現在更新されているインプットとターゲット｡ 

07:01.840 --> 07:03.550
だから､ ここにリターンを追加する｡ 

07:04.000 --> 07:06.280
では､ まずインプットをします｡ 

07:06.280 --> 07:07.480
でも､ それなら同じことです｡ 

07:07.480 --> 07:14.230
まずnumpyの配列に変換して､ D型イコールで1つの型になるように型変換をして､

07:14.230 --> 07:21.550
float 30を同じにするPが必要です｡

07:21.640 --> 07:29.440
そしてこれをtorchテンソルに変換します｡ もちろんPyTorchを使っているので､ これは完全に必須です｡

07:29.440 --> 07:33.280
それで､ NumPyのトーチを使っているんです｡ 

07:33.730 --> 07:36.010
もう一度機能を

07:36.990 --> 07:38.980
そして､ それが私たちのインプットとなるのです｡ 

07:39.000 --> 07:39.510
完璧です｡ 

07:39.510 --> 07:42.060
そして今度は､ ターゲットに対して同じことをやってみましょう｡ 

07:42.330 --> 07:44.440
今度は､ この仕掛けを使うと早いですよ｡ 

07:44.460 --> 07:46.710
ターゲットを重ねていくんです｡ 

07:46.710 --> 07:56.700
なぜなら､ ターゲットを積み重ねるためにtorchのstack関数を使うからです｡

07:57.060 --> 07:57.450
わかりました｡ 

07:57.450 --> 08:09.000
そして､ このコードの行は基本的に､ この適格なトレースソースアルゴリズムによって更新された入力とターゲットを返すのです｡

08:09.000 --> 08:20.910
さて､ これで最終的な学習を行う準備が整いました｡

08:20.910 --> 08:22.710
だから､ AIを賢くしよう｡ 

08:22.710 --> 08:25.050
次のチュートリアルでスマートになります｡ 

08:25.050 --> 08:26.910
というわけで､ それまでiをお楽しみください｡ 
