原文:Machine Learning is Fun! Part 2 -- Using Machine Learning to generate Super Mario Maker levelsgit
做者:Adam Geitgeygithub
翻譯:Kaiser(微博:王司圖)web
在系列的Part 1中咱們已經講過,機器學習是用普適的算法從數據中挖掘出有趣的東西,而無需針對具體問題寫代碼。算法
此次咱們將見識一種普適算法的炫酷表現——創造亂真的遊戲關卡。咱們將創建一個神經網絡,導入已有的超級馬里奧數據,而後創造新的關卡。編程
正如Part 1同樣,本系列教程適合全部對機器學習感興趣、但殊不知從何開始的讀者。但願全部人都能讀懂——因此不免會有些粗疏。不過但凡能把一我的帶進ML的坑裏,也就算沒白寫。bash
在Part 1中,咱們寫了一個簡單的算法來根據房產的屬性預測價格,數據以下表所示:網絡
預測函數是這樣的:less
def estimate_house_sales_price(num_of_bedrooms, sqft, neighborhood):
price = 0
# 加少許配方1
price += num_of_bedrooms * 0.123
# 加大把配方2
price += sqft * 0.41
# 適量的配方3
price += neighborhood * 0.57
return price
複製代碼
也就是說,房價的預測值是由每種屬性乘以權重再相加獲得的。用圖形來表示:機器學習
可是這個算法只對很簡單的線性問題有效,若是房價背後的真實規律沒有那麼簡單呢?好比周邊環境可能對特別大或特別小的房子影響顯著,但對於中間房型則沒有什麼影響。如何才能捕捉到這些複雜細節呢?編輯器
爲了更加的機智,咱們能夠用不一樣的權重屢次執行算法,每一組權重對應不一樣的邊界狀況。
如今咱們有四個價格預測了,而後再把這4個組合成最終結果,而且也是經過加權(只是權重值變了)。
新的_超級答案_結合了四次求解嘗試,因此相比於初始的簡單模型,可以模擬更多的狀況。
把個人四次求解嘗試整合到一張大圖裏:
這就是一個神經網絡!那個節點都有一組輸入,執行加權計算,產生一個輸出值。把這些節點串起來就可以對複雜函數進行建模了。
爲了節省篇幅,這裏我跳過了不少內容(好比特徵縮放和激勵函數),可是最重要的部分仍是如下幾點基本思想:
咱們用簡單的函數,對輸入進行加權得到輸出,這個簡單函數就叫神經元。
把許多簡單的神經元鏈在一塊兒,就能夠對單個神經元描述不了的複雜問題進行建模。
就像樂高同樣,單個積木塊或許作不出什麼,但只要有足夠多的積木,就什麼都能搭建。
給定相同的輸入,此前的神經網絡也會給出相同的輸出,用編程術語叫無狀態算法(stateless algorithm)。
在不少實例(好比房價預測)中,這正是咱們想要的。可是這類模型沒法應對數據中的時變模式。
想象一下,我給了你一個鍵盤,讓寫個故事。在開始以前,我要猜你會寫哪一個字母,那麼我該怎麼猜呢?
我能夠利用個人英語知識來增長命中率,好比你寫的第一個字母每每是一個單詞的首字母。若是我看過你的過往文章,還能夠進一步根據你的文風收縮範圍。若是我有所有數據,我就能夠搭建一個神經網絡,來計算你寫下一個字母的機率。
模型多是這樣:
再來看一個更有挑戰的問題,隨便在故事裏定個位,而後我要猜你的_下一個_字母,這就更有意思了。
用海明威的《太陽照常升起》做爲例子:
Robert Cohn was once middleweight boxi
下一個字母是什麼?
你大概會猜'n'——這個詞應該是_boxing_。這樣的猜想是基於咱們已知的經常使用英語單詞積累。同時,'middleweight' 也給出了額外的線索指向boxing。
下一個字母好猜,是由於咱們歸入了其以前的句子,並結合已有的語言知識。
若是要用神經網絡來解決這個問題,咱們須要在模型中添加一個_狀態(state)_,每次咱們向神經網絡詢問答案的時候,還會得到一箇中間計算,並在下次看成輸入的一部分重複利用。如此一來,咱們的模型就會根據以前的輸入調整預測結果。
跟着狀態走,雖然不能猜_第一個_字母,但卻能夠根據前面的字母猜_下一個_。
這就是_循環神經網絡(Recurrent Neural Network)_的基本思路。每次使用,咱們都是在更新網絡,這就能夠基於以前最多見的輸入,去更新預測。只要「記憶力」足夠,這就能夠對數據的時變模式進行建模。
猜想故事裏的下一個字母挺起來沒有什麼卵用,那還提這茬幹嗎?
手機輸入法的自動補全就是一個應用:
往計算狀況再想一想,若是咱們讓模型猜完一個再猜一個,如此循環往復——咱們就可讓計算機本身來寫個故事了!
知道了如何猜海明威句子裏的下一個字母,讓咱們試着產生一個完整的海明威風格故事。
咱們將使用Andrej Karpathy開發的循環神經網絡。Andrej是斯坦福大學的深度學習研究者,而且他寫了一個極好的循環神經網絡文本生成入門,你能夠在GitHub查看完整代碼。
模型創建在《太陽照常升起》的文本數據基礎上——362,239個字,84個字符(包括標點符號)。相比於實際應用,這一數據量其實小的很。爲了真正搭建一個好的海明威文風的模型,至少須要若干倍的樣本文字量,不過對於一個入門實例來說,如今的就足夠了。
剛開始訓練RNN的時候,預測能力還不太行,這是100次訓練迭代後的成果:
hjCTCnhoofeoxelif edElobe negnk e iohehasenoldndAmdaI ayio pe e h’e btentmuhgehi bcgdltt. gey heho grpiahe.
Ddelnss.eelaishaner」 cot AAfhB ht ltny
ehbih a」on bhnte ectrsnae abeahngy
amo k ns aeo?cdse nh a taei.rairrhelardr er deffijha
能夠看見詞與詞之間已經有空格了。
1000次迭代以後,明顯看起來更上道了:
hing soor ither. And the caraos, and the crowebel for figttier and ale the room of me? Streat was not to him Bill-stook of the momansbed mig out ust on the bull, out here. I been soms inick stalling that aid.
「Hon’t me and acrained on .Hw’s don’t you for the roed,」 In’s pair.」
「Alough marith him.」
模型已經識別出了基本句型模式,而且知道在句末加句號,給對話加引號,個別單詞已經能讀懂了,但整篇還是一派胡言。
又通過幾千次迭代以後,如今已經看起來很是好了:
He went over to the gate of the café. It was like a country bed.
「Do you know it’s been me.」
「Damned us,」 Bill said.
「I was dangerous,」 I said. 「You were she did it and think I would a fine cape you,」 I said.
「I can’t look strange in the cab.」
「You know I was this is though,」 Brett said.
「It’s a fights no matter?」
「It makes to do it.」
「You make it?」
「Sit down,」 I said. 「I wish I wasn’t do a little with the man.」
「You found it.」
「I don’t know.」
「You see, I’m sorry of chatches,」 Bill said. 「You think it’s a friend off back and make you really drunk.」
至此,算法已經捕捉到了海明威對話短小精悍的特徵,有些句子甚至已經可以達意了。
跟書中的真實文本對照一下:
There were a few people inside at the bar, and outside, alone, sat Harvey Stone. He had a pile of saucers in front of him, and he needed a shave.
「Sit down,」 said Harvey, 「I’ve been looking for you.」
「What’s the matter?」
「Nothing. Just looking for you.」
「Been out to the races?」
「No. Not since Sunday.」
「What do you hear from the States?」
「Nothing. Absolutely nothing.」
「What’s the matter?」
即使是循着單個字母的模式,咱們的算法已經模仿得有鼻子有眼了,這好的很吶!
無需從零開始生成文本,咱們能夠提供前幾個字母做爲「種子」,而後讓算法本身尋找後面的。
處於娛樂目的,咱們來作一本假書,用"Er","He","The S"做爲種子生成新的做者名字和新標題:
還不賴!
真正使人振奮的是,這一算法能夠從任意數據中識別模式,可以輕易地生成以假亂真的菜譜和 假的奧巴馬講話。爲何要侷限在人類語言當中呢?咱們大能夠應用在任何內含模式的數據之中。
2015年,任天堂推出了用於Wii U遊戲機的超級馬里奧編輯器。
這個遊戲讓你能夠自由設計超級馬里奧的關卡,而且上傳到網上和朋友們分享。你能夠加入老遊戲中的全部經典機關和敵人,簡直是馬里奧時代生人的虛擬樂高。
能不能用生成假海明威文字的模型,來生成假馬里奧關卡呢?
首先須要準備訓練數據,從1985年原版超級馬里奧兄弟裏提取出全部的室外關卡。遊戲中共有32關,其中約70%是在室外,因此就從這下手。
爲了獲取每一個關卡的設計,我寫了一個程序從遊戲中提取出關卡設計,超級馬里奧已有三十多年曆史,因此網上關於遊戲設計的資源很是多。從老遊戲中提取數據也是個頗有意思的編程練習,你也能夠試一試。
湊近了看,遊戲關卡實際上是由一組物體網格構成的:
咱們能夠用一組字符來表明這個網格,每一個字符就是一個物體:
--------------------------
--------------------------
--------------------------
#??#----------------------
--------------------------
--------------------------
--------------------------
-##------=--=----------==-
--------==--==--------===-
-------===--===------====-
------====--====----=====-
=========================-
複製代碼
每一個物體是一個字符:
字符替換後的效果就是這樣:
觀察文本文件能夠發現,馬里奧的關卡若是逐行來看,並無什麼模式:
可是若是逐列來看,模式就很明顯了:
爲了讓算法可以識別模式,須要逐列輸入數據。從輸入數據中找出最有效的表徵方式(即特徵選擇)是用好機器學習算法關鍵。
爲了訓練模型,咱們把文本文件反轉90度,這讓特徵更加顯而易見:
-----------=
-------#---=
-------#---=
-------?---=
-------#---=
-----------=
-----------=
----------@=
----------@=
-----------=
-----------=
-----------=
---------PP=
---------PP=
----------==
---------===
--------====
-------=====
------======
-----=======
---=========
---=========
複製代碼
就像模仿海明威文風的例子同樣,模型是越訓練越好的。只通過不多量訓練的結果,看起來真垃圾:
--------------------------
LL+<&=------P-------------
--------
---------------------T--#--
-----
-=--=-=------------=-&--T--------------
--------------------
--=------$-=#-=-_
--------------=----=<----
-------b
-
複製代碼
大概摸索出了'-'和'='出現的比較多,但僅僅如此,沒有真正發現什麼模式。
通過幾千次迭代,開始有點樣子了:
--
-----------=
----------=
--------PP=
--------PP=
-----------=
-----------=
-----------=
-------?---=
-----------=
-----------=
複製代碼
模型已經基本知道了每行的長度應該一致,而且也開始發現了遊戲中的一些特色:管子老是兩塊寬、至少兩塊長,因此"P"以2X2的小組出現,這很不錯!
在更多的訓練以後,模型已經生成了不少有效的數據:
--------PP=
--------PP=
----------=
----------=
----------=
---PPP=---=
---PPP=---=
----------=
複製代碼
來看看模型生成的完整關卡(轉回橫版):
看起來至關好!有幾個亮點值得注意:
開始有一個Lakitu(空中浮游怪)在天上——就像真實的馬里奧關卡同樣。
空中的管子必須底部有磚塊,而不能孤立地飄在半空。
怪物的分佈比較合理。
不會出現組織玩家前進的死路。
感受上確實很像一個真實的關卡。
若是你有超級馬里奧編輯器的話,你能夠經過bookmarking it online或者查找代碼4AC9-0000-0157-F3C3來玩這一關卡。
咱們用來訓練模型的循環神經網絡算法,跟現實世界裏不少公司用來解決難題(如語音識別,機器翻譯)的算法是同樣的。但咱們的模型只創建在不多的數據量之上,因此只能算是一種「玩具」而不能動真格的。原版超級馬里奧遊戲裏的關卡數不足以訓練出一個真正好的模型。
若是咱們能像任天堂同樣,拿到數以十萬計的玩家自制關卡數據,咱們就能夠作個更強的模型了。不過任天堂不會坐視其發生的,大公司都不會免費開放數據。
隨着機器學習在不少行業裏愈來愈重要,好程序和壞程序的差異愈來愈多地體如今,訓練模型的數據量。這就是爲何Google和Facebook等公司如此須要你的數據。
好比Google最近開源了用於搭建大規模機器學習應用的軟件包TensorFlow,Google免費開放了如此重要而強力的技術,引發了巨大反響,而TensorFlow正是支撐Google Translate的後臺。
但如若是沒有Google在每種語言上留下的海量數據寶藏,你也不可能作出Google Translate的對手,數據纔是Google真正的殺手鐗。下次當你打開Google Maps Location History或Facebook Location History的時候,留意它們記錄了你的一切所到之處。