Глубокое обучение
Нежное введение в классификацию аудио с помощью Tensorflow
Применение глубокого обучения для классификации аудио с помощью Tensorflow
Мы видели много недавних достижений в глубоком обучении, связанных с полями зрения и языка, интуитивно понятно, почему CNN очень хорошо работает с изображениями с пиксельной локальная корреляция, и как последовательные модели, такие как RNN или преобразователи, также очень хорошо работают с языком с его последовательной природой, но как насчет звука? какие типы моделей и процессов используются, когда мы имеем дело с аудиоданными?
В этой статье вы узнаете, как решить простую задачу классификации звука, узнаете о некоторых распространенных и эффективных методах, а также о коде Tensorflow для этого.
Отказ от ответственности: представленный здесь код основан на моей работе, разработанной для конкурса Kaggle Обнаружение звука видов связи в тропических лесах, но в демонстрационных целях я буду использовать набор данных Речевые команды.
Сигналы
Обычно у нас есть аудиофайлы в формате «.wav», их обычно называют сигналами, сигнал — это временной ряд с амплитуда сигнала в каждый конкретный момент времени, если мы визуализируем один из этих образцов сигнала, мы получим что-то вроде этого:
Интуитивно можно рассмотреть возможность моделирования этих данных как обычного временного ряда (например, прогнозирование курса акций) с использованием какой-либо модели RNN, на самом деле это можно сделать, но поскольку мы используют аудиосигналы, более подходящим выбором является преобразование образцов формы волны в спектрограммы.
Спектрограммы
Спектрограмма представляет собой изображение сигнала формы волны, она показывает его диапазон интенсивности частоты во времени. Она может быть очень полезна, когда мы хотим оценить частотное распределение сигнала во времени. . Ниже представлена спектрограмма изображения формы сигнала, которое мы видели выше.
Пример использования речевых команд
Чтобы упростить этот урок, мы будем использовать набор данных Речевые команды, в этом наборе данных есть односекундные аудиоклипы с произносимыми словами, такими как: вниз, иди, влево, нет, вправо. , стоп, вверх и да.
Обработка звука с помощью Tensorflow
Теперь, когда у нас есть представление о том, как мы обрабатываем аудиоданные для использования с моделями глубокого обучения, мы можем перейти к рассмотрению реализации кода для этого. Наш конвейер будет следовать простому рабочему процессу, описанному на диаграмме ниже:
Обратите внимание, что в нашем случае на 1-м шаге данные загружаются непосредственно из файлов «.wav», а 3-й шаг является необязательным, так как аудиофайлы имеют только один второй каждый, в некоторых случаях обрезка звука может быть хорошей идеей для более длинных файлов, а также для сохранения фиксированной длины для всех сэмплов.
Загрузка данных
def load_dataset(filenames): dataset =tf.data.Dataset.from_tensor_slices(
filenames)
return dataset
Функция load_dataset
будет отвечать за загрузку файлов .wav
и преобразование их в набор данных Tensorflow.
Извлечение сигнала и метки
commands = np.array(tf.io.gfile.listdir(str(data_dir))) commands = commands[commands != 'README.md']
def decode_audio(audio_binary): audio, _ = tf.audio.decode_wav(audio_binary) return tf.squeeze(audio, axis=-1)
def get_label(
filename): label = tf.strings.split(
filename, os.path.sep)[-2] label = tf.argmax(label == commands) return label
def get_waveform_and_label(
filename): label = get_label(
filename) audio_binary = tf.io.read_file(
filename) waveform = decode_audio(audio_binary) return waveform, label
После загрузки файлов .wav
нам нужно их декодировать, это можно сделать с помощью функции tf.audio.decode_wav
, она превратит файлы .wav
в тензоры с плавающей запятой. Затем нам нужно извлечь метки из файлов, в этом конкретном случае мы можем получить метки из пути к файлу каждого образца, после чего нам просто нужно их закодировать.
Вот пример:
Во-первых, мы получаем такой путь к файлу:
"data/mini_speech_commands/up/50f55535_nohash_0.wav"
Затем мы извлекаем текст после второго «/», в данном случае это метка UP, наконец, мы используем список commands
для прямого кодирования меток.
Commands: ['up' 'down' 'go' 'stop' 'left' 'no' 'yes' 'right'] Label = 'up' After one-hot encoding: Label = [1, 0, 0, 0, 0, 0, 0, 0]
Преобразование сигналов в спектрограммы
Следующим шагом является преобразование файлов сигналов в спектрограммы, к счастью, в Tensorflow есть функция, которая может это сделать, tf.signal.stft
применяет кратковременное преобразование Фурье (STFT), чтобы преобразовать звук в частотно-временную область, затем мы применяем оператор tf.abs
, чтобы удалить фазу сигнала и сохранить только величину. Обратите внимание, что функция tf.signal.stft
имеет некоторые параметры, такие как frame_length
и frame_step
, они будут влиять на сгенерированную спектрограмму, я не буду вдаваться в подробности о том, как их настроить, но вы можете обратиться к этому видео, чтобы узнать больше.
def get_spectrogram(waveform, padding=False, min_padding=48000):
waveform = tf.cast(waveform, tf.float32)
spectrogram = tf.signal.stft(waveform, frame_length=2048, frame_step=512, fft_length=2048)
spectrogram = tf.abs(spectrogram)
return spectrogram
def get_spectrogram_tf(waveform, label):
spectrogram = get_spectrogram(waveform)
spectrogram = tf.expand_dims(spectrogram, axis=-
1)
return spectrogram, label
Преобразование спектрограмм в изображения RGB
Последним шагом является преобразование спектрограмм в изображения RGB, этот шаг не является обязательным, но здесь мы будем использовать модель, предварительно обученную на наборе данных ImageNet, и для этой модели требуются входные изображения с 3 каналами, в противном случае вы можете сохранить спектрограммы. только с одним каналом.
def prepare_sample(spectrogram, label): spectrogram = tf.image.resize(spectrogram, [HEIGHT, WIDTH]) spectrogram = tf.image.grayscale_to_rgb(spectrogram) return spectrogram, label
Объединение всего вместе
HEIGHT, WIDTH = 128, 128AUTO = tf.data.AUTOTUNE
def get_dataset(filenames, batch_size=32): dataset = load_dataset(filenames)dataset
= files_ds.map(get_waveform_and_label, num_parallel_calls=AUTO)
dataset = dataset.map(get_spectrogram_tf, num_parallel_calls=AUTO) dataset = dataset.map(prepare_sample, num_parallel_calls=AUTO) dataset = dataset.shuffle(256) dataset = dataset.repeat() dataset = dataset.batch(batch_size) dataset = dataset.prefetch(AUTO
) return dataset
Собрав все вместе, у нас есть функция get_dataset
, которая принимает имена файлов в качестве входных данных и после выполнения всех шагов, описанных выше, возвращает набор данных Tensorflow с изображениями спектрограмм RGB и их метками.
Модель
def model_fn(input_shape, N_CLASSES): inputs = L.Input(shape=input_shape, name='input_audio') base_model = efn.EfficientNetB0(input_tensor=inputs, include_top=False, weights='imagenet') x = L.GlobalAveragePooling2D()(base_model.output) x = L.Dropout(.5)(x) output = L.Dense(N_CLASSES, activation='softmax',name='output')(x) model = Model(inputs=inputs, outputs=output) return model
Наша модель будет иметь магистраль EfficientNetB0, а наверху мы добавили GlobalAveragePooling2D, за которым следует Dropout и последний Плотный слой, который будет выполнять фактическую мультиклассовую классификацию.
С небольшим набором данныхEfficientNetB0 может быть хорошей базой, она имеет приличную точность, даже будучи быстрой и легкой моделью.
Обучение
model = model_fn((None, None, CHANNELS), N_CLASSES) model.compile(optimizer=tf.optimizers.Adam(), loss=losses.CategoricalCrossentropy(), metrics=[metrics.CategoricalAccuracy()]) model.fit(x=get_dataset(FILENAMES), steps_per_epoch=100, epochs=10)
Обучающий код очень стандартный для модели Keras, так что вы вряд ли найдете здесь что-то новое.
Вывод
Теперь у вас должно быть более четкое представление о рабочем процессе для применения глубокого обучения к аудиофайлам, хотя это не единственный способ сделать это, это один из лучших вариантов в отношении компромисса между простотой и производительностью. Если вы собираетесь моделировать аудио, возможно, вы захотите рассмотреть и другие многообещающие подходы, такие как трансформаторы.
В качестве дополнительных шагов предварительной обработки вы можете обрезать или дополнить сигналы, это может быть хорошей идеей в тех случаях, когда ваши сэмплы имеют разную длину или если сэмплы слишком длинные, и вам просто нужна меньшая часть из них, вы можете найти код о том, как сделать это в разделе ссылок ниже.
Ссылки
- Простое распознавание аудио: Распознавание ключевых слов
- Классификация Rainforest-Audio Tensorflow starter
- Классификация Rainforest-Audio TF Improved