1. 程式人生 > 其它 >基於Q_learning的寶藏獵人

基於Q_learning的寶藏獵人

技術標籤:強化學習

文章目錄

前言

本博文將簡單用Q-learning實現一個例子,在世界的右邊有寶藏, 探索者只要得到寶藏嚐到了甜頭, 然後以後就記住了得到寶藏的方法, 這就是他用強化學習所學習到的行為。

-o—T
T 就是寶藏的位置, o 是探索者的位置

Q-learning 是一種記錄行為值 (Q value) 的方法, 每種在一定狀態的行為都會有一個值 Q(s, a), 就是說 行為 as 狀態的值是 Q(s, a). s 在上面的探索者遊戲中, 就是 o 所在的地點了. 而每一個地點探索者都能做出兩個行為 left/right

, 這就是探索者的所有可行的 a
如果在某個地點 s1, 探索者計算了他能有的兩個行為, a1/a2=left/right, 計算結果是 Q(s1, a1) > Q(s1, a2), 那麼探索者就會選擇 left 這個行為. 這就是 Q learning 的行為選擇簡單規則.

預設值

這一次需要的模組和引數設定:

import numpy as np
import pandas as pd
import time

N_STATES = 6   # 1維世界的寬度
ACTIONS = ['left', 'right']     # 探索者的可用動作
EPSILON = 0.9   # 貪婪度 greedy
ALPHA = 0.1 # 學習率 GAMMA = 0.9 # 獎勵遞減值 MAX_EPISODES = 13 # 最大回合數 FRESH_TIME = 0.3 # 移動間隔時間

Q 表

對於 tabular Q learning, 我們必須將所有的 Q values (行為值) 放在 q_table 中, 更新 q_table 也是在更新他的行為準則. q_table 的 index 是所有對應的 state (探索者位置), columns 是對應的 action (探索者行為)。

def build_q_table(n_states, actions):
    table =
pd.DataFrame( np.zeros((n_states, len(actions))), # q_table 全 0 初始 columns=actions, # columns 對應的是行為名稱 ) return table # q_table: """ left right 0 0.0 0.0 1 0.0 0.0 2 0.0 0.0 3 0.0 0.0 4 0.0 0.0 5 0.0 0.0 """

定義動作

接著定義探索者是如何挑選行為的. 這是我們引入 epsilon greedy 的概念. 因為在初始階段, 隨機的探索環境, 往往比固定的行為模式要好, 所以這也是累積經驗的階段, 我們希望探索者不會那麼貪婪(greedy). 所以 EPSILON 就是用來控制貪婪程度的值. EPSILON 可以隨著探索時間不斷提升(越來越貪婪), 不過在這個例子中, 我們就固定成 EPSILON = 0.9, 90% 的時間是選擇最優策略, 10% 的時間來探索.

# 在某個 state 地點, 選擇行為
def choose_action(state, q_table):
    state_actions = q_table.iloc[state, :]  # 選出這個 state 的所有 action 值
    if (np.random.uniform() > EPSILON) or (state_actions.all() == 0):  # 非貪婪 or 或者這個 state 還沒有探索過
        action_name = np.random.choice(ACTIONS)
    else:
        action_name = state_actions.argmax()    # 貪婪模式
    return action_name

環境反饋 S_, R

做出行為後, 環境也要給我們的行為一個反饋, 反饋出下個 state (S_) 和 在上個 state (S) 做出 action (A) 所得到的 reward ®. 這裡定義的規則就是, 只有當 o 移動到了 T, 探索者才會得到唯一的一個獎勵, 獎勵值 R=1, 其他情況都沒有獎勵.

def get_env_feedback(S, A):
    # This is how agent will interact with the environment
    if A == 'right':    # move right
        if S == N_STATES - 2:   # terminate
            S_ = 'terminal'
            R = 1
        else:
            S_ = S + 1
            R = 0
    else:   # move left
        R = 0
        if S == 0:
            S_ = S  # reach the wall
        else:
            S_ = S - 1
    return S_, R

環境更新

接下來就是環境的更新了, 不用細看.

def update_env(S, episode, step_counter):
    # This is how environment be updated
    env_list = ['-']*(N_STATES-1) + ['T']   # '---------T' our environment
    if S == 'terminal':
        interaction = 'Episode %s: total_steps = %s' % (episode+1, step_counter)
        print('\r{}'.format(interaction), end='')
        time.sleep(2)
        print('\r                                ', end='')
    else:
        env_list[S] = 'o'
        interaction = ''.join(env_list)
        print('\r{}'.format(interaction), end='')
        time.sleep(FRESH_TIME)

強化學習主迴圈

最重要的地方就在這裡. 你定義的 RL 方法都在這裡體現. 在之後的教程中, 我們會更加詳細得講解 RL 中的各種方法, 下面的內容, 大家大概看看就行, 這節內容不用仔細研究.
在這裡插入圖片描述

def rl():
    q_table = build_q_table(N_STATES, ACTIONS)  # 初始 q table
    for episode in range(MAX_EPISODES):     # 回合
        step_counter = 0
        S = 0   # 回合初始位置
        is_terminated = False   # 是否回合結束
        update_env(S, episode, step_counter)    # 環境更新
        while not is_terminated:

            A = choose_action(S, q_table)   # 選行為
            S_, R = get_env_feedback(S, A)  # 實施行為並得到環境的反饋
            q_predict = q_table.loc[S, A]    # 估算的(狀態-行為)值
            if S_ != 'terminal':
                q_target = R + GAMMA * q_table.iloc[S_, :].max()   #  實際的(狀態-行為)值 (回合沒結束)
            else:
                q_target = R     #  實際的(狀態-行為)值 (回合結束)
                is_terminated = True    # terminate this episode

            q_table.loc[S, A] += ALPHA * (q_target - q_predict)  #  q_table 更新
            S = S_  # 探索者移動到下一個 state

            update_env(S, episode, step_counter+1)  # 環境更新

            step_counter += 1
    return q_table

寫好所有的評估和更新準則後, 我們就能開始訓練了, 把探索者丟到環境中, 讓它自己去玩吧.

if __name__ == "__main__":
    q_table = rl()
    print('\r\nQ-table:\n')
    print(q_table)

參考

https://mofanpy.com/tutorials/machine-learning/reinforcement-learning/general-rl/