日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Deep QLearning算法详解(强化学习 Reinforcement Learning)

發布時間:2023/12/3 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 Deep QLearning算法详解(强化学习 Reinforcement Learning) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、算法詳解

文章最后附有博主自己實現的深度qlearning玩space invader游戲

本文介紹的是基于神經網絡的qlearning算法。我們知道傳統的qlearning算法只能處理狀態和動作有限的情況,對于無窮多,則是無法有效處理的。現實生活中,環境的狀態肯定是無窮多的,而神經網絡正好可以處理這樣的情況。這里深度qlearning算法使用一個神經網絡來表示一個q表,無論環境的狀態有沒有出現過,我們都可以將狀態輸入到神經網絡,去評估價值函數。

1.1 幾個概念

1.1.1 什么是critic?

critic:批評家,評論家。
在這里算法要更新就是一個critic,而不是一個actor(agent),使用critic來間接指導actor做決策,critic的作用就是評估一個actor有多好,水平高不高。

1.1.2 狀態價值函數Vπ(s)V ^{\pi }(s)Vπ(s)和狀態動作價值函數Qπ(s,a)Q^{\pi }(s,a)Qπ(s,a),以及他們之間的關系

π\piπ表示一個actor,s是一個狀態,a是指actor看到狀態s時做出的動作

  1. Vπ(s)V ^{\pi }(s)Vπ(s)指使用actor π\piπ時,當看到狀態s時,計算累計獎勵的期望值
    舉個例子吧,不然有點難以理解,這里計算的依然是累計獎勵的期望值。我個人理解,如果要寫出具體 Vπ(s)V ^{\pi }(s)Vπ(s)公式的話,應該是這樣
    Vπ(s)=∑τR(τ,s)p(τ)(1)V^{\pi}(s)=\sum_{\tau }R(\tau ,s)p(\tau)\tag{1}Vπ(s)=τ∑?R(τ,s)p(τ)(1)
    公式解釋:R(τ,s)R(\tau ,s)R(τ,s)表示在一個eposide內,只計算s之后的所有累計獎勵的和。比如τ={s1,a1,r1,s2,a2,r2,...,sT,aT,rT,End}\tau =\{s_{1},a_{1},r_{1},s_{2},a_{2},r_{2},...,s_{T},a_{T},r_{T},End\}τ={s1?,a1?,r1?,s2?,a2?,r2?,...,sT?,aT?,rT?,End},我們計算R(τ,s2)R(\tau ,s_{2})R(τ,s2?),由上面的定義知道,R(τ,s2)=r2+...+rTR(\tau ,s_{2})=r_{2}+...+r_{T}R(τ,s2?)=r2?+...+rT?,這里沒有計算r1r_{1}r1?,只計算看到s2s_{2}s2?之后的所有獎勵。p(τ)p(\tau)p(τ)表示eposide τ\tauτ出現的概率。
    舉一個sutton強化學習書上的例子。
    例子1:
    假設我們采樣得到8個eposides,分別如下:
    1、sa,r=0,sb,r=0,Ends_{a},r=0,s_{b},r=0,Endsa?,r=0,sb?,r=0,End
    2、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    3、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    4、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    5、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    6、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    7、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    8、sb,r=0,Ends_{b},r=0,Endsb?,r=0,End
    這里給出了8個采樣得到的eposide,并且忽略所采取的動作,這里是采樣得到8個eposide來逼近Vπ(s)V^{\pi}(s)Vπ(s),選擇采樣來逼近Vπ(s)V^{\pi}(s)Vπ(s),是因為actor所處的環境和actor本身都具有隨機性,由上面的公式(1)可以看到,如果所有的eposides有無窮多個,那么計算機根本無法實現計算Vπ(s)V^{\pi}(s)Vπ(s)
    根據上面的8個eposides,可以計算得到:
    Vπ(sb)=1+1+1+1+1+18=34V^{\pi}(s_{b})=\frac{1+1+1+1+1+1}{8}=\frac{3}{4}Vπ(sb?)=81+1+1+1+1+1?=43?
    只有在第二到第七個eposide時,遇到狀態sbs_{b}sb?才有獎勵,第一個eposide中,當遇到狀態sbs_{b}sb?時,所有累積的獎勵值是0。第8個eposide也是如此。就算第一個eposide變成sa,r=1,sb,r=0,Ends_{a},r=1,s_{b},r=0,Endsa?,r=1,sb?,r=0,End,Vπ(s)V^{\pi}(s)Vπ(s)依然不變還是34\frac{3}{4}43?.

  2. Qπ(s,a)Q^{\pi }(s,a)Qπ(s,a)指actor看到狀態sss之后確定選擇動作aaa之后的獎勵累積期望
    為什么說確定選擇動作aaa呢?看到狀態sss,其實有很多個動作可以選擇,但是在這里就是確定選擇動作aaa,而不是別的動作。還有一個因素就是選擇動作的時候具有隨機性,比如采用ε?greedy\varepsilon -greedyε?greedy方法,會有一定的幾率隨機選擇動作。

  3. 兩者之間的關系
    假設有...,st,at,rt,st+1,......,s_{t},a_{t},r_{t},s_{t+1},......,st?,at?,rt?,st+1?,...,那么就有Qπ(st,at)=E(rt+Vπ(st+1))Q^{\pi }(s_{t},a_{t})=E(r_{t}+V ^{\pi }(s_{t+1}))Qπ(st?,at?)=E(rt?+Vπ(st+1?))
    這里還是要求期望的。不過在實際操作的時候需要采樣或者直接把變成Qπ(st,at)=rt+Vπ(st+1)Q^{\pi }(s_{t},a_{t})=r_{t}+V ^{\pi }(s_{t+1})Qπ(st?,at?)=rt?+Vπ(st+1?)。這種情況就是只采樣一個用來逼近期望。這樣網絡收斂的效果可能不是太好,畢竟用一條樣本來逼近還是效果不大好的。

1.1.3 如何計算Vπ(s)V ^{\pi }(s)Vπ(s)?

  1. Monte-Carlo(MC)方法
    如下圖,我們使用一個神經網絡來計算Vπ(s)V ^{\pi }(s)Vπ(s),并且根據actor玩游戲的實際情況,來優化這個神經網絡,并且利用這個神經網絡(q表,我們前面說到了使用神經網絡來表示這個q表以處理狀態極其復雜多變的情況,所以神經網絡==q表)來指導actor進行決策。

    例子:假設有狀態 sa和sbs_{a}和 s_{b}sa?和sb?,計算Vπ(sa)和Vπ(sb)V ^{\pi }(s_{a})和V ^{\pi }(s_{b})Vπ(sa?)和Vπ(sb?)的步驟如下:
    對于Vπ(sa)V ^{\pi }(s_{a})Vπ(sa?):
    (1) actor(agent)玩游戲或者和環境互動.
    (2) 狀態 sas_{a}sa? 出現在某個回合(episode)中.
    (3) 記錄從狀態 sas_{a}sa? 出現到這個回合結束后的累積的獎勵,我們將其記為GaG_{a}Ga?.
    (4) 將狀態sas_{a}sa?輸入到神經網絡然后輸出 Vπ(sa)V ^{\pi }(s_{a})Vπ(sa?),這個神經網絡輸出的是個標量.
    (5) 利用 回歸(regression) 的方法來優化神經網絡,使得神經網絡的輸出的Vπ(sa)V ^{\pi }(s_{a})Vπ(sa?)來逼近GaG_{a}Ga?.
    (6) 對于任何一個狀態都可以重復以上過程,直到神經網絡收斂。
    對于Vπ(sb)V ^{\pi }(s_{b})Vπ(sb?)的計算也是如此。

  2. Temporal-Difference-Approach(時間差分方法)
    時間差分方法,顧名思義,肯定是需要兩個連續時間步上的狀態才能達到訓練神經網絡的目的。
    假設actor玩游戲或者與環境互動的一個episode中的連續兩步是...,st,at,rt,st+1,......,s_{t},a_{t},r_{t},s_{t+1},......,st?,at?,rt?,st+1?,...
    首先,Vπ(st)=rt+Vπ(st+1)(2)V^{\pi }(s_{t})=r_{t}+V^{\pi }(s_{t+1})\tag{2}Vπ(st?)=rt?+Vπ(st+1?)(2)
    π{\pi}π表示agent或者actor
    時間差分方法每連續的兩個時間步都會訓練一次神經網絡,因此收斂的速度也會相對來說較快。步驟如下
    (1) 假設在時間步 ttt 觀測到狀態 sts_{t}st?
    (2) actor根據現在的狀態 sts_{t}st? 做出動作 ata_{t}at? ,得到獎勵 rtr_{t}rt?
    (3) actor觀測到下一個時間步 t+1t+1t+1 的狀態 st+1s_{t+1}st+1?
    (4) 將狀態 sts_{t}st?, st+1s_{t+1}st+1? 輸入進神經網絡得到 Vπ(st)V^{\pi }(s_{t})Vπ(st?) 和 Vπ(st+1)V^{\pi }(s_{t+1})Vπ(st+1?)
    (5) 利用公式2,我們將Vπ(st)V^{\pi }(s_{t})Vπ(st?) 和 Vπ(st+1)V^{\pi }(s_{t+1})Vπ(st+1?)的差值逼近時間步的獎勵 rtr_{t}rt?. 還是利用回歸(Regression)的方法來訓練神經網絡。

    圖片來自李宏毅老師的強化學習課程,侵刪!!!

  3. 兩種方法之間的關系
    蒙特卡洛方法有更大的方差,方差大說明效果不好,相比來說時間差分方法的訓練速度更加高效,收斂的更快,時間差分方法只需要使用兩個時間步的信息就可以訓練網絡,而蒙特卡洛方法卻需要等待一個完整的episode完成之后才可以進行訓練。不知道大家發現沒有,突然覺得這個方法也是有點類似監督學習方法,這個深度qlearning算法里面的“監督信息是環境反饋過來的獎勵”,我們需要使用獎勵來指引actor的學習。
    對于同一個采樣出來的樣本,使用兩種方法計算出來的同一個狀態 sas_{a}sa? 的價值函數是不一樣的
    比如下面的例子:
    假設我們采樣得到8個eposides,分別如下:
    1、sa,r=0,sb,r=0,Ends_{a},r=0,s_{b},r=0,Endsa?,r=0,sb?,r=0,End
    2、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    3、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    4、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    5、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    6、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    7、sb,r=1,Ends_{b},r=1,Endsb?,r=1,End
    8、sb,r=0,Ends_{b},r=0,Endsb?,r=0,End
    我們先使用蒙特卡洛方法計算 Vπ(sa)V^{\pi}(s_{a})Vπ(sa?):
    觀察采樣出來的數據,我們可以看到狀態 sas_{a}sa? 只是出現在 第一條樣本里面,而且直到游戲結束,得到的兩個獎勵值都是0,所以 Ga=0G_{a}=0Ga?=0,因為我們需要讓 Vπ(sa)V^{\pi}(s_{a})Vπ(sa?) 逼近 GaG_{a}Ga?,所以理想情況下有Vπ(sa)=0V^{\pi}(s_{a})=0Vπ(sa?)=0.
    接著使用時間差分方法來計算Vπ(sa)V^{\pi}(s_{a})Vπ(sa?):
    從第一條采樣樣本可以看到狀態 sas_{a}sa? 和 sbs_{b}sb? 是兩個相鄰的狀態,因此由公式2可以知道計算 Vπ(sa)V^{\pi}(s_{a})Vπ(sa?),需要使用 Vπ(sb)V^{\pi}(s_{b})Vπ(sb?)的值。
    根據采樣的8條樣本,我們使用這八條樣本的 $V^{\pi}(s_{b})_{i},i=1,2,…,8的期望值來近似逼近 Vπ(sb)V^{\pi}(s_{b})Vπ(sb?)
    因此有Vπ(sb)=1+1+1+1+1+18=34V^{\pi}(s_{b})=\frac{1+1+1+1+1+1}{8}=\frac{3}{4}Vπ(sb?)=81+1+1+1+1+1?=43?
    由在第一條樣本中在狀態 sas_{a}sa? 時actor得到的獎勵是0,所以Vπ(sa)=0+Vπ(sb)=34V^{\pi }(s_{a})=0+V^{\pi }(s_{b})=\frac{3}{4}Vπ(sa?)=0+Vπ(sb?)=43?.
    可以看到,不同的計算方法得到的價值函數的值是不一樣的。

二、算法運行流程

步驟一: actor(agent) π{\pi}π和環境(Environment)互動
步驟二: 使用蒙特卡洛方法或者時間差分方法來計算狀態價值函數Vπ(s)V^{\pi}(s)Vπ(s)或者狀態動作價值函數Qπ(s,a)Q^{\pi}(s,a)Qπ(s,a)
步驟三: 使用回歸(Regression)方法訓練神經網絡
步驟四: 價值函數指導actor做出更好的策略,循環以上步驟,直到收斂。

基于TD方法的QLearning具體如下圖:

算法流程里面的butter要改為buffer。

三、幾個小技巧

3.1 技巧1 target網絡和predict網絡

其實在傳統的qlearning里面以及涉及到了“q_target和q_predict”的概念了,這里的深度qlearning在訓練的時候同樣也是由target網絡和predict網絡,只不過是兩個網絡需要共享參數,其中target是固定的,只有在predict網絡以target的輸出為目標更新若干次之后采后將predict網絡的參數重新賦給target網絡。
有需要可以看看傳統的qlearning算法。傳送門:傳統qlearning算法講解

我們以李宏毅老師的課程講解如何訓練的

這里使用的是時間差分方法來訓練的
右邊的 Target 網絡的參數在一定時間內是固定的,Target網絡輸出的值是左邊網絡需要回歸的目標,然后更新這個來更新左邊的predict網絡,更新若干次之后,然后將predict網絡的參數重新賦給Target網絡,一直訓練,直到收斂。

3.2、技巧2之 ε?greedy\varepsilon -greedyε?greedy選擇動作

使用這個技巧有利于actor學會探索,也可以確保當訓練的次數足夠多時,所有的動作都可以被的更新到。隨機探索的可能性會隨著訓練的進行逐漸變小的
我們之前在強化學習(RL)QLearning算法詳解介紹過了這個技巧,不再重復。

3.3 技巧3 Boltzmann選擇動作

利用狀態動作價值函數的大小來選擇動作,值越大,這個對于的動作被選擇的概率就越大,對于的動作被選擇的概率公式如下:
P(a∣s)=exp(Q(s,a))∑aexp(Q(s,a))(3)P(a|s)=\frac{exp(Q(s,a))}{\sum_{a}exp(Q(s,a))}\tag{3}P(a∣s)=∑a?exp(Q(s,a))exp(Q(s,a))?(3)

3.4 技巧4 RePlay Buffer

設計一個Buffer將actor玩過的experience存儲起來,可以重復使用這個數據更新網絡。
假如使用時間差分方法,我們可以在Buffer存儲器里面存儲只需要兩個時間步就可以,比如其中一條數據可以是:st,at,rt,st+1s_{t},a_{t},r_{t},s_{t+1}st?,at?,rt?,st+1?,當儲存很多時,也可以進行batch學習。

四、小例子

基于卷積神經網絡的小例子

4.1 readme

  1. 安裝gym
  2. 安裝atari-py
    在第二步很容易出現ale_c.dll不存在的問題。
    以下是解決方法
    分三步:
    第一步:先卸載atari-py。pip uninstall atari-py
    第二步:再重新安裝這個。pip install --no-index -f https://github.com/Kojoley/atari-py/releases atari_py
    第三步:pip install gym
# -*- coding: utf-8 -*-import gym
import torch.nn as nn
import torch as t
from torch.nn import functional as F
import randomdicount_factor = 0.9
eplison = 0.1
lr = 0.001
epochs = 50
nums_p2t = 100 #每隔100詞將Q_Net_predict的參數賦給Q_Net_target,然后繼續固定target網絡
env = gym.make("SpaceInvaders-v0") # 構造一個太空入侵者的環境# 下面這個神經網絡是用來預測
class Q_Net_predict(nn.Module):    def __init__(self, nums_action):super(Q_Net_predict,self).__init__()#下面開始定義卷積和全連接層,計劃使用兩個全連接層和兩個卷積層self.conv1 = nn.Conv2d(3, 16, 5, 2)self.conv2 = nn.Conv2d(16, 16, 5, 2)self.linear1 = nn.Linear(1728,256)self.linear2 = nn.Linear(256,nums_action)def forward(self, x):#先進行類型的轉換state = t.from_numpy(x[:,:,::-1].copy())state = state.permute((2,0,1)).unsqueeze(dim=0).float()#開始使用卷積,最大池化和線性層out = self.conv1(state)out = F.relu(out)out = F.max_pool2d(out,(2,2))out = self.conv2(out)out = F.relu(out)out = F.max_pool2d(out,(2,2))s = out.size()out = out.view(1,s[1]*s[2]*s[3])out = F.relu(self.linear1(out))out = self.linear2(out)return out# 下面這個神經網絡是用來作為Q_Net_predict擬合的目標函數
class Q_Net_target(nn.Module):    def __init__(self, nums_action):super(Q_Net_target,self).__init__()#下面開始定義卷積和全連接層,計劃使用兩個全連接層和兩個卷積層self.conv1 = nn.Conv2d(3, 16, 5, 2)self.conv2 = nn.Conv2d(16, 16, 5, 2)self.linear1 = nn.Linear(1728,256)self.linear2 = nn.Linear(256,nums_action)def forward(self, x):#先進行類型的轉換state = t.from_numpy(x[:,:,::-1].copy())state = state.permute((2,0,1)).unsqueeze(dim=0).float()#開始使用卷積,最大池化和線性層out = self.conv1(state)out = F.relu(out)out = F.max_pool2d(out,(2,2))out = self.conv2(out)out = F.relu(out)out = F.max_pool2d(out,(2,2))s = out.size()out = out.view(1,s[1]*s[2]*s[3])out = F.relu(self.linear1(out))out = self.linear2(out)return outdef choose_action(logits):## 使用eplison-greedy選擇agent需要執行的動作v = random.uniform(0, 1)q_value, index = t.topk(logits, 1, dim = 1)#下面開始eplison-greedy 算法if v > eplison:#這里是求最大的狀態價值函數對應的動作q_value_t = logits[0,index[0][0]]action = index[0][0].item()else:#下面是隨機產生動作action = random.randint(0, 5)q_value_t = logits[0, action]return action, q_value_tdef q_learning():all_count = 0#下面開始#先定義兩個狀態價值函數網絡q_target = Q_Net_target(6)q_predict = Q_Net_predict(6)#定義一個優化器opt_Adam = t.optim.Adam(q_predict.parameters(),lr = lr)#將target網絡的參數凍結for p in q_target.parameters():p.requires_grad = Falsefor _ in range(epochs):done = False#初始化一個狀態observation = env.reset() #每個episode的初始狀態while not done:env.render()#下面開始網絡的參數復制if all_count % nums_p2t == 0:target_paras = q_target.state_dict()predict_paras = q_predict.state_dict()target_paras.update(predict_paras)q_target.load_state_dict(target_paras)#下面使用q_predict網絡的輸出選擇動作predict_logits = q_predict(observation)action, q_value_t = choose_action(logits= predict_logits)#下面根據動作得到獎勵以及下一個時間步的狀態observationobservation, reward, done, info = env.step(action)#現在有了observation,需要使用使用target網絡計算observation的狀態價值函數target_qvalue = q_target(observation)q_value_t_ = max(target_qvalue[0]).item()#我們需要使reward+q_value_t_ 和 q_value_t接近loss = (reward + q_value_t_ - q_value_t)**2loss.backward()opt_Adam.step()all_count +=1env.close()if __name__ == '__main__':q_learning()

五、參考文獻

1、李宏毅老師的強化學習算法
2、莫煩python的強化學習系列
3、ale_c.dll確實解決方法
4、openai官網

總結

以上是生活随笔為你收集整理的Deep QLearning算法详解(强化学习 Reinforcement Learning)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。