導言
我一直對遊戲著迷。在緊湊的時間線下執行一個動作似乎有無限的選擇——這是一個令人興奮的體驗。沒有什麼比這更好的了。
所以當我讀到DeepMind提出的不可思議的演算法(如AlphaGo和AlphaStar)時,我被吸引了。我想學習如何在我自己的機器上製造這些系統。這讓我進入了深度強化學習(Deep RL)的世界。
即使你不喜歡玩遊戲,深度強化學習也很重要。只用看當前使用深度強化學習進行研究的各種功能就知道了:
那工業級應用程式呢?這裡有兩個最常見的深度強化學習用例:
谷歌雲自動機器學習(Google’s Cloud AutoML)
臉書Horizon平臺(Facebook's Horizon Platform)
深度強化學習的範圍是巨大的。現在是一個進入這個領域並並以此作為職業的好時機。
在這篇文章中,我的目標是幫助您邁出第一步,進入深度強化學習的世界。我們將使用強化學習中最流行的演算法之一,Deep Q-Learning,來了解強化學習是怎樣工作的。錦上添花的是什麼呢?我們將使用python在一個很棒的案例研究中實現我們的所有學習。
目錄
一、Q-Learning之路
二、為什麼要做“深度”Q-Learning?
三、Deep Q-Learning的簡介
四、與深度學習相比,深度強化學習面臨的挑戰
4.1 目標網路
4.2 經驗回放
五、使用Keras & Gym 在Python中實現Deep Q-Learning
一、Q-Learning之路
在正式深度強化學習之前,您應該瞭解一些概念。別擔心,我已經為你安排好了。
我以前寫過很多關於強化學習的文章,介紹了多臂抽獎問題、動態程式設計、蒙特卡羅學習和時間差分等概念。我建議按以下順序瀏覽這些指南:
強化學習的基礎學習:使用動態程式設計的基於模型的規劃
https://www.analyticsvidhya.com/blog/2018/09/reinforcement-learning-model-based-planning-dynamic-programming/
強化學習指南:從零開始用Python解決多臂抽獎問題
https://www.analyticsvidhya.com/blog/2018/09/reinforcement-multi-armed-bandit-scratch-python/?utm_source=blog&utm_medium=introduction-deep-q-learning-python
強化學習:通過OpenAI GymToolkit介紹蒙特卡洛學習
https://www.analyticsvidhya.com/blog/2018/11/reinforcement-learning-introduction-monte-carlo-learning-openai-gym/?utm_source=blog&utm_medium=introduction-deep-q-learning-python
蒙特卡羅樹搜尋簡介:DeepMind的AlphaGo背後的遊戲改變演算法
https://www.analyticsvidhya.com/blog/2019/01/monte-carlo-tree-search-introduction-algorithm-deepmind-alphago/
強化學習的基礎:時間差(TD)學習介紹
https://www.analyticsvidhya.com/blog/2019/03/reinforcement-learning-temporal-difference-learning/?utm_source=blog&utm_medium=introduction-deep-q-learning-python
這些文章足以從一開始就獲得基本強化學習的詳細概述。
但是,請注意,以上鍊接的文章絕不是讀者理解Deep Q-Learning的先決條件。在探究什麼是Deep Q-Learning及其實現細節之前,我們將快速回顧一下基本的強化學習概念。
強化學習代理環境
強化學習任務是訓練與環境互動的代理。代理通過執行操作到達不同的場景,稱為狀態。行動會帶來正面和負面的回報。
代理只有一個目的,那就是最大限度地提高一段經歷的總回報。這個經歷是環境中第一個狀態和最後一個或最終狀態之間發生的任何事情。我們加強了代理的學習,以經驗來執行最佳的行動。這是戰略或原則。
讓我們舉一個非常流行的PubG遊戲的例子:
士兵是這裡與環境互動的代理;
狀態就是我們在螢幕上看到的內容;
一段經歷是一個完整的遊戲;
動作包括向前、向後、向左、向右、跳躍、躲避、射擊等;
獎勵是根據這些行動的結果確定的。如果士兵能夠殺死敵人,那就獲得一個正面的回報,而被敵人射殺是一個負面的回報。
現在,為了殺死敵人或得到正面的回報,需要一系列的行動。這就是延遲或延遲獎勵的概念開始發揮作用的地方。強化學習的關鍵是學習執行這些序列並最大化回報。
馬爾科夫決策過程(MDP)
需要注意的一點是,環境中的每個狀態都是其先前狀態的結果,而先前狀態又是其先前狀態的結果。然而,儲存所有這些資訊,即使是在短時間的經歷中,也變得不可行。
為了解決這一問題,我們假設每個狀態都遵循馬爾可夫屬性,即每個狀態僅依賴於先前的狀態以及從該狀態到當前狀態的轉換。看看下面的迷宮,以更好地瞭解這項工作背後的思想:
現在,有兩個場景具有兩個不同的起點,代理通過不同的路徑到達相同的倒數第二狀態。現在,不管代理通過什麼路徑到達紅色狀態。走出迷宮併到達最後一個狀態的下一步是向右走。顯然,我們只需要紅色/倒數第二狀態的資訊就可以找到下一個最佳的行為,這正是馬爾可夫屬性所暗示的。
Q 學習
假設我們知道每一步行動的預期回報。這基本上就像是給代理的一張備忘單!我們的代理會確切知道該採取什麼行動。
它將執行最終產生最大總獎勵的動作序列。總回報也稱為Q值,我們將把我們的策略公式化為:
上述方程表明,在狀態s和執行動作a產生的Q值是立即獎勵r(s, a)加上下一狀態s’ 可能的最高Q值。這裡的gamma是折現係數,它控制著未來獎勵的貢獻。
q(s’, a)又取決於q(s”, a),該q(s”, a)將具有伽馬平方係數。因此,Q值取決於未來狀態的Q值,如下所示:
調整gamma的值將減少或增加未來獎勵的貢獻。
由於這是一個遞迴方程,我們可以從對所有Q值進行任意假設開始。根據經驗,它將收斂到最優策略。在實際情況下,這是作為更新實現的:
其中alpha是學習速率或步長。這就決定了新獲取的資訊在多大程度上會覆蓋舊資訊。
二、為什麼選擇“深度”Q-Learning
Q-Learning是一個簡單但功能強大的演算法,可以為我們的代理提供一個備忘單,有助於代理準確地確定要執行的操作。
但如果這張備忘單太長怎麼辦?設想一個有10000個狀態的環境,每個狀態有1000個行動。這將建立一個包含1000萬個單元格的表。事情很快就會失控!
很明顯,我們不能從已經探索過的狀態中推斷出新狀態的Q值。這有兩個問題:
首先,儲存和更新該表所需的記憶體量將隨著狀態數的增加而增加。
第二,探索每個狀態建立所需Q表所需的時間量是不現實的。
這裡有一個想法——如果我們用機器學習模型(比如神經網路)來估計這些Q值會怎麼樣?好吧,這就是DeepMind演算法背後的想法,它使得谷歌以5億美元收購DeepMind!
三、Deep Q-Learning的簡介
在深度Q學習中,我們使用神經網路來近似Q值函式。狀態作為輸入,所有可能動作的Q值作為輸出生成。Q-Learning和深度Q-Learning之間的比較如下:
那麼,使用深度Q學習網路(DQNs)強化學習的步驟是什麼?
所有過去的經驗都由使用者儲存在記憶體中。
下一步動作由Q網路的最大輸出決定。
這裡的損失函式是預測的Q值和目標Q值–Q*的均方誤差。
這基本上是一個迴歸問題。然而,我們不知道這裡的目標或實際價值,因為我們正在處理一個強化學習問題。回到由貝爾曼方程匯出的Q值更新方程。我們有:
綠色部分表示目標。我們可以說,它是在預測自己的價值,但由於R是無偏的真實回報,網路將使用反向傳播更新其梯度,最終收斂。
四、與深度學習相比,深度強化學習面臨的挑戰
到目前為止,這一切看起來都很棒。我們瞭解了神經網路如何幫助代理學習最佳行動。然而,當我們將深度強化學習與深度學習(DL)進行比較時,存在一個挑戰:
非固定或不穩定目標
讓我們回到深度Q學習的虛擬碼:
正如您在上面的程式碼中看到的,目標在每次迭代中都在不斷地變化。在深度學習中,目標變數不變,因此訓練是穩定的,這對強化學習來說則不然。
綜上所述,我們經常依賴於政策或價值函式來加強學習,以獲取行動樣本。然而,隨著我們不斷學習要探索什麼,這種情況經常發生變化。當我們玩遊戲時,我們會更多地瞭解狀態和行為的基本真值,因此輸出也在變化。
因此,我們嘗試學習對映不斷變化的輸入和輸出。但是解決辦法是什麼呢?
4.1 目標網路
由於同一個網路正在計算預測值和目標值,這兩者之間可能存在很大的差異。因此,我們可以使用兩個神經網路來代替使用1個神經網路來學習。
我們可以使用單獨的網路來估計目標。該目標網路與函式逼近器具有相同的結構,但引數是固定的。對於每個C迭代(超引數),預測網路中的引數都會複製到目標網路中。這將導致更穩定的訓練,因為它保持目標功能不變(在一段時間之內):
4.2 經驗回放
要執行經驗回放,我們儲存代理的經驗 – et=(st,at,rt,st+1)
上面的陳述是什麼意思?在模擬或實際經驗中,系統不會在狀態/動作對上執行Q-Learning,而是將為[狀態、動作、獎勵、下一個狀態]發現的資料儲存在一個大表中。
讓我們用一個例子來理解這一點。
假設我們試圖構建一個視訊遊戲機器人,其中游戲的每一幀表示不同的狀態。在訓練過程中,我們可以從最後100000幀中隨機抽取64幀來訓練我們的網路。這將使我們得到一個子集,其中樣本之間的相關性較低,也將提供更好的取樣效率。
結合到一起
到目前為止我們學到的概念是什麼?它們結合在一起,形成了用於在Atari遊戲中實現人類級效能的深度Q學習演算法(僅使用遊戲的視訊幀)。
我在下面列出了Deep Q-Network(DQN)中涉及的步驟:
對遊戲畫面(狀態S)進行預處理並反饋給DQN,DQN將返回狀態下所有可能動作的Q值
使用epsilon貪婪策略選擇操作。用概率epsilon,我們選擇一個隨機動作a並且概率為1-epsilon,我們選擇一個最大Q值的動作,例如a=argmax(Q(s, a, w))
在s狀態下執行此操作並移動到新的s狀態以獲得獎勵。此狀態s'是下一個遊戲螢幕的預處理影象。我們將此轉換儲存在重播緩衝區中,如<s, a, r, s'>
接下來,從重放緩衝區中隨機抽取若干批轉換並計算損失。
已知:,即目標Q與預測Q的平方差。
根據我們的實際網路引數進行梯度下降,以儘量減少損失。
每次C迭代後,將我們的實際網路權重複製到目標網路權重
對m個經歷重複這些步驟
五、使用Keras & OpenAI Gym 通過Python實現Deep Q-Learning
好吧,這樣我們對深度Q學習的理論方面有了很好的瞭解。現在就開始行動怎麼樣?沒錯——讓我們啟動我們的python notebook吧!
我們會創造一個可以玩CartPole的代理。我們也可以使用Atari遊戲,但是訓練一個代理來玩需要一段時間(從幾個小時到一天)。我們的方法背後的思想將保持不變,所以你可以在你的機器上的Atari遊戲上嘗試這個。
CartPole是OpenAI gym(遊戲模擬器)中最簡單的環境之一。正如你在上面的動畫中看到的,CartPole的目標是平衡一個杆,這個杆與一個運動車頂部的接合處相連。
這裡有四種由狀態給出的資訊(如杆的角度和推車的位置),而不是畫素資訊。代理可以通過執行一系列0或1操作來移動車,將車向左或向右推。
我們將在這裡使用Keras-rl庫,它允許我們實現深度Q學習。
第一步:安裝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 greedy,把我們的記憶體設定為順序記憶體,因為我們希望儲存我們所執行的操作的結果以及每個操作獲得的獎勵。
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'])
#好吧,現在該學點東西了!我們把這裡的訓練具象化展示出來,但這會大大降低訓練的速度。
dqn.fit(env, nb_steps=5000, visualize=True, verbose=2)
測試我們的強化學習模型:
dqn.test(env, nb_episodes=5, visualize=True)
這將是我們模型的輸出:
不錯!祝賀您建立了第一個深度Q學習模型。
最後幾點
Openai Gym提供了幾種將DQN融合到Atari遊戲中的環境。那些處理過計算機視覺問題的人可能會直觀地理解這一點,因為這些問題的輸入在每個時間步驟都是遊戲的直接幀,因此該模型由基於卷積神經網路的體系結構組成。
有一些更先進的深度強化學習技術,如雙DQN網路,雙DQN和優先經驗回放,可以進一步改善學習過程。這些技巧讓我們用更少的片段獲得更好的分數。我將在以後的文章中介紹這些概念。
我建議您在Cartpole之外的至少一個環境中嘗試DQN演算法,以練習和理解如何調整模型以獲得最佳結果。
原文標題:
A Hands-On Introduction to Deep Q-Learning using OpenAI Gym in Python
原文連結:https://www.analyticsvidhya.com/blog/2019/04/introduction-deep-q-learning-python/