Верен ли мой вывод librosa MFCC? Я думаю, что получаю неправильное количество кадров при использовании librosa MFCC

avatar
Rasula
1 июля 2021 в 16:47
698
1
2
result=librosa.feature.mfcc(signal, 16000, n_mfcc=13, n_fft=2048, hop_length=400)
result.shape()

Сигнал имеет длину 1 секунду с частотой дискретизации 16000, я вычисляю 13 MFCC с длиной 400 переходов. Выходные размеры: (13,41). Почему я получаю 41 кадр, разве это не должно быть (time*sr/hop_length)=40?

Источник

Ответы (1)

avatar
Hendrik
1 июля 2021 в 20:21
4

TL;DR ответ

Да, верно.

Длинный ответ

Вы используете временной ряд в качестве входных данных (signal), что означает, что librosa сначала вычисляет mel-спектрограмму, используя функцию melspectrogram. Он принимает кучу аргументов, один из которых вы уже указали (n_fft). Важно отметить, что melspectrogram также предлагает два параметра center и pad_mode со значениями по умолчанию True и "reflect" соответственно.<6803985809192

Из документов:

pad_mode: строка: Если center=True, режим заполнения для использования на краях сигнала. По умолчанию STFT использует заполнение отражения.

центр: логическое значение: Если True, сигнал y дополняется так, чтобы центр кадра t находился в точке y[t * длина_прыжка]. Если False, то кадр t начинается с y[t * hop_length]

.

Другими словами, по умолчанию librosa делает ваш сигнал длиннее (пэды) для поддержки центрирования.

Если вы хотите избежать такого поведения, вам следует передать center=False в вызов mfcc.

При этом при установке center на False имейте в виду, что с длиной n_fft 2048 и длиной прыжка 400 вы не обязательно получите (time*sr/hop_length)=40 кадров, потому что вы также должны учитывать длину окна, а не только длину прыжка (если только вы каким-то образом не дополните). Длина скачка просто указывает, на сколько семплов вы перемещаете это окно.

В качестве предельного примера рассмотрим очень большое окно и очень короткую длину перехода: предположим, что 10 выборок (например, time=1s, sr=10Hz), длина окна n_fft=9 и hop_length=1 с center=False . Теперь представьте, что вы перемещаете окно по 10 образцам.

   ◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◻︎
   ◻︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎◼︎
t  0123456789

◻︎ sample not covered by window
◼︎ sample covered by window

Сначала окно начинается с t=0 и заканчивается на t=8. Сколько раз мы можем сдвинуть его на hop_length и при этом ожидать, что выборки не закончатся? Ровно один раз, пока он не начнется с t=1 и не закончится с t=9. Добавьте первый несмещенный, и вы получите 2 кадра. Это явно отличается от неправильного (time*sr/hop_length)=1*10/1=10.

Правильно: (time*sr-n_fft)//hop_length+1=(1*10-9)//1+1=2 с //, обозначающим целочисленное деление в стиле Python.

При использовании значения по умолчанию, т.е. center=True, сигнал дополняется сэмплами n_fft // 2 на обоих концах, поэтому n_fft выпадает из уравнения.

Rasula
2 июля 2021 в 12:06
1

Вы знаете, почему я получаю 41? Кажется, что количество кадров всегда равно ((time*sr/hop_length))+1. Независимо от того, что (nfft) прошло.

Hendrik
4 июля 2021 в 20:24
0

Когда center=True, librosa заполняет сэмплами n_fft // 2 на обоих концах. Таким образом, n_fft не влияет на количество кадров. Но с center=False это не так, и вы должны принять во внимание n_fft. Я добавлю это к своему ответу.

Chong Onn Keat
26 сентября 2021 в 11:38
0

@ Хендрик, можете ли вы объяснить, как window приводит к тому, что количество кадров равно 41, показав пример расчета?

Hendrik
27 сентября 2021 в 12:22
0

Я не писал, что длина окна приводит к тому, что количество кадров равно 41. Я просто написал, что если отключить center, нужно учитывать длину окна.