編者按:“如果語音是計算的未來,那么對于不能說話或有聽力障礙的人該怎么辦?”本文作者Abhishek Singh就描述了它是如何用TensorFlow設計一套系統,讓亞馬遜的語音助理Echo能“看懂”手語的。
幾個月前,當我躺在床上時,一個想法突然閃過:“如果語音是計算的未來,那么對于不能說話或有聽力障礙的人該怎么辦?”不知道為什么會產生這種想法,我本身說話和聽力都沒有問題,身邊也沒有這樣的殘疾人士,而且我也沒有語音助手。也許是最近關于語音助手的文章太多了,或者是各大公司之間關于語音助手的競爭太多,亦或者總是在朋友的家里看到語音助手的身影。有了想法之后,我就立刻行動起來。
最終我完成了這個項目,讓亞馬遜的語音助手Echo能夠對美國手語(ASL)做出更準確的反應(手語也分很多種,這里用的是美國手語)。下面的視頻能更好地幫助大家看看這個項目的效果,并且我希望這一方法能讓大家將關注重點從技術要素上轉移到人類要素上,也就是說要更看重技術能否像人一樣為我們提供服務。
本文將展示系統背后的原理,另外這里有一個Demo可以自己玩一下:shekit.github.io/alexa-sign-language-translator/
早期研究
在我剛有想法的時候,我就對這一項目所需要的元素有了大致掌握:
一個能讀懂手語的神經網絡(即將視頻中的手勢轉換成文字)
一個文本轉語音系統,可以將轉換過后的動作讀給語音助手Alexa聽(注:Alexa是Echo音箱的語音服務,二者是硬件和系統的關系)
一個語音轉文字系統,將Alexa的回復展示給用戶
一個可以運行該系統的設備(電腦或平板),以及一個可以互動的Echo音箱
一個交互界面
一開始,我花了大量時間嘗試各種神經網絡架構,想找出最合適的一個。以下是幾個備選項:
由于手語有視覺和時間兩方面要考慮,所以我最初想結合一個CNN和RNN,其中最后一個卷積層的輸出可以輸入到RNN中作為序列。之后我發現長期循環卷積網絡可以做到這一點。
利用一個3D卷積網絡,其中的卷積可以用到三個維度中,前兩個維度用于圖像分辨,第三個維度處理時間。然而這些網絡需要大量內存,我是想在我用了7年的MacBook Pro上訓練的。
與傳統的視頻流在CNN上一幀一幀地訓練不同,我只在光流表示上進行訓練,這樣會在兩個連續幀之間顯示出明顯的動作變化。我設想的是,可以在其中對動作進行編碼,從而創造一款通用的手語模型。
利用雙流CNN,其中空間流是單幀(RGB),時間流則用光流表示。
在之后的研究中,我發現了好幾篇用到上述方法做視頻動作識別的論文。但是我發現不僅是計算力限制了我的操作,而且我自己的能力的確無法從零開始實現這些方法。所以無奈之下只好放棄。
最終我使用的方法完全不同。
進入TensorFlow.js的世界
TensorFlow.js團隊既推出了針對機器學習專業的人的程序,也對那些不熟悉機器學習的人提供了開源庫,可以自己用JavaScript定義、訓練并運行機器學習模型。作為入門可以試試這兩個有趣的Demo:
Pacman Webcam Controller:storage.googleapis.com/tfjs-examples/webcam-transfer-learning/dist/index.html
Teachable Machine:teachablemachine.withgoogle.com/
雖然它們都將攝像頭捕捉到的圖像作為輸入,并根據訓練數據輸出一個預測,但是二者內部是截然不同的。
Pacman Webcam:它所運用的卷積神經網絡將輸入其中的圖片通過一系列卷積傳遞到最大池化層。這一過程可以提取圖像的主要特征,并且根據訓練樣本預測它的標簽。由于訓練過程成本較高,它是用的一個名為MobileNet的預訓練模型進行的遷移學習。該模型在1000個ImageNet類別中進行的訓練,之后進行了優化。
Teachable Machine:它所用到的是kNN(k-Nearest-Neighbours),這種方法非常簡單,基本不需要任何學習。捕捉到網絡攝像頭的圖像后,它會對其打上標簽進行分類(用訓練樣本中相似的函數或距離矩陣)。但是在輸入到kNN之前,圖像會首先通過一個名為SqueezeNet的小型神經網絡。將網絡倒數第二層的輸出輸入到kNN中,然后訓練自己的類別。這樣做的好處是,不直接將原始像素值輸入到kNN中,而是用SqueezeNet所學的高層次表示來訓練分類器。
現在你可能會想,那手語表示所用的時間怎么辦?這些系統都是一幀一幀地輸入圖像,同時在下一幀之前作出預測。查看RNN的時機是否過早了?有必要真正了解手勢嗎?在我為了這個項目學習手語時,我發現當你想要用手語表示的時候,不同話語之間,開始和結束的手勢以及手的位置都是不同的。跟人交流的時候可能需要看完整個動作才知道說的是什么,但是機器只需要看懂開頭和結尾即可。所以我決定只讓機器辨認最后的動作。
決定使用TensorFlow.js也有其他幾個好處:
不用寫代碼我就能用這些demo做出原型。剛開始時,我只是在瀏覽器上簡單運行原始案例,讓后用手勢訓練它們,看看系統的表現。
我能直接用TensorFlow.js在瀏覽器上運行,雖然這個很大,但是不用向服務器發送數據即可直接運行模型。
由于可以在瀏覽器上運行,我可以用語音轉文字和文字轉語音API進行交互。
測試、訓練、調整的速度都很快。
由于沒有手語數據集,所以我要重復地做很多動作用來訓練,電腦攝像頭能很方便地采集數據。
測試了上述兩種方法后(Pacman和Teachable Machine),我發現二者都能勝任。但是我最終決定用Teachable Machine,因為:
在小數據集上,kNN比CNN表現得更好更快。如果訓練樣本很多的話,kNN可能會變慢,性能也會下降。但是我的數據集很小。
由于kNN并不需要學習,所以它們泛化的能力很弱。所以模型做出的預測并不能很好地進行遷移。不過這對我來說也不是什么障礙,因為模型的訓練和測試都是用我自己的手語動作。
TensorFlow.js團隊開源了一個簡單的模型——boilerplate,對我很有幫助。(github.com/googlecreativelab/teachable-machine-boilerplate)
運行情況
從宏觀角度,系統從頭到尾的運行原理如下:
將系統安裝到瀏覽器后,第一步是提供訓練樣本。也就是要用攝像頭捕捉你的每個手語動作。
訓練完成工,就進入預測模式。將輸入圖像經過分類器,找到與它最相近的訓練模型并打標簽。
如果通過了預測,屏幕左側就會顯示標簽。
之后用Web Speech API進行語音合成,說出檢測出的標簽。
說出“Alexa”喚醒Echo。注意,這里我創建了一個隨機動作來表示“Alexa”這個單詞。
完成整個手語動作后,我用Web Speech API將Echo的回復進行轉換。轉換后的文字出現在屏幕右側讓用戶閱讀。
重新喚醒Alexa,清除屏幕進行再次對話。
雖然系統運行的不錯,它還需要一些改進,例如:
必須等到Alexa被喚醒后才開始檢測手語動作。
加入更多的訓練樣本。
將閾值提高,防止出現預測錯誤。
減少預測率,避免在最大幀率時出現預測,控制每秒預測的量有助于減少錯誤。
保證每個單詞都被檢測到。
由于手語通常忽略冠詞,而是依賴語境。所以我訓練了包括特殊單詞的模型,其中加入了特殊的冠詞或介詞,例如天氣等等。
另一個挑戰就是在用戶完成手語后要精確地做出預測,這就需要精確的文字語音轉換。如果轉換得太快,系統就會開始轉換自己的語音,太慢的話就會錯過Echo的回復。為了解決這個問題,我用了兩種獨立的技術,每種都有自己的優缺點:
首先就是在訓練時將特定的詞語作為結束單詞。例如如果用戶說:“Alexa, what’s the weather?”我們將”the weather”作為結束詞,如果系統檢測到它,就會觸發正確的轉換過程。這個方法不錯,但是這也需要用戶記住訓練時候那個結束詞是什么。
第二種方法是讓用戶特地做出一個結束詞的動作,讓系統知道他說完了。所以整個對話過程中,用戶要先喚醒,再說自己的問題,最后做結束動作。這種方法的缺點是,用戶可能會忘了做結束動作。
我認為還有很多種方法可以實現這個項目,如果你想試試不妨參考以下建議:
TensorFlow.js還發布了PoseNet,這也是個有趣的工具。從機器的角度來看,追蹤手腕、手肘、肩膀的位置,比預測話語更有效。
利用基于CNN的方法可能會提高準確度,并且模型會更穩定。
CNN+RNN或PoseNet+RNN的結合有可能會讓精確度提高一大截哦。
利用新的kNN分類器。
降低網絡的復雜性,利用簡單架構創造模型,一定會讓該項目得到快速應用。我的目標并不僅僅是解決手語到文字的難題,而是用一種全面的設計進行對話,讓機器學習落到實處,從而激勵人們在這個領域進行更多思考。
-
亞馬遜
+關注
關注
8文章
2650瀏覽量
83317 -
tensorflow
+關注
關注
13文章
329瀏覽量
60527 -
語音助理
+關注
關注
0文章
27瀏覽量
8683
原文標題:用TensorFlow.js搭建手語識別器,讓聾啞人也能和語音助手“對話”
文章出處:【微信號:jqr_AI,微信公眾號:論智】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論