Мел-шкала: как слышит человек

Подгоняем частотную ось под человеческое ухо — и признаки для речи резко улучшаются.

Мел-шкала — перцептивная шкала частот, на которой равные расстояния соответствуют равной воспринимаемой разнице высоты тона; она нелинейна относительно герц.

Линейная спектрограмма честно показывает герцы, но человек слышит не так. Разницу между 100 и 200 Гц мы воспринимаем как большой скачок, а между 5000 и 5100 Гц — почти не замечаем, хотя в герцах разница одинаковая (100 Гц). Чтобы модель работала с теми же различиями, что и ухо, частоты пересчитывают в мелы.

Нелинейность слуха

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

герцы:   0    1000   2000   4000        8000
         |     |      |       |            |
мелы:    0    1000  1520    2150        2840
         <-равномерно-><--- сжимается -->

Формула мел

Переход герц → мел задаётся логарифмической формулой. Посчитаем её — это ровно то, что внутри librosa.

import math

def hz_to_mel(f):
    return 2595 * math.log10(1 + f / 700)

for hz in [100, 500, 1000, 2000, 4000, 8000]:
    print(hz, "Гц ->", round(hz_to_mel(hz), 1), "мел")

Вывод:

100 Гц -> 150.5 мел
500 Гц -> 607.4 мел
1000 Гц -> 1000.0 мел
2000 Гц -> 1521.4 мел
4000 Гц -> 2146.1 мел
8000 Гц -> 2840.0 мел

Смотрите: от 100 до 1000 Гц (×10) мелы выросли с 64 до 1000, а от 1000 до 8000 Гц (тоже большой рост в герцах) — лишь до 2840. Высокие частоты «сжаты», как и в восприятии.

Мел-фильтры

На практике частоты не пересчитывают по одной, а группируют треугольными мел-фильтрами: спектр (скажем, 201 бин) сворачивают в 40–80 мел-каналов. Каждый фильтр суммирует энергию в своей полосе, узкой внизу и широкой вверху. Результат — мел-спектрограмма: компактнее линейной и ближе к слуху.

# упрощённо: сворачиваем 6 частотных бинов в 3 мел-канала
spectrum = [0.2, 0.5, 0.8, 0.4, 0.1, 0.05]
# границы каналов (узкие внизу, шире вверху)
bands = [(0, 1), (1, 3), (3, 6)]

mel = []
for lo, hi in bands:
    mel.append(round(sum(spectrum[lo:hi]), 3))

print("Линейный спектр:", spectrum)
print("Мел-каналы:", mel)

Вывод:

Линейный спектр: [0.2, 0.5, 0.8, 0.4, 0.1, 0.05]
Мел-каналы: [0.2, 1.3, 0.55]

Шесть бинов «схлопнулись» в три канала, причём верхние частоты объединены грубее нижних — это и есть суть мел-сжатия.

Нелинейность слуха легко проверить на пианино, и это отличная интуиция для мел-шкалы. Самые низкие клавиши идут с шагом всего в единицы и десятки герц, а каждая следующая октава удваивает частоту: переход на октаву внизу — это +100 Гц, а та же октава вверху — уже +2000 Гц. Но для уха обе октавы звучат как одинаковый музыкальный шаг! Наш слух меряет высоту не в герцах, а почти в «октавах», то есть логарифмически. Мел-шкала просто оцифровывает это ощущение: равные отрезки в мелах соответствуют равным воспринимаемым шагам высоты, а не равному числу герц.

Почему именно низким частотам мел-шкала отдаёт больше разрешения — не прихоть, а точное попадание в физику речи. Основной тон голоса (100–250 Гц) и первые две форманты, по которым различаются гласные, живут как раз в нижней части спектра, обычно до 3–4 кГц. Выше располагаются в основном шипящие и тонкие краски тембра, где грубого деления вполне достаточно. Получается, мел-фильтры тратят «бюджет точности» именно там, где сосредоточен смысл речи, и экономят на зоне, которая для разбора слов почти бесполезна. Это редкий случай, когда выбрасывание данных делает признак лучше, а не хуже.

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

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

Лог-мел-спектрограмма (мел-спектрограмма с логарифмом по амплитуде) — самый частый вход для современных ASR. Whisper использует 80 мел-каналов. Почему это работает: мел-представление выкидывает информацию, к которой ухо нечувствительно, оставляя главное для разбора речи. Меньше входных данных — быстрее и устойчивее обучение.

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

  • Считать мел-шкалу «просто логарифмом». Внизу она почти линейна; формула с +700 это учитывает.
  • Брать слишком мало мел-каналов. 10 каналов потеряют форманты; стандарт — 40–80.
  • Забыть логарифм амплитуды. Лог-мел работает лучше линейного мела для речи.

Итоги

  • Мел-шкала отражает нелинейность слуха: внизу подробно, вверху грубо.
  • Переход герц → мел — логарифмическая формула с константой 700.
  • Мел-фильтры сворачивают спектр в 40–80 каналов = мел-спектрограмма.
  • Лог-мел-спектрограмма — стандартный вход современных ASR (Whisper — 80 каналов).
Проверьте себя
1. Что отражает мел-шкала?
AГромкость звука
BНелинейность человеческого слуха по частоте
CДлину записи
DЧисло каналов
2. Как мел-шкала обращается с высокими частотами?
AРастягивает их
BСжимает их (логарифмически), как и слух
CУдаляет их
DНе меняет
3. Что делают мел-фильтры со спектром?
AУдаляют все частоты
BСворачивают много частотных бинов в 40–80 мел-каналов
CПереводят речь в текст
DУвеличивают громкость