Спектрограмма: как её читать

Превращаем таблицу STFT в картину, которую можно читать глазами и подавать нейросети.

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

STFT дал нам таблицу частота × время. Если раскрасить значения этой таблицы, получится спектрограмма — самое важное изображение в аудио-AI. Научиться её читать — всё равно что научиться читать рентген: видно структуру звука, скрытую в волне.

Оси и цвет

Горизонтальная ось — время (слева направо). Вертикальная — частота (снизу низкие, сверху высокие). Цвет/яркость — энергия: яркое = много энергии на этой частоте в этот момент, тёмное = мало. Гласный выглядит как горизонтальные полосы (гармоники), шипящий — как размытое облако вверху, тишина — тёмное поле.

частота
  ^   .  шипящий (шум вверху)
  |  тишина        ___        ___
  |              =====  гласный  =====  (полосы-гармоники)
  |              =====            =====
  +------------------------------------> время

Зачем логарифмировать в децибелы

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

Считаем одну колонку спектрограммы в дБ

Возьмём амплитуды спектра одного окна и переведём в дБ — ровно то, что делает librosa.amplitude_to_db.

import math

# амплитуды по частотным бинам одного окна
amps = [1.0, 0.5, 0.1, 0.01, 0.001]

ref = max(amps)
db = [round(20 * math.log10(a / ref), 1) for a in amps]

for i, (a, d) in enumerate(zip(amps, db)):
    print("бин", i, "амплитуда", a, "->", d, "дБ")

Вывод:

бин 0 амплитуда 1.0 -> 0.0 дБ
бин 1 амплитуда 0.5 -> -6.0 дБ
бин 2 амплитуда 0.1 -> -20.0 дБ
бин 3 амплитуда 0.01 -> -40.0 дБ
бин 4 амплитуда 0.001 -> -60.0 дБ

Линейный диапазон от 1.0 до 0.001 (в 1000 раз) превратился в удобную шкалу от 0 до -60 дБ. Теперь и сильные, и слабые частоты различимы — именно так выглядит «правильная» спектрограмма.

Линейная и мел-спектрограмма

Спектрограмма выше — линейная по частоте: бины равномерно расположены в герцах. Но человек слышит частоты неравномерно (об этом следующий урок). Поэтому для речи чаще строят мел-спектрограмму, где частотная ось искажена под человеческий слух. Для ASR это почти всегда стандартный вход.

Аналогия с медицинским снимком тут не случайна. Как рентгенолог по теням и плотностям читает то, что невидимо снаружи, так инженер по спектрограмме «видит» структуру звука, спрятанную в монотонной на вид волне. Опытный взгляд за секунды отличит мужской голос от женского (полосы-гармоники гуще или реже), найдёт фоновый гул сети (ровная горизонтальная линия внизу на 50 Гц), заметит обрезанные высокие частоты у телефонной записи (тёмная пустота сверху). Эта «читаемость глазами» — огромный практический плюс: отлаживая аудио-конвейер, вы буквально видите проблему, а не гадаете по числам.

Чтобы прочувствовать, зачем нужен логарифм в децибелах, представьте фотографию против света. Если выставить экспозицию по яркому небу, лица людей в тени станут чёрными провалами; если по лицам — небо выгорит в белизну. Линейная спектрограмма страдает тем же: сильные форманты «засветят» картинку, а тихие, но важные для смысла высокие частоты утонут в черноте. Перевод в дБ работает как режим HDR — поджимает огромный диапазон так, чтобы и громкое, и тихое оказались в одной видимой шкале. Не зря шаг amplitude_to_db почти всегда стоит перед подачей спектрограммы в модель.

Полезно держать в голове, что у спектрограммы есть «тайная» третья компонента, которую обычная картинка выбрасывает, — фаза. Раскрашивая спектрограмму, мы показываем только амплитуду (силу частоты), а информацию о сдвиге волны отбрасываем. Для распознавания и классификации это не беда: смысл речи живёт в амплитудах. Но если вы захотите превратить спектрограмму обратно в звук (например, в нейросетевом синтезе), отсутствие фазы становится проблемой — её приходится восстанавливать отдельными алгоритмами вроде Griffin-Lim или нейровокодером. Так одна и та же картинка идеальна для «слушать», но недостаточна для «говорить».

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

Спектрограмма для нейросети — это просто двумерный массив чисел (как чёрно-белая картинка). Свёрточная сеть или трансформер обрабатывают её теми же приёмами, что и изображения. Поэтому многие приёмы из компьютерного зрения (аугментации, свёртки, attention по «патчам») напрямую переносятся в аудио. Whisper, например, подаёт лог-мел-спектрограмму в трансформер-энкодер.

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

  • Рисовать спектрограмму линейно по амплитуде. Тихие, но важные детали исчезнут — нужен логарифм (дБ).
  • Путать оси. Время — горизонталь, частота — вертикаль; перепутав, вы «прочитаете» звук неверно.
  • Подавать линейную спектрограмму туда, где ждут мел. Многие модели обучены именно на мел-входе.

Итоги

  • Спектрограмма — картина звука: время × частота × энергия (цвет).
  • Амплитуду логарифмируют в дБ, чтобы видеть и громкое, и тихое.
  • Гласные — полосы-гармоники, шипящие — облако вверху, тишина — тёмное поле.
  • Для нейросети это 2D-массив, к нему применимы приёмы компьютерного зрения.
Проверьте себя
1. Что показывают оси спектрограммы?
AОбе оси — время
BГоризонталь — время, вертикаль — частота, цвет — энергия
CГоризонталь — громкость, вертикаль — язык
DОси не имеют смысла
2. Зачем амплитуду спектрограммы переводят в децибелы?
AЧтобы файл был меньше
BЧтобы одновременно видеть и громкие, и слабые частоты (логарифм сжимает диапазон)
CЧтобы изменить частоту
DЭто не нужно
3. Почему к спектрограмме применимы методы компьютерного зрения?
AПотому что это 2D-массив чисел, по сути картинка
BПотому что в ней есть слова
CПотому что она цветная
DЭто неверно