Sơ lược về Mel Frequency Cepstral Coefficients (MFCCs)
MFCC là một cách để trích xuất các đặc trưng (feature extraction) giọng nói (speech) thường được sử dụng trong các model nhận dạng giọng nói (Automatic Speech Recognition) hay phân loại giọng nói (Speech Classification). Đúng như tên gọi của nó, MFCC sẽ cho ra kết quả là các hệ số (coefficients) ...
MFCC là một cách để trích xuất các đặc trưng (feature extraction) giọng nói (speech) thường được sử dụng trong các model nhận dạng giọng nói (Automatic Speech Recognition) hay phân loại giọng nói (Speech Classification). Đúng như tên gọi của nó, MFCC sẽ cho ra kết quả là các hệ số (coefficients) của cepstral (từ này mình không biết dịch sao hết) từ Mel filter trên phổ lấy được từ các file âm thanh chứa giọng nói.
Giọng nói thì thường sẽ được biểu diễn dưới dạng hai chiều (x,y)(x, y)(x,y) với xxx là thời gian (time) theo miliseconds (ms) và yyy là amplitude (dịch ra là biên độ). Trong đó những giá trị trên yyy được sinh ra trực tiếp từ bộ thu âm, do đó người ta thường gọi là speech signal.
Đầu tiên, ta sẽ biến đối speech signal thành âm phổ (hay còn gọi là spectrum) bằng cách áp dụng Fast Fourier Transform, mình sẽ không giải thích giải thuật này, các bạn có thể xem khái niệm ở wikipedia.
Kết quả của việc biến đổi này, tức là spectrum, được biểu diễn dưới dạng hai chiều (x′,y′)(x', y')(x′,y′) với x′x'x′ là tần số (Hz) và y′y'y′ là cường độ (dB).
Ở hình trên, các điểm màu đỏ được gọi là Formants, là nơi có các tần số áp đảo (dominant), mang đặc tính của âm thanh. Đường màu đỏ gọi là Spectral Envelopes. Mục tiêu chính của ta là lấy được đường màu đỏ này.
Gọi spectrum là X[k]X[k]X[k] có hai thành phần là spectral envelopes H[k]H[k]H[k] và spectral details E[k]E[k]E[k]
Để tách được H[k]H[k]H[k], ta cần phải lấy logarithm của spectrum và lấy phần ở tần số thấp (low frequency):
X[k]=H[k]∗E[k]⇔log(X[k])=log(H[k])+log(E[k])egin{aligned} X[k] &= H[k] * E[k] \ Leftrightarrow log(X[k]) &= log(H[k]) + log(E[k]) end{aligned} X[k]⇔log(X[k])=H[k]∗E[k]=log(H[k])+log(E[k])
Người ta thấy rằng tai người hoạt động như một bộ lọc, chỉ tập trung vào một phần thay vì hết cả spectral envelopes. Thế là một bộ lọc lấy ý tưởng này ra đời, gọi là Mel-Frequency Filter:
Chi tiết về bộ lọc này sẽ được nói ở phần sau. Sau khi áp dụng bộ lọc này, ta sẽ sử dụng Inverse Fast Fourier Transform lên logarithm của spectrum:
IFFT(log(X[k]))=IFFT(log(H[k])+log(E[k]))⇔x[k]=h[k]+e[k]egin{aligned} IFFT(log(X[k])) &= IFFT(log(H[k]) + log(E[k])) \ Leftrightarrow x[k] &= h[k] + e[k] end{aligned} IFFT(log(X[k]))⇔x[k]=IFFT(log(H[k])+log(E[k]))=h[k]+e[k]
Trong đó, x[k]x[k]x[k] được gọi là cepstrum vì IFFT là nghịch đảo của FFT và cepstrum cũng là nghịch đảo của spectrum, hay chứ nhỉ.
Cepstrum bây giờ sẽ giống như Speech Signal, biểu diễn dưới dạng hai chiều (x′′,y′′)(x', y')(x′′,y′′), nhưng giá trị sẽ khác nên người ta cũng gọi hai cột với tên khác là y′′y'y′′ là magnitude (không có đơn vị) và x′′x'x′′ là quefrency (ms).
Và MFCCs cũng chính là các giá trị lấy từ Cepstrum này, thông thường người ta sẽ lấy 12 hệ số của y′′y'y′′ vì mấy cái còn lại không có tác dụng trong các hệ thống nhận diện âm thanh.
Tóm lại, pipeline của ta sẽ là speech signal → ightarrow→ spectrum → ightarrow→ mel-freq filter → ightarrow→ cepstral.
Với nguyên lý hoạt động ở trên, để hiện thực cho máy tính trích xuất được MFCCs thì ta sẽ phải thêm một số thành phần khác. Pipeline cơ bản như sau:
Preemphasis
Ta sẽ áp dụng công thức sau lên speech signal:
y(t)=x(t)−αx(t−1)y(t) = x(t) - alpha x(t-1) y(t)=x(t)−αx(t−1)
Có nhiều lý do để áp dụng preemphasis như:
- Tránh vấn đề về số khi áp dụng FFT
- Làm cân bằng tần số spectrum
- Khuếch đại tần số cao (để lọc tần số thấp dễ hơn)
Nhưng mà preemphasis không bắt buộc sử dụng nữa vì FFT đã được cải thiện.
Framing
Speech signal ở dạng liên tục theo từng ms, do đó khó để giải quyết nên người ta sẽ chia speech signal thành các frames.
Mỗi frame có kích thước khoảng 20-40 ms và chồng lên nhau (tức là từ đầu frame sau tới cuối frame trước) khoảng 10-15 ms.
Kết quả sẽ ở dưới dạng hai chiều (x,y)(x, y)(x,y) với xxx là frame_length và yyy là number_of_frames.
Windowing
Do framing làm rời rạc hóa speech signal ta sẽ áp dụng một hàm gọi là Hamming Window để làm smooth các frames:
w[n]=0.54−0.46cos(2πnN−1),0≤n≤N−1w[n] = 0.54 - 0.46cos Big (frac{2pi n}{N - 1} Big ), 0 le n le N - 1 w[n]=0.54−0.46cos(N−12πn),0≤n≤N−1
Trong đó NNN là frame_length
Fourier Transform and Power Spectrum
Đây là bước ta chuyển speech signal thành spectrum, ta sẽ áp dụng công thức sau:
P=∣FFT(xi)2∣NFFTP = frac{lvert FFT(x_i)^2 lvert}{N_{FFT}} P=NFFT∣FFT(xi)2∣
Trong đó NFFTN_{FFT}NFFT bằng 256 hoặc 512, xix_ixi là frame thứ iii của speech signal xxx.
Filter Banks
Đây là bước ta áp dụng bộ lọc Mel-Frequency FIlter.
Các phương trình sau dùng để chuyển giữa Hert (f)(f)(f) và Mel (m)(m)(m):
m=2595log10(1+f700)f=700(10m/2595−1)egin{aligned} m &= 2595log_{10}(1 + frac{f}{700}) \ f &= 700(10^{m/2595} - 1) end{aligned} mf=2595log10(1+700f)=700(10m/2595−1)
Sau đây là chi tiết về bộ lọc này, đó là các phương trình sau:
Hm(k)=0iff k<f(m−1)=k−f(m−1)f(m)−f(m−1)iff f(m−1)≤k<f(m)=1iff k=f(m)=f(m+1)−kf(m+1)−f(m)iff f(m)<k≤f(m+1)=0iff k>f(m+1)egin{aligned} H_m(k) &= 0 & ext{iff} space k < f(m - 1) \ &= frac{k - f(m-1)}{f(m) - f(m-1)} & ext{iff} space f(m-1) le k < f(m) \ &= 1 & ext{iff} space k = f(m) \ &= frac{f(m+1) - k}{f(m+1) - f(m)} & ext{iff} space f(m) < k le f(m+1) \ &= 0 & ext{iff} space k > f(m+1) end{aligned} Hm(k)=0=f(m)−f(m−1)k−f(m−1)=1=f(m+1)−f(m)f(m+1)−k=0iff k<f(m−1)iff f(m−1)≤k<f(m)iff k=f(m)iff f(m)<k≤f(m+1)iff k>f(m+1)
Discrete Cosine Transform and MFCCs
Đây là bước ta chuyển từ spectrum qua cepstrum, áp dụng DCT (1 dạng IFFT) lên kết quả của filter banks ta sẽ có được các MFCCs, sau đó lấy 12 hệ số như đã nói.
- https://wiki.aalto.fi/display/ITSP/Cepstrum+and+MFCC
- http://practicalcryptography.com/miscellaneous/machine-learning/guide-mel-frequency-cepstral-coefficients-mfccs/
- https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html ở đây có cách hiện thực trong python
- http://www.speech.cs.cmu.edu/15-492/slides/03_mfcc.pdf