Реализация кратковременного преобразования Фурье

Я обнаружил, что обработка звука в TensorFlow затруднена, вот мое решение

Есть бесчисленное множество способов выполнить обработку звука. Обычный процесс проведения экспериментов с искусственными нейронными сетями в TensorFlow с аудиовходами - это сначала предварительно обработать звук, а затем передать его в нейронную сеть.

Но что происходит, когда кто-то хочет выполнить обработку звука где-то в середине графа вычислений?
TensorFlow поставляется с реализацией быстрого преобразования Фурье, но этого недостаточно.

В этом посте я объясню, как мы его реализовали, и предоставлю код, чтобы кратковременное преобразование Фурье можно было использовать в любом месте графа вычислений.

Код

Весь код доступен на моем GitHub: Обработка аудио в Tensorflow.
Не стесняйтесь добавлять туда свой вклад.

Предварительная обработка звука: обычный подход

При разработке механизма распознавания речи с использованием глубоких нейронных сетей нам необходимо передать звук в нашу нейронную сеть, но ... как правильно обработать этот ввод?

Есть 2 распространенных способа представления звука:

  • Временной интервал. Каждая выборка представляет собой изменение давления воздуха.
  • Частотный домен: на каждой временной отметке мы указываем амплитуду для каждой частоты.

Несмотря на то, что глубокие нейронные сети чрезвычайно хороши в автоматическом обучении функциям, всегда полезно полагаться на известные функции, которые несут информацию, необходимую для задачи, которую мы пытаемся решить.

Для большинства приложений, включая механизм распознавания речи, интересующие нас функции закодированы в представлении звука в частотной области.

Спектрограмма и кратковременное преобразование Фурье

Спектрограмма показывает, как частотный состав сигнала изменяется с течением времени, и может быть вычислена на основе сигнала во временной области.
Операция или преобразование, используемое для этого, известно как Кратковременное преобразование Фурье.

Я мог бы позволить нейронной сети выяснить, как изучить эту операцию, но оказалось, что это довольно сложно изучить с 1 скрытым слоем. (см. Универсальную аппроксимационную теорему)

Я мог бы добавить больше слоев, но я хочу, чтобы сложность нейронных сетей была как можно меньше, и изучать функции только там, где это больше всего необходимо.

Я использовал пример разработки механизма автоматического распознавания речи, но использование спектрограммы в качестве входных данных для глубоких нейронных сетей также распространено для аналогичных задач, связанных с неречевым звуком, например, с шумоподавлением, классификацией музыкальных жанров, обнаружением китов и т. Д.

Особый проект, который я хочу упомянуть, - это Magenta от Google Brain team, цель которого - продвигать передовые достижения в области машинного интеллекта для создания музыки и искусства.

Почему TensorFlow?

Я в основном использую TensorFlow при реализации искусственных нейронных сетей, и, поскольку я не нашел реализации кратковременного преобразования Фурье в TF, я решил реализовать нашу собственную.
[редактировать: 4 июня 2018 г.] - начиная с TensorFlow 1.3 они добавили несколько полезных функций DSP.

Также может быть несколько причин, по которым практик глубокого обучения может захотеть включить кратковременное преобразование Фурье (STFT для моих друзей) в граф вычислений, а не просто как отдельный шаг предварительной обработки.

Имейте в виду, что я не сосредоточился на том, чтобы сделать это эффективным. Он должен (и будет) улучшен перед использованием в производстве.

Что вам нужно знать

Чтобы понять, как вычисляется STFT, вам необходимо понять, как вычислить дискретное преобразование Фурье.

Дискретное преобразование Фурье - ДПФ

Эта часть может показаться довольно технической для тех, кто не знаком с этими концепциями, но я думаю, что важно пройти некоторую математику, чтобы дать полное понимание кода.

Теория
Анализ Фурье - это, по сути, метод выражения функции в виде суммы периодических компонентов и восстановления функции по этим компонентам. Когда и функция, и ее преобразование Фурье заменяются дискретными аналогами, это называется дискретным преобразованием Фурье (ДПФ).

Дан вектор x из n входных амплитуд, например:

{x[0], x[1], x[2], x[3], …, x[N-1]}

Дискретное преобразование Фурье дает набор из n значений частоты.

ДПФ определяется этим уравнением:

  • k используется для обозначения порядкового номера частотной области
  • n используется для представления порядкового номера во временной области
  • N - длина преобразуемой последовательности.

Быстрое преобразование Фурье
Быстрое преобразование Фурье - это эффективная реализация уравнения ДПФ. Размер сигнала должен быть ограничен степенью двойки.

Это объясняет, почему N (размер сигнала на входе функции DFT) должен быть степенью 2 и почему в противном случае он должен быть дополнен нулями.

В python можно очень просто определить, является ли x степенью двойки:

Нам нужна только его половина
Настоящие синусоидальные волны можно выразить как сумму сложных синусоид с помощью тождества Эйлера

Поскольку ДПФ является линейной функцией, ДПФ суммы синусоидальных волн является суммой ДПФ каждой синусоидальной волны. Итак, для спектрального случая вы получаете 2 ДПФ, одно для положительных частот и одно для отрицательных частот, которые являются симметричными.
Эта симметрия возникает для реальных сигналов, которые можно рассматривать как бесконечные (или конечные в нашем случае) сумма синусоидальных волн.

Окно
Усечение сигнала во временной области приведет к появлению ряби в частотной области.
Это можно понять, если подумать об усечении сигнала, как если бы вы применили прямоугольную окно. Применение окна во временной области приводит к свертке в частотной области.
Волны возникают, когда мы сворачиваем 2 представления частотной области вместе.

Если вам интересно, узнайте больше о spectral_leakage.

Вот пример реализации управления окнами в Python:

Заполнение нулевой фазы

Чтобы использовать БПФ, входной сигнал должен иметь мощность 2 длины. Если входной сигнал не имеет нужной длины, нули могут быть добавлены к самому сигналу как в начале, так и в конце.
Поскольку нулевой отсчет изначально находится в центре входного сигнала, я разделил заполненный сигнал через середину и поменять местами эти 2 части.

В следующем фрагменте кода показано, как это сделать в TensorFlow для пакета входных данных:

БПФ, амплитуда и фаза
Теперь у вас есть все необходимое для расчета амплитуды спектрограммы в децибелах и фазы сигнала:

Кратковременное преобразование Фурье

Теперь вы знаете, как вычислить DFT для оценки частотного содержания сигнала.
STFT используется для анализа частотного содержания сигналов, когда это частотное содержание изменяется со временем.
Вы можете сделать это следующим образом:

  1. Взятие сегментов сигнала.
  2. Выделение их из остальной части сигнала и применение ДПФ к каждому сегменту.
  3. Сдвигая это окно по каждому сегменту.

Вы получаете коэффициенты ДПФ как функцию как от времени, так и от частоты.

Полный код разделен на 2 части: helpers.py и stft.py.

Заключение

Возможность выполнения STFT в TensorFlow позволяет специалистам по машинному обучению выполнять преобразование сигнала из временной области в частотную в любом месте графа вычислений.
Новые инструменты всегда приносят новые идеи, и мы надеемся, что этот пост поможет быть источником новых идей для разработки новых решений глубокого обучения.