如何使用kaldi訓練得到錄製音頻的mfcc數據
之前跑了幾個kaldi的開源的測試例子,由於有很多參考,所以也就很好入門,但是我們總歸是要使用kaldi來測試自己的語音數據的,於是就想着能不能使用kaldi來訓練自己提供的數據wav文件,從而得到其mfcc特徵值呢?這篇博客就是一次探索,先是實現語音文件的錄製,然後再實現其特徵提取。
1.使用python錄製語音數據
1.1 安裝pyaudio
pip install pyaudio
因爲我的已經安裝了,所以就提示這樣了:
1.2 錄音程序
在該程序中,有以下幾個動態參數可供調整:
- 調整錄製語音數據的時間長短,此處默認我設置爲5s;
- 設置傅里葉變換點數,默認爲1024點;
- 設置採樣率,默認爲16K,當然也可以根據需要設置爲8K、44100以及48000;
- 設置文件的保存名稱及路徑。
# @Time : 2020/2/20 14:45
# @Author : kingback
# @File : python_talker.py
# @Software: PyCharm
import pyaudio
import logging
import wave
logging.basicConfig(level=logging.DEBUG)
#定義錄音函數
def recording():
CHUNK = 1024
#點數
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
#採樣率fs
RECORD_SECONDS = 5
#採集時間長度
WAVE_OUTPUT_FILENAME = "test1.wav"
#文件命名
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
logging.info('錄音開始(時長5s),請講話:')
frames = []
for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
logging.info('錄音結束,程序正在退出...')
stream.stop_stream()
stream.close()
p.terminate()
#將音頻文件真正的寫入.wav文件
wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()
#調用錄音函數
recording()
我使用該函數,分別將"你好",“武漢加油”,“中國加油”,錄製爲.wav文件,且將其分別命名爲test1.wav、test2.wav、test3.wav
此處僅展示一個文件的錄製:
2.使用kaldi訓練語音數據
將前邊錄製得到的語音數據test1.wav、test2.wav、test3.wav,複製到kaldi的egs,並新建一個test文件夾,用於訓練自己的樣本數據。
2.1 文件複製及建立
想要直接訓練我們自己的數據,當然我們需要藉助kaldi已經封裝好的包,我們可以按照如下步驟建立文件夾:
Step 1. 我們進入egs/thchs30文件夾下,將其s5文件夾複製並拷貝至我們的egs/test文件夾下,確保你的s5文件夾有conf local step utils文件夾
Step 2. 然後把我們的數據保存到egs/test/s5/test文件夾下,此時test文件夾下存在test1.wav、test2.wav、test3.wav。
Step 3. 在s5文件夾下新建個data文件夾,data文件夾新建個test文件夾,這個test文件夾裏需要三個文件:wav.scp、utt2spk 、spk2utt
其中wav.scp文件內容設置如下:
test1 test/test1.wav
test2 test/test2.wav
test3 test/test3.wav
utt2spk文件內容設置如下:
test1 global
test2 global
test3 global
spk2utt文件內容設置如下:
global test1 test2 test3
Step 4. 創建文件run1.sh
在s5文件夾下執行如下文件創建run1.sh,並編輯其內容
touch run1.sh
vi run1.sh
將其中內容設置如下即可:
#!/bin/bash
train_cmd="utils/run.pl"
decode_cmd="utils/run.pl"
# Feature extraction
for x in test ; do
steps/make_mfcc.sh --nj 2 data/$x exp/make_mfcc/$x mfcc
done
Step 5. 執行run1.sh
chmod 777 run1.sh
#修改文件執行權限
./run1.sh
執行結果如下所示:
顯示這樣就說明.wav文件成功獲取mfcc數據,並存入s5文件夾下的mfcc文件夾內。
生成成功之後,我們可以看一下此時的s5文件路徑下包含以下文件:
3.mfcc數據解讀
我們進入剛剛生成的mfcc文件夾,查看其內文件:
我們可以看到其內生成了.ark文件和.scp文件,但是我們無法看到其內訓練得出的mfcc數據,我之前的博客中有過介紹,對於.ark文件,我們可以使用如下命令解碼至新的txt.ark文件:
/home/king/kaldi-test/src/featbin/copy-feats ark:raw_mfcc_test.1.ark ark,t:txt1.ark
#其中前邊的 路徑可以根據自己的文件路徑自行修改爲自己kaldi所在路徑
#這裏的對應文件也需要具體情況而更改。
如下所示:
上圖即表示文件解碼成功,並分別生成了解碼後的新文件txt1.ark和txt2.ark文件,接下來使用cat命令查看其內數據:
在分別查看了txt1.ark和txt2ark文件內的內容後發現,其內存儲的是test1.wav、test2.wav、test3.wav文件的mfcc數據,且每一個.wav語音文件都對應一個498*13的矩陣,也就是說每一個語音文件都被分成了498幀。以下我僅列出第一個語音文件的部分mfcc特徵值:
test1 [
30.44016 -31.4298 -6.260107 -6.011955 -8.00444 -7.065151 1.920065 5.144895 6.186597 -7.191596 -2.794114 -4.910667 -2.422569
29.42849 -33.16988 -4.229344 -6.521392 1.159485 -3.974985 -5.769829 -1.018203 2.786052 4.171975 5.907083 2.159832 2.405282
28.92266 -36.21503 -13.62797 -18.04583 -9.414276 -10.67035 -13.57087 -5.664696 3.919567 0.1199163 2.768946 -9.609997 -18.02723
29.93433 -32.29984 -9.380675 -9.578018 -5.88969 -6.550123 -5.769829 -7.689703 -8.019772 0.4817072 0.914593 -2.06467 4.922556
28.92266 -32.29984 -4.857034 -7.693099 -7.299522 -8.095207 -3.642273 -6.677198 6.186597 -5.205961 -2.936756 -6.807999 -8.497049
28.41683 -36.21503 -8.773919 -5.910067 -10.11919 -16.85068 -9.315755 -10.47409 0.9472036 3.665468 2.98291 -7.464767 -8.497049
28.92266 -31.4298 -8.773919 -14.58349 -6.594604 -5.005041 3.148366 4.272104 1.879241 4.099617 1.913091 -1.480875 -0.4302626
28.92266 -37.52009 -13.62797 -11.61577 -3.774937 -14.27554 -13.21627 -8.44908 -0.1468101 -0.1695165 -7.496267 1.875942 -3.231944
29.42849 -30.55976 -6.813951 -10.69878 -4.479855 -6.550123 -3.996864 -4.621746 -1.104072 -2.889387 -3.913794 -0.7511325 -1.862233
......
......
59.27252 -12.28889 -9.380675 -9.578018 7.584411 10.84045 10.31671 4.578789 6.640003 10.7249 4.052729 3.579283 2.764893
60.03772 -9.678764 -7.712094 -5.451573 7.059104 10.43035 -0.8055305 -9.461584 0.878828 9.446206 12.2964 -9.967535 -11.17741
60.43855 -9.101912 -8.015472 -11.46294 8.576657 11.4146 -5.769829 -8.702206 -1.377575 8.513467 13.60441 2.443722 -6.407183
60.88654 -8.219669 -3.749345 -7.693099 9.160332 12.15279 -0.4509373 -14.01785 -10.79376 13.28229 3.910087 1.875942 2.405282
59.27252 -11.41885 -4.155498 -5.859123 6.125225 16.73914 5.749472 -5.917821 0.1266932 5.98093 0.9859142 -9.252459 -6.220404
60.17919 -7.507088 -3.490885 -8.813862 10.09074 10.10226 0.2582474 -4.161719 3.692864 18.39708 10.33439 -1.991695 0.4274244
61.12232 -6.455182 -2.530888 -7.794986 4.374202 7.969719 7.628049 0.5918908 -1.240824 10.7249 1.342521 3.011503 9.237883 ]
4.總結
此篇博客的工作主要完成了對於自己語音數據的mfcc數據的提取,後續還可以將這些提取出來的mfcc數據與之前自己編輯的matlab代碼進行比較,比較一下其差別。其實此篇博客得到的mfcc數據,也主要是對自己設計的算法進行一下驗證。前邊的道路還有很長,對於kaldi的瞭解也只是剛剛展開,還需要不斷的學習,不斷地遷移。