在Unity環境中用強化學習訓練Donkey Car
來自專欄論智15 人贊了文章
作者:Felix Yu
編譯:Bing
Donkey Car是一種為模型車開源的DIY自動駕駛平台,它利用一個帶有相機的樹莓派單片機,讓模型車可在賽道上自動駕駛,Donkey Car會學習你的駕駛方法,在訓練後懂得自動駕駛。對於那些沒有背景知識的人來說,該平台能提供你所需要的必要細節,它既包含硬體也帶有軟體。閱讀完這一教程,你也可以無需硬體背景知識組裝一輛自己的自動駕駛汽車。
現在,訓練汽車進行自動駕駛最常見的方法就是行為克隆和路線跟隨。在高級層面,行為克隆是利用卷積神經網路學習汽車前方攝像機所拍攝的圖像之間的映射,並通過監督學習控制角度和throttle values。而路線跟隨是利用計算機視覺技術跟蹤路線,並且利用一個PID控制器讓小車跟著該路線。我嘗試了兩種方法,它們都很有用!
用強化學習訓練Donkey Car
重要的一點是,Donkey Car的目標是搭建一輛在比賽中跑的最快的車(能以最快速度跑完一圈)。我認為強化學習是訓練的好方法,只需設計一種獎勵,讓汽車的速度達到最快,並且讓它能一直保持在軌道內即可。聽上去很簡單對吧?但事實上,很多研究表示在實體目標上訓練強化學習是很困難的。強化學習主要通過試錯法訓練,放在汽車身上,我們只能保佑車子不會在一次次的實驗中撞碎。另外,訓練時長也是一個問題,通常,強化學習智能體都要訓練個幾百回合才能掌握些許規律。所以,強化學習很少用在現實物體中。
模擬現實
最近有一些科學家們研究對現實進行模擬,即先用強化學習在虛擬模擬器上訓練小車,然後將其遷移到現實世界裡。例如,最近OpenAI就訓練了一個靈活的機械手臂,可以做出多種動作,整個過程就是在虛擬中訓練的。除此之外,谷歌大腦也曾訓練過一個四足機器人,可以用模擬現實的技術學習靈活的動作。在虛擬器中學習控制策略,然後再將其部署到真正的機器人上。這樣看來,若想用強化學習訓練Donkey Car,一個可行方案就是先用模擬器訓練,再把學到的策略用在真的小車上。
Donkey Car模擬器
第一步是先為Donkey Car建造一個高保真度的模擬器。幸運的是,Donkey Car社區里一位愛好者在Unity中創建好了一個模擬器。但是它設計的目的主要針對行為學習(即將相機中的圖片保存在對應的控制角度和throttle values文件中以進行監督學習),但是和強化學習無關。我希望的是有一個類似OpenAI Gym那樣的交互界面,可以用reset( )重置環境、對其進行操作。所以,我決定在現有的Unity模擬器基礎上對其進行修改,讓它更適合強化學習。
4.1 創建一種能用Python和Unity溝通的方法
因為我們要用Python書寫強化學習代碼,所以我們首先要找到一種方法能讓Python在Unity環境中使用。結果我發現這現有的模擬器也是用Python代碼進行溝通的,但它是通過Websocket協議進行的,Weosocket和HTTP不同,它支持伺服器和客戶端之間進行雙向通信。在我們的案例中,我們的Python「伺服器」可以直接向Unity推送信息(方向和油門),而我們的Unity「客戶端」也可以反向對伺服器推送信息(狀態和反饋)。
除了Websocket,我還考慮使用gRPC,這是一種高性能伺服器-客戶端通信框架,用谷歌在2016年八月開源。Unity將其用於機器學習智能體介面通信的協議。但是它的設置有點麻煩,並不高效,所以我還是選擇Websocket。
4.2 為Donkey Car創建一個定製化的環境
下一步是創建一個類似於OpenAI gym的交互界面,用於訓練強化學習演算法。之前訓練過強化學習演算法的人可能對各種API的使用很熟悉。常見的就是reset( )、step( )、is_game_over( )等。我們可以將OpenAI gym的種類進行擴展,然後用上面的方法創建自己的gym環境。
最終成果能和OpenAI gym相媲美,我們科用類似的指令與Donkey環境交互:
env = gym.make("donkey-v0")state = env.reset()action = get_action()state, action, rewards, next_state = env.step(action)
環境同樣可以讓我們設置frame_skipping,並且用headless模式訓練智能體(也就是無需Unity GUI)。
同時,Tawn Kramer還有3中Unity場景可用:生成道路、倉庫和Sparkfun AVC,都可以用於訓練。在我們開始運行自己的強化學習演算法之前,我們要麼自己搭建Donkey Car的Unity環境,要麼下載預先搭建好的環境可執行程序。具體的環境設置和訓練指導可以在我的GitHub中找到:github.com/flyyufelix/donkey_rl
4.3 用DDQN訓練Donkey Car
準備好了對強化學習友好的環境,我們現在就可以搭建自己的強化學習演算法啦!我採取的是用Keras書寫的Double Deep Q學習演算法,這是DeepMind開發的經典強化學習演算法,易於測試,編寫簡單。我已經在OpenAI gym中的cartpole和VizDoom中測試了,所以如果有什麼問題,應該是Unity環境的問題,演算法沒有問題。關於DQN的文章,大家可以參考我之前的博文。flyyufelix.github.io/2017/10/12/dqn-vs-pg.html
4.3.1 狀態空間
我們用Donkey Car前方安裝的攝像機所拍攝的像素照片,執行以下轉換:
- 將尺寸從(120, 160)改為(80, 80)
- 變為灰度圖像
- 框架堆疊:去前面幾個步驟中的4個框架堆在一起
最後的狀態維度應該是(1, 80, 80, 4)。
4.3.2 動作空間
現實和虛擬世界中的Donkey Car都是將持續的方向控制和油門數值作為輸入。為了簡介,我們將油門數值設為常量(例如0.7),僅僅改變控制方向。控制方向的值從-1到1,但是,DQN只能處理分離的動作,所以我將方向的值分為15個種類。
4.3.3 Q網路框架
我們的Q網路是一個3層卷積神經網路,以堆疊的框架狀態為輸入,輸出表示方向值分類的15個值。
4.3.4 獎勵
獎勵是有關汽車偏離中線程度的函數,它由Unity環境所提供。獎勵函數用以下公式表達:
其中max_cte是一個歸一化常數,所以獎勵的範圍在0到1之間。如果abs(cte)大於max_cte,循環即終止。
4.3.5 其他重要變數
Frame skipping設置為2以穩定訓練。Memory replay buffer的值為10000.Target Q網路在最終訓練時會更新。CNN訓練時的Batch size為64。貪婪函數用於探索。Epsilon初始值為1,逐漸在10000次訓練後會成為0.02。
4.3.6 結果
經過上面的設置,在單個CPU和一個GTX 1080 GPU上,我訓練了DDQN差不多100次。整個訓練用了2到3個小時。可以從上面的視頻中看到,小車跑得很好!
去除背景雜訊
我們想讓我們的強化學習智能體只根據路線的位置和方向進行決策輸出(即方向控制),不要受環境中的其他因素影響。但是,由於我們的輸入是全像素的圖像,它可能對背景模式過度擬合,而無法認出行進路線。這在現實中尤其重要,因為旁邊的車道可能會有障礙物(例如桌子、椅子、行人等)。如果我們想從虛擬世界將學習策略進行遷移,我們應該讓智能體顧略背景中的噪音,只關注於車道。
為了解決這個問題,我創建了一個預處理通道,可以將行車路線從原始像素圖像中分離出去,再輸入到CNN中。分割過程受@ldesegur/a-lane-detection-approach-for-self-driving-vehicles-c5ae1679f7ee" title="這篇博文">這篇博文的啟發。這一過程概括如下:
- 用Canny Edge檢測器檢測並提取所有邊框
- 用Hough直線轉換確定所有直線
- 將直線分成positive sloped和negative sloped兩類
- 刪除所有不屬於車道的直線
最終轉換出的圖片應該有最多2條直線,具體情況如下:
接著我把分割後的圖像重新調整到(80, 80)的,將4個連續的框架堆疊在一起,用它們作為新的輸入狀態。我使用新狀態再次訓練了DDQN,生成的強化學習智能體可以學習良好策略進行駕駛!
然而,我注意到不僅僅訓練時間會變長,學習策略也會變得不穩定,車子會經常在轉彎的時候搖晃。我想可能是因為在訓練的時候丟掉了有用的背景信息。不然的話,智能體應該不會過度擬合。
下一步
在這篇文章中,我們介紹了一種能和OpenAI gym相比的環境,用來訓練Unity模擬器中的Donkey Car。還用DDQN訓練它自動成功地自動駕駛。接下來,我計劃讓小車通過訓練加速到最大值,並且將這一策略遷移到現實中。
推薦閱讀:
※張亞勤王傳福再次合體談智能交通
※Drive.ai自動駕駛汽車活力亮相,外掛LED屏幕備受關注
※千尋位置高精度絕對定位技術 助一汽解放低速自動駕駛研發
※加州路測群俠傳:滴滴獲批准,Waymo景馳率先切入無人路測
※高通放棄收購後,恩智浦高調亮相:三大趨勢推動汽車市場發展
TAG:Unity桌面環境 | 強化學習ReinforcementLearning | 自動駕駛 |