WEBVTT

00:00.300 --> 00:06.270
大家好, 欢迎来到我们创造的超级激动人心的部分, 我们让它变聪明的部分｡ 

00:06.270 --> 00:13.260
所以这就是训练人工智能时所发生的事情, 训练它的智能来达到我们希望它完成的目标｡

00:13.260 --> 00:19.020
为了做到这一点, 我们将基本上训练神经网络输出正确的预测,

00:19.020 --> 00:27.510
然后一切都已经准备好了, 因为这些来自大脑的输出信号已经有了正确的传输到身体, 以发挥最后的行动｡

00:27.510 --> 00:32.220
所以基本上我们现在要做的是我们之前已经做过的事情｡ 

00:32.220 --> 00:37.410
我们将从内存中随机取出一些批次, 从这些样本中获取输入,

00:37.410 --> 00:42.810
获取输出, 获取目标, 获取预测,

00:42.810 --> 00:47.970
计算预测和目标之间的最后一个区域, 然后使用随机梯度下降执行反向传播,

00:47.970 --> 00:51.660
根据权重对最后一个误差的贡献程度来更新权重｡

00:51.750 --> 00:53.040
所以让我们来做这一切｡ 

00:53.040 --> 00:58.140
您将看到这是多么容易, 因为我们已经有了实现它的所有工具｡

00:58.140 --> 01:04.740
我们不仅有PyTorch工具, 比如Optimizer和丢失的函数, 还有我们之前创建的所有类,

01:04.740 --> 01:10.530
比如我们的大脑, 我们将用它来得到预测｡

01:10.530 --> 01:17.640
然后我们的经验, 重放, 实现,

01:17.640 --> 01:24.360
资格跟踪和所有这些工具结合到PyTorch工具将使训练超级性能, 因此最终我们将得到一个超级强大的人工智能｡

01:24.540 --> 01:26.340
所以, 让我们来进行培训｡ 

01:26.340 --> 01:28.260
让我们的人工智能变得更聪明｡ 

01:28.260 --> 01:33.390
我们现在要做的第一件事是得到最后一个函数, 我们在训练过程中计算误差和优化器时会用到这个函数,

01:33.390 --> 01:37.860
这是我们要做的第一件事｡

01:37.860 --> 01:40.590
所以让我们为最后一个函数创建一个变量｡ 

01:40.590 --> 01:42.390
我们称之为损失｡ 

01:42.720 --> 01:50.550
这将等于来自RN模块的MSI损失函数｡ 

01:50.760 --> 01:56.910
然后是MSI损失, 这是我们要使用的最后一个函数, 因为基本上我们的预测是Q值｡

01:57.120 --> 01:59.940
我们在预测不同动作的Q值｡ 

01:59.940 --> 02:05.970
因为这些都是真实的, 我们在做一些回归的神经网络,

02:05.970 --> 02:09.060
最后一个函数是均方误差｡

02:09.060 --> 02:12.090
这是最后一个我们通常用于回归的函数｡ 

02:12.420 --> 02:13.020
好吧, 我会的

02:13.020 --> 02:16.290
现在我们有了最后一个函数, 下面我们来看看优化器｡ 

02:16.440 --> 02:21.240
这里的optimizer是我们为它创建的变量optimizer｡ 

02:21.240 --> 02:23.940
我们要像往常一样｡ 

02:23.940 --> 02:31.950
至于自动驾驶汽车, 原子优化器, 这是一个非常强大的优化器, 将创造奇迹的训练｡

02:31.950 --> 02:36.060
让我们把它放到原子上｡ 

02:36.780 --> 02:39.990
记住, 这是针对自动驾驶汽车的｡ 

02:39.990 --> 02:42.930
我们必须输入两个基本参数｡ 

02:42.930 --> 02:49.200
第一个是在优化器和神经网络的参数之间建立联系, 也就是说,

02:49.200 --> 02:52.890
我们大脑神经元的权重｡

02:52.890 --> 02:56.880
为了做到这一点, 我们用我们的大脑, 我们称之为CNN｡ 

02:56.880 --> 02:59.220
那是我们为大脑创造的东西｡ 

02:59.220 --> 03:03.210
所以CNN不记得参数｡ 

03:03.450 --> 03:04.320
我们走吧｡ 

03:04.320 --> 03:06.120
和一些括号｡ 

03:06.270 --> 03:12.660
这就建立了优化器和人工智能大脑中神经元权重之间的联系｡

03:12.690 --> 03:18.870
第二个参数是学习率, 它是由误差给出的.

03:18.870 --> 03:24.480
所以这里我们必须取一个小的学习率因为我们不想收敛得太快, 我们想进行一些探索, 所以这里我们可以取一个很好的学习率,

03:24.480 --> 03:33.360
就是0｡

03:33.360 --> 03:33.360
01, 即打开1%｡ 

03:33.360 --> 03:36.450
我想这和我们在自动驾驶汽车上用的是一样的｡ 

03:37.390 --> 03:40.570
好了, 现在我们有了最后一个函数, 一个优化器｡ 

03:40.570 --> 03:43.450
现在我们几乎可以开始完整的循环了｡ 

03:43.450 --> 03:46.060
好吧, 实际上, 我们现在就开始整个循环｡ 

03:46.060 --> 03:51.250
但是在我们开始之前, 我们要决定纪元的数量｡ 

03:51.250 --> 03:58.390
我们将训练人工智能, 因此我在这里创建了一个新的变量, 它将与这个纪元的数量相对应｡

03:59.290 --> 04:02.360
让我们把它设为100｡ 

04:02.380 --> 04:04.790
这将是足够的方式来训练眼睛｡ 

04:04.810 --> 04:11.350
我甚至敢打赌, 人工智能将设法达到最好的方式之前100, 像20或30｡ 

04:11.380 --> 04:12.010
让我想想｡ 

04:12.010 --> 04:13.870
但现在, 让我们拿100｡ 

04:13.870 --> 04:16.060
如果我们需要, 我们会增加它｡ 

04:16.060 --> 04:17.980
但我觉得没这个必要｡ 

04:18.420 --> 04:18.620
好吧, 我会的

04:18.640 --> 04:26.880
现在我们有了历元的数量, 我们可以开始让for循环成为训练的主要循环, 当我们在历元上训练时｡

04:26.890 --> 04:31.520
所以迭代变量是epoch｡ 

04:31.540 --> 04:34.450
这就是我们选择的新纪元｡ 

04:34.930 --> 04:41.740
当然, 我们要用范围函数来表示, 我们要从第一个历元,

04:41.740 --> 04:44.710
一个历元到若干个历元｡

04:47.130 --> 04:51.960
加一, 因为记住, 范围的上限不包括在内｡ 

04:51.960 --> 04:58.920
因此, 如果我们想增加到100, 我们必须指定一个盒子加一, 以增加到100｡

04:59.400 --> 05:00.960
好吧, 科林.

05:00.960 --> 05:03.030
现在让我们进入循环｡ 

05:03.600 --> 05:03.930
好吧, 我会的

05:03.930 --> 05:08.550
所以我们要做的第一件事是每十步跑200次｡ 

05:08.550 --> 05:13.810
因此, 每个历元将是200次运行, 一次接一次, 每次10步｡ 

05:13.830 --> 05:18.420
为了做到这一点, 我们从我们经验丰富的重放类中找到了这个运行步骤函数｡ 

05:18.420 --> 05:23.400
因此, 使用这个函数,

05:23.400 --> 05:32.520
它实际上是一个方法, 因为我们将从内存对象中获得它, 它是来自重放内存类的对象, 以生成这200个运行的10个步骤, 我们必须在其中使用内存对象｡

05:33.350 --> 05:36.140
我提醒你我们在这里创造的｡ 

05:36.140 --> 05:43.520
存储器是具有MN步骤的重放存储器类的对象, 即10个步骤和10, 000的容量｡ 

05:43.790 --> 05:52.250
我们创建了这个对象, 并从这个对象中提取了井, 这个运行, 步骤, 函数,

05:52.250 --> 05:56.630
运行步骤, 我们指定了200个连续的10个步骤的运行｡

05:56.930 --> 06:00.680
因此, 在每个时期, 基本上运行200个步骤｡ 

06:00.740 --> 06:09.110
现在, 我们在每个时期都运行了200个步骤, 那么, 是时候从这些运行中对一些批次进行采样了｡

06:09.110 --> 06:10.610
并对这些批次进行取样｡ 

06:10.610 --> 06:16.700
内存中还有另一个函数, 即sample batch,

06:16.700 --> 06:19.100
它将从这200次运行中生成一些批处理｡

06:19.340 --> 06:25.010
但请记住, 这些批次是一系列转变的时间批次｡ 

06:25.010 --> 06:31.640
这是一系列的十个步骤, 而不是以前, 在那里的批次只是一些批次的单一过渡｡

06:31.640 --> 06:37.130
这一次它们是十步, 十个过渡的批处理,

06:37.130 --> 06:47.060
所以现在是时候从内存中得到这些随机批处理了, 为了得到它们, 我们使用了样本批处理函数, 我们必须对它应用批处理大小｡

06:47.060 --> 06:53.690
对于批量, 我们可以选择32个甚至64个甚至128个｡ 

06:54.050 --> 06:57.140
请记住, 对于批量大小, 这是一种常见的做法｡ 

06:57.140 --> 07:03.620
[ 32]这就是在进行批处理学习时, 在神经网络架构中通常会看到的情况｡ 

07:03.620 --> 07:05.600
但这次完全不同｡ 

07:05.600 --> 07:11.630
我们只是对10个步骤的一些批次进行抽样, 因此最好采用更大规模的批次｡ 

07:11.630 --> 07:14.990
所以我们可以选择64或128｡ 

07:14.990 --> 07:17.000
所以我们选128号｡ 

07:17.240 --> 07:24.770
实际上, 这是一个四循环, 因为我们要处理几个批处理,

07:24.770 --> 07:29.090
我们把它们放入这个批处理函数的返回值中.

07:29.330 --> 07:38.750
所以这个for循环, for batch in memory, sample,

07:38.750 --> 07:47.390
batch, 128意味着每128步, 我们的内存会给予我们一个大小为128的批, 它实际上包含了刚刚运行的最后128步｡

07:47.810 --> 07:54.230
我们只是得到了一些128号的批次, 学习将在这些批次上发生｡ 

07:54.230 --> 07:58.700
此外, 在这些批次中, 我们将有资格, 跟踪运行, 你知道,

07:58.700 --> 07:59.660
学习每十步｡

08:00.200 --> 08:00.620
好吧, 我会的

08:00.620 --> 08:07.550
现在在这个循环中, 它仍然在一个时期内发生, 但现在我们在一个特定的批处理中｡

08:07.670 --> 08:14.300
现在我们要做的第一件事就是分别获取输入和目标｡ 

08:14.450 --> 08:16.610
就像我告诉你的, 这很简单｡ 

08:16.610 --> 08:21.500
我们可以使用我们实现的工具之一, 即资格跟踪来实现这一点｡ 

08:21.500 --> 08:28.160
正如您在此处所看到的, 此资格跟踪函数将一个批处理作为输入, 现在我们有了作为输出的批处理和返回､

08:28.160 --> 08:32.270
输入和目标｡

08:32.270 --> 08:37.640
现在我们要做的就是创建两个新的变量, 分别作为输入和目标,

08:37.640 --> 08:42.290
然后输入到达目标.

08:43.220 --> 08:44.000
相等｡ 

08:44.030 --> 08:48.840
此资格跟踪函数的返回内容完全适用于批｡ 

08:48.860 --> 08:52.190
因此, 我们将把这个函数应用到循环的批处理中｡ 

08:52.190 --> 08:55.340
所以我们要做的只是资格｡ 

08:56.410 --> 09:00.340
应用于循环批处理的跟踪｡ 

09:00.640 --> 09:04.210
好的, 这样我们就有了输入和目标｡ 

09:04.210 --> 09:08.020
但在PyTorch中, 总有更多的事情我们必须做｡ 

09:08.020 --> 09:15.220
当然, 这是把神经网络的输入和目标转换成一些折磨变量, 但没有释放｡

09:15.220 --> 09:16.140
没有什么新鲜事｡ 

09:16.150 --> 09:17.430
我们知道怎么做｡ 

09:17.440 --> 09:18.460
我们可以这样做｡ 

09:18.460 --> 09:26.740
我们取输入值, 然后取目标值, 它们等于可变输入值｡ 

09:27.740 --> 09:33.800
这是输入和可变目标, 这是目标｡ 

09:34.070 --> 09:34.880
好吧, 我会的

09:35.210 --> 09:44.130
因此, 大脑的输入被转换成一些火炬变量, 目标也被转换成一些火炬变量｡

09:44.150 --> 09:48.530
现在我们可以把输入输入到神经网络中｡ 

09:48.530 --> 09:50.120
我们为什么要这么做？

09:50.150 --> 09:55.430
这是因为下一步是获得我们所拥有的预测, 我们必须针对的输入｡ 

09:55.460 --> 10:02.360
当然, 现在我们需要预测, 因为接下来我们要计算预测和目标之间的损失｡

10:02.900 --> 10:06.570
所以让我们来看看这些预测｡ 

10:06.590 --> 10:07.910
好吧, 再说一次, 这太简单了｡ 

10:07.910 --> 10:16.970
现在我们只需要把我们的大脑, 也就是CNN, 我们的卷积神经网络, 应用到我们的输入中｡

10:17.240 --> 10:18.140
我们走吧｡ 

10:18.230 --> 10:23.480
输入进入神经网络, 神经网络将输出预测｡ 

10:24.150 --> 10:24.870
好极了｡ 

10:24.870 --> 10:28.560
所以现在我们有了预测, 我们有了目标, 这样我们就可以得到损失｡ 

10:28.560 --> 10:30.030
这就是下一步｡ 

10:30.210 --> 10:35.070
我们要引入一个新变量, 因为现在我们要得到最后一个错误, 这和最后一个函数不同,

10:35.070 --> 10:39.900
因为我们用最后一个函数来得到最后一个错误.

10:39.930 --> 10:48.960
所以这里的误差更小, 我们可以用最后一个函数来预测｡ 

10:49.650 --> 10:51.360
还有目标｡ 

10:52.170 --> 10:52.980
我们走吧｡ 

10:53.370 --> 10:55.020
现在一切都很顺利｡ 

10:55.050 --> 10:56.160
一切都合乎逻辑｡ 

10:56.160 --> 10:58.230
我们先输入目标｡ 

10:58.230 --> 11:00.540
然后, 由于输入, 我们得到了预测｡ 

11:00.540 --> 11:03.960
多亏了预测和目标, 我们得到了更少的误差｡ 

11:04.990 --> 11:07.200
所以非常逻辑和顺利｡ 

11:07.210 --> 11:09.040
那么现在下一步该怎么办呢？

11:09.070 --> 11:10.770
同样的逻辑路径｡ 

11:10.780 --> 11:17.080
现在我们有了最后一个可以返回的值, 将这个较小的误差传播回神经网络以更新权重｡

11:17.080 --> 11:22.150
我们用随机梯度下降法来实现, 为了执行随机梯度下降法, 我们需要优化器,

11:22.150 --> 11:26.290
但我们已经有了, 我们的原子优化器｡

11:26.290 --> 11:29.230
但现在, 记住我们要做的｡ 

11:29.230 --> 11:32.380
我们必须对它进行初始化｡ 

11:32.380 --> 11:40.780
请记住, 我们使用优化器对象, 然后应用零网格方法｡ 

11:41.460 --> 11:41.920
那我们走吧｡ 

11:41.920 --> 11:45.240
我们不会忘记初始化它的括号｡ 

11:45.360 --> 11:50.900
现在, 下一步是将最后一个误差反向传播到神经网络中｡ 

11:50.910 --> 11:58.960
为了做到这一点, 我们取最后一个误差, 并对其应用向后的方法｡ 

11:58.980 --> 12:02.010
这就是应用反向传播｡ 

12:02.010 --> 12:09.780
最后, 最后一个误差已经传播到新的网络中, 我们可以用随机梯度下降法来更新权重｡

12:10.260 --> 12:17.190
要做到这一点, 请记住, 我们使用优化器, 然后应用此步骤方法｡ 

12:17.370 --> 12:18.310
我们走吧｡ 

12:18.330 --> 12:20.120
现在, 权重已更新｡ 

12:20.130 --> 12:25.740
正如我告诉你的, 我们不仅已经做到了, 而且现在看起来如此简单, 如此自然｡ 

12:26.070 --> 12:28.520
所以现在我们要做点有趣的事｡ 

12:28.530 --> 12:36.040
我们将打印每个纪元的平均奖励, 这样我们就可以跟踪人工智能的进展, 以及训练的进展｡

12:36.060 --> 12:40.530
我们希望看到平均报酬随着时代的发展而增加｡ 

12:40.530 --> 12:44.040
当然, 一开始是探索阶段｡ 

12:44.040 --> 12:49.680
因此, 平均奖励可能在开始时不会增加,

12:49.680 --> 12:58.860
但一旦进入开发阶段, 我们就会看到平均奖励肯定会增加, 而且会增加到一定水平, 也就是它尽快到达背心的时候｡

12:59.310 --> 13:01.470
我们从指纹开始吧｡ 

13:01.980 --> 13:07.500
你知道, 我们在一个历元中做这个,

13:07.500 --> 13:16.380
所以我们必须回到这里的循环, 然后我们要先打印一个历元, 一个列, 然后是百分比, 因为我们要把所有的东西都转换成一个更好的字符串｡

13:16.710 --> 13:21.300
然后我们再加上平均奖励｡ 

13:22.540 --> 13:25.300
然后再加上百分比｡ 

13:25.600 --> 13:27.880
然后, 我们将结束报价｡ 

13:28.960 --> 13:30.700
然后再加上一个百分比｡ 

13:30.700 --> 13:36.670
在另一边, 我们输入变量,

13:36.670 --> 13:42.940
就是第一个人, 这里是EPC, 第二个变量对应的是平均报酬, 我们现在就来计算.

13:42.940 --> 13:45.670
所以平均报酬变量还不存在｡ 

13:45.670 --> 13:47.770
我们现在就去创建它｡ 

13:48.010 --> 13:52.120
所以我们要用STR历元｡ 

13:52.450 --> 13:55.450
即使epoch是一个数字, 我们也会将其转换为字符串｡ 

13:55.450 --> 13:57.340
这样更好｡ 

13:58.030 --> 14:02.080
我们要加一颗星星, 可以是平均奖励｡ 

14:02.080 --> 14:10.000
我们将创建一个变量, 称为VG奖励, 现在我们将创建此变量并计算它｡

14:10.960 --> 14:12.430
所以我们开始吧｡ 

14:12.430 --> 14:13.930
那是我们唯一要做的事了

14:13.930 --> 14:16.090
所以我们已经有了一个时代

14:16.120 --> 14:20.140
现在我们来计算平均报酬, 我们需要在这里计算｡ 

14:20.140 --> 14:28.210
仍然在循环中, 但不在批处理循环中, 因为现在我们对批处理进行了采样, 并且在批处理中进行了训练｡

14:28.210 --> 14:32.080
但现在, 正向传播和反向传播是在批处理中完成的｡ 

14:32.080 --> 14:38.890
现在我们回到epoch循环, 我们可以计算累积奖励, 这可以用我们的end step对象来完成,

14:38.890 --> 14:44.920
因为我们的end step对象包含这个函数｡

14:44.920 --> 14:51.490
我们可以在步骤运行过程中获得累积奖励｡

14:51.490 --> 14:59.500
所以我们现在要用它来更新步骤的新奖励,

14:59.500 --> 15:07.750
然后我们会更新移动平均线对象, 把累积奖励加到移动平均线对象上, 然后重新计算平均值｡

15:07.750 --> 15:10.090
这就是我们获得平均奖励的方法｡ 

15:10.480 --> 15:11.500
所以我们开始吧｡ 

15:11.500 --> 15:14.890
我们首先需要的是更新的奖励｡ 

15:14.890 --> 15:17.140
所以我们称之为奖励｡ 

15:18.080 --> 15:19.010
脚步声｡ 

15:19.250 --> 15:24.000
然后, 正如我们所说, 我们采取PN步骤｡ 

15:24.020 --> 15:30.830
在此处创建的提醒对象是我们的经验重放文件中PN Step Progress类的对象, 因此PN

15:30.830 --> 15:33.530
Steps对象｡

15:33.920 --> 15:39.710
然后, 我们添加奖励步骤, 然后一些括号｡ 

15:39.710 --> 15:43.930
好的, 这样我们就可以得到新的累积奖励了｡ 

15:43.940 --> 15:50.930
好的, 但是我们需要把这些新的累积奖励加到我们的移动平均线对象中｡ 

15:50.930 --> 15:57.320
要做到这一点, 我们有一个方法, 这次在移动平均类中, 就是这个ADD方法｡ 

15:57.410 --> 15:58.220
所以这很简单｡ 

15:58.220 --> 16:05.330
我们以移动平均线为对象, 这里创建了100个步长,

16:05.330 --> 16:15.350
然后我们将使用ADD方法, 然后在广告方法中, 我们输入奖励步长, 这将把步长的奖励添加到移动平均线中｡

16:15.950 --> 16:16.340
好吧, 我会的

16:16.340 --> 16:22.220
最后, 我们可以计算平均奖励, 这是, 你知道, 这是相同的变量在这里｡

16:22.640 --> 16:26.720
所以这就是平均报酬｡ 

16:26.720 --> 16:33.440
为了得到它, 我们只需要用移动平均对象的平均方法｡ 

16:33.590 --> 16:45.650
我们做点平均, 因为我们的移动平均线已经更新了新的奖励步骤, 我们刚刚增加了感谢添加方法｡

16:46.350 --> 16:46.930
好极了｡ 

16:46.970 --> 16:50.130
现在我们有了平均奖励, 这样我们就能在这里繁殖了｡ 

16:50.130 --> 16:53.160
这将在每一个纪元被印刷｡ 

16:53.430 --> 16:53.850
好吧, 我会的

16:53.850 --> 16:54.960
所以我们结束了｡ 

16:54.960 --> 16:57.150
所以我很期待看到结果｡ 

16:57.150 --> 17:01.620
事实上, 在下一个教程中, 我会在观看结果的同时给你们一个惊喜｡ 

17:01.620 --> 17:03.600
所以这将是非常令人兴奋的｡ 

17:03.600 --> 17:06.960
所以现在我想是时候和人工智能一起玩了｡ 

17:07.620 --> 17:11.380
好吧, 那就给自己准备一杯好咖啡或好茶｡ 

17:11.400 --> 17:16.950
现在是时候舒舒服服地坐在椅子上, 观看一些非常酷的视频, 我们的人工智能玩厄运｡ 

17:16.980 --> 17:18.750
所以我们在下一个教程中做这个｡ 

17:18.750 --> 17:20.040
在那之前, 好好享受吧｡ 

17:20.040 --> 17:20.460
一､ 
