大家好,我们再次见面。我是你的朋友。
零,为什么需要深Q
在上一期的文章“网格迷宫,Q-,”的结尾,我们提到了Q学习的固有缺陷:因为()依靠Q函数表(q)将其作为自变量。基于此,使用策略π进行了对当前状态的估计,并选择该动作。 Q函数表必须包含可能发生在环境中的所有动作状态对及其相应的Q值。显然,当多步决策问题变得足够复杂,甚至成为一个持续的决策或控制问题时,Q学习本身就无法应对。例如,对于复杂的多步骤决策问题,巨大而复杂的结构化Q表将变得难以存储和阅读;网格迷宫的长度和宽度每个将为10次,Q表将成为原始的100倍。对于持续的决策/控制问题,Q表无法记录所有状态。那么,如何解决这个问题?一个直接的想法是选择一个多函数,以近似q表中的“自变量”动作状态对与“因变量”的Q值之间的关系。但是,这样做仍然存在问题:对于不同的强化学习问题,Q表中的数据呈现出不同的曲线特征,并且只有通过找到与Q表数据匹配的函数形式,才能很好地近似Q表。显然,很难通过选择传统功能进行近似来自动化编程。神经网络()完全是与传统函数近似不同的解决方案。从数学角度来看,神经网络本质上是强大的非线性函数近似值。使用深层神经网络将神经网络与Q学习相结合会导致Q解决更复杂的问题和深Q-(DQN)。深Q-算法到底是什么样的?千江大学的MOOC有一个粗略的解释。以及如何实施深Q-? 和北京技术学院还详细介绍了该语言。尽管关于深Q程序和解释有许多权威且易于理解的内容;准确地了解深Q-算法并在其上实施它是实现强化学习控制的最终目标的关键。特别是在实施深Q-时,它不仅与程序结构中的先前Q差异很大,而且直接将其应用于连续的控制问题也将是一个非常跳跃的步骤。因此,在这个问题中,这个问题将重点放在之前和之后的两个问题上:如何使用神经网络使代理在网格迷宫中行走?为了分解这个问题,它包括两个部分:
如何使用神经网络盒?如何实施深度Q学习算法?
第三期主要包含两个部分。第一部分是上述内容,它简要介绍了深度Q学习的存在基础,另一部分解决了第一个小问题,并讨论了神经网络工具箱的使用。在第四期中,让我们详细讨论网格迷宫中深Q学习的实施。
1。神经网络工具箱()
自发布以来,我们提供了自定义神经网络模型的功能。到目前为止,除了机器学习方面的科学研究人员外,神经网络工具箱还能够满足其他用户对神经网络模型的大多数需求。除了使用()函数构建自定义的完全连接的前馈神经网络外,用户还可以直接调用封装的经典卷积神经网络()模型等。本文无意介绍或讨论有关神经网络中有关神经网络的理论知识细节,作者本人认为他没有对这些知识的全面讨论的能力和水平。如果您想了解有关这些知识的更多信息,则可以搬到千江大学的“机器学习与人工智能” MOOC和Zhou 教授的 Book。然而,这里需要在这里澄清一些概念,以促进随后的深Q-实施。
图1神经网络模型
简而言之,神经网络结构由多层神经单位和彼此之间的联系组成。对于完全连接的神经网络,A层的任何神经元A_1与下一个层B的所有神经元B_I都有连接,并且A层中的神经元与彼此没有连接;换句话说,任何B层都是任意的,神经元B_1的输入是上一层中所有神经元输出的加权总和。假设A层具有M神经元,并且B层具有n,则B层中的jth神经元的输入为:
其中w_ij是神经元对的连接重量。如上述公式所示,不同的权重反映了两个神经元之间连接的亲密性。在B层中的神经元内部,输入通过诸如relu之类的函数进行非线性转换以获得输出,然后传输到下一层。通过上述输送方法,前馈神经网络映射了从第一层到最后一层的输入以获得输出,而该结果是神经网络的预测输出。对于未经训练的神经网络,预测的输出显然不等于实际的预期结果。因此,我们需要训练具有正确结果的神经网络,使其能够真正适合数据集输入和输出之间的映射关系。这种训练方法称为()。最基本的反向传播训练方法是梯度下降()。基于这一点,为了提高向后流向训练的收敛速度,提出了梯度下降(带)和其他训练方法。此外,还提供了包括-之类的反向传播算法。考虑到特定的网格迷宫问题和构成控制问题,卷积神经网络(CNN)适合图像识别是我们所需要的。普通的前馈神经网络模型就足够了。除了使用()函数构建馈电神经网络外,它还提供了两个特殊的前馈神经网络,功能拟合网络()和模式识别网络()。对于网格迷宫问题,我们希望神经网络模型可以输出以状态行动对作为输入的相应Q值。因此,可以调用()函数以适合从状态行动对到Q函数值的映射关系。
2。致电和培训()
作为前馈神经网络的一种特殊形式,()与()本质上没有太大不同。两者的语言,呼叫,训练,计算和参数调整也是一致的。神经网络工具箱非常友好,可以直接使用代码线来完成前馈神经网络的结构初始化:
代码语言:
复制
%%构建指定层数及神经元数目的fitnet
QNet=fitnet([10,10,5]); %行向量的元素数为神经网络隐层的数目,每一个元素对应该层的神经元个数
同样,在构建了满足格式要求的培训数据集后,还提供了综合培训功能()用于培训神经网络:
代码语言:
复制
QNet=train(QNet,TrainsSet,TargetSet);
完成神经网络的培训后,我们可以使用神经网络来预测结果:
代码语言:
复制
Output=QNet(Input);
当训练神经网络和调用神经网络进行计算时,提供了使用GPU计算的选项:
代码语言:
复制
QNet=train(QNet,TrainsSet,TargetSet,’useGPU’,’yes’);
Output=QNet(Input,’useGPU’,’yes’);
对于普通的个人计算机,直接调用GPU进行神经网络操作的速度不如使用CPU操作快。因此,在随后的DQN实施中,我们不会致电GPU进行操作。
以后要使用的另一件事是神经网络模型中的一系列训练参数设置。在函数()中,本身并未定义用于反向传播和迭代收敛的任何参数,而是将这些参数保存在神经网络对象中。在培训过程中,()函数访问保存在神经网络对象中的训练参数以训练神经网络。通过这种方式,对于几乎所有神经网络,用户都可以以目标方式训练神经网络,而无需积极调整()参数。 ()函数的默认反向传播训练算法是 - 方法;虽然DQN所需的训练算法是梯度下降,但可以通过以下方式进行修改。其他培训参数的呼叫和修改也相似。
代码语言:
复制
QNet.trainFcn=’traingdx’ %修改为自适应动量梯度下降法
3。锻炼:安装二维表面
具体来说,我们使用拟合二维表面的问题来熟悉使用神经网络对象的使用:
代码语言:
复制
clear all;
%%构建指定层数及神经元数目的fitnet
QNet=fitnet([10,10,5]); %行向量的元素数为神经网络隐层的数目,每一个元素对应该层的神经元个数
%神经网络初始化后,内部参数尚处于没有训练的过程,输入层和输出层元素的个数也没有定义,可以通过训练进行定义
%%训练神经网络
%使用标记好的数据集对QNet进行训练。假设有k个样本,神经网络的输入变量为m个,输出变量为n个,则输入数据的格式为m行*k列的矩阵,输出数据为n行*k列的矩阵。
%我们在测试该网络时,假设它有两个自变量输入以及一个输出,因此如下生成训练数据集。
%假设目标函数为如下形式:
[X1,Y1]=meshgrid(0.1:0.1:3,0.2:0.2:6); %绘图用横纵坐标
target1=sin(1.5*sqrt(X1)+1*Y1);
x=0.1:0.1:3;
y=0.2:0.2:6;
%将上述结构转换成符合神经网络输入、输出的格式
Dataset=zeros(3,900);
for i=1:30
for j=1:30
Dataset(1,(i-1)*30+j)=x(i);
Dataset(2,(i-1)*30+j)=y(j);
Dataset(3,(i-1)*30+j)=target1(i,j);
end
end
%抽取其中部分数据得到训练数据集1
num1=200;
Trainset11=zeros(3,num1);
for i=1:num1
Trainset11(:,i)=Dataset(:,unidrnd(900));
end
%训练神经网络
QNet=train(QNet,Trainset11(1:2,:),Trainset11(3,:));
%%使用神经网络预测结果
%获得训练好的神经网络后,我们即可以用该神经网络根据输入预测输出
Input=Dataset(1:2,:); %生成与目标数据集相同的输入数据
Output1=QNet(Input);
Surf1=zeros(30,30);
for i=1:30
for j=1:30
Surf1(i,j)=Output1((i-1)*30+j);
end
end
%%绘图对比结果
%我们将神经网络的预测输出和实际函数值采用surf()函数进行可视化的对比
%彩色表面图为真实输出
surf(X1,Y1,target1,'FaceAlpha',0.5);
hold on;
%绿色表面图为预测输出
CO(:,:,1) = zeros(30); % red
CO(:,:,2) = ones(30).*linspace(0.2,0.8,30); % green
CO(:,:,3) = zeros(30); % blue
surf(X1,Y1,Surf1,CO,'FaceAlpha',0.7);
4。神经网络通话效率问题
在熟悉神经网络对象的一些基本用法方法之后,让我们最终谈论神经网络调用的效率。在传统的Q学习中,我们需要在代理商两次学习时获得当前状态行动对的Q值和下一个州行动对的Q值。该方法不断迁移到神经网络模型,这意味着我们需要调用qnet()分别计算两组数据集。这样,计算效率非常低。在上面训练的神经网络下,我们以以下方式进行比较:
代码语言:
复制
%代码1
num2=400;
Input1=Dataset(1:2,1:num2);
Output1=QNet(Input1);
代码语言:
复制
%代码2
num2=400;
Input1=Dataset(1:2,1:num2);
Output1=zeros(1,num2);
for i=1:num2
Output1(i)=QNet(Input(:,i));
End
使用运行和计时器函数比较两个代码的使用:
显然,这两个代码实现了相同的功能,但是时间显然不同。代码1的时间约为0.2,而代码2则需要超过4s。这是因为神经网络对象中的单个呼叫net。()和net。()需要很长时间。因此,在随后的编程中,为了提高程序的整体效率,必须考虑对神经网络的有效呼吁是必须考虑的关键点。
以上是我们要在第三期中讨论的全部内容。由于此问题不涉及复杂的代码,因此所有代码均在文章中介绍。欢迎所有读者讨论和奖励〜
版权声明:本文为 “博览广文网” 原创文章,转载请附上原文出处链接及本声明;
工作时间:8:00-18:00
客服电话
0755-88186625
电子邮件
admin@lanyu.com
扫码二维码
获取最新动态