Kaldi 資料準備

Thu, Jan 03, 2019
CHINPO-CHEN

tags: ASR

reference

這篇主要會講一些資料準備好用的撇步。

  1. 首先當你有很多個音檔,卻要準備以下三個文件
    • text
    • wav.scp
    • spk2utt
    • utt2spk

要怎麼快速上手呢?很簡單。我們假設你的音檔們都放在/Volumes/Transcend/an4/wav/an4_clstk/fash裡面,資料夾長這樣

fash/
├── an251-fash-b.sph
├── an253-fash-b.sph
├── an254-fash-b.sph
├── an255-fash-b.sph
├── cen1-fash-b.sph
├── cen2-fash-b.sph
├── cen4-fash-b.sph
├── cen5-fash-b.sph
└── cen7-fash-b.sph

這邊我用sph的音檔格式來舉例,如果是wav檔也一樣照我的方法來操作。

wav.scp的建置

find ./fash -iname "*.sph" | awk -F"[./]" '{print $4" "$0}'

輸入以上這行指令就會出現以下的結果

an251-fash-b ./fash/an251-fash-b.sph
an253-fash-b ./fash/an253-fash-b.sph
an254-fash-b ./fash/an254-fash-b.sph
an255-fash-b ./fash/an255-fash-b.sph
cen1-fash-b ./fash/cen1-fash-b.sph
cen2-fash-b ./fash/cen2-fash-b.sph
cen4-fash-b ./fash/cen4-fash-b.sph
cen5-fash-b ./fash/cen5-fash-b.sph
cen7-fash-b ./fash/cen7-fash-b.sph

這個就是wav.scp需要的格式(細節在SSP課有講不贅述)。
現在來分開解釋這“兩”條指令,首先是

find ./fash -iname "*.sph"

指令的標準格式是:

find <要找的資料夾> [command] <要找的匹配字串>

"-iname" 可以忽略大小寫的不同,所以請都這樣用! ".sph"指的是所有以sph結尾的檔案(記得匹配字串是需要用雙引號括起來的),所以單單這行find ./fash -iname ".sph"跑出的結果就會是:

./fash/an251-fash-b.sph
./fash/an253-fash-b.sph
./fash/an254-fash-b.sph
./fash/an255-fash-b.sph
./fash/cen1-fash-b.sph
./fash/cen2-fash-b.sph
./fash/cen4-fash-b.sph
./fash/cen5-fash-b.sph

接下來下一步就是要從上面的字串從中間截出一些代表那個檔案的字(比方說utterance) 這時候用的是awk得指令

 awk -F"[./]" '{print $4" "$0}'

指令的標準格式是:

awk -F"[用來split的字元]" '{print $從左邊數來第幾個字串}'

這邊比較難講,總之這個格式要背起來,然後可以調整的是"[用來split的字元]" 和$4 或 $0等擷取出來的字。比如就這個例子來說:./fash/cen5-fash-b.sph 就是

要注意的是$0代表是整條路徑,所以print $4" "$0就能製造出:

cen5-fash-b 空格 ./fash/cen5-fash-b.sph

的效果

spk2utt

通常spk2utt是要放:

speaker utterance

可是當你沒辦法確定speaker是誰的時候,你可以放

utterance utterance

只是kaldi裡面tri5 可能就無法加入speaker的資訊來增加準確率了(但code還是可以跑得過)。spk2utt也可以上面的指令整理

find ./fash -iname "*.sph" | awk -F"[./]" '{print $4" "$4}'

出來的結果會是

an251-fash-b an251-fash-b
an253-fash-b an253-fash-b
an254-fash-b an254-fash-b
an255-fash-b an255-fash-b
cen1-fash-b cen1-fash-b
cen2-fash-b cen2-fash-b
cen4-fash-b cen4-fash-b
cen5-fash-b cen5-fash-b
cen7-fash-b cen7-fash-b

跟剛剛的道理一樣,只是$4重複print一次。

text

text本身就會存在資料庫的transcript裡面,通常很容易用python直接f=open(file)然後f.read()來讀入,並且用一些字串處理的方式來解析裡面的字,所以目前沒有general 的撇步可以進行。

utt2spk

utt2spk和spk2utt是一體兩面,有了其中一個就可以生出另一個。方法是可以用spk2utt_to_utt2spk.pl(通常會在utils資料夾下面) 這個檔案幫你做指令是:

utils/spk2utt_to_utt2spk.pl  spk2utt > utt2spk

標準格式是:

utils/spk2utt_to_utt2spk.pl  輸入檔案 > 輸出檔案

這樣就省去一份工了。


當你以上的資料備齊後(就kaldi的規則,應該會放在data/train之類的資料夾)有時候裡面的檔案順序如果不對,還是會跑出

error: file data/train is not in sorted order or has duplicates

的錯誤。這個問題只是表示utterance可能在每份file裡面順序不一樣,或是每份file沒有全部sort過。這時候其實不用把file都sort一遍,可以用kaldi本身提供的fix_data_dir.sh(也是在utils資料夾下面)用法:

utils/fix_data_dir.sh data/train

指令的標準格式是:

utils/fix_data_dir.sh <那些檔案放置資料夾>

這個腳本大致上可以幫你處理80%的狀[^footnote reference]況,如果有這招解不了的問題,我可以在未來的文章中講出解法。

資料都備齊之後程式之後kaldi/egs/ 資料夾下提供的recipe應該都可以跑了,下一篇會告訴大家有哪些方向可以調參數

^kaldi要怎麼調參數

Select a repo