和其它文章初衷一樣潭千,網(wǎng)上解釋很多,但是講的不是很明白,在看完幾篇參考博客后特此記錄
簡介
先拿語音識別任務來說本砰,如果現(xiàn)在有一個包含剪輯語音和對應的文本,我們不知道如何將語音片段與文本進行對應钢悲,這樣對于訓練一個語音識別器增加了難度点额。
為了解決上述問題,我們可以先制定一個規(guī)則莺琳,例如“一個字符對于是個語言片段輸入”还棱。對于不同的人來說,他們說話的語速也不一樣惭等,這樣導致了上述的定義規(guī)則不可行珍手。另一個解決辦法,手動對齊每個字符在音頻中的位置辞做。這種方法對于我們訓練模型非常有效琳要,但是不可否認的是這種做法非常耗時。
上面只是拿語音識別來舉例秤茅,其實在其他一些識別任務中也會出現(xiàn)這個問題稚补,例如手寫字符識別,上面兩例如下圖所示
Connectionist Temporal Classification (CTC)正適合這種不知道輸入輸出是否對齊的情況使用的算法框喳,所以CTC適合語音識別和手寫字符識別的任務
為了方便下面的描述课幕,我們做如下定義,輸入(如音頻信號)用符號序列表示帖努,對應的輸出(如對應的標注文本)用符號序列撰豺,為了方便訓練這些數(shù)據(jù)我們希望能夠找到輸入與輸出之間精確的映射關系。
在使用有監(jiān)督學習算法訓練模型之前拼余,有幾個難點:
- 和都是變長的
- 和的長度比也是變化的
- 和相應的元素之間沒有嚴格的對齊(即與不一定對齊)
使用CTC算法能克服上述問題污桦。到這里可以知道CTC就是可以解決輸入輸出對應問題的一種算法。
這里我們首先需要明確的是匙监,還拿語音識別來說凡橱,現(xiàn)在使用的CTC常用的場景是RNN后接CTC算法小作,RNN模型輸入是個個音頻片段,輸出個數(shù)與輸入的維度一樣稼钩,有T個音頻片段顾稀,就輸出T個維度的概率向量,每個向量又由字典個數(shù)的概率組成坝撑。例如網(wǎng)絡輸入音頻個數(shù)定為T静秆,字典中不同字的個數(shù)為N,那么RNN輸出的維度為巡李。根據(jù)這個概率輸出分布抚笔,我們就能得到最可能的輸出結果。在接下來的討論中可以把RNN+CTC看成一個整體侨拦,當然也可以將RNN替換成其他的提取特征算法
損失函數(shù)的定義:對于給定的輸入殊橙,我們訓練模型希望最大化的后驗概率,應該是可導的,這樣我們就能利用梯度下降訓練模型了狱从。
測試階段:當我們已經訓練好一個模型后膨蛮,輸入,我們希望輸出的條件概率最高即季研,而且我們希望盡量快速的得到值敞葛,利用CTC我們能在低投入情況下迅速找到一個近似的輸出。
算法
CTC算法對于輸入的能給出非常多的Y的條件概率輸出(可以想象RNN輸出概率分布矩陣与涡,所以通過矩陣中元素的組合可以得到很多Y值作為最終輸出)制肮,在計算輸出過程的一個關鍵問題就是CTC算法如何將輸入和輸出進行對齊的。在接下來的部分中递沪,我們先來看一下對齊的解決方法,然后介紹損失函數(shù)的計算方法和在測試階段中找到合理輸出的方法综液。
對齊
CTC算法并不要求輸入輸出是嚴格對齊的款慨。但是為了方便訓練模型我們需要一個將輸入輸出對齊的映射關系,知道對齊方式才能更好的理解之后損失函數(shù)的計算方法和測試使用的計算方法谬莹。
為了更好的理解CTC的對齊方法檩奠,先舉個簡單的對齊方法。假設對于一段音頻附帽,我們希望的輸出是這個序列埠戳,一種將輸入輸出進行對齊的方式如下圖所示气忠,先將每個輸入對應一個輸出字符给郊,然后將重復的字符刪除。
上述對齊方式有兩個問題:
- 通常這種對齊方式是不合理的拷获。比如在語音識別任務中喳钟,有些音頻片可能是無聲的屁使,這時候應該是沒有字符輸出的
- 對于一些本應含有重復字符的輸出在岂,這種對齊方式沒法得到準確的輸出。例如輸出對齊的結果為蛮寂,通過去重操作后得到的不是“hello”而是“helo”
為了解決上述問題蔽午,CTC算法引入的一個新的占位符用于輸出對齊的結果。這個占位符稱為空白占位符酬蹋,通常使用符號及老,這個符號在對齊結果中輸出,但是在最后的去重操作會將所有的刪除得到最終的輸出范抓。利用這個占位符骄恶,可以將輸入與輸出有了非常合理的對應關系,如下圖所示
在這個映射方式中尉咕,如果在標定文本中有重復的字符叠蝇,對齊過程中會在兩個重復的字符當中插入占位符。利用這個規(guī)則年缎,上面的“hello”就不會變成“helo”了悔捶。
回到上面這個例子來,下圖中有幾個示列說明有效的對齊方式和無效的對齊方式单芜,在無效的對齊方式中舉了三種例子蜕该,占位符插入位置不對導致的輸出不對,輸出長度與輸入不對齊洲鸠,輸出缺少字符a
CTC算法的對齊方式有下列屬性:
- 輸入與輸出的對齊方式是單調的堂淡,即如果輸入下一輸入片段時輸出會保持不變或者也會移動到下一個時間片段
- 輸入與輸出是多對一的關系
- 輸出的長度小于等于輸入
損失函數(shù)
這里要明確一點,對于一個標定好的音頻片段扒腕,訓練該片段時绢淀,我們希望的輸出就是標定的文本,如下圖所示瘾腰,音頻說的一個hello皆的,RNN或者其他模型輸出的是相同數(shù)量的向量,向量里是每個字母的概率
對于一對輸入輸出來說蹋盆,CTC的目標是將下式概率最大化
解釋一下费薄,對于RNN+CTC模型來說,RNN輸出的就是概率栖雾,t表示的是RNN里面的時間的概念楞抡。乘法表示一條路徑的所有字符概率相乘,加法表示多條路徑析藕。因為上面說過CTC對齊輸入輸出是多對一的召廷,例如與對應的都是“hello”,這就是輸出的其中兩條路徑,要將所有的路徑相加才是輸出的條件概率
但是對于一個輸出柱恤,路徑會非常的多数初,這樣直接計算概率是不現(xiàn)實的,CTC算法采用動態(tài)規(guī)劃的思想來求解輸出的條件概率梗顺,如下圖所示泡孩,該圖想說明的是通過動態(tài)規(guī)劃來進行路徑的合并(看不懂也沒關系,下面有詳細的解釋)
假設我們現(xiàn)在有輸入音頻對應的標定輸出為單詞“ZOO”寺谤,為了方便解釋下面動態(tài)規(guī)劃的思想仑鸥,現(xiàn)在每個字符之間還有字符串的首位插入空白占位符,得到下面結果
為了便于說明变屁,先定義好下圖的橫縱坐標軸的含義眼俊,橫軸是的時間片單位為t,縱軸為序列單位為s粟关。根據(jù)CTC的對齊方式的三個特征疮胖,輸入有9個時間片,標簽內容是“ZOO”闷板,的所有可能的合法路徑如下圖
表示對齊結果合并后(如圖3.png)節(jié)點的概率澎灸。表示上圖中坐標為(s,t)節(jié)點的概率,該點的概率計算分為下面兩種情況:
Case 1:
1)如果遮晚,則只能由前一個字符或者本身得到
2)如果不等于性昭,但是為連續(xù)字符的第二個,即()县遣,則只能由一個空白符或者其本身得到糜颠,而不能由前一個字符得到。
上述兩種情況中萧求,可以由下式算出其兴,其中表示在時刻t輸出字符的概率。
Case 2:
如果不等于夸政,則可以由忌警,以及得來,可以表示為
從圖7中可以看到合法路徑由兩個起始點秒梳,輸出兩個終止點,最后輸出的條件概率為兩個終止點輸出概率的和箕速。使用這種計算方法就能高效的計算損失函數(shù)酪碘,下一步的工作表示計算梯度用于訓練模型。由于P(Y|X)的計算只涉及加法和乘法盐茎,因此是可導的兴垦。對于訓練集,模型優(yōu)化的目標是最小化負對數(shù)似然函數(shù)
預測
當我們訓練好一個模型后,我們輸入探越,我們的目的是計算下式得到輸出
1.一種方法是貪婪算法狡赐,取RNN每次輸出概率最大的節(jié)點,計算方式如下
然后通過去重得到輸出結果钦幔。
通常這種啟發(fā)式的算法很有效枕屉,但是這種方法忽略了一個輸出可能對應多個對齊結果。例如和各自的概率均小于的概率鲤氢,但是他們相加的概率比概率高搀擂。簡單的啟發(fā)是算法得到結果為,但是結果為更為合理卷玉∩谒蹋考慮到這點第二種方式變的更為合理
2.第二種算法是Beam search的一種變形
先來說一下Beam search算法,該算法有個參數(shù)叫做寬度相种,假設寬度設為3威恼,在RNN的輸出中,該算法每個時間t輸出時寝并,不同于貪婪算法只找最高的箫措,而是找最高的三個概率作為下一次的輸入,依次迭代食茎,如下圖所示蒂破,每次t時間都是基于t-1輸出的最高三個查找當前概率最高的三個。(這里也可以看出别渔,當寬度設置為1時就是貪婪算法)
因為我們這里想要結合多個對齊能夠映射到同一輸出的這種情況附迷,這時每次t時間的輸出為去重后以及移除的結果,具體如下圖所示
當輸出的前綴字符串遇上重復字符時哎媚,可以映射到兩個輸出喇伯,如圖9所示,當T=3時拨与,前綴包含a稻据,遇上新的a,則[a]和[a,a]兩個輸出都是有效的买喧。
當我們將[a]擴展為[a, a]時捻悯,我們只需統(tǒng)計之前以空白標記結尾的所有路徑的概率(位于字符中間的?也要統(tǒng)計)。同樣的淤毛,如果是擴展到[a]今缚,那我們計算的就是不以結尾的所有路徑概率。所以每次的輸出只需要記錄空白標記結尾的所有路徑的概率和不以結尾的所有路徑概率來進行下一次的概率計算低淡。這個算法的實現(xiàn)姓言,Awni Hannun給出了示例
CTC的特征
- 條件獨立:CTC的一個非常不合理的假設是其假設每個時間片都是相互獨立的瞬项,這是一個非常不好的假設。在OCR或者語音識別中何荚,各個時間片之間是含有一些語義信息的囱淋,所以如果能夠在CTC中加入語言模型的話效果應該會有提升。
- 單調對齊:CTC的另外一個約束是輸入與輸出之間的單調對齊餐塘,在OCR和語音識別中妥衣,這種約束是成立的。但是在一些場景中例如機器翻譯唠倦,這個約束便無效了称鳞。
- 多對一映射:CTC的又一個約束是輸入序列的長度大于標簽數(shù)據(jù) 的長度,但是對于的長度大于的長度的場景稠鼻,CTC便失效了冈止。
參考
[1] https://distill.pub/2017/ctc/
[2] https://gist.github.com/awni/56369a90d03953e370f3964c826ed4b0
[3] https://zhuanlan.zhihu.com/p/42719047
[4] https://www.zhihu.com/question/47642307
[5] https://www.cs.toronto.edu/~graves/icml_2006.pdf
歡迎加入OCR交流群:785515057(此群已滿)
歡迎加入OCR交流群2:826714963