識別王者英雄 - 一個 PM 的機器學習入門之旅

基礎概念

上個月開始從原理層面了解機器學習,選了一本在線電子書《Neural Networks and Deep Learning》作為教材,事實證明該書實在不錯,讓一個毫無神經網路、機器學習背景知識的 PM 很快就讀懂了其中的基本原理。

附上此書第一章我的讀書筆記,對於 PM 而言,讀完第一章就夠了,基本概念和方法論在這章里解釋得十分清楚。讀完之後有一種打開新世界大門的感覺。

行動誘因

上周末看到 Twitch 做的 ClipMine,基於遊戲直播畫面識別出守望先鋒、爐石傳說中玩家正在玩的英雄和段位,供觀眾在多個主播間篩選自己想看的英雄。頓時手癢,想著這樣的需求在國內直播行業里其實也是存在的,比如將幾千個正在直播的王者榮耀直播流識別出當前在玩的英雄,這樣觀眾就可以選擇自己想看的英雄專註的看了。

手癢,又碰上周末,看來不得不做點啥了。

工程分析

王者榮耀這款遊戲,想要識別其中正在玩的英雄,有幾個思路:

1. 遊戲開始前選擇英雄的界面

2. 遊戲開始後載入資源時的 Loading 界面

3. 遊戲進行中屏幕正中央的英雄本身

4. 遊戲進行中屏幕右下角的技能圖標

分析如下:

  • 在整個直播時長中,1 和 2 的時間佔比是很短的,而且如果玩家直接直播遊戲進行中的畫面,那就沒法獲取英雄信息了。
  • 並且 1 和 2 的界面里,當前玩家所處的位置並不固定,如果還要加上玩家位置的判定,工程複雜度上升不止一點點。
  • 因為英雄在遊戲中永遠處於正中央,所以 3 其實挺適合用來做訓練素材。但考慮到英雄有不同的動作和朝向,最重要的是這個遊戲單一英雄還有不同的皮膚。各種條件綜合起來,一方面需要提供更多的訓練素材,一方面也加大了機器學習的難度。
  • 而 4 這個界面,英雄的技能在較長的時間段內是不會變的,而且位置穩定,在整個直播時長里出現的時間佔比也很高,唯一變化較大的是技能發動間歇里的讀秒倒計時。綜合考慮,4 是最適合用來做訓練素材的。

確定了這點後,就能理清整個項目的運轉流程了:

  1. 獲取 60 幾個英雄對應的遊戲進行中圖片,每個英雄不少於 1000 張(拍腦袋的,我也不知道多少張合適)
  2. 將 1 中圖片的右下角截取出來,作為機器學習的訓練資料
  3. 運行機器學習代碼,訓練出可以識別不同英雄技能的模型
  4. 從待識別的直播流中抽取畫面,截取右下角的技能畫面,用 3 中的模型去識別看是哪個英雄的技能,從而完成對直播流英雄的識別

流程已然清晰,但後面的工作量才是最大的,先來看看如何獲取訓練資料吧。

收集素材

做機器學習的都知道,寫代碼不是最難的部分,收集優質的訓練素材才是。如何能夠快速獲得 60 多個英雄分別對應的 1000 張圖片呢?且不說找到 6 萬多張圖片的難度,找到後難道要我人肉來標記哪張圖片是哪個英雄?如果真要這麼做,估計一個人是很難完成了。

這一次想出的取巧方法是直接去優酷上搜索「王者榮耀」+「英雄名字」,就能搜到很多玩家錄好的英雄視頻。於是讓團隊里的同學幫忙,很快收集齊了所有英雄的對戰視頻各 1 個。然後用 Adapter 這樣的軟體將視頻按一秒一幀轉化為幾千張圖片。(不過一開始沒有發現 Adapter 這個軟體,當時是用 OpenCV 去一幀幀把視頻里的畫面讀取出來的。)

唯一的坑是優酷上的視頻往往並不只是對戰過程本身,還會有一些製作者加入的視頻特效、文字、轉場動畫啥的。一開始沒留意,污染了一小批訓練素材,後來重新找了幾個乾淨的視頻解決此問題。

於是就這樣,輕鬆獲得了含有英雄標記信息的近 10 萬張圖片。

後面的事情就簡單了,用 OpenCV 統一對圖片進行裁剪。一開始是裁到三個技能的區域,但因為這個區域覆蓋的面積較大,會包含進來很多不必要的圖像信息,導致訓練出來的結果不理想。在後期調優時,想到每個英雄的技能其實是唯一的,沒必要識別全部,於是將素材全都裁剪到第二個技能,果然大大提升了識別準確度。

技術實施

早有耳聞 Google 家 TensorFlow 上手容易且性能還不錯,加上是 G 家產品,自然和 Python 配合度最好,適合常年寫 Python 的我。於是果斷開始讀 TensorFlow 的文檔。

不得不說周末那個晚上有很多時間花在了如何在 virtualenv 里安裝 TensorFlow 和 OpenCV。網上的教程沒有一個是可以完全順利在 Mac 上跑完的,還好最後在 Google 和 Stack Overflow 的雙重加持下,這倆個組件都在我 Mac 上編譯成功了。

很快,在 TensorFlow 官方教程里找到一篇關於圖片識別的文章。跑了一下 demo,運行正常。於是開始研究如何訓練自己的模型。

既然都按照官方教程走了,所以直接用了 Inception V3 的網路結構。近 10 萬張圖片,在沒有 GPU 加持的 Macbook Pro 上,差不多得跑 10 個小時才能跑完第一次訓練。

不過其中最耗時是計算 Bottleneck 值,因為這個值在每次訓練時其實都不會變。所以教程中會讓在第一次計算每張圖片的 Bottleneck 值後,將之保存下來,這樣下次訓練只需要計算新增圖片素材的 Bottleneck 值即可,不需要每次都全量計算。這樣優化之後,效率飛升。

到此時,已經是周日凌晨 3 點了,趕緊讓模型跑起來,睡覺去。

性能調優

周日中午醒來,第一次訓練已經跑完了,趕緊拿新模型去做各種測試,準確率超乎想像的高。但如「收集素材」那一段里提到,一開始是識別三個技能,所以在某些英雄的識別上不太理想。

將所有素材調整為單個技能截圖後,又跑了一次,出結果時已經是周日晚上。這個時候的準確率靠我找到的測試圖片已經沒有失敗的例子了。

截止這個時候,識別單張圖片大概需要 5 秒,倒也不是不能接受,但還想更快。在沒有 Nvidia 顯卡的情況下,只能依賴於在本地編譯 TensorFlow,從而讓 TensorFlow 能用上本地 CPU 的 SSE、AVX 這類指令,加快運算速度。如何在 Mac 上編譯 TensorFlow,可以參考這裡。

附加功能

在本地已經能完美識別英雄了,但總想著讓更多的同事能體驗這個功能。周二晚回家想起了之前用 itchat 寫的微信機器人,於是立馬將機器人和王者識別代碼結合起來,實現了在微信里給機器人發遊戲圖片,機器人立即回復這個圖片里的英雄是誰。

結語

實際的學習和開發時間就是周六晚 8 點到凌晨 3 點。這 8 個小時讓我從原理及代碼層面認識到了機器學習的魅力和實施細節,真真切切的看到了另一個世界的入口以及未來無窮的可能性。

最大的觸動是開始思考未來產品經理在設計產品邏輯時,如果理解機器學習,那麼很多以往被認為不可能的事情,都將成為產品邏輯的一部分。而能否建立這種新的認知,運用好新的工具,將在未來某些領域裡區分出產品經理的高下。

學習,是一個 PM 永遠不該停下的生存技巧。


推薦閱讀:

機器學習系列-Logistic回歸:我看你像誰 (下篇)
Python語言下的機器學習庫
深度學習在推薦領域的應用
機器學習-異常檢測演算法(一):Isolation Forest
這樣能解決知乎質量越來越低,老用戶離開的情況么?

TAG:机器学习 | TensorFlow | 产品经理 |