在MATLAB中结合MFCC特征提取与SVM训练,是语音识别、说话人识别等音频分类任务的经典流程。
从原始音频到分类结果的完整实现路径:
第二阶段: SVM模型训练与测试
第一阶段: MFCC特征提取
原始音频
预处理
预加重/分帧/加窗
计算Mel滤波器组能量
DCT变换得到MFCC
动态特征
(一阶/二阶差分)
特征与标签
数据分割
训练集/测试集
训练SVM模型
测试与评估
MFCC特征提取的核心步骤与MATLAB实现
MFCC旨在模仿人耳听觉特性。以下是核心步骤和MATLAB实现要点(可结合官方mfcc函数或以下自定义流程):
1. 预处理
matlab
% 读取音频
[audio, Fs] = audioread('your_audio.wav');
% 预加重:提升高频,常用 y(t) = x(t) - 0.97 * x(t-1)
pre_emphasis = 0.97;
emphasized = filter([1, -pre_emphasis], 1, audio);
2. 分帧与加窗
matlab
frame_length = round(0.025 * Fs); % 25ms
frame_step = round(0.01 * Fs); % 10ms重叠
frames = buffer(emphasized, frame_length, frame_length-frame_step, 'nodelay');
% 汉明窗减小帧边缘效应
hamming_win = hamming(frame_length);
windowed_frames = frames .* hamming_win;
3. Mel滤波器组能量
matlab
% 关键:将线性频谱映射到Mel刻度
num_mel_filters = 26; % 常用26-40个
low_freq_mel = 0;
high_freq_mel = 2595 * log10(1 + (Fs/2) / 700); % Hz转Mel
mel_points = linspace(low_freq_mel, high_freq_mel, num_mel_filters + 2);
hz_points = 700 * (10.^(mel_points/2595) - 1); % Mel转回Hz
bin = floor((frame_length + 1) * hz_points / Fs); % 对应FFT点数
% 构建三角Mel滤波器组
filter_bank = zeros(num_mel_filters, floor(frame_length/2) + 1);
for m = 1:num_mel_filters
f_left = bin(m);
f_center = bin(m + 1);
f_right = bin(m + 2);
for k = f_left:f_center
filter_bank(m, k) = (k - bin(m)) / (bin(m+1) - bin(m));
end
for k = f_center:f_right
filter_bank(m, k) = (bin(m+2) - k) / (bin(m+2) - bin(m+1));
end
end
% 计算每个滤波器能量
mag_frames = abs(fft(windowed_frames, frame_length));
power_frames = mag_frames.^2 / frame_length;
filter_bank_energies = filter_bank * power_frames(1:size(filter_bank,2), :);
4. 对数能量与DCT
matlab
% 取对数(模仿人耳对数响应)
log_filter_bank = log(filter_bank_energies + eps); % eps防止log(0)
% DCT得到MFCC系数(通常取前12-13个,加上能量共13-14维)
num_cepstral = 13;
mfcc = dct(log_filter_bank);
mfcc = mfcc(1:num_cepstral, :);
5. 增加动态特征(一阶/二阶差分)
matlab
% 一阶差分(Delta)
delta = zeros(size(mfcc));
for t = 2:size(mfcc, 2)-1
delta(:, t) = (mfcc(:, t+1) - mfcc(:, t-1)) / 2;
end
% 二阶差分(Delta-Delta)
delta_delta = zeros(size(delta));
for t = 2:size(delta, 2)-1
delta_delta(:, t) = (delta(:, t+1) - delta(:, t-1)) / 2;
end
% 组合成最终特征向量(通常为39维:13 MFCC + 13 Delta + 13 Delta-Delta)
features = [mfcc; delta; delta_delta];
SVM训练与分类
推荐使用MATLAB内置的fitcsvm或功能更强大的libsvm工具箱。
1. 准备数据与标签
matlab
% 假设已提取所有音频样本的MFCC特征,每个样本的特征矩阵已转换为行向量
% features_all: N个样本 x 特征维度 矩阵
% labels: N个样本 x 1 标签向量(如1, -1 或 1, 2, 3...)
% 分割训练集和测试集(80%/20%)
cv = cvpartition(size(features_all, 1), 'HoldOut', 0.2);
train_features = features_all(cv.training, :);
train_labels = labels(cv.training, :);
test_features = features_all(cv.test, :);
test_labels = labels(cv.test, :);
2. 训练SVM模型
matlab
% MATLAB内置fitcsvm(适用于二分类,多分类需用fitcecoc)
SVMModel = fitcsvm(train_features, train_labels, ...
'KernelFunction', 'rbf', ... % 常用'linear', 'rbf'
'BoxConstraint', 1, ... % 正则化参数C
'KernelScale', 'auto', ... % RBF核的gamma
'Standardize', true); % 标准化特征
% 或使用libsvm(需先安装:https://www.csie.ntu.edu.tw/~cjlin/libsvm/)
% model = svmtrain(train_labels, train_features, '-c 1 -g 0.07');
3. 预测与评估
matlab
% 预测
[predicted_labels, scores] = predict(SVMModel, test_features);
% 评估准确率
accuracy = sum(predicted_labels == test_labels) / numel(test_labels);
fprintf('准确率: %.2f%%\n', accuracy * 100);
% 绘制混淆矩阵(多分类)
figure;
confusionchart(test_labels, predicted_labels);
参考代码 mfcc特征提取法 www.3dddown.com/csa/95858.html
注意事项与技巧
-
特征标准化:SVM对特征尺度敏感,务必在训练前标准化。
matlab[train_features_scaled, mu, sigma] = zscore(train_features); test_features_scaled = (test_features - mu) ./ sigma; -
SVM参数调优 :使用交叉验证寻找最优
C(惩罚系数)和gamma(RBF核参数)。matlabcv_svm = fitcsvm(train_features, train_labels, 'KernelFunction', 'rbf', ... 'OptimizeHyperparameters', {'BoxConstraint', 'KernelScale'}, ... 'HyperparameterOptimizationOptions', struct('ShowPlots', false)); -
处理多分类问题:
- 一对一 :为每对类别训练一个SVM(MATLAB的
fitcecoc默认采用)。 - 一对多:为每个类别训练一个"本类 vs 其余"的SVM。
- 一对一 :为每对类别训练一个SVM(MATLAB的
-
特征降维:MFCC特征维度过高时(如39维 x 帧数),可考虑:
- 计算每维特征的统计量(均值、标准差等)作为全局特征。
- 使用PCA降维后再输入SVM。