DeepMind在2013年發表了一篇題為《用深度強化學習翫Atari》的文章,介紹了一種新的用於強化學習的深度學習模型,並展示了它僅使用原始像素作為輸入來掌握Atari 2600計算機遊戲難度控制策略的能力。在本教程中,我將使用Keras實現本文。我們將從增強學習的基礎開始,然後深入代碼中進行實踐性的理解。
我在2018年3月初開始了這個項目,並取得了一些不錯的成果。但是,只有CPU的系統是學習更多功能的瓶頸。強大的GPU極大地提升了性能。
在我們運行模型之前,我們需要了解許多步驟和概念。
步驟:
- 在瀏覽器(JavaScript)和模型(Python)之間構建雙向接口
- 捕獲和預處理圖像
- 訓練模型
- 評估
源代碼:https://github.com/Paperspace/DinoRunTutorial.git
入門
要按照原樣訓練和玩遊戲,請在設置環境後克隆GitHub存儲庫
Git克隆:https://github.com/Paperspace/DinoRunTutorial.git
並在jupyter notebook上工作。
Reinforcement Learning Dino Run.ipynb
確保你第一次運行init_cache()來初始化文件系統結構。
強化學習
對許多人來說,這可能是一個新詞,但我們每個人都已經學會了使用強化學習(RL)的概念,這就是我們的大腦仍然工作的方式。獎勵系統是任何RL算法的基礎。如果我們回到兒童走路的比喻,積極的獎勵將是來自父母的鼓掌或能夠得到糖果,而負面獎勵將是沒有糖果。孩子在開始走路之前首先學會站起來。就人工智能而言,代理商的主要目標(在我們的案例中是Dino)是通過在環境中執行特定的操作序列來最大化某個數值獎勵。RL中最大的挑戰是缺乏監督(標記數據)來指導代理人。它必須自己探索和學習。代理從隨機執行行動開始,觀察每個行動帶來的回報,並學習如何在面臨類似環境狀況時預測最佳行動。
Q-learning
我們使用Q-learning, RL的一種技術,在這裡我們嘗試去近似一個特殊的函數,它可以驅動任意環境狀態序列的動作選擇策略。Q- Learning是一種沒有模型的強化學習的實現,它根據每個狀態、所採取的行動和所產生的獎勵來維護一個Q值表。一個示例q表應該告訴我們數據是如何構造的。在我們的例子中,狀態是遊戲截圖和動作,什麼都不做,然後跳轉[0,1]。
我們利用深度神經網絡通過迴歸來解決這個問題,並選擇具有最高預測Q值的動作。有關Q-learning的詳細瞭解,請參閱Tambet Matiisen撰寫的這篇令人驚歎的博客文章。你也可以參考我以前的文章,瞭解所有Q-learning特有的超參數。
建立
讓我們設置我們的環境來開始訓練過程。
1.選擇虛擬機:
我們需要一個完整的桌面環境,在這裡我們可以捕獲和利用屏幕截圖進行培訓。我選擇了一個Paperspace ML-in-a-box(MLIAB)Ubuntu鏡像 MLIAB的優勢在於它預裝了Anaconda和許多其他ML庫。
2.配置和安裝Keras以使用GPU:
我們需要安裝keras和tensorflow的GPU版本。Paperspace的虛擬機具有這些預先安裝的,但是如果不安裝它們的話
pip install keras
pip install tensorflow
另外,確保GPU可以被設置識別。執行下面的python代碼,你應該看到可用的GPU設備
from keras import backend as K
K. tensorflow_backend._get_available_gpus()
3.安裝依賴項
Selenium pip install selenium
OpenCV pip install opencv-python
從 http://chromedriver.chromium.org上下載Chromedriver
遊戲框架
你可以通過將瀏覽器指向chrome://dino或只要拔掉網絡插頭來啟動遊戲。如果我們想修改遊戲代碼的話,另一種方法是從chromium的開源存儲庫中提取遊戲。
我們的模型是用python編寫的,遊戲是用JavaScript構建的,我們需要一些接口工具讓它們相互通信。
【Selenium是一種流行的瀏覽器自動化工具,用於向瀏覽器發送操作,並獲取當前分數等不同的遊戲參數。】
現在我們有一個接口來發送動作到遊戲中,我們需要一種機制來捕獲遊戲屏幕。
【Selenium和OpenCV分別為屏幕捕獲和圖像預處理提供了最佳性能,實現了6-7 fps的下降幀率。】
我們每個時間幀只需要4幀,足以將速度作為一項功能來學習。
遊戲模塊
我們使用這個模塊實現了Python和JavaScript之間的接口。下面的代碼片段會給你一個關於模塊中發生的事情的要點。
代理模塊
我們使用代理模塊來封裝所有的接口。我們使用此模塊控制Dino,並獲取環境中的代理狀態。
遊戲狀態模塊
要將操作發送到模塊並獲得環境作為該操作的結果轉換為的結果狀態,我們使用遊戲狀態模塊。它通過接收和執行動作、決定獎勵和返回經驗元組來簡化過程。
圖像管道
圖像捕捉
我們可以通過多種方式捕獲遊戲屏幕,例如使用PIL和MSS python庫截取整個屏幕和裁剪區域。 然而,最大的缺點是對屏幕分辨率和窗口位置的敏感度。幸運的是,遊戲使用了HTML Canvas。我們可以使用JavaScript輕鬆獲得base64格式的圖像。我們使用selenium來運行這個腳本。
圖像處理
所捕獲的原始圖像的分辨率約為600x150,有3個(RGB)通道。我們打算使用4個連續的屏幕截圖作為模型的一個輸入。這就使得我們對尺寸600x150x3x4的單個輸入。這在計算上是昂貴的,並不是所有的功能都可用於玩遊戲。所以我們使用OpenCV庫來調整大小、裁剪和處理圖像。最終的處理輸入僅為80x80像素和單通道(灰度)。
模型架構
我們得到了輸入和一種利用模型輸出來玩遊戲的方法,讓我們來看看模型架構。
我們使用了一系列的三層卷積層,然後將它們壓平為密集層和輸出層。僅限CPU的模型不包含池化層,因為我已經刪除了許多功能,並且添加池化層會導致已稀疏功能的顯著損失。但藉助GPU的強大功能,我們可以容納更多功能,而不會降低幀頻。
【最大池圖層顯著改善了密集特徵集的處理。】
模型架構
我們的輸出圖層由兩個神經元組成,每個神經元代表每個動作的最大預測回報。然後我們選擇最大回報(Q值)。
訓練
這些是訓練階段發生的事情:
- 以無動作開始並獲得初始狀態(s_t)
- 觀察遊戲步數
- 預測並執行操作
- 在回放記憶中存儲經驗
- 從回放記憶中隨機選擇一個批次並在其上訓練模型
- 重新開始遊戲結束
這個代碼很長,但很容易理解
請注意,我們正在從回放記憶中抽取32次隨機經驗回放,並使用批量的訓練方法。其原因是遊戲結構中的動作分配不平衡,以及避免過度擬合。
結果
我們應該能夠通過使用這個體系結構得到好的結果。GPU顯著改善了結果,通過平均分數的提高可以驗證。下圖顯示了訓練開始時的平均成績。每10場遊戲的平均分在訓練結束時都保持在1000分以上。
最高的記錄是4000+,遠遠超過了之前250的模型(也遠遠超出了大多數人的能力!)圖中顯示了訓練期間遊戲最高分數的進度(比例= 10)。
Dino的速度與分數成正比,這使得它更難以檢測並以更快的速度進行動作。因此整個遊戲都是在恆定的速度下進行的。本博客中的代碼片段僅供參考。請參考GitHub repo中的函數代碼,並添加其他設置。
以上為譯文。
本文由阿里云云棲社區組織翻譯。
文章原標題《Build an AI to play Dino Run》,作者:Ravi Mude ,譯者:董昭男,審校:。
閱讀更多 阿里云云棲號 的文章