18+
реклама
18+
Бургер менюБургер меню

Александр Иванов – Python в аудио-спецэффектах. Как работают нейросети изнутри. (страница 8)

18

0.5 * np.sin(2 * np.pi * 880 * t[:int(1.5 * sr)]))

# Шум

test_signal[int(1.5 * sr):int(3.0 * sr)] = np.random.randn(int(1.5 * sr)) * 0.3

# Речь (если есть файл) или ещё один тон другой частоты

try:

speech, _ = librosa.load('voice_sample.wav', sr=sr, mono=True)

test_signal[int(3.0 * sr):] = speech[:len(test_signal) - int(3.0 * sr)]

except:

test_signal[int(3.0 * sr):] = np.sin(2 * np.pi * 220 * t[int(3.0 * sr):])

import soundfile as sf

sf.write('test_mixed.wav', test_signal, sr)

print("Создан test_mixed.wav — смесь музыки, шума и речи")

# Классифицируем

predictions = classify_audio_file('test_mixed.wav', model, label_names)

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

За кулисами: история перцептрона

Первый искусственный нейрон — перцептрон — был предложен Фрэнком Розенблаттом в 1958 году. Это было аналоговое устройство размером с комнату, которое использовало резисторы и потенциометры для настройки весов. Розенблатт верил, что перцептроны станут основой искусственного интеллекта.

В 1969 году Марвин Минский и Сеймур Пейперт опубликовали книгу, в которой математически доказали, что однослойный перцептрон не может решить даже простейшую логическую задачу XOR — исключающее ИЛИ. Это доказательство охладило интерес к нейросетям на десятилетие — период, известный как «зима искусственного интеллекта».

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

Лаборатория ошибок

Модель не обучается, потери не уменьшаются. Проверьте скорость обучения. Слишком большая — модель «перепрыгивает» минимум и расходится. Слишком маленькая — обучение идёт слишком медленно. Попробуйте значения 0.1, 0.01, 0.001. Для Adam хороший стартовый диапазон — 0.001–0.0001.

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

Точность на одном классе высокая, на других — низкая. Данные несбалансированы. Если речевых примеров в десять раз больше, чем шумовых, модель будет предсказывать речь чаще. Решение: сбалансировать выборку или использовать взвешенную функцию потерь.

При попытке обучить модель на CPU всё работает очень медленно. Для маленьких моделей и небольших данных процессора достаточно. Если данных много, используйте GPU: в PyTorch это делается переносом модели и данных на устройство командой .to('cuda').

Творческое задание

Запишите три типа звуков: речь, музыку и шум — по несколько минут каждого. Извлеките из них реальные признаки с помощью extract_features. Обучите модель на реальных данных и сравните точность с синтетическими данными. Насколько реальные данные сложнее?

Добавьте четвёртый класс — например, тишину или звук природы. Измените модель так, чтобы она классифицировала четыре класса. Понадобится ли изменить архитектуру или достаточно просто переобучить выходной слой?

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

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

Глава 2. Спектрограмма как картинка: звук глазами нейросети

О чём эта глава

В предыдущей главе мы сделали первый шаг в нейросетевую обработку звука. Мы обучили полносвязную сеть классифицировать аудиофрагменты по нескольким числовым признакам: громкости, частоте пересечений нуля, спектральному центроиду. Это работало, но у такого подхода есть фундаментальное ограничение. Мы сами решали, какие признаки важны. Мы говорили сети: «Смотри на среднюю громкость, на центроид, на частоту пересечений нуля». А что, если мы упустили что-то важное? Что, если ключевое отличие речи от музыки скрыто не в этих четырёх числах, а в каком-то тонком паттерне, который мы не догадались измерить?

В идеальном мире мы бы не выбирали признаки вручную. Мы бы отдали сети весь сигнал целиком и сказали: «Смотри сама. Найди закономерности». Но у полносвязной сети есть проблема: она не умеет работать с длинными последовательностями. Аудиофрагмент длиной в одну секунду при частоте дискретизации 22 050 Гц — это 22 050 чисел. Полносвязная сеть с таким количеством входов будет огромной, медленной и склонной к переобучению.

Решение было найдено в области, далёкой от звука — в компьютерном зрении. Там исследователи столкнулись с похожей проблемой: изображение содержит миллионы пикселей, и подавать их все на вход полносвязной сети неэффективно. Они придумали свёрточные сети — архитектуру, которая смотрит на изображение через маленькие скользящие окна и выделяет локальные паттерны. И кто-то заметил: спектрограмма звука — это тоже изображение. По горизонтали — время, по вертикали — частота, а цвет или яркость — энергия. И на этом изображении есть текстуры, формы, линии — всё то, что свёрточные сети отлично умеют анализировать.

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

Почему спектрограмма — это картинка

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

Когда человек смотрит на спектрограмму, он видит осмысленные структуры. Речь выглядит как серия горизонтальных полос — это основной тон и обертоны, — перемежающихся вертикальными тёмными полосами пауз. Гласные звуки выглядят как яркие области в определённых частотных диапазонах — формантах. Согласные — как короткие шумовые всплески. Музыка выглядит как множество параллельных горизонтальных линий на частотах, кратных основному тону. Шум — как равномерная текстура без выраженной структуры.

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

От сигнала к спектрограмме

Давайте напишем код, который превращает аудиосигнал в спектрограмму — тензор, готовый для подачи в нейросеть.

python

import torch

import torchaudio

import librosa

import numpy as np

def audio_to_mel_spectrogram(y, sr, n_mels=128, n_fft=2048, hop_length=512):

"""

Превращает аудиосигнал в мел-спектрограмму.

Мел-шкала имитирует восприятие частоты человеческим ухом:

низкие частоты представлены подробнее, высокие — грубее.

"""

# Преобразуем в тензор PyTorch, если пришёл numpy-массив

if isinstance(y, np.ndarray):

y = torch.tensor(y, dtype=torch.float32)

Конец ознакомительного фрагмента.

Текст предоставлен ООО «Литрес».

Прочитайте эту книгу целиком, купив полную легальную версию на Литрес.

Безопасно оплатить книгу можно банковской картой Visa, MasterCard, Maestro, со счета мобильного телефона, с платежного терминала, в салоне МТС или Связной, через PayPal, WebMoney, Яндекс.Деньги, QIWI Кошелек, бонусными картами или другим удобным Вам способом.