当前位置: 首页 > 科技观察

使用Python和Keras创建一个简单的语音识别引擎_0

时间:2023-03-17 16:30:23 科技观察

语音识别是机器或程序识别口语中的单词和短语并将其转换为机器可读格式的能力。通常,这些算法的简单实现具有有限的词汇量,并且它可能只能识别单词/短语。但是,更复杂的算法(例如CloudSpeech-to-Text和AmazonTranscribe)具有广泛的词汇表,并包含方言、噪音和俚语。在这篇文章中,我演示了:语音转文本的工作原理如何处理要转录的音频使用Keras解决问题的深度学习模型评估此模型的方法编写脚本以将预测模型集成到您的项目中介绍语音只是由我们的一系列声音制作由声带引起周围空气振动而产生的波。这些声波被麦克风记录下来并转换成电信号。然后使用高级信号处理技术处理信号以分离音节和单词。由于深度学习取得了令人难以置信的新进展,计算机还可以从经验中学习理解语音。语音识别通过声学和语言建模使用算法进行工作。声学建模表示语音和音频信号的语言单元之间的关系;语言建模将声音与单词序列进行匹配,以帮助区分发音相似的单词。通常,基于循环层的深度学习模型用于识别语音中的时间模式,以提高系统内的准确性。也可以使用其他方法,例如隐马尔可夫模型(第一个语音识别算法使用这种方法)。在本文中,我将只讨论声学模型。信号处理有几种方法可以将音频波转换成算法可以处理的元素,其中一种(也是我们将在本教程中使用的一种)是在等距点记录声波的高度:我们每秒读取数千个次数,并记录一个代表当时声波高度的数字。这是一个未压缩的.wav音频文件。“CD质量”音频以44.1kHz(每秒44,100次读数)采样。但对于语音识别,16khz(每秒16,000个样本)的采样率足以覆盖人类语音的频率范围。在这种方法中,音频由数字向量表示,其中每个数字代表以1/16000秒为间隔的声波振幅。这个过程类似于图像预处理,如下例所示:得益于奈奎斯特定理(1933——VladimirKotelnikov),我们知道只要采样率至少是我们想要的最高记录频率的两倍,我们可以使用数学方法从间隔样本中完美地重建原始声波。Python库对于此任务,我使用Anaconda环境(Python3.7)和以下Python库:ipython(v7.10.2)keras(v2.2.4)librosa(v0.7.2)scipy(v1.1.0)sklearn(v0.20.1)sounddevice(v0.3.14)tensorflow(v1.13.1)tensorflow-gpu(v1.13.1)numpy(v1.17.2)fromtensorflow.compat.v1importConfigProtofromtensorflow.compat.v1importSessionimportosimportlibrosaimportIPython.displayasipdimportnummatplotlib.pyplotasnpltioimportwavfileimportwarningsconfig=ConfigProto()config.gpu_options.allow_growth=Truesess=Session(config=config)warnings.filterwarnings("ignore")1.数据集我们在实验中使用TensorFlow提供的语音命令数据集。它包括65,000个一秒长的话语,由数以万计的不同人说出的30个短词组成。我们将构建一个可以理解简单语音命令的语音识别系统。您可以从此处下载数据集(https://www.kaggle.com/c/tensorflow-speech-recognition-challenge)。2.PreprocessingAudioWaves在使用的??数据集中,一些记录的持续时间小于1秒,采样率过高。那么让我们读取声波并使用以下预处理步骤来解决这个问题。以下是我们将执行的两个步骤:重采样删除少于1秒的短命令让我们在以下Python片段中定义这些预处理步骤:train_audio_path='./train/audio/'all_wave=[]all_label=[]forlabelinlabels:print(label)waves=[ffforfinos.listdir(train_audio_path+'/'+label)iff.endswith('.wav')]forwavinwaves:samples,sample_rate=librosa.load(train_audio_path+'/'+label+'/'+wav,sr=16000)samples=librosa.resample(samples,sample_rate,8000)if(len(samples)==8000):all_wave.append(samples)all_label.append(label)从上面可以看出信号的采样率为16000赫兹。我们将其重新采样到8000Hz,因为大多数与语音相关的频率都在8000Hz。第二步是处理我们的标签,这里我们将输出标签转换为整数编码,将整数编码标签转换为单热向量,因为这是一个多目标问题:.fit_transform(all_label)classes=list(label_enconder.classes_)y=np_utils.to_categorical(y,num_classes=len(labels))预处理步骤的最后一步是将2D数组reshape为3D,因为conv1d的输入必须是一个3D数组:all_wave=np.array(all_wave).reshape(-1,8000,1)3.创建训练集和验证集为了执行我们的深度学习模型,我们需要生成两组(训练集和验证集)).对于这个实验,我使用了80%的数据来训练模型,并在剩下的20%的数据上进行了验证:fromsklearn.model_selectionimporttrain_test_splitx_train,x_valid,y_train,y_valid=train_test_split(np.array(all_wave),np.array(y),stratify=y,test_size=0.2,random_state=777,shuffle=True)4.机器学习模型架构我使用Conv1d和GRU层对网络建模以进行语音识别。Conv1d是一种卷积神经网络,只在一个维度上进行卷积,而GRU旨在解决标准递归神经网络的梯度消失问题。GRU也可以看作是LSTM的变体,因为两者在设计上相似,并且在某些情况下可以产生同样好的结果。该模型基于两种著名的语音识别方法,deepspeechh2和Wav2letter++算法。下面的代码演示了使用Keras提出的模型:fromkeras.layersimportBidirectional,BatchNormalization,CuDNNGRU,TimeDistributedfromkeras.layersimportDense,Dropout,Flatten,Conv1D,Input,MaxPooling1Dfromkeras.modelsimportModelfromkeras.callbacksimportEarlyStopping,ModelCheckpointfromkerasimportbackendasKK.clear_session()inputs=Input(shape=(8000,1))x=BatchNormalization(axis=-1,momentum=0.99,epsilon=1e-3,center=True,scale=True)(inputs)#FirstConv1Dlayerx=Conv1D(8,13,padding='valid',activation='relu',strides=1)(x)x=MaxPooling1D(3)(x)x=Dropout(0.3)(x)#SecondConv1Dlayerx=Conv1D(16,11,padding='valid',activation='relu',strides=1)(x)x=MaxPooling1D(3)(x)x=Dropout(0.3)(x)#ThirdConv1Dlayerx=Conv1D(32,9,padding='valid',activation='relu',strides=1)(x)x=MaxPooling1D(3)(x)x=Dropout(0.3)(x)x=BatchNormalization(axis=-1,momentum=0.99,epsilon=1e-3,center=True,scale=True)(x)x=双向(CuDNNGRU(128,return_sequences=True),merge_mode='sum')(x)x=双向(CuDNNGRU(128,return_sequences=True),merge_mode='sum')(x)x=Bidirectional(CuDNNGRU(128,return_sequences=False),merge_mode='sum')(x)x=BatchNormalization(axis=-1,momentum=0.99,epsilon=1e-3,center=True,scale=True)(x)#Flattenlayer#x=Flatten()(x)#DenseLayer1x=Dense(256,activation='relu')(x)outputs=Dense(len(labels),activation="softmax")(x)model=Model(inputs,outputs)model.summary()注意:如果你只用CPU训练这个模型,请把CuDNNGRU层换成GRU下一步是将损失函数定义为分类交叉熵,因为它是一个多类分类问题:model.compile(loss='categorical_crossentropy',optimizer='nadam',metrics=['accuracy'])checking的重点是在适当的时候停止训练神经网络并在每个epoch之后保存最好的模型的回调:early_stop=EarlyStopping(monitor='val_loss',mode='min',verbose=1,patience=10,min_delta=0.0001)checkpoint=ModelCheckpoint('speech2text_model.hdf5',monitor='val_acc',verbose=1,save_best_only=True,mode='max')让我们在32的批量大小上训练机器学习模型并评估保留setPerformance:hist=model.fit(x=x_train,y=y_train,epochs=100,callbacks=[early_stop,checkpoint],batch_size=32,validation_data=(x_valid,y_valid))这个命令的输出是:5。可视化我将依靠可视化来了解机器学习模型随时间的性能:frommatplotlibimportpyplotpyplot.plot(hist.history['loss'],label='train')pyplot.plot(hist.history['val_loss'],label='test')pyplot.legend()pyplot.show()6.预测在此步骤中,我们将加载最佳权重并定义识别音频并将其转换为文本的函数:fromkeras.modelsimportload_modelmodel=load_model('speech2text_model.hdf5')defs2t_predict(audio,shape_num=8000):prob=model.predict(audio.reshape(1,shape_num,1))index=np.argmax(prob[0])returnclasses[index]预测验证数据:importrandomindex=random.randint(0,len(x_valid)-1)samples=x_valid[index].ravel()print("Audio:",classes[np.argmax(y_valid[index])])ipd.Audio(samples,rate=8000)这是一个提示用户录制语音命令的脚本。您可以录制自己的语音命令并在机器学习模型上对其进行测试:importsounddeviceassdimportsoundfileassfsamplerate=16000duration=1#secondsfilename='yes.wav'print("start")mydata=sd.rec(int(samplerate*duration),samplerate=samplerate,channels=1,blocking=True)print("end")sd.wait()sf.write(filename,mydata,samplerate)最后,我们创建一个脚本来读取保存的语音命令并将它们转换为文本:#读取语音命令test,test_rate=librosa.load('./test/left.wav',sr=16000)test_sample=librosa.resample(test,test_rate,4351)print(test_sample.shape)ipd.Audio(test_sample,rate=8000)#convertingvoicecommandstotexts2t_predict(test_sample)最后,语音识别技术已经成为我们日常生活的一部分,但它仍然局限于相对简单的命令。随着技术的进步,研究人员将能够创造出更智能的系统来理解对话。