介紹
目前,對於全球的科學家而言,“如何去學習一種新技能”已經成為最基本的研究課題之一。解決這個問題的意願顯而易見——如果能夠解決這個問題,那麼人類就有望做到某些從未想過的事情。換句話說,我們可以訓練機器去做更多原本人類要做的工作,迎來真正的人工智慧時代。
雖然,對於上述問題,目前我們還沒有一個完整的回答,但有一些事情是十分明確的。不考慮技能方面的學習,我們首先的是在與環境的互動過程中進行學習。不管是學習開車,還是嬰兒學習走路,學習的基礎都是與環境的互動過程。在互動中學習是所有學習理論以及智力發展理論的最根本的概念。
強化學習
今天,我們將探討強化學習。其中與環境的互動是深度學習的基礎,通常伴有明確的目的。有些人認為,強化學習是實現強人工智慧的真正希望。這麼說確實沒錯,因為強化學習擁有著巨大的潛力。
目前,有關強化學習的研究正在快速增長,人們為不同的應用程式生成了各種各樣的學習演算法。因此,熟悉強化學習的技術變得尤其重要。如果你還不是很熟悉強化學習,那麼我建議你可以去看看我以前有關強化學習的文章和一些開源的強化學習平臺。
如果你已經掌握並理解了強化學習的基礎知識,那麼請繼續閱讀這篇文章。讀完本文之後,你將會對強化學習以及程式碼實現過程有一個透徹的瞭解。
注:在程式碼實現部分,我們假設你已經有了 Python 的基本知識。如果你還不知道 Python,那麼你應該先看看這篇教程。
A Complete Tutorial to Learn Data Science with Python from Scratch
目錄
-
強化學習問題的表現形式
-
與其他機器學習方法的比較
-
解決強化問題的框架
-
強化學習的實現
-
增加強化學習的複雜性
-
深入瞭解強化學習的最新進展
-
其他資源
1. 強化學習問題的表現形式
強化學習不僅需要學習做什麼,也需要學習如何根據與環境的互動採取相應的行動。強化學習的最終結果,就是要實現系統回報訊號的最大化。學習者事先並不知道要去執行什麼行為,需要自己去發現哪種行動能產生最大的回報。讓我們通過一個簡單的例子來解釋一下。
我們以一個正在學習走路的孩子為例進行講解。
以下是孩子在學習走路時所要採取的步驟:
-
孩子關注的第一件事,就是觀察身邊的人是如何走路的。身邊的人使用兩條腿走路,一次走一步,一步一步按照次序往前走。孩子會抓住這個概念,然後努力去模仿這個過程。
-
但很快他/她又會明白,在走路之前,必須先站起來!在學習走路的過程中,站立對於孩子來說是一個挑戰。因此,孩子試圖自己站起來,他/她不斷跌倒,但是仍然決定站起來。
-
然而接下來,還有另外一個挑戰需要應付。站起來是相對容易的,但是要保持站立狀態就是另一個挑戰了。在狹小的空間中找到支撐,孩子就能成功保持站立狀態。
-
現在,孩子的真正任務就是開始學習走路了。但是學習走路說起來很容易,而實際做起來就不是那麼容易了。在孩子的大腦中需要處理很多事情,比如平衡身體、決定接下來放哪個腳、放在哪裡。
這聽起來像是一個很困難的任務,對嗎?事實上,這確實是一個挑戰,先要學習站立,然後才能學習行走。但是,現在我們不都學會了走路嘛,再也不會被這個問題所困擾了。現在你應該可以明白,為什麼學習走路對於孩子來說非常困難了。
讓我們用具體的形式來表述上面的例子。例子所要陳述的問題是“走路問題”,其中孩子是一個試圖通過採取行動(走路)來操縱環境(在地上走路)的智慧體,他/她試圖從一個狀態(即,他/她走的每一步)轉移到另一個狀態。當他/她完成任務的一個子模組(即孩子走了幾步)時,孩子會獲得獎勵(比如,一些巧克力),但是當他/她不會走路時,他/她不會收到任何巧克力(這是一個負反饋過程)。這就是對強化學習問題的簡單描述。
下面的連結,是介紹強化學習的很好的視訊。
2. 與其他機器學習方法的比較
強化學習是機器學習演算法中的一類。以下是有關機器學習演算法型別的描述。
讓我們比較一下強化學習演算法和其他型別演算法之間的區別:
監督學習與強化學習:在監督學習中,其外部有一個“監督主管”,這個“監督主管”擁有環境方面的知識,並且與智慧體一起共享這個知識,從而幫助智慧體完成任務。但是這存在一些問題,因為存在如此多的子任務之間的組合,智慧體要實現其目標的話,這些組合都是可以利用的。所以,建立一個“監督主管”幾乎是不切實際的。例如,在象棋遊戲中,存在數萬個移動方法。因此,建立玩法知識庫的任務將會單調而乏味。有一個更加合理可行的方法,就是設法從自己的經歷中學習,並以此獲得所需的知識。這就是強化學習和監督學習的主要區別。在監督學習和強化學習中,輸入和輸出之間都存在對映。但是在強化學習中,存在的是對智慧體的獎勵反饋函式,而不是像監督學習一樣,直接告訴智慧體最終的答案。
無監督學習與強化學習:在強化學習中,有一個從輸入到輸出的對映過程,但是這個過程在無監督學習中是不存在的。在無監督學習中,主要任務是找到一種最基本的模式,而不是對映關係。例如,如果任務是向使用者推薦新聞文章,那麼無監督學習演算法首先將會檢視該人以前讀過的類似文章,並把它們推薦給其他人。而強化學習演算法則是,通過使用者閱讀的某文章,不斷獲得使用者的反饋,從而構建一個“知識圖譜”,推測使用者喜歡的文章。
還有第四種型別的機器學習,稱為半監督學習。半監督學習本質上是監督學習和無監督學習的組合。它不同於強化學習,而是與監督學習相類似。半監督學習會直接給出參照答案,而強化學習不會。
3. 解決強化學習問題的框架
為了理解解決強化學習問題的過程,讓我們通過一個經典的例子來解釋一下強化學習問題——多臂賭博機。首先,我們需要了解探索與開發的基本問題,然後去定義解決強化學習問題的框架。
如上圖中的老虎機,假設你已經在老虎機上面玩了很多次了。
現在你想做的是從老虎機上面獲得最大的回報,並且儘可能快地獲得這個回報。你會怎麼做呢?
一個比較天真的想法是,只選擇一個老虎機,然後一整天都去玩它。這聽起來非常無聊,但老虎機確實可能會給你一些“回報”,即讓你贏錢。使用這種方法,你可能中獎的概率大約是0.00000…..1。也就是說,大多數時間你可能知識坐在老虎機面前虧錢。正式說明一下,我們可以將其定義為一種純粹的開發方法。但是這是最佳選擇嗎?答案當然是否定的。
讓我們看看另外一種方法。我們可以拉每個老虎機的拉桿,並且向上帝祈禱,讓我們至少打中一個。當然,這是另一種天真的想法,它只會讓你一天都在拉動拉桿,但只是給你一點點報酬。正式說明一下,這種方法只是一種純粹的探索方法。
這兩種方法都不是最優的,我們必須在它們之間找到適當的平衡點,以獲得最大的回報。這就是強化學習中“探索VS開發”的兩難選擇。
首先,我們來正式地定義一下解決強化學習問題的框架,然後列出可能的方法來解決這個問題。
馬爾科夫決策過程
在強化學習場景中,用於解決問題的數學框架叫做馬爾科夫決策過程。這可以被設計為:
-
狀態集合:S
-
動作集合:A
-
獎勵函式:R
-
策略:π
-
價值:V
要想從開始狀態轉變到結束狀態(S),我們必須採取一定的行動(A)。每當我們採取一個行動之後,我們都會得到一定的回報作為獎勵。當然,所獲得的獎勵的性質(正面獎勵還是負面獎勵)是由我們的行動決定的。
策略集合(π)取決於我們的動作集合,而我們得到的回報將會決定我們的價值(V)。在這裡,我們的任務就是選擇正確的策略來最大化我們的價值。所以我們必須最大化下面的方程:
在時間點t,我們必須最大化S中所有可能的值。
旅行推銷員問題
讓我們通過另外一個例子來說明一下。
這個問題是一系列旅行商(TSP)問題的代表。任務是以儘可能低的成本從地點A到達地點F。兩個字母之間的每條邊上的數字表示兩地之間的花費。如果這個值是負數,那麼表示經過這條路,你會得到一定的報酬。這裡我們定義的價值(Value)是運用選擇的策略走完整個路程時,所獲得的總價值。
這裡說明一下符號:
-
所有狀態的集合相當於圖中的節點:{A,B,C,D,E,F}
-
動作集合相當於是從一個地點到另一個地點的過程:{A→B, C→D, etc}
-
獎勵函式相當於邊上的值,例如“成本”
-
策略函式相當於完整的路徑規劃,比如: {A → C → F}
現在假設你在地點A,唯一你能看見的路就是你的下一個目的地(也就是說,你只能看見B,D,C,E),而別的地點你是不知道的。
你可以採取貪心演算法,選擇當前狀態下最有利的步驟,也就是說,從{A → (B,C,D,E)}中選擇採取 {A→D} 這種方法。同樣地,如果現在你所在的地點是D,想要到達地點F,你就可以從{D → (B, C, F)} 中採取 {D → F} 這個方法,這可以讓你得到最大的報酬。因此,我們選取這一條路。
至此,我們的策略就是{A → D → F},這種策略所獲得的回報是-120。
恭喜!你剛剛就已經實現了強化學習演算法。這種演算法被稱之為 epsilon 貪婪演算法。這是一種通過逐步測試而解決問題的貪婪演算法。現在,如果見你(推銷員)想再次從地點A到達地點F的話,你大概會一直選擇這條路線了。
其他旅遊方式?
你能猜出我們的策略是屬於哪個類別(純粹的探索VS純粹的開發)嗎?
請注意,我們採取的策略並不是最佳的策略。要想尋找最佳的策略,我們必須更具“探索精神”。在這裡,我們採取的方法是局域策略學習,我們的任務是在所有可能的策略中找到最佳的策略。有很多的方法都可以解決這個問題,在這裡,我簡要的列出一些主要的內容:
-
策略優先:我們的重點是找到最佳的策略
-
回報優先:我們的重點是找到最佳的回報價值,即累計獎勵
-
行動優先:我們的重點是在每個步驟上採取最佳行動
在以後的文章中,我會深入討論強化學習演算法。到那時,你可以參考這篇關於強化學習演算法的調研論文
https://www.jair.org/media/301/live-301-1562-jair.pdf
4. 強化學習的實現
接下來,我們將使用深度Q學習演算法。Q學習是一種基於策略的學習演算法,它的函式表示和神經網路近似。Google就是採用了這種演算法打敗了Atari遊戲。
讓我們看看Q學習的虛擬碼:
-
初始化價值表 ‘Q(s, a)’。
-
觀察當前的狀態值 ‘s’。
-
基於動作選擇一個策略(例如,epsilon貪婪)作為該狀態選擇的動作。
-
根據這個動作,觀察回報價值 ’r’ 和下一個新的狀態 ‘s’。
-
使用觀察到的獎勵和可能的下一個狀態所獲得的最大獎勵來更新狀態的值。根據上述公式和引數進行更新。
-
將狀態設定為新的狀態,並且重複上述過程,直到達到最終狀態。
Q學習的簡單描述可以總結如下:
我們首先來了解一下 Cartpole 問題,然後再繼續編寫我們的解決方案。
當我還是一個孩子的時候,我記得我會挑選一根木棍,並試圖用一隻手指去使它保持平衡。過去,我和我的朋友有過這樣一個比賽:誰能讓木棍保持平衡的時間更久,誰就能得到一塊巧克力作為獎勵。
以下連結是一個簡短的視訊,描述的是真正的 Cart-Pole 系統。
讓我們開始編寫程式碼吧!
在開始編寫之前,我們需要先安裝幾個軟體。
步驟一:安裝keras-rl包
在終端中,你可以執行以下命令:
git clone https://github.com/matthiasplappert/keras-rl.git
cd keras-rl
python setup.py install
步驟二:為CartPole環境安裝依賴程式
我們假設你已經安裝好了pip,那麼你只需要使用以下命令進行安裝:
pip install h5py
pip install gym
步驟三:開始編寫程式碼
首先我們需要匯入一些我們需要的模組。
import numpy as np
import gym
from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten
from keras.optimizers import Adam
from rl.agents.dqn import DQNAgent
from rl.policy import EpsGreedyQPolicy
from rl.memory import SequentialMemory
然後,設定相關變數。
ENV_NAME = `CartPole-v0`
# Get the environment and extract the number of actions available in the Cartpole problem
env = gym.make(ENV_NAME)
np.random.seed(123)
env.seed(123)
nb_actions = env.action_space.n
之後,我們來構建一個非常簡單的單層神經網路模型。
model = Sequential()
model.add(Flatten(input_shape=(1,) + env.observation_space.shape))
model.add(Dense(16))
model.add(Activation(`relu`))
model.add(Dense(nb_actions))
model.add(Activation(`linear`))
print(model.summary())
接下來,我們對智慧體進行相關的配置並進行編譯。我們運用的策略是 Epsilon 貪婪演算法。同時,我們還將我們的儲存空間設定為序列儲存,因為我們需要儲存執行操作後的結果以及每一個操作所獲得的獎勵。
policy = EpsGreedyQPolicy()
memory = SequentialMemory(limit=50000, window_length=1)
dqn = DQNAgent(model=model, nb_actions=nb_actions, memory=memory, nb_steps_warmup=10,
target_model_update=1e-2, policy=policy)
dqn.compile(Adam(lr=1e-3), metrics=[`mae`])
# Okay, now it`s time to learn something! We visualize the training here for show, but this slows down training quite a lot.
dqn.fit(env, nb_steps=5000, visualize=True, verbose=2)
現在,讓我們來測試一下我們的強化學習模型。
dqn.test(env, nb_episodes=5, visualize=True)
下圖是模型的輸出結果:
瞧,你剛剛就建立了一個強化學習機器人!
5. 增加複雜性
現在,你已經看到了一個強化學習的基本的實現過程,讓我們開始學習更多的問題吧,每次增加一點點複雜性。
漢諾塔問題
有些人可能還不知道漢諾塔問題:漢諾塔問題是在1883年發明的,由3根木棍和一系列大小不一的圓盤組成(比如上圖中的3個)。從最左側的木棍開始,目的是以最少的移動次數,把最左邊的圓盤移動到最右邊的圓盤上。
要解決這個問題,我們需要先從其狀態開始談起:
-
初始狀態:三個圓盤都在最左邊的木棍上(從上到下,依次編號為1,2,3)
-
結束狀態:三個圓盤都在最右邊的木棍上(從上到下,依次編號為1,2,3)
所有可能的狀態:
這裡,我們會得到27種可能的狀態:
其中,(12)3* 表示,圓盤1和圓盤2在最左邊的木棍上面(從上往下編號),圓盤3在中間那個木棍上面,最右邊的木棍沒有圓盤。
數值獎勵:
由於我們想要以最少的移動步數解決這個問題,所以,我們可以將每次移動的獎勵設為 -1 。
策略:
現在,如果不考慮任何的技術細節,那麼從前一個狀態過渡到下一個狀態過程中,我們可以預測出其可能的狀態。比如,當數值獎勵為-1時,狀態 (123)** 會轉移到狀態 (23)1*,或者狀態 (23)*1 。
如果你現在看到了一個同時進行的狀態,那麼上面提到的這27個狀態的每一個都可以表示成一個類似於旅行商問題的圖,我們可以通過實驗各種狀態和路徑來找到最優的解決方案。
3 x 3 魔方問題
雖然我可以為你解決這個問題,但是我想讓你自己去解決這個問題。你可以按照我上述提到的思路來進行,應該就可以解決了。
從定義開始狀態和結束狀態開始,接下來,定義所有可能的狀態、轉換過程、獎勵和策略。最後,你應該就可以使用相同的方法來構建自己的解決方案了。
6. 深入瞭解強化學習的最新進展
你可能已經意識到,魔方的複雜性要比漢諾塔問題高出很多倍,可供選擇的數量要比漢諾塔問題多得多!現在,讓我們來想象一下棋類遊戲中的狀態和選擇的策略數量吧,比如圍棋。最近,Google DeepMind公司建立了一個深度強化學習演算法,並且打敗了李世石。
在深度學習不斷取得成功的過程中,人們關注的焦點正逐漸發生變化,檢視應用深度學習來解決強化學習問題。最近有一則訊息,如洪水般向我們湧來:由Google DeepMind建立的深度強化學習演算法打敗了李世石。在視訊遊戲中也出現了類似的情況,深度強化學習演算法達到了人類水平的準確性,甚至在某些遊戲中,超越了人類。研究和實踐仍然需要共同發展,工業界和學術界需要共同努力,以建立出更好地、能自我學習的機器人。
http://www.tomshardware.com/news/alphago-defeats-sedol-second-time,31377.html
以下是幾個已經應用強化學習的重要領域:
-
博弈論和多個智慧體互動
-
機器人
-
計算機網路
-
車載導航
-
醫學
-
工業物流
我們可以看到,仍然有許許多多的領域尚未得以開發,加之人們對深度學習的熱情非常高漲,我相信以後肯定會有更多的突破!
下面是一則最近的訊息:
7. 其他資源
我希望你現在能夠深入瞭解強化學習的工作原理。這裡還是一些額外的資源,可以幫助你學習更多有關強化學習的內容。
有關強化學習的視訊
21 Deep Learning Videos, Tutorials & Courses on Youtube from 2016
有關強化學習的書籍
https://webdocs.cs.ualberta.ca/~sutton/book/bookdraft2016sep.pdf
GitHub上有關強化學習的資料庫
https://github.com/aikorea/awesome-rl
David Silver的強化學習課程
本文作者 Faizan Shaikh
是 AnalyticsVidhya 的資料科學實習生,目前致力於研究深度學習,目標是利用自己的技能,推動AI研究的進展。