Глубокое обучение

Нежное введение в классификацию аудио с помощью 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, 128
AUTO = 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