強化學習裡的 env.reset() env.step() 就是訓練環境。其編寫流程如下:
先寫一個簡化版的訓練環境。把任務難度降到最低,確保一定能正常訓練。記錄正常訓練的智慧體的分數,與隨機動作、傳統演演算法得到的分數做比較。
DRL演演算法的分數應該明顯高於隨機動作(隨機執行動作)。DRL演演算法不應該低於傳統演演算法的分數。如果沒有傳統演演算法,那麼也需要自己寫一個區域性最優的演演算法
評估策略的效能: 大部分情況下,可以直接是對Reward Function 給出的reward 進行求和得到的每輪收益episode return作為策略評分。有時候可以需要直接拿策略的實際分數作為評分
需要保證這個簡化版的程式碼:高效、簡潔、可拓展
讓任務難度逐步提高,對訓練環境env 進行緩慢的修改,時刻儲存舊版本的程式碼同步微調 Reward Function,可以直接代入自己的人類視角,為某些行為新增正負獎勵。注意獎勵的平衡(有正有負)。注意不要為Reward Function 新增太多額外規則,時常回過頭取消一些規則,避免過度矯正。
同步微調 DRL演演算法,只建議微調超引數,但不建議對演演算法核心進行修改。因為任務變困難了,所以需要調整超引數讓訓練變快。同時摸清楚在這個訓練環境下,演演算法對哪幾個超引數是敏感的。有時候為了節省時間,甚至可以為 off-policy 演演算法儲存一些典型的 trajectory(不建議在最終驗證階段使用)。
每一次修改,都需要跑一下記錄不同方法的分數,確保:隨機動作 < 傳統方法 < DRL演演算法。這樣才能及時發現程式碼邏輯上的錯誤。要極力避免程式碼中出現複數個的錯誤,因為極難排查。
嘗試慢慢刪掉Reward Function 中一些比較複雜的東西,刪不掉就算了。
選擇高低兩組超引數再跑一次,確認沒有優化空間。
【網路寬度、網路層數】 越複雜的函數就需要越大容量的神經網路去擬合。在需要訓練1e6步的任務中,我一般選擇 寬度128、256,層數小於8的網路(請注意,乘以一個w算一層,一層LSTM等於2層)。使用ResNet等結構會有很小的提升。一般選擇一個略微冗餘的網路容量即可,把調整超引數的精力用在這上面不划算,我建議這些超引數都粗略地選擇2的N次方,
因為:防止過度調參,超引數選擇x+1 與 x-1並沒有什麼區別,但是 x與2x一定會有顯著區別
2的N次方大小的資料,剛好能完整地放進CPU或GPU的硬體中進行計算,如Tensor Core
過大、過深的神經網路不適合DRL,
因為:深度學習可以在整個訓練結束後再使用訓練好的模型。
而強化學習需要在幾秒鐘的訓練後馬上使用剛訓好的模型。
這導致DRL只能用比較淺的網路來保證快速擬合(10層以下)
並且強化學習的訓練資料不如有監督學習那麼穩定,無法劃分出訓練集測試集去避免過擬合,
因此DRL也不能用太寬的網路(超過1024),避免引數過度冗餘導致過擬合
【dropout、批歸一化】 她們在DL中得到廣泛地使用,可惜不適合DRL。如果非要用,那麼也要選擇非常小的 dropout rate(0~0.2),而且要注意在使用的時候關掉dropout。我不用dropout。
好處:在資料不足的情況下緩解過擬合;像Noisy DQN那樣去促進策略網路探索
壞處:影響DRL快速擬合的能力;略微增加訓練時間
【批歸一化】 經過大量實驗,DRL絕對不能直接使用批歸一化,如果非要用,那麼就要修改Batch Normalization的動量項超引數。
【記憶容量】 經驗回放快取 experimence replay buffer 的最大容量 max capacity,如果超過容量限制,它就會刪掉最早的記憶。在簡單的任務中(訓練步數小於1e6),對於探索能力強的DRL演演算法,通常在快取被放滿前就訓練到收斂了,不需要刪除任何記憶。然而,過大的記憶也會拖慢訓練速度,我一般會先從預設值 2 ** 17 ~ 2 ** 20 開始嘗試,如果環境的隨機因素大,我會同步增加記憶容量 與 batch size、網路更新次數,直到逼近伺服器的記憶體、視訊記憶體上限(放在視訊記憶體訓練更快)
【批次大小、更新次數】 一般我會選擇與網路寬度相同、或略大的批次大小batch size。我一般從128、256 開始嘗試這些2的N次方。在off-policy中,每往Replay 更新幾個資料,就對應地更新幾次網路,這樣做簡單,但效果一般。(深度學習裡)更優秀的更新方法是:根據Replay中資料數量,成比例地修改更新次數。Don't Decay the Learning Rate, Increase the Batch Size. ICLR. 2018 。,經過驗證,DRL也適用。
【折扣因子】 discount factor、discount-rate parameter 或者叫 gamma 。0.99
同策略(A3C、PPO、PPO+GAE)與異策略(DQN、DDPG、TD3、SAC)的主要差異是:
異策略off-policy:ReplayBuffer內可以存放「由不同策略」收集得到的資料用於更新網路
同策略on-policy:ReplayBuffer內只能存放「由相同策略」收集得到的資料用於更新網路
因此以下超引數有不同的選擇方法:
記憶容量:經驗回放快取 experimence replay buffer 的最大容量 max capacity
批次大小:batch size。使用優化器更新時,每次更新使用的資料數量
更新次數:update times。使用梯度下降更新網路的次數
【記憶容量】 on-policy 演演算法每輪更新後都需要刪除「用過的資料」,所以on-policy的記憶容量應該大於等於【單輪更新的取樣步數】,隨機因素更多的任務需要更大的單層取樣步數才能獲得更多的 軌跡 trajectory,才能有足夠的資料去表達環境與策略的互動關係。詳見下面PPO演演算法的【單輪更新的取樣步數】
【批次大小】 on-policy 演演算法比off-policy更像深度學習,它可以採用稍大一點的學習率(2e-4)。因為【單輪更新的取樣步數】更大,所以它也需要搭配更大的batch size(29 ~ 212)。如果記憶體視訊記憶體足夠,我建議使用更大的batch size,我發現一些很難調的任務,在很大的batch size(2 ** 14) 面前更容易獲得單調上升的學習曲線(訓練慢但是及其穩定,多GPU分散式)。請自行取捨。
【更新次數】 一般我們不直接設定更新次數,而是通過【單輪更新的取樣步數】、【批次大小】和【資料重用次數】一同算出【更新次數】,詳見下面PPO演演算法的【資料重用次數】
如果你擅長調參,那麼可以可以考慮TD3演演算法。如果你的演演算法的最優策略通常是邊界值,那麼你首選的演演算法就是TD3----最佳策略總在動作邊界
【TD3的探索方式】 讓其很容易在探索「邊界動作」:
好處: 一些任務的最優策略本就存在存在大量邊界動作,TD3可以很快學得很快。
壞處: 邊界動作都是 -1或 +1,這會降低策略的多樣性,網路需要在多樣性好資料上訓練才不容易過擬合。對於clip 到正負1之間的action,過大的噪聲方差會產生大量邊界動作 。
【探索噪聲方差 exploration noise std】 就是上圖中的s。需要先嚐試小的噪聲方差(如0.05),然後逐漸加大。大的噪聲方差刻意多探索邊界值,特定任務下能讓探索更快。且高噪聲下訓練出來的智慧體更robust(穩健、耐操)。
請注意:過大的噪聲方差(大於上圖藍線的0.5)並不會讓探索動作接近隨機動作,而是讓探索動作更接近單一的邊界動作。此外,過大的噪聲會影響智慧體效能,導致她不容易探索到某些state。
因此,合適的探索噪聲方差只能慢慢試出來,TD3適合願意調參的人使用。在做出錯誤動作後容易挽回的環境,可以直接嘗試較大的噪聲。
我們也可以模仿 epslion-Greedy,設定一個使用隨機動作的概率,或者每間隔幾步探索就不新增噪聲,甚至也在TD3中使用探索衰減。這些操作都會增加超引數的數量,慎用。
【策略噪聲方差 policy noise std】 確定了探索噪聲後,策略噪聲只需要比探索噪聲稍大(1~2倍)。TD3對策略噪聲的解釋是「計算Q值時,因為相似的動作的Q值也是相似的,所以TD3也為動作加一個噪聲,這能使Q值函數更加光滑,提高訓練穩定性 我們還能多使用幾個新增噪聲的動作,甚至使用加權重要性取樣去算出更穩定的Q值期望。在確定策略梯度演演算法裡的這種「在計算Q值時,為動作加noise的操作」,讓TD3變得有點像隨機策略梯度。無論是否有clip,策略噪聲方差最大也不該超過0.5。
【延遲更新頻率 delay update frequency】 TD3認為:引入目標網路進行 soft update 就是為了提高訓練穩定性,那麼既然 network 不夠穩定,那麼我們應該延遲更新目標網路 target network,即多更新幾次 network,然後再更新一次target network。從這個想法再拓展出去,我們甚至可以模仿TTUR的思想做得更細緻一點,針對雙層優化問題我們能做:
環境隨機因素多,則需要嘗試更大的延遲更新頻率,可嘗試的值有 1~8,預設值為2
提供策略梯度的critic可以多更新幾次,再更新一次actor,可嘗試的值有 1~4<
提供策略梯度的critic可以設計更大的學習率,例如讓critic的學習率是actor 的1~10倍
由於critic 需要處理比 actor 更多的資料,因此建議讓critic網路的寬度略大於actor
儘管下面列舉了4個超引數,但是後三個超引數可以直接使用預設值(預設值只會有限地影響訓練速度),第一個超引數甚至可以直接通過計算選擇出來,不需要調整。
reward scaling 是指直接讓reward 乘以一個常數k (reward scale),在不破壞reward function 的前提下調整reward值,從而間接調整Q值到合適的大小。 修改reward scale,相當於修改lambda1,從而讓可以讓 reward項 和 entropy項 它們傳遞的梯度大小接近。與其他超引數不同,只要我們知曉訓練環境的累計收益範圍,我們就能在訓練前,直接隨意地選定一個reward scaling的值,讓累計收益的範圍落在 -1000~1000以內即可,不需要精細調整:
【溫度係數、目標策略熵】 Temperature parameters (alpha)、target 'policy entropy'。SAC的第二篇論文加入了自動調整 溫度係數 alpha 的機制:通過自動調整溫度係數,做到讓策略的熵維持在目標熵的附近(不讓alpha過大而影響優化,也不讓alpha過小而影響探索)
策略熵的預設值是 動作的個數 的負log,詳見SAC的第二篇論文 section 5 Automating Entropy Adjustment for Maximum Entropy 。SAC對這個超引數不敏感,一般不需要修改。有時候策略的熵太大將導致智慧體無法探索到某些有優勢的state,此時需要將目標熵調小。
【溫度係數 alpha 的學習率】 learning rate of alpha 溫度係數alpha 最好使用 log 形式進行優化,因為alpha是表示倍數的正數。一般地,溫度係數的學習率和網路引數的學習率保持一致(一般都是1e-4)。當環境隨機因素過大,導致每個batch 算出來的策略熵 log_prob 不夠穩定時,我們需要調小溫度係數的學習率。
【溫度係數 alpha 的初始值】 initialization of alpha 溫度係數的初始值可以隨便設定,只要初始值不過於離奇,它都可以被自動調整為合適的值。一般偷懶地將初始值設定為 log(0) 其實過大了,這會延長SAC的預熱時間,我一般設定成更小的數值,詳見 The alpha loss calculating of SAC is different from other repo · Issue #10 · Yonv1943/ElegantRL 。
常規引數:
無人機初始位置 | 使用者初始位置 | 無人機覆蓋半徑(米) | 最大關聯數 | UAV飛行距離 |
---|---|---|---|---|
【20,180】 | 【20,180】 | 【75,100】 | 【20,30】 | 【0,30】 |
時延記錄: | ||||
前景(MB) | 0.125 | 0.5 | 1 | 1.25 |
-- | -- | -- | -- | -- |
背景(MB) | 0.5 | 2 | 4 | 5 |
local(ms) | 13 | 52 | 105 | --- |
UAV(ms) | 47 | 29.4 | 39.7 | --- |
coop(ms) | 44 | 29.6 | 38.2 | ---- |
超引數: | ||||
ACTOR_LR | CRITIC_LR | BATCH_SIZE | GAMMA | TAU |
-- | -- | -- | -- | -- |
【1e-4 ,1e-5】 | 【1e-3 ,1e-4】 | 【256,512】 | 0.99】 | 0.005 |
EXPL_NOISE | policy_noise | noise_clip | policy_freq | hid_size |
0.1、0.05 | 0.2、0.1 | 0.5 | 【1,8】預設:2 | 【128,512】 |
目前採用組合有如下:
可以看到模型訓練的穩定性和收斂效果越來越好,調多了你也就知道哪些超引數影響的大了