online的操作介紹
在windows下裝虛擬機器UBuntu的機器上玩。你的虛擬機器記憶體要大些(4g--8g最好)。不然很痛苦。
找感覺一定要從中文開始,我們直接拿那個清華大學的中文例子(thchs30)開練,
1 首先進入githab下載的原始碼中egs目錄下找到這個例子,然後要看一遍它的介紹。在readme裡面有語料庫的下載方式。把它下完(3個壓縮包全下)。4個多G比較大。
2 考到對應的資料夾下(與s5同級別即可),取名叫thchs30-openslr,將所有壓縮包解壓到這下面
3 開啟s5目錄,編輯cmd.sh. 如下:()
export train_cmd=run.pl
export decode_cmd=run.pl
export mkgraph_cmd=run.pl
export cuda_cmd=run.pl
4 開啟run.sh,看到#data preparation這句,在它之後就全是shell的命令。建議一條一條的跑。不然中間會有莫名奇妙的斷檔和錯誤。如何一條條跑呢? 使用註釋:
<<!EOF! !EOF! 這兩句相當於C語言的/* */. 但願這個你能看懂。在此謝謝小凡妹妹的線上指導。
5按照上面的一句一句的來。它大概有幾個過程:資料準備,monophone單音素訓練, tri1三因素訓練, trib2進行lda_mllt特徵變換,trib3進行sat自然語言適應,trib4做quick(這個我也不懂),後面就是dnn了
6當執行到dnn時候會報錯,因為預設dnn都是用GPU來跑的。它會檢查一下,發現只在CPU下,就終止了。這裡建議不要跑dnn了。因為我試過,改成CPU之後跑了7,8天,才迭代17,18次。太慢了。而一次訓練怎麼的也得20多次。還要訓練好幾回。所以,想跑dnn的話還是找GPU吧。
7.下面說說前面的幾個步驟幹啥用。其實每一次都會有個模型,這些模型都可以用了,你可以看它的exp目錄,所有的步驟都在這裡面輸出。我們先簡單看一個,tri1,開啟後,有個decode_test_word,裡面有個scoring_kaldi,best_wer就是它的錯誤率,36.15%.好回到tri1下,看到final.mdl了嗎,這個就是有用的東西,學出來的模型。另外還得到graph_word下面,找到words.txt,和HCLG.fst,一個是字典,一個是有限狀態機。有這3個檔案,就可以來使用你的識別功能了。
8.這步是比較好玩的了。我們用這個模型來識別自己的語言。(是非常的不準,只是感受一下而已),回到原始碼的src下。make ext 編譯擴充套件程式。(在這之前確定你的tools資料夾下的portaudio已經裝好)之後,會看到onlinebin資料夾。裡面有兩個程式,online-wav-gmm-decode-faster 用來回放wav檔案來識別的,online-gmm-decode-faster用來從麥克風輸入聲音來識別的。
8.1 這裡開個小差:portaudio 裝好後,有可能收不到聲音,可以裝個audio recoder(用apt-get),之後用它錄音試試,測測是否有聲音,只要能錄音,portaudio就沒問題,一般裝完就好了,不行就再重啟一下。不知道為啥。
8.2 介紹下online。很鄙視kaldi在這塊的設計,居然搞出來兩個版本。online是不再維護了。但是非常好用,online2是新的。引數n多。也不支援從麥克風採集。特別不人性化,如果有那個朋友把online2研究好了,請把經驗也分享一下。
9.我們找一個例子吧:去egs下,開啟voxforge,裡面有個online_demo,直接考到thchs30下。在online_demo裡面建2個資料夾online-data work,在online-data下建兩個資料夾audio和models,audio下放你要回放的wav,models建個資料夾tri1,把s5下的exp下的tri1下的final.mdl和35.mdl(final.mdl是快捷方式)考過去。把s5下的exp下的tri1下的graph_word裡面的words.txt,和HCLG.fst,考到models的tri1下。
10。開啟online_demo的run.sh
a)將下面這段註釋掉:(這段是voxforge例子中下載現網的測試語料和識別模型的。我們測試語料自己準備,模型就是tri1了)
if [ ! -s ${data_file}.tar.bz2 ]; then
echo "Downloading test models and data ..."
wget -T 10 -t 3 $data_url;
if [ ! -s ${data_file}.tar.bz2 ]; then
echo "Download of $data_file has failed!"
exit 1
fi
fi
b) 然後再找到如下這句,將其路徑改成tri1
ac_model_type=tri2b_mmi
# Alignments and decoding results
---------------------------------------------------------------
改成:
ac_model_type=tri1
c)
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85\
--max-active=4000 --beam=12.0 --acoustic-scale=0.0769 \
scp:$decode_dir/input.scp $ac_model/model
————————————————————————————
改成:online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85\
--max-active=4000 --beam=12.0 --acoustic-scale=0.0769 \
scp:$decode_dir/input.scp $ac_model/final.mdl
11。直接./run.sh吧,就是開始回放識別了。裡面有提示,./run.sh --test-mode live命令就是從麥克風識別。
12.昇華部分在這裡。我們試完tri1的模型後,一定很想試試tri2或3.但當你操作時,會遇到如下的問題:
ERROR (online-wav-gmm-decode-faster:LogLikelihoods():diag-gmm.cc:533) DiagGmm::ComponentLogLikelihood, dimension mismatch 39vs. 40
怎麼解決? 仔細看看這個原始檔,它是dieta的。如果要是ldp還得加matrix引數(拿tri2b舉例)。
於是修改run.sh成如下這個樣子 :(就是把final.mat考過來,引入命令中)
if [ -s $ac_model/matrix ]; then
trans_matrix=$ac_model/12.mat
fi
同時把把s5下的exp下的tri2b下的12.mat考到models的tri2b下。
13 再次修改run.sh成如下這個樣子(新增2個引數--left-context=3 --right-context=3)
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85 \
--max-active=4000 --beam=12.0 --acoustic-scale=0.0769 --left-context=3 --right-context=3\
scp:$decode_dir/input.scp $ac_model/final.mdl $ac_model/HCLG.fst \
$ac_model/words.txt '1:2:3:4:5' ark,t:$decode_dir/trans.txt \
ark,t:$decode_dir/ali.txt $trans_matrix;;
14 執行./run.sh,結果如下。怎麼樣,有點酷不? 如果想使用tri2等模型做麥克風線上的,也同理修改就可以了。
online-wav-gmm-decode-faster --verbose=1 --rt-min=0.8 --rt-max=0.85 --max-active=4000 --beam=12.0 --acoustic-scale=0.0769 --left-context=3 --right-context=3 scp:./work/input.scp online-data/models/tri2b/final.mdl online-data/models/tri2b/HCLG.fst online-data/models/tri2b/words.txt
1:2:3:4:5 ark,t:./work/trans.txt ark,t:./work/ali.txt online-data/models/tri2b/12.mat
File: D4_750
蘇北 軍禮 下跪 將 是 馬 湛 殺人 裡 杜 唐 據 五 蘇 並 案 但 甜美 但 也 分析 抗戰
科大訊飛的語音識別庫,感覺只有後半部分,想實現前半部分的採集卻找不到可以用的東西。於是自己做一個。
可以隨便拿個開源的程式碼改一下,我們就使用arecord吧。
這只是個簡單的端點檢測,根據聲音能量,也就是分貝大小來調整的。
下載原始碼:
http://www.alsa-project.org/main/index.PHP/Main_Page
arecord在alsa的alsa-utils裡面。當然依賴於Library (alsa-lib),所以兩個都要下下來
下載頁在這:
http://www.alsa-project.org/main/index.php/Download
然後在本地就可以編譯了。編譯時會提示需要各種工具,直接按提示下載即可。 我用的是ubuntu直接apt-get,就得到了。
編好之後,進入aplay資料夾下。可以看到arecord其實是一個連結鏈到aplay了。aplay.c就是原始碼,我們直接改它就行
一:定義變數:
95行左右,
static char *command;
static snd_pcm_t *handle;
static struct {
snd_pcm_format_t format;
unsigned int channels;
unsigned int rate;
} hwparams, rhwparams;
static int timelimit = 0;
//add by ljh
static int silflag = 0; //出現靜音情況
static off64_t silcount= 0; //j靜音時要收到的包
static int enablesil = 0; //啟用靜音檢測狀態
1648行,修改函式如下
static void print_vu_meter_mono(int perc, int maxperc)//因為是單音輸入,所以我們只改這一塊,呼叫時配合mono設定。
{
const int bar_length = 50;
char line[80];
int val;
//add by ljh
if(perc>=2)//speak
{
enablesil = 1;// sel open
silflag = 0;
}else if(silflag==0)//into silflag
{
//init silcount 1s
silcount = 2* snd_pcm_format_size(hwparams.format, hwparams.rate * hwparams.channels);
silflag =1;
}else // already silence
{
}
for (val = 0; val <= perc * bar_length / 100 && val < bar_length; val++)
line[val] = '#';
for (; val <= maxperc * bar_length / 100 && val < bar_length; val++)
line[val] = ' ';
line[val] = '+';
for (++val; val <= bar_length; val++)
line[val] = ' ';
if (maxperc > 99)
sprintf(line + val, "| MAX");
else
sprintf(line + val, "| %02i%%", maxperc);
fputs(line, stderr);
if (perc > 100)
fprintf(stderr, _(" !clip "));
}
最後是capture函式,分別在 3050和3103處修改:
static void capture(char *orig_name)
{
int tostdout=0;/* boolean which describes output stream */
int filecount=0;/* number of files written */
char *name = orig_name;/* current filename */
char namebuf[PATH_MAX+1];
off64_t count, rest;/* number of bytes to capture */
struct stat statbuf;
/* get number of bytes to capture */
count = calc_count();
if (count == 0)
count = LLONG_MAX;
/* compute the number of bytes per file */
max_file_size = max_file_time *
snd_pcm_format_size(hwparams.format,
hwparams.rate * hwparams.channels);
/* WAVE-file should be even (I'm not sure), but wasting one byte
isn't a problem (this can only be in 8 bit mono) */
if (count < LLONG_MAX)
count += count % 2;
else
count -= count % 2;
/* display verbose output to console */
header(file_type, name);
/* setup sound hardware */
set_params();
/* write to stdout? */
if (!name || !strcmp(name, "-")) {
fd = fileno(stdout);
name = "stdout";
tostdout=1;
if (count > fmt_rec_table[file_type].max_filesize)
count = fmt_rec_table[file_type].max_filesize;
}
init_stdin();
//add by ljh
silcount = 2* snd_pcm_format_size(hwparams.format, hwparams.rate * hwparams.channels);
do {
/* open a file to write */
if(!tostdout) {
/* upon the second file we start the numbering scheme */
if (filecount || use_strftime) {
filecount = new_capture_file(orig_name, namebuf,
sizeof(namebuf),
filecount);
name = namebuf;
}
/* open a new file */
if (!lstat(name, &statbuf)) {
if (S_ISREG(statbuf.st_mode))
remove(name);
}
fd = safe_open(name);
if (fd < 0) {
perror(name);
prg_exit(EXIT_FAILURE);
}
filecount++;
}
rest = count;
if (rest > fmt_rec_table[file_type].max_filesize)
rest = fmt_rec_table[file_type].max_filesize;
if (max_file_size && (rest > max_file_size))
rest = max_file_size;
/* setup sample header */
if (fmt_rec_table[file_type].start)
fmt_rec_table[file_type].start(fd, rest);
/* capture */
fdcount = 0;
while (rest > 0 && recycle_capture_file == 0 && !in_aborting) {
size_t c = (rest <= (off64_t)chunk_bytes) ?
(size_t)rest : chunk_bytes;
size_t f = c * 8 / bits_per_frame;
if (pcm_read(audiobuf, f) != f)
break;
if (write(fd, audiobuf, c) != c) {
perror(name);
prg_exit(EXIT_FAILURE);
}
count -= c;
rest -= c;
fdcount += c;
//add by ljh
if(silflag == 1 && enablesil == 1)//silence sil open
{
silcount -= c;
if(silcount <= 0)// after 1s
{
// game over
count = 0;
rest = 0;
}
}
}
/* re-enable SIGUSR1 signal */
if (recycle_capture_file) {
recycle_capture_file = 0;
signal(SIGUSR1, signal_handler_recycle);
}
/* finish sample Container */
if (fmt_rec_table[file_type].end && !tostdout) {
fmt_rec_table[file_type].end(fd);
fd = -1;
}
if (in_aborting)
break;
/* repeat the loop when format is raw without timelimit or
* requested counts of data are recorded
*/
} while ((file_type == FORMAT_RAW && !timelimit) || count > 0);
}
然後再編譯就好了。配合到程式碼裡使用可以這樣:
system("./arecord -D hw:0,0 -f S16_LE -V mono -r8000 -c 2 -t wav wav/mytest.wav");
把aplay拷過去,建立個連結ln ./alplay arecord
記得把依賴的庫libasound.so.2也得考過去哦。
原理:capture中,每次會把讀到的資料做個能量計算並列印出來,通過其計算的部分來設定個靜音開始狀態,同時在設定接下來需要讀多少個位元組,這部分可以仿照其原有的count計算方法。這樣,當進入靜音狀態開始時,系統再讀入設定好的位元組後,就自動退出了。當然在此期間,假如使用者又說話了。那麼靜音狀態關閉,silcount將不會生效。直到再此進入靜音狀態開始
還有一個點是當錄音剛啟動時,如果使用者不說話,我們不希望它退出,要一直等在那裡,於是又需要個變數就是啟用錄音狀態enablesil ,預設是不啟用,一旦有使用者說話,就把它啟用。這樣silflag就開始生效了。
如果想直接拿來用,這裡有編譯好的程式,和原始碼可以下載:
http://download.csdn.NET/detail/lijin6249/9580171
在linux上如何做一個簡單的vad功能,即錄音時說話停止即錄音停止。
相關文章
- Linux SOCKET介紹 www.weiboke.onlineLinux
- MySQL DDL執行方式-Online DDL介紹MySql
- pt-online-schema-change工作過程介紹
- Git 分支操作介紹Git
- etcd 常用操作介紹
- Java中的13個原子操作類介紹Java
- 關於keras框架的介紹以及操作使用Keras框架
- 關於python操作excel,xlwt,xlwd,最簡單的操作介紹PythonExcel
- Docker 映象及容器操作命令介紹Docker
- java8 Stream流操作介紹Java
- MyBatis框架介紹及實戰操作MyBatis框架
- 介紹幾種List集合分批操作的工具
- Python 複數屬性及操作介紹Python
- einsum函式介紹-張量常用操作函式
- 記錄一次 Online DDL 操作
- 優雅的操作檔案:java.nio.file 庫介紹Java
- MYSQL SET型別欄位的SQL操作知識介紹MySql型別
- Django 2.0 模型層中 QuerySet 查詢操作介紹Django模型
- Spread表格元件For JAVA功能介紹—表格相關操作元件Java
- Linux入門教程之sed 命令常用操作介紹Linux
- Flownet 介紹 及光流的簡單介紹
- Cloudera的介紹Cloud
- HikariCP 的介紹
- CyclicBarrier的介紹
- VQGAN的介紹
- DruidDataSource的介紹UI
- ThreadLocal的介紹thread
- ProxmoxVE的介紹
- 表空間與資料檔案的offline和online操作
- C# 資料操作系列 - 19 FreeSql 入坑介紹C#SQL
- MySQL 執行 Online DDL 操作報錯空間不足?MySql
- python類的介紹Python
- Flink - datagen 的介紹
- QPS/TPS 的介紹
- hazelcast的基本介紹AST
- Mongo的bulkWrite介紹Go
- spring框架的介紹Spring框架
- 事務的介紹
- 介紹