大家好, 欢迎学习本Python教程｡
好了, 我们有非常令人兴奋的教程在等着我们｡
我们将从创建神经网络的架构开始｡
也就是说, 我们将制作一个神经网络, 它将是我们人工智能的核心, 它将在每次播放时返回动作｡
看到了吗？
所以我们开始吧｡
既然我们想让神经网络成为一个对象, 我们就创建一个类｡
那是因为这样更方便｡
知道一个类是我们要构建的东西的模型｡
我们想建立一个神经网络, 我们需要编写一些指令, 这些指令都包含在一个类中｡
在这节课里我们要做两个函数｡
首先是init函数, 这个函数在创建类的时候经常出现,
它基本上定义了对象的变量.
这就是神经网络, 你知道, 变量附加到对象上, 而不是全局变量｡
在这个init函数中, 定义了神经网络的架构,
定义了由五个输入神经元组成的输入层, 因为我们有五个维度来表示输入状态的编码向量,
然后我们定义了一些隐藏层｡
也许我们可以从一个隐藏层开始, 然后欢迎您尝试神经网络的其他架构｡
当然, 最后我们会得到输出层, 它包含了我们每次可以播放的可能动作｡
这就是我们在init函数中要做的｡
然后我们会在类中创建另一个函数,
它是前向函数, 这个函数会激活神经网络中的神经元, 激活信号.
因此, 我们将使用整流器激活函数, 因为我们处理的是纯非线性问题,
而整流器函数会破坏线性｡
但我们主要是让这个正向函数返回Q值, 这是神经网络的输出｡
但是我们为每个动作设置了一个提示值, 稍后我们将通过取提示值的最大值或使用软最大值方法返回最终动作｡
我们以后会看到的｡
因此, 在本教程中, 我们将从实现init函数开始, 在下一个教程中,
我们将实现forward函数｡
所以我们开始吧｡
首先, 我们需要介绍一下我们的类｡
所以我们从课堂开始｡
然后我们给我们的类取一个名字, 我们可以称之为网络｡
然后在这个网络类中, 我将使用一种对象编程技术, 叫做继承,
也就是从父类的所有工具中继承.
所以我们要创建的网络类是一个更大类的子类, 这个更大的类是一个RN DOT模块｡
这就是从这个模块类的所有工具继承而来的, 当然这些工具是用来实现神经网络的｡
这是面向对象编程中一个非常强大和有效的技巧, 叫做继承｡
现在我们继承的是这个模块的父类｡
好吧, 我会的
现在我们可以进入课堂了｡
所以我实际上按了两次回车键, 因为我们将创建两个函数, 我们从init函数开始｡
初始化函数, 我们必须用两个下划线来命名.
再强调一下, 这只是Python语法, 这就是我们必须要做的, 然后我们需要输入参数｡
所以我们有三个论点｡
第一个是强制性的论证, 实际上是自我和自我｡
这并不神秘, 它指的是, 从这个类中创建的对象, 我们将要创建的对象｡
你知道吗, 我们正在上这门课｡
这就像是一些指令, 一些我们想要建立的神经网络的模型｡
一旦课程准备好了, 我们就可以制作任意多个神经网络｡
每一个神经网络都是这个类的对象｡
因为我们将把对象用于其他目的, 所以我们需要找出对象的变量｡
为了发现这一点, 我们在这里用这个自我来说明我们所指的对象｡
所以每当我想使用对象的变量时, 我会在变量前使用self来指定这是对象的变量｡
好吧, 我会的
这是第一个论点｡
然后我们还有另外两个参数, 当然是输入神经元的数量和输出神经元的数量｡
输入神经元的数量, 我们称之为输入大小｡
这实际上是五个, 因为我们的输入向量有五个维度, 三个信号加上方向加上方向｡
这是我们的编码值向量, 描述了环境的一种状态｡
这五个值足以描述环境的状态｡
我们可以考虑更少的值或更多的值, 但这就是我所尝试的｡
这是有道理的, 因为我们实际上需要一个来自左边的信号, 一个在我们前面, 一个在右边｡
你知道, 当我们开车的时候, 我们可以选择360度的信号, 你知道,
就像谷歌汽车顶部的信号｡
但我们完全可以用三个传感器自行驾驶｡
然后我们有这个方向和负方向, 你知道, 跟踪我们试图达到的目标｡
当然, 我们还有神经网络的输出神经元, 它们对应于这些动作｡
我们有三种可能的行动, 向左, 直行, 或向右｡
所以我打算跟注并采取行动｡
而且会有三个人｡
好吧, 我会的
但到目前为止, 我们只需要给予输入命名, 然后我们将使用这些变量在神经网络内部进行计算｡
好吧, 那么｡
我将从另一个PyTorch技巧开始｡
这一招就是超级功能｡
这是一个从RN模块继承的函数｡
所以这就是为什么我们必须使用继承来继承模块工具｡
这是我们使用的第一个工具｡
所以基本上我们只使用了这个超级技巧, 这个超级函数, 来使用模块的工具｡
这样效率更高｡
在这个超级函数中, 我只需要首先指定网络｡
这就是我们的网络子类,
因为它继承自模块父类, 然后是我们的对象, 然后我添加点和/或init函数, 就像我们命名的那样｡
好吧, 我会的
这只是一个技巧, 就是使用该模块中的和的所有工具, 然后我们可以继续下一步,
即指定输入层｡
所以基本上我要做的就是引入一个新的变量, 这个变量将被附加到这个对象上,
这个变量将包含输入神经元的数量｡
因此不要与输入大小混淆｡
Input size是init函数的参数, 但它不是附加到对象的变量,
而是附加到对象的变量｡
正如我刚才提到的, 我们需要指定它被附加到对象上｡
所以我们用了一个self点, 现在我们给予这个对象的第一个变量命名｡
所以我们可以简单地给予出与输入相同的名称｡
我们可以称之为输入大小, 我们会说它等于init函数的参数, 即输入大小｡
好吧, 我会的
所以每次我从网络类创建一个对象, 我指定输入大小,
比如说, 我输入5,
这里会有一个5, 所以我们对象的输入大小变量的值会是5, 因为这里的输入大小是5,
所以我们的神经网络在输入层会有5个输入神经元｡
好吧, 我会的
对于另一个我们想附加到对象上的变量也是一样的｡
你可能已经猜到了, 这是输出神经元数量的变量｡
比如说, 我们取对象self, 然后我们给对象的第二个变量取一个名字,
我们称它为action｡
这将等于这个参数, 给出动作的数量, 也就是输出神经元的数量｡
所以我们把它设为等于和是行动｡
所以实际上和被作用的将等于三｡
因此, 把变量和作用附加到我们的对象网络上就会得到三的值｡
实际上, 我们可以在这里看到一个警告｡
它写着未定义的名称, 因为这里我们使用了RN的快捷方式, 我们需要在这里使用这个快捷方式,
然后在模块的末尾, 它就会消失｡
我们走吧｡
好极了｡
现在我们没有任何警告｡
这里的所有警告只是为了指明我们导入的内容尚未使用｡
不过没关系
之后我们会用到它们｡
好的, 我们还有另外两个变量｡
我们要定义四个对象｡
这将是完整的连接, 我们神经网络不同层之间的完整连接｡
既然现在我们要做一个只有一个隐藏层的神经网络, 那么, 就有两个完整的连接｡
在输入层和隐藏层之间将存在1/1全连接, 并且在隐藏层和输出层之间将存在1/2全连接｡
让我们从第一个完整连接开始｡
我们称之为FC 1｡
同样, 我在这里用self来指定FC1是对象的变量｡
所以我就是FC的那个｡
这将等于｡
现在我们使用RN模块, 我们将使用一个叫做线性的函数｡
这就是在输入层的神经元和隐藏层的神经元之间建立完整的连接｡
我说的完全连接是什么意思？
这意味着输入层的所有神经元都将连接到隐藏层的所有神经元｡
为了建立完整的联系, 我们使用这个线性函数, 我们需要输入一些参数｡
正如你所看到的, 这些论点都在功能中｡
这就是我们想要连接的第一层神经元的数量｡
然后是输出特征, 也就是我们想要连接的第二层神经元的数量｡
这是右边的层, 这是隐藏的层, 偏置等于真｡
所以有偏见就等于正确｡
我们将保留默认值, 这是为了有一个偏置, 而不仅仅是一些连接到神经元的方式,
我们将有权重和每层的一个偏置｡
让我们看看需要输入什么｡
因此, 特征中的第一个参数是输入层中输入神经元的数量｡
那是什么呢？
这实际上是输入大小｡
这是init函数的参数, 它在后面会等于5, 这三个信号的方向和负方向｡
我们开始吧｡
我们输入第一个参数输入大小｡
第二个论点是关于特性的｡
这就是我们想要在第二层中的神经元的数量, 第二层与第一层完全相连.
所以现在的问题是, 我们想要在这个隐藏层中有多少个神经元？
嗯, 我做了很多参数调整｡
我做了很多实验｡
这就是我们在人工智能或深度学习中所做的｡
一般来说, 我们会做很多实验, 看看什么样的神经网络最适合我们的特定问题｡
所以我尝试了很多数值, 最后我选择了30个, 30个神经元在一个隐藏层｡
你会看到, 用这个数字, 我们会得到一些相当不错的结果｡
但随后可以随意更改神经网络的架构｡
随便玩吧｡
你不仅可以改变隐藏层中隐藏神经元的数量, 还可以添加更多的层,
这样也许你就能得到一辆更好的车｡
但是3000个神经元会给我们带来一个好的神经网络和一辆好车｡
这就是我们的目标｡
好了
我们第一次和这个线性函数建立了完整的联系｡
我们在输入层和隐藏层之间建立了完整的连接｡
现在是时候进行第二次完全连接了｡
这是隐藏层和输出层之间的完整连接｡
好了, 我们走吧｡
我们称之为第二个全连接｡
FC 2我们走.
这仍然是一个来自对象的变量｡
我在这里用了一些东西, 然后我们再用,
实际上我们可以复制它, 因为我们要用RN模块, 然后是线性函数, 但是我们首先需要改变参数｡
那是一样的｡
首先是我们希望在食物连接的第一层中有多少神经元｡
这是隐藏层, 因此是30｡
第二个参数是食物连接的第二层中的神经元数量, 这对应于输出层｡
输出层有和是动作神经元, 以后会有三个, 因为我们有三种可能的动作｡
但是到目前为止我们必须使用我们定义的名字, 也就是init函数的参数的名字, 因此我们在这里输入和be
action｡
好了
首先, 我们的两个完整连接已经就绪, 其次, 我们的init函数已经就绪｡
这就是我们在从网络类创建对象时, 初始化对象的方法.
一旦我们创建了一个对象, 所有这些变量, 这里输入的四个变量的大小和动作FC 1和FC
2将被定义｡
这就是我们如何得到神经网络的架构｡
对于我们创建的每个对象, 每个对象将对应于一个由5个输入神经元､
30个隐藏神经元和3个输出神经元组成的神经网络｡
好了, 我们走吧｡
我们已经完成了第一个初始化函数,
现在我们可以转到第二个函数, 它是前向函数,
将用于通过整流器激活函数激活神经网络中的神经元, 并且主要用于最终返回Q值, 即神经网络的输出｡
所以我迫不及待地想在下一个教程中做这件事｡
在那之前, 好好享受吧｡
一､