Классификация аудио и регрессия с использованием Pytorch

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

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

Поскольку covid-19 сейчас является актуальной темой, я решил создать звуковой регрессор, который может предсказывать интенсивность кашля у человека. Это регрессионная модель, но если вы хотите научиться строить модель классификации, я расскажу об этом в конце. Этот блог предназначен как для новичков, так и для опытных людей и будет охватывать все, от предварительной обработки данных до создания модели. Итак, давайте начнем.

1. Инициализация

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

Приведенный выше код импортирует все необходимые библиотеки и инициализирует ваше устройство либо на CPU, либо на GPU. Поскольку модель не будет такой ресурсоемкой, графический процессор не нужен, но будет лучше, если он у вас есть. Если у вас его нет, просто используйте Google Colab.

Что касается данных, давайте воспользуемся набором данных кашвид. Вы можете скачать его отсюда https://zenodo.org/record/4498364.

Общедоступная версия набора данных содержит около 2000 аудиофайлов, содержащих аудиосэмплы от субъектов, представляющих широкий спектр пола, возраста, географического положения и статусов covid-19, которые были помечены опытными пульмонологами.

2. Предварительная обработка данных

На этом этапе я рассмотрю весь конвейер предварительной обработки данных и создания набора данных pytorch. Но прежде всего давайте взглянем на данные.

Аудиофайлы имеют формат .webm, а данные конфигурации — в формате JSON. Одна большая проблема здесь заключается в том, что если аудиоданные не в формате .wav, pytorch становится очень суетливым по этому поводу. И поверьте мне, преобразование форматов файлов без их повреждения - это кошмар, если вы делаете это впервые. Но не волнуйтесь, у меня есть сценарий, который сделает всю работу за вас.

Этот сценарий использует ffmpeg, инструмент командной строки, используемый для преобразования аудио- и видеоформатов (серьезно, это очень полезно для изменения наборов данных) для преобразования всех файлов .webm в файлы .wav. Обратите внимание, что это займет некоторое время в зависимости от вашего оборудования, а также того, что размер файлов .wav в 8–10 раз больше, чем файлов .webm, поэтому убедитесь, что у вас есть место для хранения. После этого вы можете удалить файлы .webm, но не изменяйте файлы JSON.

Теперь давайте на самом деле перейдем к просмотру части данных (я знаю, что мы сделали длинный крюк 😅).

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

Как вы можете видеть выше, у нас есть много различной информации о субъекте, такой как его возраст, географическое положение и количество кашля, которое у него есть. Параметр «cough_detected» здесь является нашей меткой. Это то, что мы хотим, чтобы наша модель машинного обучения предсказывала.

Теперь давайте посмотрим на последнюю строку блока кода. Здесь мы используем метод загрузки, который возвращает нам форму волны, которая представляет собой тензор формы [каналы, время] и частоты дискретизации. Форма сигнала в основном представляет собой двумерный массив частот во времени с интервалами «частоты дискретизации» в секунду, которые мы передаем в нашу модель машинного обучения.

Если все эти термины кажутся вам непонятными, попробуйте прочитать этот блог, который даст вам некоторое представление о частоте дискретизации, битрейте и т. д. https://www.vocitec.com/docs-tools/blog/sampling-rates-sample- глубина-и-битрейт-основные-аудио-концепции

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



Итак, давайте начнем. Как вы можете видеть в приведенном выше коде, методы __init__, __len__ и __getitem__ говорят сами за себя (мы используем индекс, чтобы получить путь к аудиофайлу и метку). Если вы хотите узнать о них больше, ознакомьтесь с документацией pytorch.



В методе __getitem__ мы в основном делаем некоторые преобразования формы сигнала, чтобы сделать его пригодным для нашей модели. Наиболее важным из них является преобразование мелспектрограммы из звука факела. Это в основном преобразует форму волны из шкалы Гц в шкалу Мел. Шкала Мел построена таким образом, что звуки, находящиеся на одинаковом расстоянии друг от друга по шкале Мел, также «звучат» для человека, поскольку они находятся на одинаковом расстоянии друг от друга. Он призван имитировать нелинейное человеческое восприятие звука. Для лучшего понимания взгляните на код.

Здесь частота дискретизации — это желаемая частота дискретизации, которую мы хотим, n_fft (неоднородное быстрое преобразование Фурье) или в контексте кода длина n_fft короткого сегмента. Длина прыжка — это промежуток между началом одного сегмента и последующим сегментом, это делается для того, чтобы сегменты не перекрывали друг друга полностью. Он также напрямую отвечает за форму ввода. Параметр n_mels — это, по сути, количество банков Mel или фильтров в спектрограмме. В основном количество разделов, на которые была разделена шкала Гц.

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

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



Также ознакомьтесь с этой статьей о переполнении стека о коде.



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

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

_mix_down: этот метод гарантирует, что наш аудиосигнал имеет только один канал (превратит его в «моно» сигнал). Это достигается за счет объединения всех каналов в один.

_cut: этот метод обрезает продолжительность аудиосигнала, если он превышает определенную длину, т. е. если он имеет более определенной длины сэмплов.

_right_pad: этот метод противоположен методу _cut, т. е. он дополняет аудиосигнал справа, если количество сэмплов меньше желаемого.

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

3. ML-моделирование

Уф 😅 последний раздел был немного ошеломляющим, поэтому давайте приступим к созданию модели. Для этого я не собираюсь вдаваться в какую-то сложную архитектуру модели, поскольку цель этого блога — просто охватить основы. Поэтому для этой задачи мы будем использовать простую модель CNN. Я знаю, вы задаетесь вопросом, как можно использовать модель CNN, которая используется в основном для компьютерного зрения, для звуковой задачи, разве аудио и видео не отличаются?

Да, они. Но наш звуковой сигнал/волну после предварительной обработки можно интерпретировать как двумерное изображение (частота X время). Удивительно, но CNN эффективны, когда дело доходит до аудиоданных. Для лучшего понимания прочитайте этот блог, модель, которую я вам покажу, также сильно вдохновлена ​​отсюда.



Выше приведен код для нашей модели. Он имеет 4 блока свертки, каждый из которых состоит из слоя Conv2d с функцией активации relu, за которым следует слой максимального объединения для уменьшения размера изображения (спектрограммы) на 2. За блоками свертки следует простой плоский слой, пара линейных/плотных слои и, наконец, выходной слой, который в нашем случае является сигмовидным слоем, поскольку наши выходные данные ограничены от 0 до 1. Если бы это была задача классификации, вы бы просто заменили сигмовидный слой на слой softmax или log softmax.

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

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

Как вы можете видеть рядом со слоем conv2d 2–1, наша входная форма (-1,16,66,46). 16 — это количество фильтров, после вычитания 2, которое является заполнением, мы получаем (64,44), что не что иное, как (n_mels, sample_rate/hop_length), как обсуждалось выше.

4. Обучение и прогнозирование

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



Здесь функция train просто обучает модель с помощью функции train_single_epoch. Значения, константы и другой обучающий код приведены ниже. В этой части больше нечего объяснять, если у вас возникнут трудности, ознакомьтесь с документацией pytorch.

А вот код для запуска функций предсказания.

Вот и все, надеюсь, он был вам полезен. 😃

Для кода проверьте мой репозиторий github.



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

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