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
要做到这一点, 我们要加上四个｡ 

00:11.730 --> 00:17.580
所以这次, 迭代变量将是我们的步长, 因为我们将从最后一步,

00:17.580 --> 00:21.660
到一系列转换的第一步, 依此类推｡

00:21.660 --> 00:29.850
现在从右到左的技巧是用四个步骤, 反向, 反向.

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-1开始｡ 

00:41.730 --> 00:43.890
所以我们不从最后一步开始｡ 

00:43.890 --> 00:48.120
这是终端状态, 但在此之前的状态, 也就是t减1｡ 

00:48.120 --> 00:50.160
但两个开始那是第一步｡ 

00:50.160 --> 00:58.980
所以这里不是从最后一个状态开始而是从之前的状态开始, 我们需要在括号里加上, 列减一｡

00:59.160 --> 01:03.630
我敢肯定, 对于那些学过机器和深度学习课程的人来说,

01:03.630 --> 01:11.850
你知道, 这个技巧, 科林, 减一, 意味着你要去最后一个元素之前的元素, 但不是最后一个元素｡

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
我们将更新累积奖励, 方法是将它乘以Gamma, 再加上在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
这里我们把它乘以Gemma｡ 

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:51.950
现在, 大家还记得, 做这一切的目的是准备好我们的输入和目标,

02:51.950 --> 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
所以我在这里引入了一个新的变量, 目标, 它等于第一步的Q值｡ 

03:53.330 --> 03:58.670
并且由于Q值由神经网络返回, 因此它包含在输出中｡ 

03:58.670 --> 04:05.660
因为输出是与输入相关联的输出,

04:05.660 --> 04:12.830
它包含了跃迁的第一个元素, 我们可以通过取这里的输出和索引0来得到第一个状态的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:32.900
然后, 我们将更新此目标变量, 但仅针对在该系列的第一步中选择的操作｡

04:32.900 --> 04:42.680
为了得到这个级数的第一步, 我们需要取第一个级数0因为这正是级数0的第一步｡

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
对于第一步, 我们只需要更新序列的第一步, 因为, 你知道,

05:51.130 --> 05:55.930
我们训练眼睛十步, 因此输入是十步中的第一步｡

05:55.930 --> 06:01.000
我们在第一步就得到了目标,

06:01.000 --> 06:06.150
但是我们不需要在接下来的十步中得到任何输入或目标, 因为基本上学习是在十步之后进行的｡

06:06.160 --> 06:11.110
这就是为什么现在我们只得到了这个系列的第一步的状态和目标｡ 

06:11.620 --> 06:13.240
所以理解这点很重要｡ 

06:13.240 --> 06:18.280
因此, 如果我们明白了这一点, 那么现在我们明白了,

06:18.280 --> 06:20.170
我们必须把它们输入到我们的输入列表和目标列表中｡

06:20.500 --> 06:22.300
所以我们先做这个｡ 

06:22.300 --> 06:25.000
让我们将状态附加到输入中｡ 

06:25.000 --> 06:35.950
所以我们取输入列表, 用append函数添加状态, 它记住了序列第一步的输入状态｡

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
所以我们要在这里加上return｡ 

07:04.000 --> 07:06.280
然后我们要先得到我们的输入｡ 

07:06.280 --> 07:07.480
但那是一样的｡ 

07:07.480 --> 07:14.230
我们需要先把它们转换成一个numpy数组, 然后做一个类型转换,

07:14.230 --> 07:21.550
以确保我们有一个单一的类型, 其中D类型等于, P类型等于, 浮点数为30｡

07:21.640 --> 07:29.440
然后我们把它转换成火炬张量, 因为我们使用的是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:53.730
要做到这一点, 我们首先需要我们的torch库, 因为我们将使用stack函数by

07:53.820 --> 07:56.700
torch来堆叠目标｡

07:57.060 --> 07:57.450
好吧, 我会的

07:57.450 --> 08:03.960
所以这行代码基本上返回了输入和目标, 我们刚刚通过这个资格跟踪源算法更新了它,

08:03.960 --> 08:09.000
或者我们可以称之为分步学习｡

08:09.000 --> 08:14.910
现在, 恭喜你,

08:14.910 --> 08:20.910
我们准备好进行最后的训练了, 因为基本上, 训练包括最小化输入预测值和目标值之间的平方差｡

08:20.910 --> 08:22.710
所以让我们的人工智能变得更聪明｡ 

08:22.710 --> 08:25.050
它将在下一个教程中变得智能｡ 

08:25.050 --> 08:26.910
所以在那之前, 好好享受我｡ 
