WEBVTT

00:00.180 --> 00:02.610
大家好, 欢迎学习本Python教程｡ 

00:02.820 --> 00:07.710
好的, 在这个新的代码部分, 我们将实现体验回放｡ 

00:07.710 --> 00:13.770
所以我们要建立一个新的类, 我们称之为回放记忆, 它将实现经验, 回放,

00:13.770 --> 00:16.590
就像你们在直觉课上看到的那样.

00:16.590 --> 00:21.330
但首先, 让我们给予一个快速提醒什么是经验重放｡ 

00:21.330 --> 00:26.550
所以, 你知道, 所有这些人工智能都是基于马尔可夫决策过程｡ 

00:26.550 --> 00:31.710
马尔可夫决策过程包括观察一系列事件｡ 

00:31.710 --> 00:38.610
因此, 事件例如从一个状态S-T到下一个状态T加1｡ 

00:38.850 --> 00:44.310
但如果事件是这样的, 那么, 由于下一个状态与当前状态非常相关, 那么,

00:44.310 --> 00:46.740
网络就不会学习得很好｡

00:46.740 --> 00:54.750
所以对于那些来自深度学习课程的人来说, 这和我们只用一个时间步长学习时间序列是完全一样的｡

00:54.780 --> 01:02.550
它没有学习到任何东西, 因为一个时间步长不足以让我们的模型学习理解长期相关性｡

01:02.850 --> 01:06.960
所以这里也是一样的, 这就是为什么我们要实现体验回放｡ 

01:06.960 --> 01:08.160
那么它是如何工作的呢？

01:08.160 --> 01:09.180
这很简单

01:09.180 --> 01:13.890
而不是只考虑当前状态, 那就是一次只考虑一个状态｡ 

01:13.890 --> 01:23.610
我们会考虑更多的过去, 所以就像对于更少的TMS一样, 因此我们的一系列事件不会是SD和SD加1｡

01:23.640 --> 01:27.240
例如, 这将是过去的100个州｡ 

01:27.240 --> 01:33.600
所以T-100等于T-99, 一直到C减1, 然后s T｡ 

01:33.750 --> 01:40.230
换句话说, 我们把少了100次的转换放入我们所谓的记忆中, 这就是我们的长期记忆, 而不是短期记忆,

01:40.230 --> 01:46.080
或者甚至, 我应该说, 是瞬间记忆｡

01:46.080 --> 01:49.740
这使得整个深度学习过程更好地工作｡ 

01:50.040 --> 01:57.240
然后, 一旦我们创建了最近100个事件的内存, 我们将进行采样, 也就是说,

01:57.240 --> 02:02.100
我们将随机抽取这些转换的一些批次, 以进行下一次更新｡

02:02.100 --> 02:05.580
这就是我们选择下一步行动的下一步行动｡ 

02:05.910 --> 02:13.260
因此, 在这个我们为体验回放而实现的回放内存类中, 我们将创建三个函数｡

02:13.260 --> 02:15.630
首先, init函数照常执行｡ 

02:15.630 --> 02:17.250
任何类都是如此｡ 

02:17.250 --> 02:23.250
所以在这个init函数中, 我们将定义变量, 这些变量将被附加到类的未来实例上, 也就是说,

02:23.250 --> 02:27.060
未来的对象将从这个类中创建｡

02:27.270 --> 02:33.150
很简单,

02:33.150 --> 02:39.510
这些变量是100个转换到100个事件的内存, 容量是100, 欢迎你通过增加容量来尝试更长的内存｡

02:39.510 --> 02:42.060
这是函数中的第一个函数｡ 

02:42.210 --> 02:51.000
然后我们将创建另外两个函数, 一个是push函数, 用于确保内存中包含的转换数不超过100｡

02:51.000 --> 02:58.590
为此, 我们将通过一个简单的if条件来使用容量, 然后最终我们将创建样本函数｡

02:58.590 --> 03:04.740
当然, 这将是对最后100个转换的存储器中的一些转换进行采样｡ 

03:05.340 --> 03:05.670
好吧, 我会的

03:05.670 --> 03:08.340
我们先来介绍一下这个类｡ 

03:08.340 --> 03:12.510
像往常一样, 我们从类开始, 然后给予类命名.

03:12.510 --> 03:15.690
所以我们称之为回放记忆｡ 

03:16.980 --> 03:23.340
然后在括号中输入对象, 然后输入列, 然后开始｡ 

03:23.340 --> 03:26.730
我们从第一个函数init函数开始｡ 

03:26.970 --> 03:30.600
所以这和我们从死亡开始之前的情况完全一样｡ 

03:30.600 --> 03:36.480
然后在里面加下划线, 再加下划线然后是变量｡ 

03:36.480 --> 03:43.350
当然还有self, 它是一个变量, 附加在类的未来实例, 未来对象上｡

03:43.440 --> 03:49.170
然后我们会有另一个变量, 让你能够尝试其他的体验, 取代其他的记忆,

03:49.170 --> 03:52.410
这就是容量｡

03:52.710 --> 04:00.180
所以这个容量就是100, 因为我们要用100个最后的转换来进行体验回放｡

04:00.810 --> 04:01.230
好吧, 我会的

04:01.230 --> 04:03.810
然后是科林, 我们开始吧.

04:03.810 --> 04:10.170
让我们进入函数内部, 定义重放内存对象的变量｡ 

04:10.170 --> 04:14.670
所以第一个将是自我打点能力｡ 

04:15.970 --> 04:24.580
你们可能已经理解了, 这是我们记忆中最大的转变次数｡

04:24.580 --> 04:34.210
这将等于我们在创建重放内存类的对象时输入的参数, 因此这就是容量｡

04:34.300 --> 04:36.430
这是init函数的参数｡ 

04:36.430 --> 04:37.660
所以容｡ 

04:37.960 --> 04:46.180
因此再次强调, 不要混淆, 自我能力是附于客体和能力的变量的名称｡

04:46.180 --> 04:52.030
下面是我们在创建replay memory类的对象时将输入的参数｡ 

04:52.710 --> 04:53.550
好吧, 我会的

04:53.550 --> 04:55.770
然后我们有第二个变量｡ 

04:55.860 --> 04:57.750
那当然是记忆｡ 

04:57.750 --> 05:00.240
所以自我打点记忆｡ 

05:01.630 --> 05:02.290
好吧, 我会的

05:02.620 --> 05:05.650
那么这个内存变量等于什么呢？

05:05.770 --> 05:13.240
这个内存应该包含最近的100个事件, 因此, 这应该是一个简单的列表,

05:13.240 --> 05:18.880
一个包含最近100个事件, 最近100个转换的列表｡

05:19.210 --> 05:22.030
而要初始化列表, 没有什么比这更简单的了｡ 

05:22.030 --> 05:25.900
我们只需要加一些括号就可以了｡ 

05:25.900 --> 05:27.610
我们的内存已初始化｡ 

05:27.610 --> 05:32.590
所以当然, 在实验开始的时候, 或者更准确地说, 在探索开始的时候,

05:32.620 --> 05:34.330
记忆将是一个空的列表｡

05:34.330 --> 05:38.320
然后, 我们将在每次到达未来状态时进行转换｡ 

05:38.320 --> 05:44.590
说到这个, 这正是我们要做的下一个函数, 我们称之为push函数｡

05:44.590 --> 05:49.570
我们将使用这个push函数来将事件追加到这个内存列表中｡ 

05:49.570 --> 05:56.980
然后, 我们将使用容量来确保这个记忆列表总是包含100个事件, 而不会超过100个｡

05:57.340 --> 05:59.500
好的, 让我们在下一个教程中做这个｡ 

05:59.500 --> 06:00.820
在那之前, 好好享受吧｡ 

06:00.820 --> 06:01.330
一､ 
