iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 28
0
AI & Data

輕鬆掌握 Keras 及相關應用系列 第 28

Day 28:從直覺的角度初探強化學習

前言

2016年AI圍棋軟體AlphaGo連續擊敗韓國及中國等世界頂尖的好手,使得它背後的演算法 -- 強化學習(Reinforcement Learning)一炮而紅,發明AlphaGo的英國公司 DeepMind 也同時成為強化學習研發的龍頭,在此同時也出現了一位台灣之光 -- 黃士傑,因為他在每一次戰役中都擔任 AlphaGo 的代理人。

強化學習以 Try and Error 的方式,透過不斷的嘗試與學習,累積經驗,修正行動策略,在訓練成功後可以依情勢選擇較佳的行動決策。所以,它不只能下棋,也能應用到玩遊戲、機器人行走/揀貨/焊接、自動駕駛、醫療手術、股票投資...等方面,但是到目前為止,DeepMind 的發展還是集中在電腦遊戲的攻略上面,距離全面的開花結果,還待時間的考驗。

距離比賽要求還剩下三篇,我們就集中火力,針對強化學習一探究竟,了解其運作原理及相關程式的撰寫。

強化學習機制

強化學習機制如下圖,非常簡單:

  1. 代理人(Agent):也就是遊戲中的玩家(Player),他主要與環境互動,根據當時的狀態(State)以及之前得到的獎勵或懲罰,決定下一步的行動。
  2. 環境(Environment):會根據代理人的行動(Action),給予立即的獎勵或懲罰,統稱為獎勵(Reward)。
  3. 狀態(State):也稱為觀察(Observation),有時候代理人只能觀察到局部的狀態,例如,樸克牌遊戲21點(Black Jack),莊家有一張牌是蓋住的,玩家是看不到。
    https://ithelp.ithome.com.tw/upload/images/20200927/2000197639yFZJUioG.png
    圖一. 強化學習機制

總而言之,強化學習的目的,就是經由代理人不斷的學習,累積經驗,找到最佳行動策略,在真正派上用場時,能將學習到的最佳策略應用到實戰上。

簡單的強化學習架構

透過上面機制的描述,我們可以制定程式架構如下圖:
https://ithelp.ithome.com.tw/upload/images/20200928/20001976o1UTIJBIap.png
圖二. 強化學習程式架構

採取物件導向設計(OOP),總共有兩個類別,其職責(方法)如下:

  1. 環境(Environment):類似遊戲本身。
  • Init (初始化):需定義狀態空間(State Space)、獎勵(Reward)辦法、行動空間(Action Space)、狀態轉換(State Transition definition)。
  • Reset (重置):回合(Episode)結束時,需重新開始,重置所有變數。
  • Step (步驟):代理人行動後,會驅動下一步,環境會更新狀態,給予獎勵,並判斷回合是否結束及勝負。
  • Render (渲染):更新畫面顯示。
  1. 代理人(Agent):類似玩家。
  • Act (行動):代理人依據既定的策略以及面臨的狀態,採取行動,例如上、下、左、右。
    通常我們要訂定特定策略,就繼承基礎的代理人類別(base agent class),在衍生的類別中,撰寫策略邏輯。

最後撰寫成一個類別或一段程式,稱之為【實驗】(Experiment),用來建立環境、代理人兩個物件,讓系統動起來。

就上面設計規格,撰寫程式測試看看。

實作

  1. 載入套件。
import random
  1. 定義環境類別。
class Environment:
    # 初始化
    def __init__(self):
        # 最多走10步
        self.steps_left = 10

    def get_observation(self):
        # 狀態空間(State Space)
        return [0.0, 1.0, 2.0]

    def get_actions(self):
        # 行動空間(Action Space)
        return [0, 1]

    def is_done(self):
        # 回合(Episode)是否結束
        return self.steps_left == 0

    # 步驟
    def step(self, action):
        # 回合(Episode)結束
        if self.is_done():
            raise Exception("Game is over")
            
        # 減少1步
        self.steps_left -= 1
        
        # 隨機策略,任意行動,並給予獎勵(亂數值)
        return random.choice(self.get_observation()), random.random()
  1. 定義代理人類別。
class Agent:
    # 初始化
    def __init__(self):
        pass
        
    def action(self, env):
        # 觀察或是取得狀態
        current_obs = env.get_observation()
        # 採取行動
        actions = env.get_actions()
        return random.choice(actions)
  1. 進行實驗。
if __name__ == "__main__":
    # 實驗
    # 建立環境、代理人物件
    env = Environment()
    agent = Agent()

    # 累計報酬
    total_reward=0
    while not env.is_done():
        # 採取行動
        action = agent.action(env)
        
        # 進到下一步
        state, reward = env.step(action)
        
        # 報酬累計
        #print(reward)
        total_reward += reward
    
    # 顯示累計報酬
    print(f"累計報酬: {total_reward:.4f}")
  1. 以上程式碼存檔為 28_01_agent_env.py,執行下列指令,實驗結果如下:
    python 28_01_agent_env.py
    https://ithelp.ithome.com.tw/upload/images/20200928/20001976IlqYPFEU6a.png

使用 OpenAI Gym 套件

為了讓強化學習開發者更容易入門,OpenAI公司開發了Gym 套件,提供一個標準架構,並實現許多個遊戲,讓大家可以盡情開發各種策略,進行實驗及演算法的開發。

  1. Gym 套件安裝很簡單,執行下列指令即可:
    pip install gym
    但以上指令只會安裝簡單的文字遊戲(toy text)及傳統遊戲(classic control),如果要安裝全部遊戲,可執行下列指令,但是 Windows 環境下安裝會有錯誤,可以參考【How to Install OpenAI Gym in a Windows Environment】試試看,我照表操作是失敗的。
    pip install gym[all]

  2. Gym 官網如下:https://gym.openai.com/

  3. Gym 官網沒有列出現成的遊戲名稱,只能參考【GitHub網站】,每個目錄代表一個類別,目錄內的每個檔案是一個遊戲。

  4. 使用說明在 【這裡】,並沒有列出每一個遊戲的規則,只能直接查看原始程式碼。

實作台車(Cartpole)遊戲

台車(Cartpole)是 Gym 套件內的一個遊戲,分兩個版本,CartPole-v0 規則如下:

  1. 行動只有往左、往右兩種。
  2. 平衡桿一開始是直立(upright),要保持它在行駛中仍然保持平衡。
  3. 下列條件會使遊戲回合結束:
  • 平衡桿角度偏差12度。
  • 台車距離中心點 2.4 單位。
  • 行動超過200步 (CartPole-v1 為 500步)。
  1. 每走一步得1分。
  2. 訓練成功的條件:連續100回合平均得分>=195分 (CartPole-v1 為 >= 475分)。

Gym 程式架構與上述簡單架構相似,只是不必實作環境(Environment),即遊戲與規則,因為Gym都幫我們搞定了。以下採取隨機策略,實作台車(Cartpole)遊戲,程式碼如下:

  1. 載入套件。
import gym
import pandas as pd
  1. 載入遊戲。
env = gym.make("CartPole-v0")
  1. 初始化遊戲。
total_rewards = 0.0
total_steps = 0
obs = env.reset()
  1. 進行實驗:玩50回合。
no = 50
all_steps=[]
all_rewards=[]
while True:
    # 隨機行動
    action = env.action_space.sample()
    # 進入下一步
    obs, reward, done, _ = env.step(action)
    # 渲染
    env.render()
    
    # 累計報酬
    total_rewards += reward
    # 累計步驟總數
    total_steps += 1
    if done:
        # 重置
        env.reset()
        
        all_rewards.append(total_rewards)
        all_steps.append(total_steps)
        total_rewards = 0
        total_steps=0
        no-=1
        if no == 0:
            break
  1. 結束遊戲。
env.close()
  1. 以上程式碼存檔為 28_02_cartpole_random.py,執行下列指令,實驗結果如下:
    python 28_02_cartpole_random.py
    https://ithelp.ithome.com.tw/upload/images/20200928/20001976PfGs0gxDqC.png

沒有贏半個回合,真慘。可以參考【這裡】的程式,執行看看,會顯示在第幾回合,它贏得比賽。

結論

筆者嘗試以不一樣的切入點介紹【強化學習】(Reinforcement Learning),希望能降低初學者進入的門檻,如果要照正規的路徑學習,可參考強化學習的聖經【Reinforcement Learning: An Introduction】,全書共548頁,只含基礎理論,要涉獵較新的演算法,需另外覓食。

本篇範例包括 28_01_agent_env.py、28_02_cartpole_random.py,可自【這裡】下載,程式需要渲染畫面,Jupyter Notebook 無法顯示,故直接使用 Python 檔。


上一篇
Day 27:使用Keras撰寫 生成式對抗網路(GAN)
下一篇
Day 29:深究強化學習
系列文
輕鬆掌握 Keras 及相關應用30

尚未有邦友留言

立即登入留言