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