深度學習比古老的蠻力技術更適合解決FlowFree問題嗎?
我們都有過這種經歷。你拿著手機發呆,想要消磨一些時間,於是你決定放棄自己優秀的思考,開啟應用商店的遊戲區,看看遊戲排行榜。你找到了一個看起來很有趣的謎題遊戲,但其實遊戲是否有趣並不重要,因為你只想玩半個小時,然後就刪掉、忘記它,對麼?
2個月以後,我完成了兩千多關的Flow Free①遊戲,並且堅持每一關都得到“完美”評分。這一遊戲(自2012年發行以來,這款遊戲在iOS和Android平臺上都是最受歡迎的遊戲之一)的設定相當簡單:將不同顏色的閥門分別連起來,並且不能有線相交。
截圖中的關卡可能看起來很簡單,但是它的難度確實在不斷提升。隨著關卡的進行,我發現我自己想出了一些可以幫助我更快完成這些高階關卡的策略(例如:儘可能的保留外層邊界空白,避免在未填滿的方形中建立“港灣”等)。瀏覽網上論壇時,我看到其他的玩家都有他們自己的技巧,有的和我的一樣,有的則略微不同。這就引出了問題——計算機能否透過“經驗”,而非蠻力,來學習這些技術?
從基礎開始:A*
如今的深度學習問題大部分可以歸結為要使用哪種演算法。我以A*搜尋作為開始。儘管它本身不是深度學習,但是它也很好的說明了這個問題內部的複雜性,並且也給了我一些機會,來使用更高階的、能夠自我驅動的啟發式演算法。
由於空間的複雜性太大,以至於我無法一次性解決問題。所以我開始按顏色遞迴地解決問題(如果給定路徑被“堵塞”,就回溯到上一種顏色)。在啟發式演算法中,我使用了較為可信的曼哈頓距離。我在四種尺寸的板子上測試了我的演算法:微型(2✖4)、小型(5✖5)、中型(8✖8)、大型(14✖14)。我保證了大型和中型的板子上的顏色比一般的顏色要少。因為大、中型的板子的確會使問題更難,對人和計算機都是如此(更多可能的路徑/選擇/狀態)。
這個演算法在小型板子上執行的很好,但是花了相當多的時間。因此,我為下一個狀態的函式增加了一些規則,以此希望強化學習的演算法能夠自己找出這些規則:防止同色相鄰方格不連線,或者出現空“港灣”。
我那臺7歲的電腦得到的結果是很讓人開心的,但是仍需改進:
如果你覺得你是第一個這麼做的,那你很有可能就錯了
在我使用強化學習之前,我一直嘗試最佳化我的A*演算法。當我發現Matt Zucker的一篇優秀的部落格文章②時,他已經為Flow Free建立了一個A*解算器(很高興的看到,我不是唯一一個有這種困擾的人),並且更加仔細地考慮過要把這些狀態從他的A*搜尋中剔除。更讓人驚訝的是,他發現了一個只有6條規則的簡單SAT演算法,這比他最好的A*搜尋法還表現還要好,而且在SAT中求解時間也非常短(對於14x14的板甚至低於1秒)。
到目前為止,我們似乎都得出了同樣令人沮喪的結論:對於這類(非對抗性的,封閉的)謎題遊戲,簡單的蠻力技術將超過基本的人工智慧演算法。
不過,我不可能止步不前。畢竟,引發這一實驗的問題仍然存在:作為人類玩家,在玩了幾個關卡後,我們就能發現一些能夠更有效地打敗Flow Free謎題特定的技巧。為什麼機器不能學習同樣的技術呢?
提到強化學習
我非常興奮地在Flow Free問題中嘗試了Q-learning演算法,因為“AI”中的“I”即將要發揮它真正的作用了。A*搜尋的工作也絕不是浪費時間,因為我們可以使用它的結果作為Q-learning智慧體的狀態-動作空間。狀態空間由板上的方塊顏色和哪條路徑(顏色)目前是“活躍的”兩部分組成。一個“動作”是指填充活躍路徑的下一個方塊。
在一開始犯了一些基礎的錯誤之後,智慧體很快就學會了如何解決小型板問題(1.5秒內100次迭代)——到目前為止看起來還不錯。但在中板上,花了10分鐘,經過10000次迭代後,仍然沒有結果:
當你聽到“人工智慧”時,你想的結果可能和這個不一樣。
為了改善這種情況,我開始除錯標準Q-learning的引數(學習率α、貼現率γ、勘探/開發率ε),但這並沒有很大幫助,所以我將注意力轉向到獎勵函式。除了實際的“獎勵”之外,還需要一個引數與獎勵函式進行權衡(否則風險就會變得規範化,這會不利於整個機器學習活動):智慧體是否會因為解決了一條路徑獲得獎勵,而不是解決了整個謎題之後。不幸的是,這並沒有起到多大作用。
最後,逐漸清晰的是,演算法之所以會在更大的板上苦苦掙扎,僅僅是因為操作空間太大了。相比於A*搜尋,Q-learning在這種情況下確實做出了更明智、更有幫助的選擇,但在大多數情況下,即使在10000次迭代之後,Q-learning 智慧體還沒有看到確切的結果。因此,下一步自然就是:
近似 Q-learning
近似Q-learning的應用是十分有吸引力的,尤其是在遊戲中。與其讓智慧體在給定的狀態下決定最佳的操作,不如讓它在每一步都能快速計算出一些直觀、獨立於具體狀態(棋盤的配置)之外的特性,並讓它自己決定哪些是最重要的。這在遊戲中會擔任遊戲改變者的角色,例如Pcaman(舉個例子,下一步的決策是基於最近的豆子和最近的幽靈,而不是在每種可能狀態下的一個動作),當然也可以是狀態數量太多,以至於讓準確Q-learning失效的Flow Free。
現在是開發人員需要權衡利弊挑選“正確”的特徵的時候了。於是,我將列表精簡到只有我認為在很多情況下重要的特徵(例如,每條路徑的剩餘曼哈頓距離)。還有一些我認為重要的、只需要讓演算法計算的特徵(但無法證明)。這些特徵包括:
- “轉彎”的個數;
- “盒子”的個數;
- 盒子中閥門的個數;
- 沒有閥門的盒子的數量(人們可以從邏輯上證明這是不可能發生的——我想看看演算法能不能算出來);
- 一條路徑是否“抱牆”(即,一條路徑是否可以與相鄰的另一條路徑相連)。
不幸的是,有了這些特徵之後,Q-learning智慧體甚至不能解決小型板問題,即使我們改變了Q-learning的引數也不行。但是,這也是個有趣的實踐。例如,該演算法在“沒有閥門的盒子”上附加了一個強大的負權重,這意味著它能夠了解到,沒有閥門的盒子會導致謎題無法解決。
或許有了更大的謎題樣本,它就能更好地學會如何真正地解決它們,但我很興奮地看到它能真正地找到重要的東西。這在AI中是一個非常有趣的現象,尤其是在遊戲AI中非常普遍:即使一個演算法不能贏得遊戲,它也可以幫助人類找到玩的更好的技巧。
走向監督學習:卷積神經網路
一開始,我對透過監督的方法來實現Free Flow的想法存有偏見。首先,這需要大量的Free Flow遊戲樣本,而這些遊戲很難在公共網際網路上找到。其次,似乎與Free Flow最接近的監督學習方法——神經網路——是一個臭名昭著的黑盒演算法,它會妨礙這個練習最有趣的部分:檢視演算法學習何種技術來解決這個難題。
然而,後來我偶然讀到了Shiva Verma在《Towards Data Science 》③雜誌上的一篇文章,他在其中做了一些與數獨遊戲非常相似的事情:本質上是把一個數獨遊戲板當作一個影像,然後使用卷積神經網路(CNN)來解決它。作者在數獨遊戲中取得了很好的效果,這讓我重新審視了我最初的想法,並嘗試了這種方法來實現Flow Free。
當然,第一個困難是獲得輸入的資料:用解析文字格式來尋找Free Flow謎題的答案,要比數獨謎題更困難。最初,我發現尋找檔案最好的方法是檢視Android應用程式的程式碼,它有一千多個以文字格式儲存的謎題:
CNN的初始結果是令人失望的:儘管CNN正在學習它任務是建立路徑,而不是僅僅在孤立地填充顏色,但在測試樣本中只有0%的謎題被解決了。
我們需要更多的資料
調整分層、訓練次數、核心大小和其他類似的常見疑點並沒有多大幫助。這似乎又回到了資料科學家最常見的問題:沒有足夠的資料,世界上最好的演算法也什麼都不是。我找到的其他最好的資料來源是www.flowfreesolutions.com,它有成千上萬的對於全新的Free Flow問題的解法,比我的解法要多... 但是是圖片格式的。
儘管我嘗試了無數次,透過各種渠道聯絡他們(甚至提供了經濟獎勵),我還是沒能讓他們給我傳送一個可解析的文字版本的解決方案。好吧,這不是一篇免費的人工智慧文章——當一個人有現代影像處理器的時候,誰還需要底層的解決方案矩陣呢?使用子專案建立一個Free Flow④解決方案影像處理器:
利用對稱性來增加我們可用的資料
這就產生了幾千個用來研究的資料點,但這仍然不是很多。但後來我意識到,就CNN而言,顏色的確切值並不重要,重要的是顏色是不同的。所以我們可以將顏色重新排列,並且仍然有另一個非冗餘的資料點。即使對一個只有六種顏色的5x5的板來說,這可以給我們的CNN提供多達6!= 720倍的研究資料點(當然,等大的板和更多的顏色會有更多可選的組合)。
數學家將從群論中認識對稱群S_n
一位朋友指出,這實際上是遊戲AI中增加資料點的常見方式。在720x的資料點的情況下,我們最終在一個20-epoch模型,使用大小約為200k的資料點測試集,在我7歲的GPU上執行了20分鐘後得到的準確率為12%。需要注意的是,我們在這裡使用了一個嚴格的衡量成功的標準:即使板子少用了一個單元格,我們也將其視為失敗。
但是,失敗比成功有趣得多。在幾乎所有的失敗中,CNN正確地解決了板子的很大一部分,剩下的部分人們則很容易完成它。從這個意義上講,CNN能夠解決文章最初的問題:憑直覺學習人類的技巧:
結論
- 對於解決基於網格的、非對抗性的謎題遊戲來說,簡單的方法通常更好。事實上隨著方法逐漸變得高階,他們的表現會越來越差。
- 然而,儘管更高階的機器學習方法不能很快地解決這個難題,但它們確實發現了一些有趣的見解,並幫助人類得到更好的解決方案——卷積神經網路在這方面做得最好。而且,它們的效能比傳統的解決方法更好。
- 更好的資料比更好的演算法重要。
後續:讀者和編者的建議
我們請了一些更有經驗的AI/ML專家(非常感謝Matt Zucker⑤、Youssef Keyrouz⑥和Mark Saroufim⑦)來檢閱這篇文章,他們建議嘗試以下想法來改進CNN演算法。第2部分文章的主題可能會詳細介紹,您也可以在https://github.com/kgaspard/flow-free ai上自己動手嘗試這些想法(以及本文中詳細介紹的方法):
- 改變CNN的層數(減少特徵看上去似乎沒有什麼用);
- 除了使用對稱來增加我們的資料點,還使用旋轉、反射等方法;
- 使用CNN的預測結果作為特徵的強化學習智慧體。
連結:
①:https://www.bigduckgames.com/
②:https://mzucker.github.io/2016/08/28/flow-solver.html
③:https://towardsdatascience.com/solving-sudoku-with-convolution-neural-network-keras-655ba4be3b11
④:https://github.com/kgaspard/flow-free-ai/blob/master/imageParser.py
⑤:https://mzucker.github.io/swarthmore/
⑥:https://www.researchgate.net/profile/
Youssef_Keyrouz
⑦:https://medium.com/@marksaroufim
原文標題:
Deep Learning vs Puzzle Games
原文連結:
https://towardsdatascience.com/deep-learning-vs-puzzle-games-e996feb76162
編輯:黃繼彥
校對:汪雨晴
譯者簡介
王紫嶽,悉尼大學Data Science在讀研究生,在資料科學界努力奮鬥的求知者。喜歡有挑戰性的工作與生活,喜歡與朋友們熱切交談,喜歡在獨處的時候讀書品茶。張弛有度,才能夠以最飽滿的熱情迎接有點忙碌的生活。