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

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

Мы собираемся рассмотреть здесь довольно общую задачу. Как отличить человеческую речь от окружающего шума и убрать все посторонние звуки? Решение этого вопроса будет полезно для любой дальнейшей обработки. Это связано с тем, что системы идентификации, акустическое обнаружение событий, а также другие приложения, работающие с человеческой речью, лучше работают с сигналами без шума. Для нас такая технология может помочь улучшить качество видеозвонков на ВКонтакте, Одноклассники и Mail.ru, не допуская, чтобы фоновый шум мешал общению между участниками разговора.

Заявление о проблеме

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

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

При этом мы предъявляем к технологии следующие требования:

  • Работа в реальном времени: нет увеличения задержек более чем на 20 мс.
  • Легкость: возможность работы на пользовательских устройствах.
  • Качество: сопоставимо с другими решениями (Zoom и Krisp) и даже превосходит конкурентов.

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

Звук - это волна. Микрофон реагирует на его распространение и выдает аналоговый, то есть непрерывный, сигнал. Для передачи и обработки аналоговый сигнал преобразуется в цифровой. Для этого существуют разные аппаратные и программные решения, но наиболее распространенным из них является импульсно-кодовая модуляция, или PCM. Частота - например, 44 100 Гц - определяет качество оцифрованного звука, а значение амплитуды обычно кодируется в 16 битах.

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

Традиционные подходы

Один из старейших известных методов улучшения речи - Спектральное вычитание. Идея этого очень проста: мы вычитаем спектр шума из спектра шума и получаем только спектр чистой речи, а затем преобразовываем его обратно из спектра в сигнал.

Зашумленный сигнал можно представить как y [n] = s [n] + d [n], где s [n] - чистая речь, а d [ n] - шум.

Алгоритм спектрального вычитания математически описывается следующим образом:

где ŝ - спектр чистой речи, - предполагаемый спектр шума, X (w) - входной спектр сигнала.

Позже популярность приобрел более продвинутый метод, названный фильтром Винера. Его идея заключается в минимизации расстояния между ŝ и s. Это сформулировано следующим образом:

где s_s (w) - это рассчитанный спектр, s_n (w) - это спектр шума.

См. Общую схему улучшения речи с помощью фильтра Винера ниже.

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

Нейронные сети для фильтрации шума

В наши дни сложные математические преобразования были заменены магией нейронных сетей.

RNNoise

RNNoise стала одной из первых известных и успешных сетей, решающих проблему улучшения речи. RNNoise объединяет классические алгоритмы и сеть RNN (рекуррентную нейронную сеть). Основная идея заключается в использовании нейронной сети для объединения трех основных компонентов системы: VAD (обнаружение голосовой активности), вычисление спектра шума и вычитание спектра шума из исходного сигнала.

Сеть улавливает зашумленный спектр сигнала на входе и возвращает два тензора на выходе. Один из них предсказывает, является ли данный кадр речевым. А на второй кадр нужно умножить, чтобы получилась четкая речь.

Конечно, за один проход обрабатывается не весь отсчет сигнала, а только небольшое окно - в исходном RNNoise окно составляет 20 мс. В каждой последующей итерации окно сдвигается на 10 мс, что приводит к перекрытию и частичному повторному анализу окна.

Сама архитектура нейронной сети RNNoise выглядит примерно так:

NSNet

Более продвинутый подход предложили специалисты Microsoft. В NSNet величина извлекается из кадра после преобразований STFT (кратковременное преобразование Фурье) и LPS (логарифмический спектр мощности).

Характеристики вычисляются в окне 32 мс, перекрытие составляет 24 мс. Другими словами, сеть возвращает шумоизолированную речь в кадрах 8 мс.

Чистый сигнал дополняется шумом (см. Увеличение данных), и полученная спектрограмма подается на вход при обучении сети. Для обучения NSNet использует среднеквадратичное расстояние между исходной спектрограммой четкого сигнала и спектрограммой, полученной в результате нейронной сети.

DCCRN

Следующим шагом на пути к совершенствованию речи стала DCCRN. DCCRN имеет архитектуру типа U-net, где все операции представлены сложными операциями. Основная идея метода - использовать не только величину сигнала, но и фазы. Это улучшает качество шумоподавления, на которое способна нейронная сеть, по сравнению с предыдущим решением NSNet.

Но за высокое качество DCCRN приходится платить. Во-первых, исходная сеть не может работать в реальном времени. Авторы решили эту проблему, вставив рекурсивный слой между кодером и декодером. Во-вторых, модель сложна в реализации и не адаптирована для вдов произвольных размеров. Третий недостаток DCCRN - размер модели и скорость ее работы. По словам авторов, для обработки 32 мс на Intel i5–8250U требуется около 3 мс. То есть для этой сети с окном перекрытия 8 мс коэффициент реального времени (RT) (метрика, показывающая, во сколько раз обрабатывается сигнал быстрее, чем он принимается) будет меньше 3. На более слабом оборудовании реальный -временная обработка, вероятно, не может быть достигнута с такими параметрами.

PoCoNet

PoCoNet - это современное решение Amazon для улучшения речи, которое улучшает все предыдущие подходы.

Архитектура PoCoNet аналогична DCCRN, так как она также U-net-подобна. Но вместо сложных блоков авторы вводят блок плотного внимания. Нейронная сеть включает слои самовнимания для захвата глобального контекста.

Основное отличие PoCoNet от предыдущих работ заключается во введении частотного позиционного встраивания. Этот механизм аналогичен работе позиционного кодирования архитектуры трансформатора: входная спектрограмма объединяется с позиционными вложениями, которые вычисляются следующим образом:

Где k = 10 и зависит только от частоты, а F - от ширины полосы частот, а не от времени.

Однако у PoCoNet есть существенные недостатки:

  • Низкая скорость обучения: обучение такой модели на восьми Tesla V100 занимает четыре дня.
  • Медленная работа: 1 секунда звука занимает 0,65 секунды на Tesla V100.

DTLN

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

Идея, лежащая в основе DTLN (сеть LSTM с двойным преобразованием сигналов), включает в себя 2 этапа. Сначала, как и в предыдущих работах, мы делаем кратковременное преобразование Фурье (STFT), передаем величину в нейронную сеть и получаем вектор, на который мы умножаем величину. Затем мы выполняем обратное быстрое преобразование Фурье (ОБПФ) и отправляем полученный сигнал на вторую часть входа сети, на выходе которой мы получаем сигнал с полностью подавленным шумом.

Преимущества DTLN, которые важны для нас, заключаются в том, что модель занимает менее 4 МБ, а обработка 32 мс на Intel i5 6600k занимает 0,65 мс. Это в 5 раз быстрее, чем DCCRN, и несравнимо быстрее, чем PoCoNet. Мы рассмотрим показатели качества более подробно ниже, но в целом DTLN отстает от лучших моделей примерно на 10%. Учитывая то, что он отвечает всем остальным нашим требованиям, нас это устраивает.

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

Что мы используем

В настоящее время мы используем архитектуру, подобную DTLN, которая немного тяжелее исходной, но быстрее. Благодаря реализации на C ++ скорость работы составляет ~ 0,2 мс на 10 мс речи. Сеть работает с окном 30 мс и перекрытием 20 мс. При выборе размера окна мы отошли от классической комбинации перекрытия 32 мс и 24 мс, чтобы обеспечить более плавную интеграцию с WebRTC и Opus.

Данные обучения

Как мы все знаем, конечный результат нейронных сетей сильно зависит от данных, используемых для их обучения. К счастью, есть несколько отличных и больших наборов данных открытого доступа с разложенными шумами и четкой человеческой речью: MUSAN, AudioSet, WHARM!, LibriVox, RIR.

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

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

Обратите внимание, что мы не разделяем шумы по типам - мы просто используем их общую громкость (сейчас у нас есть около 900 часов четкой речи и 10 000 часов шумов для тренировки). Поскольку нейронная сеть должна обучаться на большом объеме разнообразных данных, она может со временем отфильтровать как стационарный, так и нестационарный шум. В настоящее время фильтрация нестационарного шума остается сложной задачей.

Обучение нашей модификации сети, подобной DTLN, на таких данных занимает около двух дней на Tesla T4.

Функция потерь и оценка качества

В большинстве статей MSE используется как функция потерь:

Мы выбрали SNR (отношение сигнал / шум) для обучения, поскольку, согласно нашим экспериментам с этой функцией потерь, это позволяет достичь более качественных результатов.

Мера «высокого качества» и как его можно оценить - здесь непростой вопрос. Простое сравнение по отклонению от эталонного теста не покажет, действительно ли улучшилось взаимодействие с пользователем.

Следовательно, показатели качества в задачах улучшения речи довольно сложны и пытаются оценить степень, в которой речь в шумоподавленном образце оказалась разборчивой. Метрики PESQ обычно используются для сравнения моделей (Perceptual Evaluation of Speech Quality). Они были специально разработаны для моделирования субъективной оценки восприятия человеческой речи, используемой в телекоммуникациях. В некотором приближении метрика PESQ должна соответствовать средней экспертной оценке по шкале от 1 (плохо) до 5 (отлично). Но поскольку абсолютные значения очень зависят от начальных условий тестирования, мы используем метрику только для определения прогресса решения, предназначенного для использования в производственной среде.

В таблице ниже, помимо самой метрики PESQ и свойств нейронной сети (обработка реверберации, а также размер окна и приращения), есть две характеристики, которые могут оказать значительное влияние на выбор архитектуры: фактор реального времени и память.

На практике коэффициент реального времени показывает скорость работы. Чем он больше, тем быстрее мы обрабатываем входящий сигнал. Коэффициент RT для модификации нашей сети DTLN, равный 45,6, означает, что 1 секунда будет обработана быстрее, чем 25 мс. И сетям, как указано, потребуется более 80 мс для обработки той же секунды. ПЗУ напрямую влияет на конечный размер приложения и очень важно, когда, как в нашем случае, подавление шума является лишь одной из функций.

Однако метрика - это всего лишь метрика, она не может учесть абсолютно все. Например, в сигнале, обработанном исходной DTLN, который имеет неприятный свист, значение показателя является отличным. Вот почему мы также проверяем результаты на слух: например, мы тестируем настройки на рабочих встречах и смотрим, можем ли мы заметить воображаемых (бесшумных) домашних животных.

Что не сработало

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

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

Последствия и советы

В настоящее время наша модель улучшения речи работает на внутреннем сервере для вызовов iOS, Android и реализована в собственном приложении для Windows, macOS и Linux. В iOS и macOS модель работает на Core ML, а для других платформ мы используем TensorFlow Lite.

Мы предлагаем читателям провести независимую оценку получаемых характеристик шумоподавителя. Подавление клиентского шума уже работает в приложении ВКонтакте для iOS и Android и доступно для настольных компьютеров в нативном клиенте для звонков.

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

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

  • Если нейронная сеть обучена работе с реверберированными сигналами, звучание улучшенной речи будет более приятным, даже если оно может не отображаться на метриках.
  • Вместо традиционного размера окна 32 мс вполне подойдет окно 30 мс с перекрытием в 20 мс. Нет разницы в производительности сети, но интеграция с WebRTC и аудиокодеком делает ее более удобной.
  • Пользовательский модуль улучшения речи может быть объединен со встроенным WebRTC, чтобы лучше уменьшить микроскопические шумы.
  • В общем, лучше всего использовать WebRTC и его возможности в полной мере. Например, WebRTC Voice Activity Detection со слабыми настройками до шумоподавления может снизить нагрузку в несколько раз. Пока никто не разговаривает, окошко идет с нулями и можно просто пролистать буфер. При такой конфигурации в серверной версии мы получили нагрузку на ЦП 3% вместо 11%.

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