MATLAB强化学习入门——三、深度Q学习与神经网络工具箱(matlab入门图文教程)
零、為什么需要深度Q學(xué)習(xí)
上一期的文章《網(wǎng)格迷宮、Q-learning算法、Sarsa算法》的末尾,我們提到了Q學(xué)習(xí)固有的缺陷:由于智能體(agent)依賴以狀態(tài)-動(dòng)作對(duì)為自變量的Q函數(shù)表(Q Function Table)來形成對(duì)當(dāng)前狀態(tài)的估計(jì),并以此為依據(jù)利用策略π選擇動(dòng)作。Q函數(shù)表就必須包含智能體在環(huán)境中所可能出現(xiàn)的所有動(dòng)作-狀態(tài)對(duì)及其對(duì)應(yīng)Q值。顯然,當(dāng)一個(gè)多步?jīng)Q策問題變得足夠復(fù)雜甚至變?yōu)檫B續(xù)決策或控制問題時(shí),Q學(xué)習(xí)本身是無力應(yīng)對(duì)的。例如,對(duì)于復(fù)雜的多步?jīng)Q策問題,龐大而結(jié)構(gòu)復(fù)雜的Q表將變得難以存儲(chǔ)和讀取;將網(wǎng)格迷宮的長(zhǎng)、寬各擴(kuò)大10倍,Q表則變成原來的100倍。對(duì)于連續(xù)決策/控制問題時(shí),Q表更是無法記錄所有的狀態(tài)。
那么,如何解決這一問題呢?
一個(gè)直截的想法就是,選擇某個(gè)多元函數(shù),逼近Q表中“自變量”動(dòng)作-狀態(tài)對(duì)與“因變量”Q值形成的關(guān)系。但這樣做依然存在問題:對(duì)于不同的強(qiáng)化學(xué)習(xí)問題,Q表中的數(shù)據(jù)呈現(xiàn)出各異的曲線特性,只有找到符合Q表數(shù)據(jù)的函數(shù)形式,才可能良好的逼近Q表。選擇傳統(tǒng)函數(shù)進(jìn)行逼近,顯然是很難實(shí)現(xiàn)編程自動(dòng)化的。
神經(jīng)網(wǎng)絡(luò)(Neural Network)恰恰是這么一種有別于傳統(tǒng)函數(shù)逼近的解決方案。而從數(shù)學(xué)的角度講,神經(jīng)網(wǎng)絡(luò)本質(zhì)上就是一種強(qiáng)大的非線性函數(shù)逼近器。將神經(jīng)網(wǎng)絡(luò)與Q學(xué)習(xí)結(jié)合起來,就得到了能夠解決更復(fù)雜問題的Q-Network以及使用深度神經(jīng)網(wǎng)絡(luò)的Deep-Q-Network (DQN)。
Deep-Q-Learning的算法究竟是什么樣的?浙江大學(xué)的《機(jī)器學(xué)習(xí)和人工智能》MOOC有著大致的講解。而如何實(shí)現(xiàn)Deep-Q-Learning?莫煩Python以及北理工的MOOC也給出了Python語言的詳細(xì)示范。
盡管有關(guān)Deep-Q-Learning的程序和講解已經(jīng)很多權(quán)威且易懂的內(nèi)容;準(zhǔn)確的理解Deep-Q-Learning算法,并在MatLab上實(shí)現(xiàn),則是完成強(qiáng)化學(xué)習(xí)控制這個(gè)最終目標(biāo)的關(guān)鍵。具體到Deep-Q-Learning的實(shí)現(xiàn)上,它不僅與之前的Q-Learning在程序結(jié)構(gòu)上有著相當(dāng)大的區(qū)別,直接將它應(yīng)用于連續(xù)控制問題也會(huì)是非常跳躍的一步。因此,在這一期的文章里,問題將聚焦在前后兩個(gè)問題之間:如何使用神經(jīng)網(wǎng)絡(luò)讓智能體走好網(wǎng)格迷宮?
將這個(gè)問題再細(xì)分開來,則包括兩部分:
- 如何使用MatLab的神經(jīng)網(wǎng)絡(luò)工具箱?
- 如何實(shí)現(xiàn)深度Q學(xué)習(xí)算法?
第三期主要包含兩部分內(nèi)容,第一部分即上文,簡(jiǎn)要介紹了深度Q學(xué)習(xí)的存在基礎(chǔ),另一部分則解決第一個(gè)小問題,討論一下MatLab神經(jīng)網(wǎng)絡(luò)工具箱的使用。在第四期,我們?cè)僭敿?xì)聊一聊深度Q學(xué)習(xí)在網(wǎng)格迷宮中的實(shí)現(xiàn)。
一、神經(jīng)網(wǎng)絡(luò)工具箱(Neural Network Toolbox)
MatLab自版本R2006a就開始提供自定義構(gòu)建神經(jīng)網(wǎng)絡(luò)模型的函數(shù);到目前為止,除機(jī)器學(xué)習(xí)方向科研人員外,Matlab的神經(jīng)網(wǎng)絡(luò)工具箱已經(jīng)能滿足其余使用者對(duì)神經(jīng)網(wǎng)絡(luò)模型的絕大部分需求。用戶除去可以使用feedforwardnet()函數(shù)構(gòu)建定制的全連接前饋神經(jīng)網(wǎng)絡(luò)外, 還可以直接調(diào)用封裝好的經(jīng)典卷積神經(jīng)網(wǎng)絡(luò)(convolutional neural network)模型ALEXnet、VGG16、Googlenet等。
本文不打算詳細(xì)介紹或討論關(guān)于神經(jīng)網(wǎng)絡(luò)方面的理論知識(shí),作者本人自忖也沒有綜論這方面知識(shí)的能力和水平。如果想要進(jìn)一步了解這方面知識(shí)的,可以移步浙江大學(xué)《機(jī)器學(xué)習(xí)和人工智能》MOOC以及周志華教授的西瓜書。盡管如此,一些概念還是需要在此闡明一下,以方便之后Deep-Q-Network的實(shí)現(xiàn)。
| 圖1 神經(jīng)網(wǎng)絡(luò)模型 |
|---|
簡(jiǎn)言之,神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)有多層的神經(jīng)元單元及相互之間的連接構(gòu)成。對(duì)于全連接神經(jīng)網(wǎng)絡(luò),任意一層A的任意一個(gè)神經(jīng)元a_1都存在與下一層B的所有神經(jīng)元b_i的連接,A層內(nèi)的神經(jīng)元?jiǎng)t不相互連接;換句話說,B層的任意一個(gè)神經(jīng)元b_1的輸入為上一層所有神經(jīng)元輸出的加權(quán)總和。假設(shè)A層有m個(gè)神經(jīng)元,B層有n個(gè),則B層第j個(gè)神經(jīng)元的輸入為:
其中w_ij為神經(jīng)元對(duì)的連接權(quán)重。如上式所表示的,不同的權(quán)重反映了兩神經(jīng)元之間聯(lián)系的緊密程度。在B層的神經(jīng)元內(nèi)部,則將輸入IN_bj通過例如Sigmoid和Relu等函數(shù)將輸入進(jìn)行非線性變換得到輸出,再傳輸至下一層。通過如上的傳遞方式,前饋神經(jīng)網(wǎng)絡(luò)將輸入從第一層映射至最后層獲得輸出,這一結(jié)果即為神經(jīng)網(wǎng)絡(luò)的預(yù)測(cè)輸出。
對(duì)于一個(gè)未訓(xùn)練的神經(jīng)網(wǎng)絡(luò),預(yù)測(cè)輸出顯然不會(huì)與實(shí)際期望結(jié)果相等。也因此,我們需要標(biāo)注了正確結(jié)果的數(shù)據(jù)訓(xùn)練神經(jīng)網(wǎng)絡(luò),使它能夠真正擬合數(shù)據(jù)集輸入與輸出間的映射關(guān)系。而這一訓(xùn)練方式,我們稱為反向傳播(backpropagation)。最基礎(chǔ)的反向傳播訓(xùn)練方法為梯度下降法(gradient descent),以此為基礎(chǔ),為提高反向傳播訓(xùn)練的收斂速度,又提出了帶動(dòng)量的梯度下降法(gradient descent with momentum)等訓(xùn)練方法;另外,在MatLab中,還提供包括Levenberg-Marquardt方法等的反向傳播算法。
考慮具體的網(wǎng)格迷宮問題以及姿態(tài)控制問題,適用于圖像識(shí)別的卷積神經(jīng)網(wǎng)絡(luò)(CNN)并不是我們所需要的。普通的前饋神經(jīng)網(wǎng)絡(luò)模型即以足夠,MatLab除去可以使用feedforwardnet()函數(shù)構(gòu)建前饋神經(jīng)網(wǎng)絡(luò)外,還提供了函數(shù)擬合網(wǎng)絡(luò)fitnet()、模式識(shí)別網(wǎng)絡(luò)patternnet()兩種特殊的前饋神經(jīng)網(wǎng)絡(luò)。
對(duì)于網(wǎng)格迷宮問題,我們希望神經(jīng)網(wǎng)絡(luò)模型能夠在以狀態(tài)-動(dòng)作對(duì)為輸入的情況下輸出對(duì)應(yīng)Q值。因此,可以調(diào)用fitnet()函數(shù)去擬合從狀態(tài)-動(dòng)作對(duì)至Q函數(shù)值的映射關(guān)系。
二、fitnet()的調(diào)用與訓(xùn)練
作為前饋神經(jīng)網(wǎng)絡(luò)的一種特殊形式,fitnet()本質(zhì)上與feedforwardnet()沒有太大差別。從MatLab語言上來說,兩者的調(diào)用、訓(xùn)練、計(jì)算以及參數(shù)的調(diào)整也都是一致的。
MatLab神經(jīng)網(wǎng)絡(luò)工具箱對(duì)用戶非常友好,可以直接使用一行代碼完成前饋神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)初始化:
%%構(gòu)建指定層數(shù)及神經(jīng)元數(shù)目的fitnet
QNet=fitnet([10,10,5]); %行向量的元素?cái)?shù)為神經(jīng)網(wǎng)絡(luò)隱層的數(shù)目,每一個(gè)元素對(duì)應(yīng)該層的神經(jīng)元個(gè)數(shù)
同樣,構(gòu)建好符合格式要求的訓(xùn)練數(shù)據(jù)集后,MatLab也提供集成化的訓(xùn)練函數(shù)train()進(jìn)行神經(jīng)網(wǎng)絡(luò)的訓(xùn)練:
QNet=train(QNet,TrainsSet,TargetSet);
完成神經(jīng)網(wǎng)絡(luò)的訓(xùn)練后,我們即可以使用該神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)結(jié)果了:
Output=QNet(Input);
在訓(xùn)練神經(jīng)網(wǎng)絡(luò)和調(diào)用神經(jīng)網(wǎng)絡(luò)進(jìn)行計(jì)算時(shí),MatLab提供了使用GPU進(jìn)行計(jì)算的選項(xiàng):
QNet=train(QNet,TrainsSet,TargetSet,’useGPU’,’yes’);
Output=QNet(Input,’useGPU’,’yes’);
對(duì)于普通個(gè)人電腦,直接調(diào)用GPU進(jìn)行神經(jīng)網(wǎng)絡(luò)運(yùn)算的速度并不如使用CPU運(yùn)算。因此,在之后的DQN實(shí)現(xiàn)中,我們也不會(huì)調(diào)用GPU進(jìn)行運(yùn)算。
另一個(gè)隨后要用到的,是神經(jīng)網(wǎng)絡(luò)模型中一系列有關(guān)訓(xùn)練的參數(shù)設(shè)置。MatLab中,train()函數(shù)本身并不定義反向傳播和迭代收斂的任何參數(shù),而將這些參數(shù)保存在神經(jīng)網(wǎng)絡(luò)對(duì)象中。在訓(xùn)練過程中,train()函數(shù)訪問神經(jīng)網(wǎng)絡(luò)對(duì)象中保存的訓(xùn)練參數(shù)對(duì)神經(jīng)網(wǎng)絡(luò)進(jìn)行訓(xùn)練。這樣,對(duì)于幾乎所有神經(jīng)網(wǎng)絡(luò),用戶都能在不主動(dòng)調(diào)整train()參數(shù)情況下有針對(duì)性地對(duì)神經(jīng)網(wǎng)絡(luò)進(jìn)行訓(xùn)練。fitnet()函數(shù)默認(rèn)的反向傳播訓(xùn)練算法為L(zhǎng)evenberg-Marquardt方法;而DQN所需要的訓(xùn)練算法則為梯度下降法,可以用如下的方式進(jìn)行修改。而其它訓(xùn)練參數(shù)的調(diào)用與修改也是類似的。
QNet.trainFcn=’traingdx’ %修改為自適應(yīng)動(dòng)量梯度下降法
三、練習(xí):擬合二維曲面
具體的來說,我們用一個(gè)擬合二維曲面的問題來熟悉神經(jīng)網(wǎng)絡(luò)這一對(duì)象的使用:
clear all;
%%構(gòu)建指定層數(shù)及神經(jīng)元數(shù)目的fitnet
QNet=fitnet([10,10,5]); %行向量的元素?cái)?shù)為神經(jīng)網(wǎng)絡(luò)隱層的數(shù)目,每一個(gè)元素對(duì)應(yīng)該層的神經(jīng)元個(gè)數(shù)
%神經(jīng)網(wǎng)絡(luò)初始化后,內(nèi)部參數(shù)尚處于沒有訓(xùn)練的過程,輸入層和輸出層元素的個(gè)數(shù)也沒有定義,可以通過訓(xùn)練進(jìn)行定義
%%訓(xùn)練神經(jīng)網(wǎng)絡(luò)
%使用標(biāo)記好的數(shù)據(jù)集對(duì)QNet進(jìn)行訓(xùn)練。假設(shè)有k個(gè)樣本,神經(jīng)網(wǎng)絡(luò)的輸入變量為m個(gè),輸出變量為n個(gè),則輸入數(shù)據(jù)的格式為m行*k列的矩陣,輸出數(shù)據(jù)為n行*k列的矩陣。
%我們?cè)跍y(cè)試該網(wǎng)絡(luò)時(shí),假設(shè)它有兩個(gè)自變量輸入以及一個(gè)輸出,因此如下生成訓(xùn)練數(shù)據(jù)集。
%假設(shè)目標(biāo)函數(shù)為如下形式:
[X1,Y1]=meshgrid(0.1:0.1:3,0.2:0.2:6); %繪圖用橫縱坐標(biāo)
target1=sin(1.5*sqrt(X1)+1*Y1);
x=0.1:0.1:3;
y=0.2:0.2:6;
%將上述結(jié)構(gòu)轉(zhuǎn)換成符合神經(jīng)網(wǎng)絡(luò)輸入、輸出的格式
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
%抽取其中部分?jǐn)?shù)據(jù)得到訓(xùn)練數(shù)據(jù)集1
num1=200;
Trainset11=zeros(3,num1);
for i=1:num1
Trainset11(:,i)=Dataset(:,unidrnd(900));
end
%訓(xùn)練神經(jīng)網(wǎng)絡(luò)
QNet=train(QNet,Trainset11(1:2,:),Trainset11(3,:));
%%使用神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)結(jié)果
%獲得訓(xùn)練好的神經(jīng)網(wǎng)絡(luò)后,我們即可以用該神經(jīng)網(wǎng)絡(luò)根據(jù)輸入預(yù)測(cè)輸出
Input=Dataset(1:2,:); %生成與目標(biāo)數(shù)據(jù)集相同的輸入數(shù)據(jù)
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
%%繪圖對(duì)比結(jié)果
%我們將神經(jīng)網(wǎng)絡(luò)的預(yù)測(cè)輸出和實(shí)際函數(shù)值采用surf()函數(shù)進(jìn)行可視化的對(duì)比
%彩色表面圖為真實(shí)輸出
surf(X1,Y1,target1,'FaceAlpha',0.5);
hold on;
%綠色表面圖為預(yù)測(cè)輸出
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);
四、神經(jīng)網(wǎng)絡(luò)的調(diào)用效率問題
在熟悉了神經(jīng)網(wǎng)絡(luò)對(duì)象的一些基本使用方法后,我們最后來聊一聊神經(jīng)網(wǎng)絡(luò)的調(diào)用效率問題。在傳統(tǒng)的Q學(xué)習(xí)中,我們需要在智能體進(jìn)行一步學(xué)習(xí)時(shí)兩次Q表以獲得當(dāng)前狀態(tài)-動(dòng)作對(duì)以及下一狀態(tài)-動(dòng)作對(duì)的Q值。將這一方法不變的遷移到神經(jīng)網(wǎng)絡(luò)模型中,也就是說我們需要調(diào)用QNet()分別對(duì)兩組單獨(dú)的數(shù)據(jù)進(jìn)行計(jì)算,在MatLab中,這樣的計(jì)算效率是非常低的。在上文訓(xùn)練完成的神經(jīng)網(wǎng)絡(luò)下,我們用下面的方式進(jìn)行對(duì)比:
%代碼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
使用運(yùn)行并計(jì)時(shí)功能對(duì)比兩段代碼的用時(shí):
顯然,這兩段代碼實(shí)現(xiàn)了相同的功能,然而耗時(shí)卻明顯不同。代碼1用時(shí)約0.2s,代碼2用時(shí)卻超過4s。這是因?yàn)镸atLab神經(jīng)網(wǎng)絡(luò)對(duì)象中的內(nèi)置函數(shù)net.Hints()及net.subserf()等函數(shù)的單次調(diào)用耗時(shí)較長(zhǎng)的原因。
也因此,在之后的編程中,為了提高程序的整體效率,高效調(diào)用神經(jīng)網(wǎng)絡(luò)是必須要考慮的重點(diǎn)。
以上就是第三期我們要討論的全部?jī)?nèi)容,由于這一期并不涉及結(jié)構(gòu)復(fù)雜的代碼,所以全部代碼均在文章中呈現(xiàn)。
十分歡迎各位讀者討論和打賞~
總結(jié)
以上是生活随笔為你收集整理的MATLAB强化学习入门——三、深度Q学习与神经网络工具箱(matlab入门图文教程)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TSQL–标示列、GUID
- 下一篇: 计算机中的五大部件分别是什么