我不知道為什么會有這樣的想法,我自己既不失聰,也不失語,而且周圍也沒有這樣的人,我甚至連語音助手也沒有。究其原因,或許是因為有很多文章都在介紹層出不窮的語音助手,也可能是因為各大公司都在爭相成為您青睞的智能家居語音助手,又或許只是因為我越來越多地在朋友家中的桌臺上看到這些設備。這個問題在我的腦海中一直縈繞不去,我知道這件事勢在必行。
于是,最后有了這個項目。這是一個概念驗證項目,我買了一個Amazon Echo,讓它對手語作出反應,更準確地說是美國手語 (ASL),因為和口語一樣,手語的種類也有很多。
原本我可以只發布代碼,不過,我覺得很多機器學習項目都缺少視覺元素,讓人們很難將它們聯系起來理解,所以后來還是決定發布一段關于系統演示的視頻。同時,我也希望這個方法能夠將人們關注的焦點從項目的科技元素轉向人類元素,即這里介紹的并非底層技術,而是此類技術賦予我們人類的能力。
既然視頻已經公開,下面就通過這篇博文介紹一下底層技術,以及如何使用TensorFlow.js構建這一系統。您也可以播放實時演示。我將其整合在了一起,以便您可以使用自己的詞集和符號/手勢組合來訓練。是否要在身邊準備一個可以響應您要求的 Echo,完全由您自選。
早期研究
在早期,我就非常明確我想要為此實驗整合哪些更廣泛的系統組成部分。我需要的組件如下:
一個神經網絡,用以解釋手勢(即將手勢視頻轉換為文本)。
一個文字轉語音系統,用于將解釋過的手勢講給 Alexa
一個語音轉文字系統,用于將 Alexa 的回應轉錄給用戶使用
一臺運行該系統的設備(筆記本電腦/平板電腦)和用于互動的 Echo
可以將這些組件整合在一起的界面
早期,我的大部分時間可能都用在了確定哪個神經網絡架構最適合此實驗上面。我想到下面幾個選擇:
1) 由于手勢兼具可視性和時效性,因此我的直覺是將 CNN 與 RNN 結合在一起,其中最后一個卷積層的輸出(分類前)作為序列饋送到 RNN 中。后來,我為此找到一個技術術語,即長期遞歸卷積網絡 (LRCN)。
2) 使用 3D 卷積網絡,以三維方式應用卷積,其中前兩個維度是圖像,第三個維度是時間。但是,這些網絡需要大量存儲設備,而我希望可以在我用了 7 年的老 Macbook Pro 上進行訓練。
3) 訓練 CNN 時,我沒有使用視頻流中的單個幀,而是只用了可以表示兩個連續幀之間視運動模式的光流表征。我的想法是它會對這種動作進行編碼,產生更通用的手語模型。
4) 使用雙流 CNN,其中空間流為單個幀 (RGB),時間流會使用光流表征。
在做進一步研究時,我發現了一些論文,其中至少使用了上述部分視頻行為識別方法(在UFC101 數據集上最常見)。但我很快發現,不僅我的計算能力有限,我從頭開始解密和實施這些論文的能力也很有限,之后幾個月,我的研究時斷時續,經常因為其他項目纏身而不得不丟下該項目,我的輸出結果一直乏善可陳。
最終,我采用了迥異的方法。
TensorFlow.js團隊一直在推出基于瀏覽器的有趣小實驗,幫助人們熟悉機器學習的概念,同時也鼓勵人們用它來構建自己的項目。對于那些不熟悉機器學習的人,TensorFlow.js 是一個開放源代碼庫,讓您可以直接在使用 Javascript 的瀏覽器中定義、訓練和運行機器學習模型。特別值得一提的是,Pacman 網絡攝像頭控制器和Teachable Machine這兩個演示似乎是很有趣的起點。
雖然這兩個演示都是從網絡攝像頭選取輸入圖像,并輸出基于訓練數據的預測,但其內部運作卻各不相同:
1) Pacman 網絡攝像頭 — 使用卷積神經網絡選取輸入圖像(來自網絡攝像頭)并通過一系列卷積和最大池化層來傳遞圖像。通過這種方式,它能提取圖像的主要特征,并根據其訓練時用過的示例預測其標簽。由于訓練過程費時費力,它使用了名為 MobileNet 的預訓練模型進行遷移學習。該模型經受過基于 ImageNet 數據集的訓練,可以區分 1000 種圖像,而且經過優化,可以在瀏覽器和移動應用中運行。
2) Teachable Machine — 使用 kNN(最鄰近規則分類),該分類非常簡單,以至于從技術上說其完全不執行任何“學習”。它會接收輸入圖像(來自網絡攝像頭),并使用相似度函數或距離度量來尋找最接近該輸入圖像的訓練示例的標簽,從而對圖像進行分類。然而,在饋送 kNN 之前,首先要通過名為 SqueezeNet 的小型神經網絡傳送該圖像。然后,將該網絡倒數第二個層的輸出饋送到 kNN 中,該 kNN 允許您訓練自己的分類。相較將來自網絡攝像頭的原始像素值直接饋送到 kNN 中,這樣做的好處在于我們可以使用 SqueezeNet 已經學過的高層抽象,由此訓練更好的分類器。
現在您可能想知道,手勢的時效性怎么辦?這兩個系統都是每幀選取一個輸入圖像,并且在預測時完全不考慮面前的這些幀。這不是考查 RNN 時關注的整個要點嗎?這對真正理解手勢并非必要?利用在線資源學習本項目的 ASL 時,我發現,當做出手勢時,不同手勢之間手的始末姿勢以及位置差別很大。與人交流時,其間發生的一切或許都很必要,但對機器而言,只使用始末姿勢就足夠了。因此,我決定棄常規作法而不用,無視過程,直奔目的。
事實證明,使用 TensorFlow.js 非常有用,其間原因包括:
我可以利用這些演示進行原型設計,而無需編寫任何代碼。最初開始原型設計時,我只是在瀏覽器中運行這些原始示例,用我計劃使用的手勢進行訓練,然后觀察系統的運行方式,即便其輸出結果意味著是 Pacman 在屏幕上移動。
我可以使用 TensorFlow.js 在瀏覽器中直接運行模型。從可移植性、開發速度和與網頁界面輕松交互的能力來看,這是巨大的。這些模型也可以完全在瀏覽器中運行,而無需向服務器發送數據。
因為模型在瀏覽器中運行,我可以將其與現代瀏覽器支持且我需要使用的語音轉文字和文字轉語音 API 連接起來。
它可以加速測試、訓練和微調操作,而這往往是機器學習中的一大難題。
由于我沒有手語數據集,并且訓練示例基本是我在重復做出手語動作,因此使用網絡攝像頭來收集訓練數據非常方便。
在全面測試這兩種方法后,我發現這兩個系統在測試中表現相當,于是決定使用 Teachable Machine 作為訓練基礎,這是因為:
如果使用較小的數據集,kNN 實際要比 CNN 運行地更快/更好。在用很多示例訓練時,它們需要存儲大量數據,性能也會下降,但我知道我的數據集不大,所以這不是問題。
由于 kNN 實際并非從示例中學習,所以它們不擅長泛化。因此,使用完全由一個人構成的示例訓練模型,其預測結果并不能很好地遷移至另一個人。但對我而言,這也不是問題,因為我會通過自己反復做出手勢來訓練并測試模型。
該團隊曾經開放過一個很好的項目剝離樣板文件的源代碼,可以作為一個非常有用的起點。
下面我們從較高層面了解一下系統由始至終的運作方式:
在瀏覽器中打開網站后,第一步是提供訓練示例。也就是,使用網絡攝像頭反復捕捉您自己做出每個手勢時的動作。這樣操作相對較快,因為只要按下特定的拍照按鈕就可以持續捕獲幀,直到您松開按鈕并使用合適的標簽標記捕獲的圖像。我訓練的這個系統包含 14 個詞匯,我可以將這些詞匯進行多種組合,用來向 Alexa 發出不同請求。
訓練完成后,輸入預測模式?,F在,系統會使用來自網絡攝像頭的輸入圖像并通過分類器運行,根據上一步中提供的訓練示例和標簽找到與其最鄰近的類別。
如果超過了某個預測閾值,它會在屏幕的左側附上標簽。
然后我使用語音合成的 Web Speech API 來讀出檢測到的標簽。
如果說出的單詞是“Alexa”,則會喚醒附近的 Echo,并且 Echo 會開始聆聽查詢。另外值得注意的是,我創建了一個任意手勢(在空中舉起右拳)來表示單詞 Alexa,因為 ASL 中不存在與這個詞對應的手勢,并且反復拼寫 A-L-E-X-A 也會讓人厭煩。
在完成整個手勢短語后,我再次使用 Web Speech API 來轉錄Echo 的反應,Echo 在回應這個查詢時完全不知道該查詢來自另一臺機器。轉錄的反應顯示在屏幕的右側,以供用戶閱讀。
再次用手勢表示喚醒詞,清除屏幕并重啟反復查詢的流程。我已將全部代碼上傳至 Github,包括實時演示。您可以按照您的想法隨意使用并修改代碼。
雖然系統運行較好,但的確需要一些簡單改動來幫助獲取所需結果并提高準確度,例如:
確保在說出喚醒詞 Alexa 之前不會檢測到任何手勢。
在訓練示例中添加一個完整的泛類,我將其歸為適用于空閑狀態的“其他”類(空白背景、我站在一旁不做任何動作,手放在身體兩邊等)。這可以防止錯誤檢測詞匯。
在接收輸出前設定高閾值,以減少預測錯誤。
降低預測率。不要按最大幀率進行預測,控制每秒的預測數量有助于減少預測錯誤。
確保預測時不會重復考慮短語中已經檢測過的詞匯。
在手語中,冠詞通常不用手勢表達,而是依靠上下文來表達意思,因此,我在訓練模型時用了某些包含相應冠詞或介詞的詞匯,例如這天氣、這清單等。
另一個難題是,準確預測用戶已在何時完成手勢查詢。這對于準確轉錄非常必要。如果太早觸發轉錄(在用戶完成手勢之前),則系統會開始轉錄其自己的語音。但如果觸發太晚,又可能會錯過轉錄 Alexa 的部分反應。為了解決這一難題,我采用了兩項獨立的方法,兩者各有利弊:
第一個選擇是在添加詞匯用于訓練時,將這些詞匯標記為終點詞匯。我說的終點詞匯是指用戶只會在短語結束時使用的手勢。例如,如果查詢語句是 “Alexa, what’sthe weather?”,則將 “the weather” 作為終點詞匯,當檢測到該詞匯時,便可以正確觸發轉錄。這個方法雖然很好用,但這意味著用戶在訓練期間必須要記得去標記終點詞匯,并且需要依賴該詞僅會出現在查詢結尾的假設。這樣,如果將查詢語句調整為 “Alexa, what’sthe weatherin New York?”,則會面臨問題。我們在演示中就使用了這個方法。
第二個選擇是讓用戶故意做出一個停用詞,讓系統知道他們的查詢語句結束了。識別到這個停用詞后,系統就可以觸發轉錄。所以用戶需要用手勢比出喚醒詞 > 查詢 > 停用詞。這個方法的風險在于,如果用戶忘記用手勢比出這個停用詞,就會導致完全不會觸發轉錄。我在另一個Github 分支中運用了這個方法,您可以使用喚醒詞 Alexa 作為查詢 “書夾”,即 “Alexa, what’s the weather in New York”(Alexa)?”。
當然,如果有一種方法可以準確區分來自內部信源(筆記本電腦)和外部信源(附近的 Echo)的語音,就可以解決整個問題,但那又是另一個難題。
日后,我想會有許多其他方法可以解決這個問題,這或許可以作為您自己項目的良好起點,用于創建更穩健而通用的模型:
Tensorflow.js 還發布了PoseNet,使用 PoseNet 也可能是一個有趣的方法。從機器的角度來看,只要追蹤幀中手腕、手肘和肩膀的位置應該就足以對大多數詞匯作出預測。在拼寫詞匯時,手指位置往往非常重要。
使用基于 CNN 的方法(例如 Pacman 示例)或許可以提高準確度,并使模型更能抵御平移不變性。該方法也有助于在不同人群中更好地實現泛化。用戶也可以納入保存模型或加載預訓練 Keras 模型的能力,這些都有清晰的文件記錄。這樣,您就不必在每次重啟瀏覽器時都要訓練系統。
某些考慮時間特性的 CNN+RNN 或 PoseNet+RNN 組合可能會使準確性受到影響。
使用 tensorflow.js 中較新的可重用kNN 分類器。
自我首次發布此項目以來,人們已在社交媒體上廣泛分享,媒體也進行了相關報道,甚至 Amazon 也在 Echo Show 上實現上無障礙功能(點擊喚醒 Alexa),用于幫助講話困難的人士。雖然我并無證據可以證明是我的項目令他們得以實現這項功能(時間高度巧合),但如果確實如此,那真的非常酷。我希望 Amazon Show 或其他基于攝像頭和屏幕的語音助手將來都可以納入此項功能。對我而言,這可能是此原型展示的最終用例,并且讓數百萬新用戶都能用上這些設備。
降低網絡復雜度,并且采用簡單地的架構來創建我的原型,這絕對有助于這個項目的快速推廣。我的目標并不是要解決整個手語轉文本問題。恰恰相反,我想要發起圍繞包容性設計的對話,以平易親和的方式介紹機器學習,并啟發人們去探索這方面的問題,這才是我希望這個項目能達成的目標。
-
語音控制
+關注
關注
5文章
481瀏覽量
28230 -
Alexa
+關注
關注
2文章
196瀏覽量
23278
原文標題:Alexa 可以響應手語啦!借助了網絡攝像頭和 TensorFlow.js
文章出處:【微信號:tensorflowers,微信公眾號:Tensorflowers】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論