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

音频处理有问题?使用Tensorflow构建语音识别模型

时间:2023-03-20 17:43:46 科技观察

【.com快速翻译】在本文中,我们将通过一个使用Tensorflow对一些声音片段进行分类的示例来帮助您了解足够的基础知识,以便能够构建您自己的语音识别模型。或者,您可以通过进一步研究将这些概念应用于更大、更复杂的音频文件。GitHub上提供了此示例的完整代码。获取数据数据收集是数据科学中的难题之一。虽然有大量可用数据,但并非所有数据都可用于机器学习问题。因此,必须确保数据是干净的、标记的和完整的。对于这个例子,我们将使用谷歌发布的一些音频文件,这些文件可以在Github上找到。首先,我们将创建一个新的Conducto管道。在这里您可以构建、训练和测试您的模型,并与其他感兴趣的人分享链接:####MainPipeline###defmain()->co.Serial:path="/conducto/data/pipeline"root=co.Serial(image=get_image())#从keras获取数据进行测试和训练root["GetData"]=co.Exec(run_whole_thing,f"{path}/raw")returnroot然后开始写run_whole_thing函数:defrun_whole_thing(out_dir):os.makedirs(out_dir,exist_ok=True)#设置实验重现性种子=55tf.random.set_seed(seed)np.random.seed(seed)data_dir=pathlib.Path("data/mini_speech_commands")接下来,设置保存音频文件的目录:ifnotdata_dir.exists():#从外部源获取文件并将它们放在可访问的目录中tf.keras.utils.get_file('mini_speech_commands.zip',origin="http://storage.googleapis.com/download.tensorflow.org/data/mini_speech_commands.zip",extract=True)预处理数据现在将数据保存在正确的目录中并且可以拆分为训练、测试和验证数据集。首先,我们需要编写一些函数来帮助预处理数据,以便它可以在我们的模型中工作。我们需要一种算法可以理解的数据格式。我们将使用卷积神经网络,因此需要将数据转换为图像。第一个函数将二进制音频文件转换为张量:#将二进制音频文件转换为张量decode_audio(audio_binary):audio,_=tf.audio.decode_wav(audio_binary)returntf.squeeze(audio,axis=-1)因为我们有一个带有原始数据的张量,所以我们需要得到与它们匹配的标签。这是以下函数通过从文件路径获取音频文件的标签所做的事情:#获取音频文件的标签(是、否、向上、向下等)。strings.split(file_path,os.path.sep)returnparts[-2]接下来,我们需要将音频文件与正确的标签相关联。执行此操作并返回可与Tensorflow一起使用的元组:#创建一个具有标记音频文件的元组defget_waveform_and_label(file_path):label=get_label(file_path)audio_binary=tf.io.read_file(file_path)waveform=decode_audio(audio_binary)returnwaveform,label前面我们简单提到了卷积神经网络(CNN)算法的使用。这是我们处理语音识别模型的方法之一。通常CNN可以很好地处理图像数据并有助于减少预处理时间。我们将利用这一点并将音频文件转换为频谱图。频谱图是频谱的图像。如果您查看音频文件,您会发现它只是频率数据。因此,我们要编写一个将音频数据转换为图像的函数:#Convertaudiofilestoimagesdefget_spectrogram(waveform):#Paddingforfileswithlessthan16000sampleszero_padding=tf.zeros([16000]-tf.shape(waveform),dtype=tf.float32)#用padding连接音频,使所有音频片段的长度相同waveform=tf.cast(waveform,tf.float32)equal_length=tf.concat([waveform,zero_padding],0)spectrogram=tf.signal.stft(equal_length,frame_length=255,frame_step=128)spectrogram=tf.abs(spectrogram)returnspectrogram现在我们已经将数据格式化为图像,我们需要将正确的标签应用于这些图像。这类似于我们处理原始音频文件的方式:#标记从音频文件创建的图像并返回一个tupledefget_spectrogram_and_label_id(audio,label):spectrogram=get_spectrogram(audio)spectrogram=tf.expand_dims(spectrogram,-1)label_id=tf.argmax(label==commands)returnspectrogram,label_id我们需要的最后一个辅助函数将为传递给它的任何一组音频文件处理上述所有操作:#预处理任何音频文件defpreprocess_dataset(files,autotune,commands):#创建数据集files_ds=tf.data.Dataset.from_tensor_slices(files)#将音频文件与正确的标签匹配output_ds=files_ds.map(get_waveform_and_label,num_parallel_calls=autotune)#将音频文件图像与正确的标签匹配num_parallel_calls=autotune)returnoutput_ds现在我们有了所有这些辅助函数,我们可以拆分数据了。将数据拆分为数据集并将音频文件转换为图像有助于使用CNN更轻松地处理数据,这就是我们编写所有这些辅助函数的原因。我们将做一些事情来简化数据拆分。首先,我们将获得所有音频文件的潜在命令列表,我们将在代码的其他地方使用它:#获取音频文件的所有命令commands=np.array(tf.io.gfile.listdir(str(data_dir)))commandscommandscommands=commands[commands!='README.md']然后我们会得到数据目录下所有文件的列表,并将其打乱,为每个想要的数据集分配随机值:#获取列表oftheallthefilesinthedirectoryfilenames=tf.io.gfile.glob(str(data_dir)+'/*/*')#打乱文件名,以便随机束可以用作训练、测试和验证集filenames=tf.random.shuffle(filenames)#创建用于训练的文件列表datatrain_files=filenames[:6400]#创建用于验证的文件列表datavalidation_files=filenames[6400:6400+800]#创建文件列表用于testdatatest_files=filenames[-800:]既然我们已经清楚地分离了训练、验证和测试文件,我们就可以继续对这些文件进行预处理以生成ma让他们准备好构建和测试模型。这里autotune用于在运行时动态调整参数的值:autotune=tf.data.AUTOTUNE第一个例子只是为了展示预处理是如何工作的,它给出了一些我们需要的spectrogram_ds值:#获取转换后的用于训练模型的音频文件步骤继续使用辅助函数处理所有数据集:#预处理训练、测试和验证数据集strain_ds=preprocess_dataset(train_files,autotune,commands)validation_ds=preprocess_dataset(validation_files,autotune,commands)test_ds=preprocess_dataset(test_files,autotune)us到设置一些在每个时期的迭代中运行的训练示例,因此我们将设置批量大小:#Batchdatasetsfortrainingandvalidationbatch_size=64train_dstrain_dstrain_ds=train_ds.batch(batch_size)validation_dsvalidation_dsvalidation_ds=validation_ds.batch(batch_size)最后,我们可以利用缓存来减少训练模型时的延迟:#Reducelatencywhiletrainingtrain_dstrain_dstrain_ds=train_ds.cache().prefetch(autotune)validation_dsvalidation_dsvalidation_ds=validation_ds.cache().prefetch(autotune)最后,我们的数据集是我们可以训练模型的形式构建模型由于数据集定义明确,我们可以继续构建模型。我们将使用CNN来创建模型,因此我们需要获取数据的形状以获得层的正确形状,然后我们继续按顺序构建模型:#Buildmodelforspectrogram,_inspectrogram_ds.take(1):input_shape=spectrogram.shapenum_labels=len(commands)norm_layer=preprocessing.Normalization()norm_layer.adapt(spectrogram_ds.map(lambdax,_:x))model=models.Sequential([layers.Input(shape=input_shape),preprocessing.Resizing(32,32),norm_layer,layers.Conv2D(32,3,activation='relu'),layers.Conv2D(64,3,activation='relu'),layers.MaxPooling2D(),layers.Dropout(0.25),layers.Flatten(),layers.Dense(128,activation='relu'),layers.Dropout(0.5),layers.Dense(num_labels),])model.summary()我们对模型进行了一些配置,以便为我们提供最佳精度:#使用损失和指标配置构建模型model.compile(optimizer=tf.keras.optimizers.Adam(),loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),metrics=['准确度'],)模型已经建立,现在剩下的就是训练它了。训练模型在完成预处理数据和构建模型的所有工作后,训练就相对简单了。我们确定使用训练和验证数据集运行多少个epoch:#最后训练模型并返回有关每个epochEPOCHS=10model.fit(train_ds,validation_data=validation_ds,epochs=EPOCHS,callbacks=tf.keras.callbacks.EarlyStopping(verbose=1,patience=2),)这样模型已经训练好了,现在需要进行测试。测试模型现在我们有了一个大约83%准确率的模型,是时候测试它在新数据上的表现了。所以我们使用测试数据集并将音频文件与标签分开:#测试模型())test_audio=np.array(test_audio)test_labels=np.array(test_labels)然后我们获取音频数据并在我们的模型中使用它来查看它是否预测了正确的标签:#查看模型在进行预测时的准确性在测试数据集上ty_pred=np.argmax(model.predict(test_audio),axis=1)y_true=test_labelstest_acc=sum(y_pred==y_true)/len(y_true)print(f'Testsetaccuracy:{test_acc:.0%}')完成管道只需编写一小段代码即可完成您的管道并使其可与任何人共享。这定义了将在Conducto管道中使用的图像,并处理文件执行:####PipelineHelperfunctions###defget_image():returnco.Image("python:3.8-slim",copy_dir=".",reqs_py=["conducto","tensorflow","keras"],)if__name__=="__main__":co.main(default=main)现在,您可以在终端中运行pythonpipeline.py-它应该将开始链接到新的Conducto管道。结论这是音频处理问题的解决方案之一,但根据要分析的数据,它可能要复杂得多。如果将其构建到管道中,则很容易与同事共享,并在遇到错误时获得帮助或反馈。【翻译稿件,合作网站转载请注明原译者和出处.com】