手把手教你訓練一個秒殺科比的投籃AI,不服來練
原作:Abe Haskins
安妮 編譯整理
量子位 出品 | 公眾號 QbitAI
在這篇教程中,谷歌工程師Abe Haskins用簡潔易懂的語言,教你用Unity3D和TensorFlow生產一隻會投籃的AI。
不少人表示,文章中的這些gif圖能看一天!教你用AI秒殺NBA球員的校車馬上就要發車了,還不快準備上車?
準備階段
在開始正式訓練前,先檢查下自己是不是準備好了下面這些工具:
模擬籃球和物理環境Unity
用於訓練模型的Node.js和TensorFlow.js
通過ML-agent asset包將模型嵌入Unity的TensorFlowSharp
將TensorFlow.js轉換成Unity中可用圖的tsjs-converter
將線性回歸簡單可視化的Google Sheets
所需工具就是這些了,接下來我將手把手教你解釋清楚這些工具是怎樣應用的。我建議大家先去將開源代碼下載下來,方便後續的學習和理解。
代碼地址:
https://github.com/abehaskins
明確目標
把目標想得簡單些更有利於完成目標,我們可以把這個任務想像成:如果投球手距離籃筐的距離為x,用y程度的力度投球則會進球的簡單問題。
這樣一想是不是覺得模型都簡單了好幾度?如果你對如何在Unity中製作更複雜的AI感興趣,你可以從Unity中查看完整的ML-Agents項目。
ML-Agents項目地址:
https://github.com/Unity-Technologies/ml-agents
籃筐和球
在這個遊戲中,我們只需要投籃就好了。首先需要用到的就是Unity,你平時打遊戲時看到的那個立方體的logo就是Unity的標誌。它是一個遊戲引擎,可以為所有平台構建2D和3D遊戲。
Unity內置物理世界系統,還包括基礎3D建模和腳本運行時(Mono),支持用C#編程。
把球場的大環境拼接起來並不複雜:
沒錯,圖中的紅色塊就代表玩家。模擬籃筐上設置有隱形觸發器,幫助檢測小球通過籃筐的具體時間。
觸發器使用教程:
https://unity3d.com/cn/learn/tutorials/topics/physics/colliders-triggers
如上圖所示,在Unity編輯器中,肉眼可見綠色的隱形觸發器。可觀察到觸發器分為上下兩個,這樣就能計算出球從籃筐頂部到底部落下消耗的時間。這兩個觸發器可在/Assets/BallController.cs中的OnTriggerEnter中查看。
上下都有觸發器的另一個好處就是,可以據此判斷小球的材料,幫助掌握distance和force.y兩個核心變數。
投籃
打開/Assets/BallSpawnerController.cs,這是一個負責生產籃球並試圖投中籃筐的腳本。你也可以在Shoot()結尾處查看這段代碼。
不知道你有沒有注意到,Instantiates代碼處表示了一個全新的實例,可以在此處設置投籃的力度和距離籃板的距離。
如果你是在/Assets/BallController.cs處打開的,可以查看Start()方法,之後在加入新籃球時會在此用到這段代碼。
換句話說,我們創建一個小球,然後給它一定大小的力,設置30秒後球將被自動銷毀,來確保我們能處理源源不斷新出現的球。
設置好一切後,我們看看自己的這個全明星投籃手是如何投籃的。你可以點擊Unity編輯器中的播放按鈕,我們會看到……
百發百不中!
為什麼會出現這樣的情況?答案就在於Assets/BallController.cs代碼中float force = 0.2f這一行。這條線讓所有球的行動軌跡保持一致,所以出現了一發都沒進的慘烈結局。
當然~這不是我們想要的,所以我進行了下一步的與探索。
隨機投籃,收集數據
我們可以通過簡單將力量變為隨機的方式,引入一些隨機噪音。
這樣就能推測出,能夠投中的力度是什麼樣的。當然這需要一些時間~
同時,我們需要考慮到,我們希望紅色的小球能從任何位置成功投籃,因此我們需要的不僅僅是只從一個地方投籃。在Assets/BallSpawnController.cs位置中,查找這些行並去掉MoveToRandomDistance()即可解決這個問題。
這樣,如果我們再次運行,就可以看到紅球在每次投籃後都能在球場上熱情地跳躍。
隨機運動和隨機力量的結合創造了一種非常奇妙的東西:數據。如果此時查看Unity中的控制台,你能看到每次投籃時記錄的數據。
每次成功投進都會被記錄,並且到目前為擊球的數量,距離籃筐的距離以及擊球所需的力量都可查看。這些數據提升的速度比較慢,我們可以將MoveToRandomDistance()中的參數0.3f(每次投籃的延遲為300毫秒)改成0.05f(延遲50毫秒)。
現在,看看我們參數調試後的結果:
有沒有發現,這其實是個不錯的訓練方式,系統顯示成功率為6.4%了。下一步,我們準備將這些數據從Unity中提取出來,並構建一個模型預測所需要的力量。
預測、模型和回歸
在用到TensorFlow之前,我們先讓Unity環境中的紅球完成大約50次命中。
此時如果查看Unity項目的根目錄,則應該能夠看到一個名為successful_shots.csv的新文件。這是來自Unity的原始轉儲,我們把這份數據導出來,以便在excel中分析它。
這個.csv文件只有三行,index,distance和force。我在谷歌表格中導入這個文件,創建了帶趨勢線的散點圖,這樣就能了解數據的分布情況了。
這些點組合起來可以發現一些規律。y軸為力度、x軸為距離。可以看到,所需的力與投籃距離之間有明顯相關性,也有一些例外情況。
是時候讓TensorFlow登場了,幫助我們用類似的代碼創建更複雜的模型。比如,在一個完整的遊戲中,我們可以涵蓋進一些新功能。
現在需要創建我們的TensorFlow.js模型了。
在你喜歡的編輯器中打開tsjs/index.js文件,這是一個基於數據訓練模型的腳本successful_shots.csv。訓練和保存模型的方法如下:
我們從.csv文件中載入數據創建一些列x和y坐標點,讓模型學會服從這些數據,之後,保存!
遺憾的是,TensorFlowSharp並不接受Tensorflow.js可以保存成的模型格式,需要我們做些翻譯工作才能將模型引入Unity。
一般來說可以將TensorFlow.js Format轉化為Keras Format,創建一個檢查點;我們也可以將它們與Protobuf Graph Definition合併,創建檢查點。
現在,我們看看在Unity里Assets/BallSpawnController.cs下的GetForceFromTensorFlow()中的模型是什麼樣子的。
比賽日
利用上面已經完成的系統,我們在模型上創建了一寫變體,在訓練500次時,模擬籃球的運行軌跡是這樣的:
正確率提升了10倍!
這還只是訓練500次的結果,剩下的交給你了~別忘了回頭看看我最後生成的結果,這是多麼可愛的遊戲啊~
傳送門
博客原文地址:
https://medium.com/tensorflow/tf-jam-shooting-hoops-with-machine-learning-7a96e1236c32?linkId=54634097
開源代碼在此:
https://github.com/abehaskins
祝你好運~
作者系網易新聞·網易號「各有態度」簽約作者
—完—
※美國最嚴數據隱私法在加州出台 谷歌Facebook亞馬遜方了
※AI晶元,為何現在成為新軍備競賽?
TAG:量子位 |