強化學習(Reinforcement Learning) — Lunar Lander v2
我們花了不少時間來解決 Lunar Lander v2 這個問題,前前後後大概幾個月。當然,我們也是用業餘的時間來解決這個問題。跑了很多方式,訓練出來的模型都是不降落,或是只會使用單一噴射器來控制。
後來發現:原來 Lunar Lander v2 的 reward 本身就是一個加權評分。其實我們可以直接用最簡單的方式來執行就可以了。
前陣子,我們發現了這篇文章,他的訓練方式很特別:每個 step 就進行一次 replay training,我們之前的實作都是每個 step 只訓練一個 step 或是每個 episode 做一次 replay training。所以,我們就這個功能加入到我們的程式碼中:沒想到,這就解決了我們的問題了。不囉唆,我們直接看影片:
遊戲分析
Lunar Lander v2 有主體、兩個腳架跟三個噴射器(請見本篇的主要圖片)。透過遊戲分析,我們可以得到的資料跟操作如下:
State — 遊戲輸出
Lunar Lander v2 一共會給我們 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
: 8action_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
,並取得 reward
、done
、跟 next_state
。
在這一步中,我們將遊戲 -100 的reward
換成 -3 來鼓勵嘗試降落。
9. Step training
每一個 step 完成後,進行一次批次訓練:
gamma
:0.95training_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,如果有什麼地方值得改進的,還請各位大大在下面留言區給小弟建議。