常用 Python 的你,真的了解他嗎?
一位來自義大利的工程師顛覆網友們對 Python 的想像!
他不做常見的爬蟲、資料分析與視覺化,他做出能辨識動作的神經網路!真的太強大啦!
[以下為自原文翻譯之內文]
打造舞步來控制電源
在今天的文章裡,我將教大家訓練一個神經網路模型,可用來識別鏡頭錄下的「舞步」,並用這些「舞步」控制燈的開關。
我們將在已有的 OpenPose 深度學習模型上建立我們的模型來識別身體位置,然後我們會建立一些樣本來代表身體的各種麼樣。
當我們建立好舞步和其他姿勢的樣本後,我們會清理數據集,然後利用這些樣本來訓練我們製作出的神經網路。
當神經網路訓練好之後,我們會用它來控制燈光。
今天的文章包括很多步驟,不過,所有的程式碼都在 Github 上,上面還包括了我已經蒐集到的原始數據樣例。
使用數據集建立自己的神經網路
首先就是大量的數據。
我們即將採用的神經網路模型,過去卡內基梅隆大學團隊也曾經使用過,他們用自己的全景數據集來訓練模型。
該數據集包括五個半小時的影片,包含了 1,500,000 個手動添加的代表骨骼位置標籤。
整個工作室的圓屋頂上裝有 500 個鏡頭,所有鏡頭皆對準人,分別從不同角度記錄他們的動作。
這個全景工作室用構造訓練數據集幾乎是完美的,對於進行電腦視覺的實驗來說非常方便。
今天,我們將建立在他們工作基礎之上開始我們的工作。首先我們會用他們的工具來創建一個很小的數據集。最終的神經網路只會使用 171 個姿勢,每一個姿態都是從卡內基梅隆大學已有的工作中提取出來的。
神經網路有一個好處,就是你可以使用別人已經建構完成的模型,然後加入一些新的神經網路層,以此來擴展該模型。這個過程被稱之為遷移學習,因此我們可以用有限的資源來進行遷移學習。
從技術上來說,我們不會在這個項目中使用遷移學習,因為我們會對 OpenPose 的工作做一些細微的修改,然後建立一個獨立的神經網路。
那麼問題來了,我們該如何獲取數據呢?
寫一個程式,並利用 OpenCV 來收集帶標籤的數據
使用 OpenPose 的成果,我們得到了 25 個代表人體骨骼架構的標籤。我們可以寫一個程式來控制網絡鏡頭,在圖像上運行 OpenPose,然後將動作與鍵盤上的按鍵相對應。
也就是說,我們做出一個 T-Pose 的動作,然後在鍵盤上點擊 M 鍵,那麼這個動作就被歸到 T-Pose 那一類裡。我們按照這個方法去添加 171 個不同的姿勢,這樣一來,我們就有數據訓練神經網路了。以下是用於數據收集的程式碼範例(完整版請看 GitHub):
然後用 NumPy 的數組來儲存特徵,並用 np.save 函數把特徵保存為二進制文件以便後續使用。我個人傾向於使用 Jupyter notebook 來觀察和處理數據。
當數據收集好之後,我們可以觀察並清理數據,以便更好地去訓練模型。
觀察、清理並使用數據訓練模型
這部分看上去很複雜,但是透過使用 Jupyter notebook、NumPy 和 Keras,我們就可以很直觀地去觀察數據、清理數據,並且使用數據來訓練神經網路。
根據我們的截圖,我們可以發現 npy 文件中保存的數據和 OpenPose 模型本身都有三個維度,25 個已知的身體位置坐標點,X、Y、以及 Confidence。
我們的模型訓練工作不需要用到 confidence。如果某個身體位置坐標點被命名了,我們就保留它,否則,我們就直接讓它為 0。
我們已經把(絶大部分)數據整理好了,現在我們需要把數據特徵和標籤結合起來。
我們用 0 代表其他姿勢,1 代表嘻哈超人舞步、2 代表 T-Pose 舞步。
接下來,我們可以使用獨熱編碼處理我們的數字標籤。也就是說,我們將標籤 0、1、2 轉換成 [1,0,0]、[0,1,0]、[0,0,1]。之後,我們可以使用 sklearn 的 shuffle 函數將數據標籤和特徵打亂(數據標籤和特徵仍保持原有的對應關係)
我們的輸入數據代表著鼻子、手等等的位置,而它們的是介於 0 到 720 和 0 到 1280 之間的像素值,所以我們需要把數據單一化,這樣一來,我們可以重複使用我們的模型而不用考慮輸入圖片數據的解析度。(完整版請看 GitHub)
在最後一步中,我們將把我們的多維數據變成一維。我們會分批向模型輸入 50 個位置資訊(25 個部位,每個部位的 X 和 Y 值)。
建構並訓練動作辨識模型
在 Jupyter notebook 中使用 Keras,可以把訓練和測試神經網路模型的工作變得十分簡單,這也是我最喜歡 Keras 的地方。
現在我們的數據已經貼上標籤準備就緒了,我們可以開始訓練一個簡單的模型了,只需要幾行程式碼。
現在我們導入 Keras 庫,然後訓練一個簡單的神經網路模型。
搞定!
這裡有個稍微需要注意的地方,輸入層的大小為 50,提醒大家一下,這個數字是 OpenPose 模型中,位置點的 X 坐標和 Y 坐標數量之和。
最後我們用到了 Softmax 層,它是用來分類的。我們將 y.shape[1] 傳入該層,這樣我們的模型就知道不同類別的數量了。
最後的最後,我們使用輸入數據,用 model.fit() 的方法去訓練模型。這裡,我已經做了 2000 次疊代(全部樣本訓練一次為一次疊代)。2000 次疊代貌似有點多了,500 次左右的疊代可能更好,因為疊代次數過多可能使我們的模型出現一些過度擬合問題。但是不論是哪一種情況,你都需要經過多次嘗試來確定疊代次數。
當我們運行這段程式碼時,我們會看到準確度在提高。如果你看不到,請再次確認當你打亂數據時,數據標籤和數據特徵的對應關係是不變的。此外,也要確認數據裡的數值是不是在 0 到 1 之間。
最後,我們可以保存訓練後的模型,也可以使用樣本數據集來測試該模型,保存模型的程式碼很簡單(完整版請看 GitHub):
一切就緒,用模型來控制燈光吧!
我們現在已經有了可以識別姿勢的模型,接下來要做的只是把這個模型和無線燈光控制連結起來就行了。
在我的這個例子中,我使用 Aeotec Z-Stick 來發送 Z-Wave 指令,並配有兩個 GE Z-Wave 的室外開關。USB 插到 NVIDIA TX2 人工智能模組,其實 NVIDIA 的 Jestson Nano 也能勝任,儘管 Jetson Nano 所能提供的解析度要低於我範例中 1280×720 的解析度。當 Z-Stick 插到 ARM 設備後,你首先需要把開關調到 Z-Wave 模式,可能需要多按幾下 USB Stick 上的按鈕和燈的開關。
程式碼並不複雜,基本上就是訓練環境再加上一個額外的步驟。現在,我們導入 Keras,然後使用整理過的數據訓練模型。(完整版請看 GitHub)
到了這一步,工作基本上就算完成了!
我們成功地訓練了一個用於識別嘻哈超人舞步、T-Pose 舞步的神經網路模型,然後我們可以讓它根據我們的舞步來製造可互動的燈。
太棒了,給自己按個讚!
建議:在 Jupyter notebook 上測試
所有程式碼、模型以及訓練數據都免費公佈在 Github 上。
我建議你們在 Jupyter notebook 上試試這個項目。我的程式碼中有個 bug,我一直無法從自己的工作簿中找出來。這個漏洞導致我的原始的 X 和 Y 標籤並沒有被正確地標記。如果你找到了解決這個 bug 的方法,記得在 Github 上建立一個 Pull Request(PR)。
另外,我們今天建構的基礎模型可以用來訓練很多類型的舞蹈動作。儘管我的模型每秒只能捕捉很少的畫面,但我們可以開始建立一個有關舞步的數據集,然後再建構一個能識別這些不同舞步的神經網路模型。
我還為剛開始學寫程式的人寫了本書,歡迎你們來看看這本書。
本文轉自原文《Building Dance Controlled Lights with Python》與大數據文摘之翻譯文章《程序员深夜用Python跑神经网络,只为用中二动作关掉台灯!》
如果你喜歡他們的文章,歡迎回到原文觀看更多:)