【論文閱讀筆記】唇語識別初探- 使用3D交叉視聽識別

讀唇術聽起來比較神秘,公眾對於這個技術的了解僅限於某唇讀大師解密名人之間耳語的內容。其實對於聽力有障礙的人,他們大多數都掌握唇讀技巧。隨著深度學習的普及,研究者們嘗試用AI去破解唇語口型的秘密。

原文地址

3D Convolutional Neural Networks for Cross Audio-Visual Matching Recognition?

ieeexplore.ieee.org

最重要的是,這篇文章的代碼已經在Github上開源,方便研究學習

astorfi/lip-reading-deeplearning?

github.com圖標

模型特點提煉:1.輸入是音頻和視頻,輸出是他們是否匹配

2.標籤是音頻視頻是否是一樣的

3.衡量音頻視頻3D卷積後的低維映射之間的歐氏距離

4.兩個重要的手段去掉多餘數據

模型結構如下,模型的四個特點後文會詳細解讀

音頻視頻識別(AVR)被認為是音頻損壞時用於語音識別任務的解決方案,以及用於多揚聲器場景中的說話者驗證的視覺識別方法。AVR系統的方法是利用一種模式提取的信息,通過補充缺失的信息來提高另一種模式的識別能力。基本問題是找到音頻和視頻流之間的對應關係。這篇文章提出了利用耦合的三維卷積神經網路(CNN)架構,該架構可以將兩種模態映射到表示空間,以使用學習到的多模態特徵來評估音頻 - 視頻流的對應關係。這種體系結構將結合空間和時間信息共同有效地發現不同模態的時間信息之間的相關性。通過使用相對較小的網路體系結構和更小的數據集,我們提出的方法超越了現有的用於視頻匹配的相似方法的性能,其使用CNN進行特徵表示。文章最後證明有效的對選擇方法可以顯著提高性能。

文章的輸入來自VGG資料庫,首先需要改造這些數據以產生 imposter pair 和genuine pair,後者是真實的說話人唇部視頻和相應的音頻,前者是音頻和視頻無法匹配的情況。文章寫作不科學的地方是作者在文章結尾才交代如何產生imposter pair,讓人閱讀文章時候始終會有些困惑,建議先跳到結尾去看下這圖

你得告訴這個網路哪個是對方哪個是錯的,才能很好地訓練網路。imposter pair就是錯誤數據,產生這個錯誤數據的方法就是在音頻上shift,具體需要如何變換就需要作者嘗試了幾個數字之後給出了結論:平移改變0.5秒對於準確率的提升比較大

音頻視頻如何匹配起來呢?熟悉CNN的同學應該知道,網路輸出的結果會是不太複雜的向量,這個向量可以看作輸出的特質圖,在本模型中,音頻和視頻做變換後會分別輸出64維的圖片,計算兩個圖片之間的歐氏距離即可的出他們之間的近似程度,原理參考如下資料

圖像匹配之歐式距離演算法_雨林木風博客_新浪博客?

blog.sina.com.cn

Loss函數如下所示,Y是標籤,imposter pair為0,genuine pair為1,兩個X分別是輸入的音頻和視頻

式子展開後是這樣的

可以看到imp的L中間帶一個μ,那個是一個預先設定的常數。max函數的作用在於篩選出歐氏距離很近的imposter pair,那些明眼人以下就能看出來的壞人,是不需要花費公安機關大量經歷的,反而是和好人相似的壞人更需要進行鑒別,所以這部提取出來的強negative例子可以減小冗餘的訓練。

模型訓練的評級指標如下,第一行代表網路正確判定是match的個數,第二行的網路錯誤把不match的輸入判定為match

最後是訓練中一個重要的trick,就是online-pair-selection,也就是在每個batch中,靈活改變imposter pair和genuine pair之間的界限。當時看到時候第一反應是這個界限有必要嗎,錢買你不都規定了真假標籤嗎,但是自習一想,著步存在於網路訓練之中,是網路做出判斷的邏輯。

online_pair_selection = True if online_pair_selection: distance = sess.run( distance_l2, feed_dict={is_training: False, batch_speech: speech_train, batch_mouth: mouth_train, batch_labels: label_train.reshape([FLAGS.batch_size, 1])}) label_keep = [] ############################### hard_margin = 10 # Max-Min distance in genuines max_gen = 0 min_gen = 100 for j in range(label_train.shape[0]): if label_train[j] == 1: if max_gen < distance[j, 0]: max_gen = distance[j, 0] if min_gen > distance[j, 0]: min_gen = distance[j, 0] # Min-Max distance in impostors min_imp = 100 max_imp = 0 for k in range(label_train.shape[0]): if label_train[k] == 0: if min_imp > distance[k, 0]: min_imp = distance[k, 0] if max_imp < distance[k, 0]: max_imp = distance[k, 0] ### Keeping hard impostors and genuines for i in range(label_train.shape[0]): # imposter if label_train[i] == 0: if distance[i, 0] < max_gen + hard_margin: label_keep.append(i) elif label_train[i] == 1: # if distance[i, 0] > min_imp - hard_margin: label_keep.append(i)

上面是相關代碼,經過這種選取,結果會改進不少

最後作者探討了不同的參數的選取,比如計算歐氏距離之前,CNN的輸出維度問題。具體可見源代碼以及文章。


推薦閱讀:

TAG:學術論文 | 深度學習DeepLearning | 唇語 |