Преобразование Фурье: интуиция

Главная идея анализа звука: посмотреть на сигнал не во времени, а по частотам.

Преобразование Фурье — математическая операция, которая раскладывает сигнал на сумму синусоид и показывает, какие частоты и насколько сильно в нём присутствуют.

Во временной области мы видим, как меняется амплитуда. Но ухо и мозг распознают звуки в основном по частотам: гласные различаются набором частот, инструменты — тембром, который тоже задан частотами. Чтобы модель «слышала» как человек, сигнал переводят из времени в частоту. Этот перевод и делает Фурье.

Метафора призмы

Преобразование Фурье — как призма для звука. Призма раскладывает белый свет на цвета (частоты света). Фурье раскладывает звук на чистые тоны (частоты звука). На входе — сложная волна, на выходе — рецепт: «здесь 30% частоты 200 Гц, 50% частоты 400 Гц, немного 800 Гц». Этот рецепт называют спектром.

временная область            частотная область (спектр)
   волна                        амплитуда
    /\  /\                          |
   /  \/  \      ---Фурье--->       |    |
  /        \                        |    |        |
 /          \                    ___|____|________|___ частота
                                  200  400       800 Гц

Зачем это нужно

В частотной области многие вещи становятся очевидными. Хотите убрать гул сети 50 Гц? В спектре это один пик — вырезали его и обратно. Хотите понять, гласный это или шипящий? Гласные имеют чёткие пики (форманты), шум — размазан. Хотите признаки для речи? Спектр — гораздо более информативный вход для нейросети, чем сырая волна.

Простейший «детектор частоты»

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

import math

n = 32
# сигнал — синусоида частоты 3
signal = [math.sin(2 * math.pi * 3 * i / n) for i in range(n)]

def correlate(freq):
    s = sum(signal[i] * math.sin(2 * math.pi * freq * i / n) for i in range(n))
    return round(s, 2)

for f in [1, 2, 3, 4, 5]:
    print("частота", f, "-> отклик", correlate(f))

Вывод:

частота 1 -> отклик -0.0
частота 2 -> отклик 0.0
частота 3 -> отклик 16.0
частота 4 -> отклик -0.0
частота 5 -> отклик -0.0

Отклик резко вырос ровно на частоте 3 — той, что заложена в сигнал. Так, проверяя резонанс на разных частотах, Фурье находит, из чего «собран» звук.

Если призма кажется слишком абстрактной, есть совсем бытовая аналогия: представьте аккорд, взятый на пианино. Ваше ухо слышит единый «густой» звук, но опытный музыкант мгновенно называет ноты, из которых аккорд собран. Преобразование Фурье — это и есть такой «абсолютный слух» для машины: оно берёт смешанную волну и возвращает точный список нот, то есть частот, с указанием громкости каждой. Именно поэтому без Фурье аудио-AI был бы глух к самому важному — к тому, из чего состоит звук, а не только к тому, насколько он громкий.

Полезно прочувствовать, почему «детектор частоты» из примера работает. Когда две синусоиды одной частоты перемножаются, в каждой точке знак произведения чаще совпадает, и сумма накапливается — это и есть резонанс. Если же частоты разные, произведение одинаково часто бывает положительным и отрицательным, и при сложении всё взаимно гасится почти в ноль. Фурье просто проделывает эту проверку на резонанс для целого веера частот сразу. Никакой магии: за впечатляющим спектром стоит честный перебор «а есть ли тут вот эта частота?».

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

Как работает под капотом

На практике используют не наивный перебор, а FFT (быстрое преобразование Фурье) — алгоритм, считающий спектр за O(n log n) вместо O(n²). FFT работает с комплексными числами: каждая частота получает амплитуду (насколько сильна) и фазу (сдвиг). Для спектрограммы фазу обычно отбрасывают, оставляя только амплитуды. Именно FFT под капотом у librosa, torchaudio и любой спектрограммы.

Частые ошибки

  • Думать, что Фурье «теряет» сигнал. Преобразование обратимо: из спектра (с фазой) восстанавливается исходная волна.
  • Считать спектр статичным. Полный Фурье даёт один спектр на всю запись; для меняющегося звука нужен STFT по окнам.
  • Игнорировать фазу. Для синтеза звука из спектра фаза важна, хотя для классификации ею часто пренебрегают.

Итоги

  • Фурье раскладывает звук на частоты, как призма — свет на цвета.
  • Результат — спектр: какие частоты и насколько сильны.
  • В частотной области легко фильтровать гул и выделять признаки речи.
  • На практике считают FFT (быстро, через комплексные числа).
Проверьте себя
1. Что делает преобразование Фурье со звуком?
AДелает его громче
BРаскладывает на составляющие частоты (спектр)
CСжимает файл
DПереводит на другой язык
2. Чем FFT отличается от наивного вычисления Фурье?
AFFT неточен
BFFT считает спектр за O(n log n) вместо O(n²)
CFFT работает только с музыкой
DЭто одно и то же по скорости
3. Почему для меняющегося звука одного преобразования Фурье недостаточно?
AФурье не работает со звуком
BПолный Фурье даёт один спектр на всю запись и не показывает, как частоты меняются во времени
CФурье слишком быстрый
DНужно больше каналов