強化學習(Reinforcement Learning) — Lunar Lander v2

John Hu
No silver bullet
Published in
6 min readAug 12, 2021

我們花了不少時間來解決 Lunar Lander v2 這個問題,前前後後大概幾個月。當然,我們也是用業餘的時間來解決這個問題。跑了很多方式,訓練出來的模型都是不降落,或是只會使用單一噴射器來控制。

後來發現:原來 Lunar Lander v2 的 reward 本身就是一個加權評分。其實我們可以直接用最簡單的方式來執行就可以了。

前陣子,我們發現了這篇文章,他的訓練方式很特別:每個 step 就進行一次 replay training,我們之前的實作都是每個 step 只訓練一個 step 或是每個 episode 做一次 replay training。所以,我們就這個功能加入到我們的程式碼中:沒想到,這就解決了我們的問題了。不囉唆,我們直接看影片:

訓練過程

遊戲分析

Lunar Lander v2 有主體、兩個腳架跟三個噴射器(請見本篇的主要圖片)。透過遊戲分析,我們可以得到的資料跟操作如下:

State — 遊戲輸出

Lunar Lander v2 一共會給我們 8 個狀態:

  1. 水平位置
  2. 垂直位置
  3. 水平加速度
  4. 垂直加速度
  5. 水平角度
  6. 水平角加速度
  7. 第一腳著地
  8. 第二腳著地

Action — 遊戲輸入

Lunar Lander v2 會接收的輸入分別是,當值是:

  • 0: 不做事
  • 1: 發射左邊的噴射器
  • 2: 發射主噴射器
  • 3: 發射右邊的噴射器

Rewards — 每個 step 評分方式

Lunar Lander 的評分標準是從 state 計算出來的一個加權值,我們就不特別討論,但是,它內建幾個調整分數的條件:

  • 每一隻腳著地給 10 分
  • 主體著地給 -100 分
  • 兩隻腳著地同時每個加速度為 0 給 100 分

終止條件

終止條件有兩個:

  • Reward 是 100
  • 玩超過 1000 步

程式設計

在一開始的時候,因為墜毀會給 -100 分,我們在訓練的時候,如果都沒有成功降落的時候,AI 很難知道成功降落會給高分。所以,我們將 -100 分改成 -3 分:

1. Init env & agent

Lunar Lander v2 使用的模型是簡單的 model 來完成這個遊戲。

遊戲分析可以得知下面的參數:

  • state_size: 8
  • action_size: 4

我們這次使用了最簡單的模型:

input(6) -> dense(16) -> dense(16) -> dense(16) -> dense(output=3)

2. Check if end of training

訓練終止條件:

  • 遊戲次數(episodes):200
  • 連續 5 次成功著地

3. Reset env

僅呼叫 Lunar Lander v2 的 reset,並未做其他特別處理。

4. Check if end of game

單局遊戲停止條件:

  • 與遊戲的終止條件相連結

5. Check if exploring phase

使用最簡單的 Uniform Random 來判斷 exploring phase:

  • 初始 exploration_rate:1
  • 每個 Step 後衰退exploration_decay:0.996 (與我們找到的文章相同)
  • 保障最小值 exploration_rate_min:0.01

6. Random choose action

進到 exploring phase 時,隨機選取 action。

7. Predict action with state

我們僅將 state 給如 model,並沒任何轉換。

  • learning_rate:0.001

8. Execution action

呼叫 Lunar Lander v2 的 step,並取得 rewarddone、跟 next_state

在這一步中,我們將遊戲 -100 的reward 換成 -3 來鼓勵嘗試降落。

9. Step training

每一個 step 完成後,進行一次批次訓練:

  • gamma:0.95
  • training_batch_size:64

當記憶資料過多時,採隨機選取。且使用單一模型進行預測與學習。

10. Pack training data

直接儲存,不做資料轉換。

  • memory_size:1,000,000

11. Batch training

我們這次已經將 batch training 移動到 step 裡面執行。

12. Update exploration rate

exploration_rate 乘以 exploration_decay 的結果當成新的 exploration_rate

訓練成果

整體看起來,這個 AI model 可以在 20 多個 episodes 後學會控制噴射器,在 60 多個 episodes 後學會緩慢降落,可以在 120 多個 episodes 知道要降落在靠近中間一點的位置。

訓練過程(與前面的影片相同)

觀察

  • 在每一個 step 中進行 batch training 是我們第一次使用的方式,它會讓每個 episode 的執行速度變慢,但是效果不錯、
  • 在訓練到 120 多個 episodes 後還是偶爾會有降落失敗的情況。

未來想法

針對整個遊戲的改進,我們可以試看看下面的方式:

  • 試看看其他的演算法:Double DQN、Dueling DQN。
  • 調整其他的參數。

程式與其他檔案

大家如果有興趣想要從新執行一次這個測試,或是修改部份程式碼的話,可以到這邊找到:https://github.com/john-hu/rl,同時可以輸入下面的指令執行起來:

python -m rl.main --game lunar_lander --model small2 --config rl/cfgs/lunar_lander.json --agent simple --display yes

我們這次測試的輸出跟模型可以在這邊找到:Google drive。如果要載入之前訓練的模型,可以在程式的目錄中建立一個 weights 的資料夾,把想要的權重檔( h5)改成 LunarLander.h5 就可以了。如果單純要執行訓練出來的結果可以執行:

python -m rl.main --game lunar_lander --model small2 --config rl/cfgs/simple_no_train.json --agent simple --display yes

最後別忘了,小弟也是剛開始學習 Reinforcement Leaning,如果有什麼地方值得改進的,還請各位大大在下面留言區給小弟建議。

--

--