Фон
В машинном обучении инженерам приходится иметь дело с различными данными, начиная от числовых, категориальных, изображений, видео, речи и т. д. В этой статье основное внимание будет уделено аудиоданным, используемым в таких действиях, как распознавание речи, преобразование речи в текст, преобразование текста в - речь, звуковая классификация и т. д. Действия, связанные с этими данными, включают, но не ограничиваются:
- захват аудио
- сохранение захваченного аудио
- воспроизведение сохраненного аудио
- объединение нескольких аудиофайлов
- разделение аудио на несколько сегментов
- просмотр различных метаданных
- преобразование данных (например, из одной частоты кадров в другую)
- устранение тишины
- инженерные функции (такие как построение сигналов, спектрограмм и т. д.)
- строительные модели
- делать прогнозы
Мы рассмотрим их с примерами кода и полными примерами.
Захват аудио
Для этой цели можно использовать различные пакеты. Здесь мы будем использовать пакет SpeechRecognition.
import speech_recognition as sr r = sr.Recognizer() with sr.Microphone() as source: r.adjust_for_ambient_noise(source) print(“Please say something: \n”) audio = r.listen(source) fname = input(“Please enter file name to save recording to: \n”) with open(fname+”.wav”, “wb”) as f: f.write(audio.get_wav_data()) print(“Recorded successfully\n”)
Сохранение записанного аудио
Мы уже видели сохранение аудио в виде файла WAV выше. Существуют различные форматы
with open(fname+".wav", "wb") as f: f.write(audio.get_wav_data())
для аудиофайлов. Несколько распространенных: MP3, WAV, AAC и т. д. Здесь — хорошая статья с их описанием. Существуют различные пакеты и методы для этих форматов.
Воспроизведение сохраненного аудио
Для этого мы будем использовать пакет pydub. Здесь мы читаем файл WAV и проигрываем его.
from pydub import AudioSegment from pydub.playback import play playaudio = AudioSegment.from_file("1.wav", format="WAV") play(playaudio)
Объединение нескольких аудиофайлов
Это можно сделать с помощью пакета AudioSegments и pydub, которые мы использовали выше. Это также можно сделать с помощью пакета wave, который мы покажем здесь.
import wave infiles = ["1.wav", "2.wav"] outfile = "out.wav" data= [] for infile in infiles: w = wave.open(infile, 'rb') data.append( [w.getparams(), w.readframes(w.getnframes())] ) w.close() output = wave.open(outfile, 'wb') output.setparams(data[0][0]) output.writeframes(data[0][1]) output.writeframes(data[1][1]) output.close()
Разделение на несколько сегментов
Здесь мы разделяем старую песню на новую, время начала и окончания которой в миллисекундах определяется первым и вторым параметрами соответственно.
from pydub import AudioSegment import sys newAudio = AudioSegment.from_wav("oldSong.wav") newAudio = newAudio[int(sys.argv[1]):int(sys.argv[2])] newAudio.export('newSong.wav', format="wav")
Метаданные
Вы можете проверить различные атрибуты метаданных как:
import wave import sys wf = wave.open(sys.argv[1], 'rb') print (input, "#channels = ", wf.getnchannels(), "#frames = ", wf.getnframes(), "sample width = ", wf.getsampwidth(), "sample rate = ", wf.getframerate())
Вы можете конвертировать файлы с одним значением атрибута метаданных в другое, используя pydub и связанные с ним методы. Следующий фрагмент кода изменяет частоту кадров с 44 100 на 48 000.
from pydub import AudioSegment as am import sys sound = am.from_file(sys.argv[1], format='wav', frame_rate=44100) sound = sound.set_frame_rate(48000) sound.export(sys.argv[2], format='wav')
Удаление тишины
Иногда в аудиофайлах есть долгое молчание, которое не может быть обработано с помощью разработки функций и построения модели, которые мы рассмотрим далее. Вот некоторый код, который удаляет такую тишину, используя метод распознавания голосовой активации (VAD).
Разработка функций
Файлы WAV уже содержат сигнал. Здесь мы увидим, как использовать TensorFlow и Keras для чтения ряда таких файлов из папки, разделения их на наборы для обучения и проверки, изменения формы и передачи их в конвейер машинного обучения.
import tensorflow as tf from keras import utils train_ds, val_ds = utils.audio_dataset_from_directory( directory='audio_samples', batch_size=64, validation_split=0.2, seed=0, output_sequence_length=16000, subset='both')
Следующий код получает спектрограмму из сигнала в TensorFlow и выполняет дальнейшие обновления по конвейеру машинного обучения.
import tensorflow as tf def get_spectrogram(waveform): # Convert the waveform to a spectrogram via an STFT. spectrogram = tf.signal.stft( waveform, frame_length=255, frame_step=128) # Obtain the magnitude of the STFT. spectrogram = tf.abs(spectrogram) # Add a `channels` dimension, so that the spectrogram can be used # as image-like input data with convolution layers (which expect # shape (`batch_size`, `height`, `width`, `channels`). spectrogram = spectrogram[..., tf.newaxis] return spectrogram def make_spec_ds(ds): return ds.map( map_func=lambda audio,label: (get_spectrogram(audio), label), num_parallel_calls=tf.data.AUTOTUNE) train_spectrogram_ds = make_spec_ds(train_ds) val_spectrogram_ds = make_spec_ds(val_ds)
Построение моделей
Мы можем использовать различные модели в зависимости от наших требований. Есть некоторые модели преобразования речи в текст, такие как шепот и wave2vec2. Есть некоторые модели на основе фонем, такие как wave2vec2phoneme. Мы можем напрямую использовать различные предварительно обученные модели. Мы можем использовать предварительно обученные модели для некоторого трансферного обучения и тонко настраивать их с нашими обучающими данными, которые не обязательно должны быть большими. Мы также можем построить и обучить нашу модель с нуля. Здесь мы будем использовать сверточную нейронную сеть (CNN) в TensorFlow, построенную и обученную с нуля.
# Instantiate the `tf.keras.layers.Normalization` layer. norm_layer = layers.Normalization() # Fit the state of the layer to the spectrograms # with `Normalization.adapt`. norm_layer.adapt(data=train_spectrogram_ds.map(map_func=lambda spec, label: spec)) model = models.Sequential([ layers.Input(shape=input_shape), # Downsample the input. layers.Resizing(32, 32), # Normalize. 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.compile( optimizer=tf.keras.optimizers.Adam(), loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), metrics=['accuracy'], ) EPOCHS = 10 history = model.fit( train_spectrogram_ds, validation_data=val_spectrogram_ds, epochs=EPOCHS, callbacks=tf.keras.callbacks.EarlyStopping(verbose=1, patience=2), ) model.save("model-dir")
Здесь мы использовали слой нормализации, два сверточных слоя, объединяющий слой, регуляризацию исключения и активацию relu.
вывод
Вывод можно сделать для сохраненного тестового звукового образца, как показано ниже:
import speech_recognition as sr model = keras.models.load_model("model-dir") # get spectrogram for each sample as above test_file = sr.AudioFile('test_file1.wav') with test_file as source: waveform = r.record(source) spectrogram = get_spectrogram(waveform) prediction = model(spectrogram) idx = np.argmax(np.array(prediction[0]))
Мы также можем сделать это с онлайн-данными в реальном времени, когда они записываются.
Вы можете найти все эти фрагменты кода и полные рабочие примеры в моем репозитории GitHub.