WEBVTT

00:00.270 --> 00:02.610
大家好, 欢迎学习本Python教程｡ 

00:02.640 --> 00:06.720
好的, 我们只是在达到新状态后更新了内存｡ 

00:06.720 --> 00:08.880
现在让我们来关注下一个更新｡ 

00:09.240 --> 00:12.240
按照你现在的说法, 下一次更新会是什么？

00:12.570 --> 00:16.560
基本上, 我们完成了一次过渡｡ 

00:16.590 --> 00:20.930
我们已经确定了过渡的最后一个元素的日期, 这就是新的状态｡ 

00:20.940 --> 00:23.310
所以现在就像我们要重新开始一样｡ 

00:23.310 --> 00:28.140
当我们重新开始的时候, 你知道, 我们处在一个新的环境中｡

00:28.140 --> 00:31.230
那么我们现在自然需要做什么呢？

00:31.260 --> 00:37.120
当然, 这是为了表演一个动作, 因为我们已经观察到了新的状态｡ 

00:37.170 --> 00:40.380
所以现在我们要做的就是表演一个动作｡ 

00:40.620 --> 00:46.720
因此, 我们现在要做的当然是, 使用选择动作功能来播放动作｡ 

00:46.740 --> 00:47.580
那就开始吧｡ 

00:47.580 --> 00:54.150
让我们创建一个新的变量操作, 并使用select action函数来播放该操作｡ 

00:54.150 --> 01:04.220
所以我用第一个self来指定select action函数是将要创建的不同类的对象的一个方法｡

01:04.230 --> 01:08.490
所以自我打点选择行动｡ 

01:08.490 --> 01:11.010
开始吧, 自我点选择动作｡ 

01:11.010 --> 01:17.550
当然,

01:17.550 --> 01:25.140
因为选择动作函数把状态作为输入, 因为当当前输入状态进入神经网络时, 选择动作函数将返回神经网络的输出｡

01:25.230 --> 01:27.450
所以我们必须在这里输入输入状态｡ 

01:27.570 --> 01:33.450
因为这是我们刚刚在环境中达到的状态,

01:33.450 --> 01:40.020
输入状态当然是新状态, 因为我们刚刚达到的状态, 在我们现在的时间是新状态｡

01:40.020 --> 01:44.970
所以在选择操作功能中, 我输入了新的状态｡ 

01:44.970 --> 01:45.420
好吧, 我会的

01:45.420 --> 01:51.480
因此, 通过这行代码, 我们只需在到达新状态后执行新操作｡ 

01:51.990 --> 01:52.340
好吧, 我会的

01:52.350 --> 01:58.740
现在我们在实际中使用它, 我们得到了奖励, 因此我们得到了反馈｡

01:58.740 --> 02:04.590
因此, 如果我们的记忆中有超过100个元素, 那么, 就到了学习的时候了｡ 

02:04.590 --> 02:10.530
因此, 我们现在必须做的是, 在选择一个行动之后, 逻辑上会发生什么,

02:10.530 --> 02:15.600
当然, 就是了解需求, 开始学习是否以正确的方式做事情｡

02:15.600 --> 02:23.850
现在, 由于它刚刚播放了动作, 我们将让人工智能从它在过去100个事件中的动作中学习｡

02:23.970 --> 02:31.260
但是在我们应用这个学习函数之前, 我们必须设置这个if条件, 以确保我们已经达到了100个以上的事件, 因为,

02:31.260 --> 02:37.260
你知道, 我们是从内存的随机样本中学习的｡

02:37.260 --> 02:40.920
我们有一万个元素的巨大记忆｡ 

02:40.920 --> 02:45.150
我们随机抽取了100个元素的记忆样本｡ 

02:45.150 --> 02:52.620
人工智能从这100个随机转换样本中所包含的信息中学习｡ 

02:52.620 --> 03:02.820
所以让我们先用if条件来确定内存的元素个数, self点内存然后再小心点｡

03:02.820 --> 03:04.140
只是一个小把戏｡ 

03:04.140 --> 03:12.330
自点内存是重播内存类的对象, 但重播内存类有一个属性, 即内存｡

03:12.330 --> 03:15.240
所以实际上我们需要采取自我记忆｡ 

03:15.240 --> 03:27.360
内存, 第一个内存是replay内存类的对象, 第二个内存是这里的self内存属性｡

03:27.980 --> 03:36.470
所以如果内存中的元素数量是我们想要的, 大于100, 那么就着色｡ 

03:36.680 --> 03:38.670
然后呢？

03:38.690 --> 03:45.470
我们可以学习, 但在学习之前, 我们需要随机抽取100个跃迁｡ 

03:45.470 --> 03:48.500
我们可以用sample函数得到这个｡ 

03:48.590 --> 03:55.130
由于sample函数返回不同的批次, 因此状态设置时间t为20加1｡

03:55.130 --> 03:57.740
这些行为的时间为t, 奖励时间为t｡ 

03:57.890 --> 04:03.320
我们现在要做的是创建一些新的变量, 这些变量是时间t的状态, 下一个状态,

04:03.320 --> 04:07.840
奖励和行为.

04:07.850 --> 04:15.950
我们可以简单地给这里的参数取相同的名字, 然后粘贴到这里｡ 

04:15.950 --> 04:25.950
而这些变量将等于示例函数返回的值, 因为它正好返回这些状态批｡

04:25.970 --> 04:28.060
下一个陈述奖励和行动｡ 

04:28.070 --> 04:33.620
所以我们现在要做的就是先得到内存对象｡ 

04:33.620 --> 04:40.280
然后从这个内存对象开始, 我们将使用sample方法, 它将作为输入｡ 

04:40.280 --> 04:46.250
我们希望人工智能从中学习的转换次数是100｡ 

04:46.370 --> 04:50.300
这就是为什么我们要确保内存有100多次转换｡ 

04:50.300 --> 04:54.620
所以它会从记忆的100次转变中学习｡ 

04:54.620 --> 04:56.390
这样学习就会好得多｡ 

04:56.390 --> 04:59.450
所以现在让我们来学习一下｡ 

04:59.450 --> 05:06.350
因为learn方法是我们的diffusion类的一个方法, 所以我们需要从将来的对象中访问这个learn方法,

05:06.350 --> 05:11.720
这些对象将从不同的类中创建｡

05:11.720 --> 05:14.240
因此, 我们需要采取的是自我｡ 

05:14.240 --> 05:23.690
所以self把这个对象引用到类中, 然后学习这个学习方法, 学习我们输入的方法｡

05:23.690 --> 05:30.080
当然, 这些家伙在这里, 批状态批, 下一个日期, 批奖励和批行动｡ 

05:30.470 --> 05:38.900
这些是从内存中采样的批处理, 我们得到了100个批处理, 因为我们有100个转换｡ 

05:38.900 --> 05:46.220
从这100个转变中, 我们得到了100种状态, 106种状态, 100种奖励和100种行动｡ 

05:47.190 --> 05:49.590
让我们在这里和那里玩这个游戏｡ 

05:49.590 --> 05:51.480
现在学习将发生｡ 

05:51.630 --> 05:54.150
它会发生在所有这些随机批次｡ 

05:54.480 --> 05:55.290
好极了｡ 

05:55.680 --> 06:04.010
现在我们需要做的是最后的更新后, 你知道, 达到一个新的状态, 并发挥一个行动｡

06:04.020 --> 06:11.460
我们已经有了要玩的动作, 但是我们还没有更新我们自己的动作, 最后一个动作变量｡

06:11.460 --> 06:13.530
所以我们一定要记住这一点｡ 

06:13.530 --> 06:14.850
我们现在就做吧｡ 

06:14.880 --> 06:26.760
我们将更新最后一个动作self, 最后一个动作equals, 当然还有我们刚才用select action函数执行的动作｡

06:27.030 --> 06:27.450
好吧, 我会的

06:27.450 --> 06:30.300
所以现在最后一个动作被更新了｡ 

06:30.300 --> 06:31.680
新状态也一样｡ 

06:31.680 --> 06:40.530
我们到达了新的状态, 但是我们还没有更新最后一个状态, 因为最后一个状态当然在20的状态之前｡

06:40.530 --> 06:44.760
但是从现在开始, 我们在时间T +1时达到了新的状态｡ 

06:44.760 --> 06:49.980
最后一个状态变成了这个新状态, 因此我们也需要更新它｡ 

06:50.010 --> 06:56.040
Self dot的最后一个状态等于我们的新状态｡ 

06:57.120 --> 06:57.940
我们走吧｡ 

06:57.960 --> 06:59.550
现在我们需要更新什么？

06:59.580 --> 07:01.460
现在只剩下一件事了｡ 

07:01.470 --> 07:03.270
当然, 这是奖励｡ 

07:03.420 --> 07:08.060
而回报正是我们在现实中得到的回报｡ 

07:08.070 --> 07:16.920
这就是这个更新函数的参数, 如果我们把它和地图连接起来, 这就是最后的奖励｡

07:16.920 --> 07:23.210
这是我们在这个达到的新状态中玩完动作后得到的奖励｡ 

07:23.220 --> 07:28.020
所以如果我们再往上送一些, 这最后的奖励就会差减一｡ 

07:28.140 --> 07:31.950
如果我们离目标更远, 我们会得到稍微好一点的奖励｡ 

07:31.950 --> 07:33.330
减去0｡  2.

07:33.360 --> 07:38.550
如果我们离目标更近了, 我们会得到一个稍微好一点的奖励开一个｡ 

07:38.550 --> 07:43.320
如果我们离地图的一边太近, 那将是一个糟糕的惩罚｡ 

07:43.320 --> 07:45.180
我们将得到每个边的负1｡ 

07:45.210 --> 07:46.980
所以这是我们最后一次了｡ 

07:46.980 --> 07:50.610
在现实中, 这是一个真正发生在地图上｡ 

07:50.610 --> 07:53.430
这将是update函数的参数｡ 

07:53.430 --> 07:55.920
最后一个词就是这个词｡ 

07:55.920 --> 08:02.250
因为这是更新函数的参数, 它对应于这个奖励,

08:02.250 --> 08:13.530
也就是说, 最后一个奖励变量, 在函数初始化的时候, 就变成了我们得到的新奖励｡

08:13.530 --> 08:19.260
实际上, 这是奖励, 或者这是同样的奖励｡ 

08:20.620 --> 08:21.250
好吧, 我会的

08:21.250 --> 08:23.530
所以现在我们更新了最后一个奖励｡ 

08:23.710 --> 08:29.650
既然我们刚刚拿到了最后一个奖励, 那么, 我们现在可以更新奖励窗口了｡ 

08:29.680 --> 08:36.910
你还记得我们在这里初始化的奖励窗口, 它是我们类的对象的变量之一｡ 

08:36.940 --> 08:44.050
这是一个窗口, 通过计算最近100次奖励的平均值, 可以跟踪本次培训的进展情况｡

08:44.140 --> 08:49.890
因此, 它将像一个滑动窗口, 向我们展示奖励的平均值是如何演变的｡ 

08:49.900 --> 08:55.180
既然我们刚刚拿到了最后一个奖励, 那么, 我们可以更新奖励窗口｡ 

08:55.300 --> 08:56.800
那么我们如何更新它呢？

08:56.830 --> 09:00.550
好吧, 我们只需要把最后一个奖励附加到窗口上｡ 

09:00.550 --> 09:05.200
因此, 我现在要做的就是利用我的奖励窗口｡ 

09:05.200 --> 09:07.490
为奖励窗口服务｡ 

09:07.510 --> 09:08.290
在这里｡ 

09:08.290 --> 09:12.280
然后我将使用append函数｡ 

09:12.280 --> 09:16.360
在append函数中, 我们需要输入元素｡ 

09:16.360 --> 09:18.670
我们要附加到奖励窗口｡ 

09:18.670 --> 09:20.560
当然, 这就是奖励｡ 

09:21.400 --> 09:21.760
好吧, 我会的

09:21.760 --> 09:22.440
好极了｡ 

09:22.450 --> 09:29.800
因为这个奖励窗口是固定的, 你知道, 它不会是一个增长的窗口｡

09:29.800 --> 09:35.200
这将是一个固定大小的窗口, 随着时间的推移而滑动, 向我们展示奖励的演变｡ 

09:35.200 --> 09:38.560
现在我们需要决定这个窗口的大小｡ 

09:38.560 --> 09:43.390
它只是我们在这个窗口中获得奖励的方式的数量｡ 

09:43.690 --> 09:49.120
比如说, 我们来看看, 最后100个单词的最后1000个意思｡ 

09:49.120 --> 09:56.200
为了确保这一点, 我们要加上, 如果, 那么, Len, 我们就得到我们的奖励｡ 

09:57.020 --> 09:57.740
窗口｡ 

09:57.980 --> 10:06.410
我们在这里简单地添加, 如果奖励窗口中的元素数量大于1000, 那么,

10:06.410 --> 10:13.640
我们要做的是删除奖励窗口中的第一个元素｡

10:13.640 --> 10:18.230
这个奖励窗口的第一个元素的索引为零｡ 

10:19.060 --> 10:19.420
好吧, 我会的

10:19.420 --> 10:24.340
而现在我们要确保这个奖励窗口永远不会得到超过1000个元素｡ 

10:24.340 --> 10:27.640
也就是说1000意味着最后的100个奖励｡ 

10:27.850 --> 10:28.570
太完美了

10:28.570 --> 10:36.640
这将是一个固定大小的窗口, 这样我们就可以看到奖励的平均值是否在增加, 从而看到培训是否进行得很顺利｡

10:36.640 --> 10:39.130
相应地, 如果这张卡片能满足我们的要求｡ 

10:39.730 --> 10:40.570
好极了｡ 

10:40.720 --> 10:44.650
现在你只剩下一件小事要做了｡ 

10:44.650 --> 10:45.920
你想怎么样？

10:45.940 --> 10:52.090
请记住, 这个更新函数不仅更新奖励窗口中转换的不同元素,

10:52.090 --> 10:57.910
而且还返回到达新状态时所执行的操作｡

10:57.940 --> 11:02.690
这就是为什么我们在地图上的行动等于脑点更新｡ 

11:02.710 --> 11:04.090
最后一句话, 最后一个信号｡ 

11:04.240 --> 11:10.330
因此它应该返回一些东西, 它应该返回的东西当然是, 动作｡

11:10.570 --> 11:16.720
最后一件简单的事情就是返回操作｡ 

11:17.080 --> 11:20.020
到达新状态时显示的操作｡ 

11:20.380 --> 11:21.310
就是这样｡ 

11:21.520 --> 11:23.600
我们的更新功能已经就绪｡ 

11:23.620 --> 11:28.990
它将执行所有必需的更新, 并在到达新状态时返回操作｡ 

11:29.230 --> 11:30.390
太完美了

11:30.400 --> 11:34.960
这是整个过程中最后一个困难的行动｡ 

11:34.990 --> 11:36.880
现在剩下的都是小孩子的事了｡ 

11:36.910 --> 11:41.800
我们将创建一个得分函数来返回奖励的平均值和奖励窗口｡ 

11:41.980 --> 11:48.520
然后, 我们将使一个保存功能, 以保存大脑的汽车, 每当你想退出应用程序, 并回到它｡

11:48.610 --> 11:54.720
当然, 既然你想在你回到车上的时候能够加载你的汽车大脑, 那就回到应用程序上｡

11:54.730 --> 12:02.320
最后我们将创建一个load函数, 在你用save函数保存模型后, 它将加载你的模型｡

12:02.620 --> 12:06.280
剩下的三个函数, 但会很简单｡ 

12:06.280 --> 12:09.990
然后我们会看到第一个模块中最激动人心的部分｡ 

12:10.000 --> 12:11.470
这就是演示｡ 

12:11.500 --> 12:13.650
我们将看看API是否有效｡ 

12:13.660 --> 12:17.980
我们将看看赛车是否达到了目标, 我们将看看我们如何改进它｡ 

12:17.980 --> 12:21.670
然后最终你将建立你的第一个人工智能｡ 

12:21.940 --> 12:23.890
我等不及要开始演示了｡ 

12:23.920 --> 12:25.810
我们先做这三个函数｡ 

12:25.810 --> 12:27.130
在那之前, 好好享受吧｡ 

12:27.130 --> 12:27.670
一､ 
