Мел-шкала: как слышит человек
Подгоняем частотную ось под человеческое ухо — и признаки для речи резко улучшаются.
Мел-шкала — перцептивная шкала частот, на которой равные расстояния соответствуют равной воспринимаемой разнице высоты тона; она нелинейна относительно герц.
Линейная спектрограмма честно показывает герцы, но человек слышит не так. Разницу между 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 каналов).