语种识别
- 1.简介
- 1.1 数据集简介
- 1.2 识别口语种类简介
- 2.项目实现概述
- 2.1音频数据转化为语谱图
- 2.2语谱图的语种识别
- 3.口语识别项目的详细实现
- 3.1 语谱图转化程序实现
- 3.1.1 划分训练集和验证集
- 3.1.2 MP3转化为语谱图
- 3.2 基于caffe的CNN网络训练程序实现
- 3.2.1 caffe环境配置
- 3.2.2 生成语谱图数据txt清单
- 3.2.3 生成leveldb数据库
- 3.2.4 caffe训练网络
- 3.3 CNN预测音频语言种类程序实现
- 4.错误集锦
- 4.1 语谱图生成程序出错
- 4.2 caffe训练网络出错
- 4.3 caffe预测语种程序出错
1.简介
基于深度卷积神经网络的语种识别最终目标是识别相应语音音频中的语言种类,项目是Hrayr Harutyunyan团队参加TopCoder上一个口语识别竞赛的CNN实现方案,项目实现代码 以及详细实现细节的博客公开在github上。
1.1 数据集简介
项目采用的数据都是44.1khz的MP3录音数据,且都是10秒长度,去燥的数据。录音数据共包含176种语言,66176(每种语言376个数据,376176=66176)个数据有标签,12320个数据无标签。共分为三种数据集:训练集共有53856(306176)个数据,验证集共有12320(70*176)个数据,测试集共有12320个数据
1.2 识别口语种类简介
项目中所涉及的176种语言以及语言对应的数字标签0-175如下所示:
(‘Adiokrou’, ‘map to’, 0)
(‘Aguaruna Awajun’, ‘map to’, 1)
(‘Akha’, ‘map to’, 2)
(‘Akoose’, ‘map to’, 3)
(‘Alangan’, ‘map to’, 4)
(‘Albanian Tosk’, ‘map to’, 5)
(‘Alladian’, ‘map to’, 6)
(‘Altai Southern’, ‘map to’, 7)
(‘Anufo’, ‘map to’, 8)
(‘Arabic’, ‘map to’, 9)
(‘Arabic Egyptian Spoken’, ‘map to’, 10)
(‘Arabic Sudanese Spoken’, ‘map to’, 11)
(‘Aruamu’, ‘map to’, 12)
(‘Ashaninca’, ‘map to’, 13)
(‘Avokaya’, ‘map to’, 14)
(‘Awa PNG’, ‘map to’, 15)
(‘Awadhi’, ‘map to’, 16)
(‘Aymara’, ‘map to’, 17)
(‘Azerbaijani North’, ‘map to’, 18)
(‘Bali’, ‘map to’, 19)
(‘Bekwarra’, ‘map to’, 20)
(‘Belize Kriol English’, ‘map to’, 21)
(‘Bench’, ‘map to’, 22)
(‘Bhojpuri’, ‘map to’, 23)
(‘Biate’, ‘map to’, 24)
(‘Bicolano Central’, ‘map to’, 25)
(‘Bokyi’, ‘map to’, 26)
(‘Bora’, ‘map to’, 27)
(‘Bru Eastern’, ‘map to’, 28)
(‘Cakchiquel South Central’, ‘map to’, 29)
(‘CandoshiShapra’, ‘map to’, 30)
(‘Carib’, ‘map to’, 31)
(‘Chamacoco’, ‘map to’, 32)
(‘Chayahuita Shawi’, ‘map to’, 33)
(‘Chinantec de Usila’, ‘map to’, 34)
(‘Chipaya’, ‘map to’, 35)
(‘Chuj Ixtatan’, ‘map to’, 36)
(‘Cofan’, ‘map to’, 37)
(‘Dan East’, ‘map to’, 38)
(‘Dangaleat’, ‘map to’, 39)
(‘Dinka Northeastern’, ‘map to’, 40)
(‘Duala’, ‘map to’, 41)
(‘Duri’, ‘map to’, 42)
(‘Dutch’, ‘map to’, 43)
(‘Eleme’, ‘map to’, 44)
(‘Ese Ejja’, ‘map to’, 45)
(‘Fai South’, ‘map to’, 46)
(‘Galela’, ‘map to’, 47)
(‘Gamo’, ‘map to’, 48)
(‘Garhwali’, ‘map to’, 49)
(‘Gidar’, ‘map to’, 50)
(‘Guahibo’, ‘map to’, 51)
(‘Guayabero’, ‘map to’, 52)
(‘Hadiyya’, ‘map to’, 53)
(‘Hiligaynon’, ‘map to’, 54)
(‘Hindi’, ‘map to’, 55)
(‘Hmong Daw’, ‘map to’, 56)
(‘Huambisa’, ‘map to’, 57)
(‘Huave de San Mateo del Mar’, ‘map to’, 58)
(‘Huli’, ‘map to’, 59)
(‘Ignaciano’, ‘map to’, 60)
(‘Ilokano’, ‘map to’, 61)
(‘Ipili’, ‘map to’, 62)
(‘Ixil Nebaj’, ‘map to’, 63)
(‘Javanese’, ‘map to’, 64)
(‘Jingpho’, ‘map to’, 65)
(‘Jola Kasa’, ‘map to’, 66)
(‘Jur Modo’, ‘map to’, 67)
(‘Kalabari’, ‘map to’, 68)
(‘KalmykOirat’, ‘map to’, 69)
(‘Kannada’, ‘map to’, 70)
(‘Karakalpak’, ‘map to’, 71)
(‘Karamojong’, ‘map to’, 72)
(‘Kashinawa’, ‘map to’, 73)
(‘Kazakh’, ‘map to’, 74)
(‘Kera’, ‘map to’, 75)
(‘Khasi’, ‘map to’, 76)
(‘Khmer Northern’, ‘map to’, 77)
(‘Kiche Cunen’, ‘map to’, 78)
(‘Kilivila Kiriwina’, ‘map to’, 79)
(‘Kok Borok’, ‘map to’, 80)
(‘Kolami Northwestern’, ‘map to’, 81)
(‘Konso’, ‘map to’, 82)
(‘Koorete’, ‘map to’, 83)
(‘Korean North’, ‘map to’, 84)
(‘Korean South’, ‘map to’, 85)
(‘Kui’, ‘map to’, 86)
(‘Kuman’, ‘map to’, 87)
(‘Kumyk’, ‘map to’, 88)
(‘Kyrgyz’, ‘map to’, 89)
(‘Lampung Api’, ‘map to’, 90)
(‘Lao’, ‘map to’, 91)
(‘Lobi’, ‘map to’, 92)
(‘Luwo’, ‘map to’, 93)
(‘Madi’, ‘map to’, 94)
(‘Maka’, ‘map to’, 95)
(‘Malagasy Plateau’, ‘map to’, 96)
(‘Malay’, ‘map to’, 97)
(‘Marba_Azumeina’, ‘map to’, 98)
(‘Maya Mopan’, ‘map to’, 99)
(‘Mazahua Central’, ‘map to’, 100)
(‘Mentawai’, ‘map to’, 101)
(‘Mixtec Ayutla’, ‘map to’, 102)
(‘MofuGudur’, ‘map to’, 103)
(‘Mongolian Halh’, ‘map to’, 104)
(‘Mongondow’, ‘map to’, 105)
(‘Morisyen’, ‘map to’, 106)
(‘Moro’, ‘map to’, 107)
(‘Mundari’, ‘map to’, 108)
(‘Munukutuba’, ‘map to’, 109)
(‘Murle’, ‘map to’, 110)
(‘Musgu’, ‘map to’, 111)
(‘Naga Ao’, ‘map to’, 112)
(‘Nahuatl Guerrero’, ‘map to’, 113)
(‘Nahuatl Highland Puebla’, ‘map to’, 114)
(‘Nahuatl Northern Puebla’, ‘map to’, 115)
(‘Napu’, ‘map to’, 116)
(‘Nigerian Pidgin’, ‘map to’, 117)
(‘Ojibwa Northwestern’, ‘map to’, 118)
(‘Oromo Eastern’, ‘map to’, 119)
(‘Otomi Mezquital’, ‘map to’, 120)
(‘Paez’, ‘map to’, 121)
(‘Palauan’, ‘map to’, 122)
(‘Palaung Ruching’, ‘map to’, 123)
(‘Pamona_Bahasa Taa’, ‘map to’, 124)
(‘Pampangan’, ‘map to’, 125)
(‘Parecis’, ‘map to’, 126)
(‘Patamona’, ‘map to’, 127)
(‘Paumari’, ‘map to’, 128)
(‘Peve’, ‘map to’, 129)
(‘Pijin’, ‘map to’, 130)
(‘Pokoot’, ‘map to’, 131)
(‘Polish’, ‘map to’, 132)
(‘Qeqchi’, ‘map to’, 133)
(‘Quechua Eastern’, ‘map to’, 134)
(‘Quechua MargosYarowilcaLauricocha’, ‘map to’, 135)
(‘Quechua North Junin’, ‘map to’, 136)
(‘Quechua Southern Conchucos Ancash’, ‘map to’, 137)
(‘Quechua Southern Pastaza’, ‘map to’, 138)
(‘Romani Sinti’, ‘map to’, 139)
(‘Romanian’, ‘map to’, 140)
(‘Samoan’, ‘map to’, 141)
(‘Sango’, ‘map to’, 142)
(‘Sanuma’, ‘map to’, 143)
(‘Sasak’, ‘map to’, 144)
(‘Sauria Paharia’, ‘map to’, 145)
(‘Sebat Bet Gurage_Gurage Chaha’, ‘map to’, 146)
(‘Shilluk’, ‘map to’, 147)
(‘ShipiboConibo’, ‘map to’, 148)
(‘Shuar’, ‘map to’, 149)
(‘Tamasheq’, ‘map to’, 150)
(‘Tektiteko’, ‘map to’, 151)
(‘Tepehua Pisaflores’, ‘map to’, 152)
(‘Tepehua Tlachichilco’, ‘map to’, 153)
(‘Terena’, ‘map to’, 154)
(‘Teribe’, ‘map to’, 155)
(‘Teso’, ‘map to’, 156)
(‘Thai’, ‘map to’, 157)
(‘Themne’, ‘map to’, 158)
(‘Ticuna’, ‘map to’, 159)
(‘Tobelo’, ‘map to’, 160)
(‘Tol’, ‘map to’, 161)
(‘Totonac Highland’, ‘map to’, 162)
(‘Trio’, ‘map to’, 163)
(‘Tucano’, ‘map to’, 164)
(‘Tuva’, ‘map to’, 165)
(‘Tzeltal Bachajon’, ‘map to’, 166)
(‘Vai’, ‘map to’, 167)
(‘Vietnamese’, ‘map to’, 168)
(‘Waimaha’, ‘map to’, 169)
(‘Waiwai’, ‘map to’, 170)
(‘Wichi Lhamtes Nocten Weenhayek’, ‘map to’, 171)
(‘Yali Angguruk’, ‘map to’, 172)
(‘Yawa’, ‘map to’, 173)
(‘Zapotec Isthmus’, ‘map to’, 174)
(‘Zapotec Sierra de Juarez’, ‘map to’, 175)
2.项目实现概述
口语识别项目的整体思想是把语音数据转化为相应的语谱图,利用卷积神经网络最终实现语种识别。如图所示,输入是语谱图,经过深度卷积神经网络训练之后,输出语种类别。
2.1音频数据转化为语谱图
项目采用python脚本,利用mpg123库把音频数据转化为wav格式,再画出相应的语谱图。音频数据生成语谱图时,用到了短时傅里叶变换,短时傅里叶变换就是先把一个函数和窗函数进行相乘,然后再进行一维的傅里叶变换。并通过窗函数的滑动得到一系列的频谱函数,将这些结果依次展开便得到一个二维的时频图。语谱图(如图2-1所示)是一个二维的时频图,横轴是频率(长),纵轴是时间(宽),导致不一样长度的频谱图是因为其原音频频率不一样,同样时间内得到的频谱采样值也就不一样多,导致语谱图长度不一样。
项目中有两个规格的语谱图,分别是256858和256768。256*768的语谱图是因为笔对音频数据的频道进行随机干扰截取9秒的长度,使得每个音频生成20张语谱图以达到扩充数据集,提高识别精度的目地。
2.2语谱图的语种识别
深度卷积神经网络针对语谱图数据进行特征提取,识别出相应语种。其卷积网络是根据AlexNet进行设计的,共有6个卷积层,2个全连接层,经过试验,采用30%的dropout技巧,最后一层有176个输出。应该注意的是,卷积神经网络的实现,并没有顾及到音频数据的时序特征。 针对项目中所设计的CNN进行训练,并测试其语种识别结果,其结果是写在一个预测的CSV表单中,采用TOP3预测,预测出最大概率的前三个语种作为音频的可能语种。 若是未标记过的音频进行预测,其显示结果如下: 例: slgrn4peqev.mp3,Korean South,1 slgrn4peqev.mp3,Morisyen,2 slgrn4peqev.mp3,Kyrgyz,3 表示slgrn4peqev.mp3音频最大概率的语种是Korean South,第二大概率可能语种是Morisyen,第三大可能语种是Kyrgyz。 若是利用已标记过语种音频进行预测,并分析其是否预测正确,其显示结果如下: 例: slgrn4peqev.mp3,Korean South,1 slgrn4peqev.mp3,Morisyen,2 slgrn4peqev.mp3,Kyrgyz,3 预测结果与真实标记值比较,如果TOP前3中有一个预测到真实标记值,我们就算预测正确。预测的示例与trainingData.csv真实标记值比较,(50813, ‘slgrn4peqev.mp3,Korean South’)可知预测正确。 项目中采用相应分值体现预测的正确性,如果top1预测到真实值标记1000分,如果top2预测到真实值标记400分,如果top3预测到真实值标记160分,否则标记0分。例: processed 60 images Final score: 58400 / 60 000 示例处理了60张图片,若都是top1预测出真实值,应得60 000分,最终得分58400说明,其中有少量数据不是top1预测出来的,或是没有预测到真实值。
3.口语识别项目的详细实现
数据文件夹trainingdata和testingdata是竞赛官方给的MP3数据,以及带有trainingData.csv和testingData.csv表单。语谱图转化程序实现MP3音频数据转化为256858和256768两种规格的语谱图,分别为数据未扩充和数据扩充后的语谱图,项目中针对两种语谱图设计了两种CNN的解决方案。
3.1 语谱图转化程序实现
3.1.1 划分训练集和验证集
1.有标签标记的MP3音频源数据文件夹:trainingdata,相应数据清单为:trainingData.csv。 2.无标签标记的MP3音频源数据文件夹:testingdata,相应数据清单为:testingData.csv。
执行命令:python choose_equal_split.py
结果将trainingData.csv分离,生成trainEqual.csv和valEqaul.csv
3.1.2 MP3转化为语谱图
1.配置环境:安装anaconda(python集成环境),在~/.bashrc文件中利用别名命名为:python-anaconda。 2.安装mpg123,程序中运行mpg123 -w 是将MP3文件打包成wav文件。 3.项目中augment_data.py和create_spectrograms.py脚本都是实现语谱图转化的程序。前者是对声道长度(a=1)进行了干扰,对音频随机截取9s的长度,进行数据扩充,每个音频生成20张随机截取的256768规格的语谱图。后者未对数据扩充,每个音频生成一张256858规格的语谱图。因数据量过万,生成时间需要40多个小时,所以另写程序,加入多进程处理,缩短程序执行时间。
执行命令: python-anaconda Process_augment_data.py
结果实现10个进程执行将trainingdata文件夹中53856个MP3文件转化为1077120(53856*20)个语谱图存储在pngaugm2文件夹中。
执行命令:python-anaconda Process_augment_data_val.py
结果实现将trainingdata文件夹中12320个MP3文件转化为226400(12320*20)个语谱图存储在pngaugm_val文件夹中。
执行命令:python-anaconda Process_png_data.py
结果实现将trainingdata文件夹中53856个MP3文件转化为53856个语谱图存储在png文件夹中。
执行命令:python-anaconda Process_png_data_val.py
结果实现将trainingdata文件夹中12320个MP3文件转化为11320个语谱图存储在png_val文件夹中。
注:转化语谱图时,可能有少量几张语谱图没有生成。有四个语谱图文件夹,pngaugm2和pngaugm_val用于数据扩充后的训练集和验证集,另外两个用于未扩充的训练集和验证集。
3.2 基于caffe的CNN网络训练程序实现
3.2.1 caffe环境配置
1.下载caffe源码包,解压在文件夹中,因转化leveldb数据需要用到caffe-master/build/tools/convert_imageset程序,训练网络的时候需要用到caffe-master/build/tools/caffe 程序,所以需要下载源码包。 2.Python脚本中如果需要导入caffe模块:
执行命令:source env.sh ,再执行python程序即可。
3.2.2 生成语谱图数据txt清单
执行命令:python get_pnglist.py
结果生成trainEqual_lmdb3.txt清单文件,同样执行get_pnglist_val.py程序生成valEqual_lmdb1.txt清单文件。这是数据扩充后语谱图清单文件,未扩充的语谱图清单文件,在程序中修改路径,就可生成trainEqual_leveldb_gray.txt和valEqual_leveldb_gray.txt清单文件。
3.2.3 生成leveldb数据库
将语谱图数据转化为caffe所支持的leveldb数据库:
执行命令:sh create_train_leveldb.sh
结果将pngaugm2中语谱图转化为leveldb数据库存储在文件夹img_train_leveldb_gray1中。
执行命令:sh create_val_leveldb.sh
结果将pngaugm_val中语谱图转化为leveldb数据库存储在文件夹img_val_leveldb_gray1中。
执行命令:sh create_png_train_leveldb.sh
结果将png中语谱图转化为leveldb数据库存储在文件夹img_png_train_leveldb_gray中。
执行命令:sh create_png_val_leveldb.sh
结果将png_val中语谱图转化为leveldb数据库存储在文件夹img_png_val _leveldb_gray中。
注:有四个leveldb文件夹,两个用于数据扩充后训练集和验证集,另外两个用于未扩充数据训练集和验证集。
3.2.4 caffe训练网络
所有训练测试的solver以及prototxt网络结构都存储在prototxt文件夹中,训练记录的日志存储在log文件夹中。
执行命令:sh train.sh
调用prototxt文件夹中针对扩充后数据设计的网络进行训练。
解决方案:solver.augm.nolrcoef.prototxt。
网络结构:augm_32r-2-64r-2-64r-2-128r-2-128r-2-256r-2-1024rd0.3-
1024rd0.3.prototxt。
训练数据:img_train_leveldb_gray1。
验证数据:img_val_leveldb_gray1。
训练时修改网络结构中TRAIN:batch_size:23—>5;
TEST:batch_size:24—>5,不然会出现显卡不够用的情况。
训练的学习率为0.001,如果采用0.01网络学不到东西,loss不下降。学
习率策略采用fixed模式。inv 这种学习策略的优势就在于它使得学习率在每一次迭代时都减小,但每次减小又都是一个非常小的数,这样就省去的自己手动调节的麻烦,solver中最后训练fixed模式和inv模式结果差不多。
训练的模型存储在models6中。
训练的日志存储在log文件夹augm_dropout0.3_on_augm84K-lr0.01_30K
_90K_gray.txt中,画出相应的loss曲线和accuracy曲线也存储在log中。
执行命令: python plot_loss.py ./log/augm_dropout0.3_on_augm84K-lr0.01
_30K_90K_gray.txt
画出的loss曲线图如图3-1所示,蓝色为训练误差loss曲线,红色为验证精度accuracy曲线,训练结果test_acurracy =0.922421, test_loss=0.28642。
执行命令:sh train_main.sh
调用prototxt文件夹中针对未扩充数据设计的网络进行训练。
解决方案:solver.main.adadelta.prototxt。 网络结构:main_32r-2-64r-2-64r-2-128r-2-128r-2-256r-2-1024rd0.5 -1024rd0.5_DLR.prototxt。 训练数据:img_png_train_leveldb_gray。 验证数据:img_png_val_leveldb_gray。 训练时修改网络结构中TRAIN:batch_size:23—>5、 TEST:batch_size:24—>5,不然会出现显卡不够用的情况。 训练的学习率为0.001。学习率策略采用fixed模式。训练的模型存储在 models_png_before_real中。 训练过程未记录在日志文件中,训练结果:test_acurracy=0.915,test_loss= 0.317812。注:针对扩充数据集和未扩充两类不同的数据集,训练了两种模型,分别存储在models6和models_png_before_real中。
3.3 CNN预测音频语言种类程序实现
选用未扩充数据集进行预测,也就是models_png_before_real中模型进行预测。选用的预测网络结构为prototxt中deploy.main_32r-2-64r-2-64r-2-128r-2-128r -2-256r-2-1024rd0.5-1024rd0.5_DLR.prototxt。预测的结果存储在prediction文件夹中。
执行命令:source /raid/zyj/env.sh
执行命令:python test_main_network.py val
使用验证集png_val中的20张图片预测进行测试,程序中修改cnt=20,预测的结果存储在predictions/ validation_main_32r-2-64r-2-64r-2-128r-2-128 r-2-256r-2-1024rd0.5-1024rd0.5_DLR_adadelta0.01_iter_800000.csv表单中。
csv中记录如下所示:
slgrn4peqev.mp3,Korean South,1
slgrn4peqev.mp3,Morisyen,2
slgrn4peqev.mp3,Kyrgyz,3
sodsik5enku.mp3,Lobi,1
sodsik5enku.mp3,Dangaleat,2
sodsik5enku.mp3,Bekwarra,3
与trainingData.csv真实标记值比较,(50813, ‘slgrn4peqev.mp3, Korean South’)可知预测正确。
共处理了20张图片,top1就预测正确20张。
processed 0 / 20 images
score: 1000
Final score: 20000 / 20 0004.错误集锦
4.1 语谱图生成程序出错
运行语谱图生成程序augment_data.py时:
1.遇到错误:TypeError: ‘numpy.float64’ object cannot be interpreted as an integer
解决方法:这个问题本质是数据类型的不匹配
查看numpy版本:python -c “import numpy; print numpy.version.version”
版本为numpy1.14.0
pip install -U numpy==1.11.0 降级numpy1.11.0
这可能是python中numpy的版本问题,所以将numpy降级
2.遇到错误:File “/usr/local/lib/python2.7/lib-tk/Tkinter.py”, line 39, in
import _tkinter # If this fails your Python may not be configured for Tk
ImportError: No module named _tkinter
解决方法:因为服务器是无界面的环境,而这个模块是对于界面操作进行画图的模块,
所以判断与python环境安装有关,另行安装一个python环境与原系统中python环境并
存。
a.安装anaconda(python环境集成安装包,版本为python2.7版本),先下载安装包,
存储在raid文件夹下。
cd /raid
bash Anaconda2-5.1.0-Linux-x86_64.sh
b.配置环境变量
echo ‘export PATH="~/anaconda2/bin: PATH"’>>/.bashrc
c.还要配置别名:vim ~/.bashrc
~/.bashrc的文件中,export PATH=“/root/anaconda2/bin:$PATH"
alias pythnotallow="/usr/local/bin/python"
alias python-anacnotallow=“/root/anaconda2/bin/python"
如果想取消别名声明,用unalias python或者删除~/.bashrc中的PATH,并且重新source ~/.bashrc
3.遇到问题:augment_data.py处理文件时3个小时大概处理了4000个MP3文件,60000多个文件初步估计需要40多个小时生成,以防程序中途出错,所以另编程序Process_augment_data.py实现多个进程同时处理文件。4.2 caffe训练网络出错
训练caffe网络时:
1.出现问题:Check failed: error == cudaSuccess (11 vs. 0) invalid argument
解决方法:查找原因 invaild function,应该是超出支持能力。invaild argument,就是明显的爆显卡了。可能是训练的数据太多,一下装载不了那么多训练数据。
修改训练网络结构:
augm_32r-2-64r-2-64r-2-128r-2-128r-2-256r-2-1024rd0.3-1024rd0.3.prototxt中
TRAIN:batch_size:23—>5
TEST:batch_size:24—>5
4.3 caffe预测语种程序出错
1.出现问题:Cannot copy param 0 weights from layer ‘conv1’; shape mismatch. Source param shape is 32 3 7 7 (4704); target param shape is 32 1 7 7 (1568). To learn this layer’s parameters from scratch rather than copying from a saved net, rename the layer. 这个问题出现的原因是因为音频生成语谱图存储的时候存成灰度图了image = image.convert(‘L’),但是利用convert_imageset转换为leveldb的时候没有设置–gray=true,导致训练的图片是3通道的,所以预测的时候,预测网络的输入设置为1,1,256,768,,是单通道的灰度图,所以出现conv1权重参数不匹配。 解决方法:在create_train_leveldb.sh程序中设置–gray=true,这是刚开始训练的时候出现的错误,在后续的实现中,已修改了这个错误,后续复现可以忽略此步。