機器學(xué)習(xí)入門——實戰(zhàn)篇之強化學(xué)習(xí)

這是本篇文章是《機器學(xué)習(xí)入門》系列文章的第五篇镐侯,該系列有如下文章:
《機器學(xué)習(xí)入門——基礎(chǔ)篇》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之監(jiān)督學(xué)習(xí)》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之非監(jiān)督學(xué)習(xí)》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之深度學(xué)習(xí)》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之強化學(xué)習(xí)》

在《機器學(xué)習(xí)入門——基礎(chǔ)篇》中已經(jīng)介紹過強化學(xué)習(xí)的概念执庐,也介紹了動態(tài)規(guī)劃和蒙特卡洛方法。因為這兩部分內(nèi)容都是可以寫成專著的大塊頭摸航,本文不做詳述,咱們直接進入實戰(zhàn)此再,用一個簡單的栗子來進入強化學(xué)習(xí)的世界饵较。

有這么一個經(jīng)典案例,就是“機器人走迷宮”镐捧,通過強化學(xué)習(xí)算法潜索,讓機器人自己學(xué)會尋找走出迷宮的辦法臭增,并不斷優(yōu)化這個路徑,最后得到較優(yōu)解竹习。

在該項目中誊抛,使用強化學(xué)習(xí)算法,實現(xiàn)一個自動走迷宮機器人整陌。

14-robot.png

1拗窃、如上圖所示,智能機器人顯示在右上角泌辫。在我們的迷宮中随夸,有陷阱(紅色炸彈)及終點(藍色的目標(biāo)點)兩種情景。機器人要盡量避開陷阱震放、盡快到達目的地宾毒。
2、機器人可執(zhí)行的動作包括:向上走 u殿遂、向右走 r诈铛、向下走 d、向左走 l勉躺。
3、執(zhí)行不同的動作后觅丰,根據(jù)不同的情況會獲得不同的獎勵饵溅,具體而言,有以下幾種情況妇萄。
撞到墻壁:-10
走到終點:50
走到陷阱:-30
其余情況:-0.1

正式開始代碼之前蜕企,我們先來理一理思路,強化學(xué)習(xí)作為機器學(xué)習(xí)算法的一種冠句,其模式是讓智能體在“訓(xùn)練”中學(xué)到“經(jīng)驗”轻掩,以實現(xiàn)給定的任務(wù)。但不同于監(jiān)督學(xué)習(xí)與非監(jiān)督學(xué)習(xí)懦底,在強化學(xué)習(xí)的框架中唇牧,我們更側(cè)重通過讓被訓(xùn)練的對象與環(huán)境的交互來學(xué)習(xí)。通常在監(jiān)督學(xué)習(xí)和非監(jiān)督學(xué)習(xí)任務(wù)中聚唐,被訓(xùn)練對象往往需要通過給定的訓(xùn)練集丐重,輔之以既定的訓(xùn)練目標(biāo)(如最小化損失函數(shù)),通過給定的學(xué)習(xí)算法來實現(xiàn)這一目標(biāo)杆查。然而在強化學(xué)習(xí)中扮惦,被訓(xùn)練對象則是通過其與環(huán)境交互得到的獎勵進行學(xué)習(xí)。這個環(huán)境可以是虛擬的(如虛擬的迷宮)亲桦,也可以是真實的(自動駕駛汽車在真實道路上收集數(shù)據(jù))崖蜜。

在強化學(xué)習(xí)中有五個核心組成部分浊仆,它們分別是:
環(huán)境(Environment)
智能體(Agent)
狀態(tài)(State)
動作(Action)
獎勵(Reward)

在某一時間節(jié)點 t:
智能體在從環(huán)境中感知其所處的狀態(tài): s_t
智能體根據(jù)某些準(zhǔn)則選擇動作: a_t
環(huán)境根據(jù)智能體選擇的動作,向智能體反饋獎勵 r_{t+1}
通過合理的學(xué)習(xí)算法豫领,智能體將在這樣的問題設(shè)置下抡柿,成功學(xué)到一個在狀態(tài)s_t選擇動作a_t的策略

對應(yīng)“機器人走迷宮”這個題目,我們就能得到以下名詞的含義:

環(huán)境 : 迷宮的各條路徑氏堤,迷宮路徑上的陷阱沙绝,最終迷宮的出口也就是目標(biāo)位置

狀態(tài) : 為了便于將機器人走迷宮的問題抽象成一個數(shù)學(xué)上好操作的模型,我們在迷宮中加入了左邊鼠锈,例如(0闪檬,0)這樣的點,這樣機器人在任何一個時間點都會對應(yīng)一個位置坐標(biāo)购笆,同時粗悯,這個坐標(biāo)會結(jié)合環(huán)境具體情況帶給機器人一個激勵,有正向激勵同欠,也有負(fù)向激勵样傍,這些激勵會直接被帶入我們的算法公式,算出具體值铺遂,來刺激機器人做出下一步動作的決策衫哥;比如終點坐標(biāo)帶來的激勵就是很大的一個正向值50,比如陷阱坐標(biāo)所帶來的就是一個很大的負(fù)向值-30襟锐,而如果不是什么特別的位置的坐標(biāo)撤逢,也就是其余情況,就會給一個恰當(dāng)?shù)呢?fù)向激勵粮坞,刺激機器人繼續(xù)尋找目標(biāo)蚊荣;以上描述就是這個模型的狀態(tài)

動作 : 向上,向下莫杈,向左互例,向右各種方向上的移動

獎勵 : 撞到墻壁:-10; 走到終點:50筝闹;走到陷阱:-30媳叨;其余情況:-0.1
這個項目中,我們采用基于 Q-Learning 的強化學(xué)習(xí)算法关顷。Q-Learning 是一個值迭代(Value Iteration)算法肩杈。與策略迭代(Policy Iteration)算法不同,值迭代算法會計算每個”狀態(tài)“或是”狀態(tài)-動作“的值(Value)或是效用(Utility)解寝,然后在執(zhí)行動作的時候扩然,會設(shè)法最大化這個值。因此聋伦,對每個狀態(tài)值的準(zhǔn)確估計夫偶,是我們值迭代算法的核心界睁。通常我們會考慮最大化動作的長期獎勵,即不僅考慮當(dāng)前動作帶來的獎勵兵拢,還會考慮動作長遠的獎勵翻斟。

在 Q-Learning 算法中,我們把這個長期獎勵記為 Q 值说铃,我們會考慮每個 ”狀態(tài)-動作“ 的 Q 值访惜,具體而言,它的計算公式為:

q(s_t, a) = R_{t+1} + \gamma \times maxq((a, s_t))

也就是對于當(dāng)前的“狀態(tài)-動作” (s_t, ??) 腻扇,我們考慮執(zhí)行動作 ?? 后環(huán)境給我們的獎勵 ??_{??+1} 债热,以及執(zhí)行動作 ?? 到達 s_{t+1} 后,執(zhí)行任意動作能夠獲得的最大的Q值 maxq(a,s_{t+1}) , \gamma為折扣因子幼苛。

不過一般地窒篱,我們使用更為保守地更新 Q 表的方法,即引入松弛變量 ?????????舶沿,按如下的公式進行更新墙杯,使得 Q 表的迭代變化更為平緩。

q(s_t, a) = (1-\alpha) \times q(s_t, a) + \alpha \times (R_{t+1}, \gamma \times maxq(a, s_{t+1}))

在強化學(xué)習(xí)中括荡,「探索-利用」問題是非常重要的高镐。具體來說,根據(jù)上面的定義畸冲,我們會盡可能地讓機器人在每次選擇最優(yōu)的決策嫉髓,來最大化長期獎勵。但是這樣做有如下的弊端:

在初步的學(xué)習(xí)中召夹,我們的 Q 值會不準(zhǔn)確岩喷,如果在這個時候都按照 Q 值來選擇恕沫,那么會造成錯誤监憎。

學(xué)習(xí)一段時間后,機器人的路線會相對固定婶溯,則機器人無法對環(huán)境進行有效的探索鲸阔。

因此我們需要一種辦法,來解決如上的問題迄委,增加機器人的探索褐筛。由此我們考慮使用 epsilon-greedy 算法(是一種貪心算法,加入了隨機因子epsilon的貪心算法)叙身,即在小車選擇動作的時候渔扎,以一部分的概率隨機選擇動作,以一部分的概率按照最優(yōu)的 Q 值選擇動作信轿。同時晃痴,這個選擇隨機動作的概率應(yīng)當(dāng)隨著訓(xùn)練的過程逐步減小残吩。

簡單的實現(xiàn)以下這個貪心算法epsilon-greedy,有如下代碼:

import random
# 動作列表如下
actions = ['u','r','d','l']
qline = {'u':1.2, 'r':-2.1, 'd':-24.5, 'l':27}
# epsilon以0.3的概率進行隨機選擇
epsilon = 0.3 
def choose_action(epsilon):
    action = None
    # 以前面定義好的一個epsilon進行選擇
    if epsilon < random.random(): 
        # 隨機選擇一個動作
        action = random.choice(actions)  
else: 
    # 否則選擇具有最大 Q 值的動作
        action = max(qline, key=qline.get) 
return action

接下來我們就可以生成迷宮啦倘核,本文開始的時候看到的迷宮太過簡單泣侮,我們給一個稍微有點難度的。

from Maze import Maze
myMaze = Maze(maze_size=(10,11), trap_number=5)

Python是不是很溫馨又簡單紧唱,居然有Maze這個東西活尊。

好了,我們生成好了這么一個迷宮漏益,準(zhǔn)備去訓(xùn)練小機器人蛹锰。接下來,就是最核心的部分遭庶,我們的小機器人啦宁仔,也就是要一個Robot類。

Robot類中峦睡,我們需要實現(xiàn)諸多功能翎苫,以使得我們成功實現(xiàn)一個強化學(xué)習(xí)智能體≌チ耍總體來說煎谍,之前我們是人為地在環(huán)境中移動了機器人,但是現(xiàn)在通過實現(xiàn) Robot 這個類龙屉,機器人將會自己移動呐粘。通過實現(xiàn)學(xué)習(xí)函數(shù),Robot 類將會學(xué)習(xí)到如何選擇最優(yōu)的動作转捕,并且更新強化學(xué)習(xí)中對應(yīng)的參數(shù)作岖。

首先 Robot 有多個輸入,其中 alpha=0.5, gamma=0.9, epsilon0=0.5 表征強化學(xué)習(xí)相關(guān)的各個參數(shù)的默認(rèn)值五芝,這些在之前我們已經(jīng)了解到痘儡,Maze 應(yīng)為機器人所在迷宮。

隨后需要一個 Robot.update 函數(shù)枢步,它指明了在每次執(zhí)行動作時沉删,Robot 需要執(zhí)行的指令。下面我們來看一看Robot這個類醉途。

需要一個初始化函數(shù)將參數(shù)引入:

def __init__(self, maze, alpha=0.5, gamma=0.9, epsilon0=0.5):

還需要一個更新函數(shù)矾瑰,每次把參數(shù)做一個更新:

def update_parameter(self):
    self.t = self.t + 1
    if self.testing:
        # 測試
        self.epsilon = self.epsilon0
    else:
        # 學(xué)習(xí)過程中更新參數(shù),讓epsilon逐漸變小
        # 從而實現(xiàn)參數(shù)的收斂
        if self.epsilon0 - self.t * 0.03 > 0:
            self.epsilon = self.epsilon0 - self.t * 0.03
        else:
            self.epsilon = 0.01
    return self.epsilon

然后有這么一個選擇動作的函數(shù):

def choose_action(self):
    def is_random_exploration():
        if random.random() < self.epsilon:
            return True
        else:
            return False
    if self.learning:
        if is_random_exploration():
            return self.valid_actions[random.randint(0, 3)]
        else:
            return max(self.Qtable[self.state], key = self.Qtable[self.state].get)
    elif self.testing:
        return max(self.Qtable[self.state], key = self.Qtable[self.state].get)
    else:
        return self.valid_actions[random.randint(0, 3)]

當(dāng)然了隘擎,必須要有一個更新知識表的函數(shù):

def update_Qtable(self, r, action, next_state):
    if self.learning:
        q_with_cur_state = self.Qtable[self.state][action]
        q_with_next_state = r + self.gamma * max(self.Qtable[next_state].values())
        self.Qtable[self.state][action] += self.alpha * (q_with_next_state - q_with_cur_state)

最后有一個整體的更新函數(shù):

def update(self):
    self.state = self.sense_state() # 取得目前的狀態(tài)
    self.create_Qtable_line(self.state) # 生成Qtable的記錄        
    action = self.choose_action() # 選擇一個動作
    reward = self.maze.move_robot(action) # 移動機器人
    next_state = self.sense_state() # 下一個狀態(tài)
    self.create_Qtable_line(next_state) # 下一個記錄
    if self.learning and not self.testing:
        # 更新Qtable殴穴,注意,這個表是機器人的“經(jīng)驗”所在
        # 初始化的時候這個表里面都設(shè)置成0
        # 隨著訓(xùn)練的深入,可以逐步更新這個表采幌,從而指導(dǎo)機器人移動
        self.update_Qtable(reward, action, next_state)
        self.update_parameter() # 更新參數(shù)
    return action, reward

上述部分并不是全部的代碼恍涂,我們略去了一些小的方法,只講了比較核心的幾個函數(shù)植榕,有心的讀者可以自己去補充并實現(xiàn)這個項目再沧。

在實現(xiàn)了上述內(nèi)容之后,我們就可以開始對我們 Robot 進行訓(xùn)練并調(diào)參了尊残。這里我們使用了另一個類Runner用來迭代這個模型炒瘸,從而實現(xiàn)整個訓(xùn)練過程及可視化。使用如下的代碼寝衫,可以成功對機器人進行訓(xùn)練顷扩。并且在當(dāng)前文件夾中生成一個視頻,記錄整個訓(xùn)練的過程慰毅。通過觀察該視頻隘截,我們能夠發(fā)現(xiàn)訓(xùn)練過程中的問題,并且優(yōu)化代碼及參數(shù)汹胃。

# 可選的參數(shù):
epoch = 40
epsilon0 = 0.5
alpha = 0.5
gamma = 0.9

maze_size = (10,11)
trap_number = 5

from Runner import Runner
g = Maze(maze_size=maze_size,trap_number=trap_number)
r = Robot(g,alpha=alpha, epsilon0=epsilon0, gamma=gamma)
r.set_status(learning=True, testing=False)
runner = Runner(r, g)
runner.run_training(epoch, display_direction=True)
# 我們姑且把整個訓(xùn)練的過程記錄成process.mp4文件吧
runner.generate_movie(filename = "process.mp4") 

至此婶芭,我們這個項目的主要代碼就介紹完了,希望大家可以對強化學(xué)習(xí)有一個直觀的認(rèn)識:)

這是本篇文章是《機器學(xué)習(xí)入門》系列文章的第五篇着饥,該系列有如下文章:
《機器學(xué)習(xí)入門——基礎(chǔ)篇》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之監(jiān)督學(xué)習(xí)》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之非監(jiān)督學(xué)習(xí)》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之深度學(xué)習(xí)》
《機器學(xué)習(xí)入門——實戰(zhàn)篇之強化學(xué)習(xí)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末犀农,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宰掉,更是在濱河造成了極大的恐慌呵哨,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轨奄,死亡現(xiàn)場離奇詭異孟害,居然都是意外死亡,警方通過查閱死者的電腦和手機挪拟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門挨务,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舞丛,你說我怎么就攤上這事耘子」” “怎么了球切?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绒障。 經(jīng)常有香客問我吨凑,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任鸵钝,我火速辦了婚禮糙臼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恩商。我一直安慰自己变逃,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布怠堪。 她就那樣靜靜地躺著揽乱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪粟矿。 梳的紋絲不亂的頭發(fā)上凰棉,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音陌粹,去河邊找鬼撒犀。 笑死,一個胖子當(dāng)著我的面吹牛掏秩,可吹牛的內(nèi)容都是我干的或舞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼蒙幻,長吁一口氣:“原來是場噩夢啊……” “哼嚷那!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起杆煞,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤魏宽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后决乎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體队询,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年构诚,在試婚紗的時候發(fā)現(xiàn)自己被綠了蚌斩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡范嘱,死狀恐怖送膳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丑蛤,我是刑警寧澤叠聋,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站受裹,受9級特大地震影響碌补,放射性物質(zhì)發(fā)生泄漏虏束。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一厦章、第九天 我趴在偏房一處隱蔽的房頂上張望镇匀。 院中可真熱鬧,春花似錦袜啃、人聲如沸汗侵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晃择。三九已至,卻和暖如春也物,著一層夾襖步出監(jiān)牢的瞬間宫屠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工滑蚯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留浪蹂,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓告材,卻偏偏與公主長得像坤次,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子斥赋,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344