一、技术原理与系统架构
1. 希尔伯特-黄变换(HHT)核心思想
HHT由经验模态分解(EMD)和 希尔伯特变换(HT)组成,特别适合处理非平稳、非线性信号:
-
EMD :将复杂信号分解为有限个固有模态函数(IMF),每个IMF代表不同时间尺度的振荡模式
-
HT :对每个IMF进行希尔伯特变换,计算瞬时频率 和瞬时幅值,构建时频能量分布
2. 神经网络分类器
-
输入层:HHT提取的时频特征(IMF能量、边际谱特征等)
-
隐藏层:全连接层或卷积层提取深层特征
-
输出层:Softmax分类器(正常/故障类型)
3. 系统架构
原始信号
EMD分解
IMF分量
希尔伯特变换
时频特征提取
特征选择与降维
神经网络分类器
故障诊断结果
二、MATLAB实现代码
1. 主程序框架
matlab
% HHT-神经网络故障诊断系统
clear; clc; close all;
% ========== 参数设置 ==========
fs = 10000; % 采样频率 (Hz)
duration = 1; % 信号时长 (s)
t = 0:1/fs:duration-1/fs;
numSamples = length(t);
% 故障类型定义
faultTypes = {'Normal', 'InnerRaceFault', 'OuterRaceFault', 'BallFault'};
numClasses = length(faultTypes);
% ========== 数据准备 ==========
% 生成模拟信号(实际应用时替换为真实数据)
[normalSig, faultSigs] = generateBearingSignals(t, fs);
% 合并数据集
allSignals = [normalSig, faultSigs];
labels = [zeros(1, size(normalSig,2)), ones(1, size(faultSigs,2))]; % 0=正常, 1=故障
% 添加噪声
SNR = 10; % 信噪比(dB)
noisySignals = awgn(allSignals, SNR, 'measured');
% ========== HHT特征提取 ==========
features = cell(1, size(noisySignals, 2));
for i = 1:size(noisySignals, 2)
signal = noisySignals(:, i);
% EMD分解
imfs = emd(signal, 'MaxNumIMF', 5, 'Display', 0);
% 希尔伯特变换与时频分析
[instFreq, instAmp, marginalSpec] = hilbertTransform(imfs, fs);
% 特征提取
feat = extractFeatures(imfs, instFreq, instAmp, marginalSpec);
features{i} = feat;
end
% 转换为特征矩阵
featureMatrix = cell2mat(features');
featureMatrix = normalize(featureMatrix, 2, 'zscore'); % 标准化
% ========== 神经网络训练 ==========
% 划分训练集和测试集
rng(42); % 设置随机种子
cv = cvpartition(size(featureMatrix, 1), 'HoldOut', 0.3);
trainIdx = training(cv);
testIdx = test(cv);
XTrain = featureMatrix(trainIdx, :);
YTrain = categorical(labels(trainIdx) + 1); % 转换为分类变量
XTest = featureMatrix(testIdx, :);
YTest = categorical(labels(testIdx) + 1);
% 创建神经网络
net = createNN(size(XTrain, 2), numClasses);
% 训练网络
options = trainingOptions('adam', ...
'MaxEpochs', 100, ...
'MiniBatchSize', 32, ...
'ValidationData', {XTest, YTest}, ...
'Plots', 'training-progress', ...
'Verbose', false);
net = trainNetwork(XTrain, YTrain, net, options);
% ========== 性能评估 ==========
YPred = classify(net, XTest);
accuracy = sum(YPred == YTest) / numel(YTest);
confMat = confusionmat(YTest, YPred);
% 显示结果
disp(['测试准确率: ', num2str(accuracy*100), '%']);
figure;
confusionchart(confMat, faultTypes);
title('混淆矩阵');
% ========== 可视化分析 ==========
visualizeResults(noisySignals, features, YTest, YPred, faultTypes);
2. EMD分解函数
matlab
function imfs = emd(signal, varargin)
% 经验模态分解(EMD)实现
% 输入: signal - 输入信号
% varargin - 可选参数: MaxNumIMF, Display
% 输出: imfs - IMF分量矩阵 (每列一个IMF)
% 参数解析
params = parseInputs(varargin{:});
maxNumIMF = params.MaxNumIMF;
display = params.Display;
residue = signal;
imfs = [];
iterCount = 0;
while ~isMonotonic(residue) && size(imfs, 2) < maxNumIMF
h = residue;
k = 0;
while ~isIMF(h) && k < 10 % 内层循环次数限制
% 寻找极值点
maxPeaks = findPeaks(h);
minPeaks = findPeaks(-h);
% 三次样条插值构造包络线
upperEnv = spline(maxPeaks(:,1), maxPeaks(:,2), 1:length(h));
lowerEnv = spline(minPeaks(:,1), minPeaks(:,2), 1:length(h));
% 计算均值包络
meanEnv = (upperEnv + lowerEnv)/2;
% 更新h
h_prev = h;
h = h - meanEnv;
% 检查终止条件
if sum(abs(h - h_prev)) < 0.01*std(signal)
break;
end
k = k + 1;
end
% 保存IMF
imfs = [imfs, h];
residue = residue - h;
iterCount = iterCount + 1;
if display
fprintf('IMF %d extracted, iterations: %d\n', size(imfs,2), k);
end
end
% 添加残差
imfs = [imfs, residue];
end
function isMono = isMonotonic(x)
% 检查信号是否单调
diffX = diff(x);
isMono = all(diffX >= 0) || all(diffX <= 0);
end
function isImf = isIMF(h)
% 检查是否满足IMF条件
% 1. 过零点数等于极值点数或相差1
% 2. 局部均值为零
numExtrema = countExtrema(h);
numZeroCrossings = countZeroCrossings(h);
if abs(numExtrema - numZeroCrossings) > 1
isImf = false;
return;
end
% 计算局部均值
maxPeaks = findPeaks(h);
minPeaks = findPeaks(-h);
meanEnv = (spline(maxPeaks(:,1), maxPeaks(:,2), 1:length(h)) + ...
spline(minPeaks(:,1), minPeaks(:,2), 1:length(h)))/2;
isImf = rms(meanEnv) < 0.1*std(h);
end
function peaks = findPeaks(x)
% 寻找极值点
dx = diff(x);
signChange = diff(dx > 0);
peakIndices = find(signChange == -1) + 1;
% 二次插值精确定位
peaks = [];
for i = 1:length(peakIndices)
idx = peakIndices(i);
if idx > 1 && idx < length(x)
a = x(idx-1); b = x(idx); c = x(idx+1);
offset = (a - c)/(2*(a - 2*b + c));
peakPos = idx + offset;
peakVal = b - (a - c)^2/(8*(a - 2*b + c));
peaks = [peaks; peakPos, peakVal];
end
end
end
3. 希尔伯特变换与特征提取
matlab
function [instFreq, instAmp, marginalSpec] = hilbertTransform(imfs, fs)
% 希尔伯特变换计算瞬时频率和幅值
numImf = size(imfs, 2);
instFreq = cell(1, numImf);
instAmp = cell(1, numImf);
marginalSpec = zeros(100, numImf); % 边际谱
for k = 1:numImf
imf = imfs(:, k);
analyticSignal = hilbert(imf);
instAmp{k} = abs(analyticSignal);
instPhase = unwrap(angle(analyticSignal));
instFreq{k} = diff(instPhase)/(2*pi) * fs; % 瞬时频率
% 计算边际谱
[freqAxis, spec] = spectrogram(instAmp{k}, 128, 120, 128, fs);
marginalSpec(:, k) = sum(abs(spec), 2);
end
end
function feat = extractFeatures(imfs, instFreq, instAmp, marginalSpec)
% 从IMF分量中提取特征
numImf = size(imfs, 2);
feat = [];
% 1. IMF能量特征
energy = zeros(1, numImf);
for k = 1:numImf
energy(k) = sum(imfs(:, k).^2);
end
feat = [feat, energy/norm(energy)]; % 归一化能量
% 2. 瞬时频率统计特征
for k = 1:numImf
if ~isempty(instFreq{k})
meanFreq = mean(instFreq{k});
stdFreq = std(instFreq{k});
skewFreq = skewness(instFreq{k});
kurtFreq = kurtosis(instFreq{k});
feat = [feat, meanFreq, stdFreq, skewFreq, kurtFreq];
else
feat = [feat, 0, 0, 0, 0];
end
end
% 3. 边际谱特征
for k = 1:numImf
[maxVal, maxIdx] = max(marginalSpec(:, k));
meanSpec = mean(marginalSpec(:, k));
stdSpec = std(marginalSpec(:, k));
feat = [feat, maxVal, maxIdx, meanSpec, stdSpec];
end
% 4. 时域统计特征
for k = 1:numImf
imf = imfs(:, k);
feat = [feat, mean(imf), std(imf), rms(imf), kurtosis(imf)];
end
end
4. 神经网络创建与训练
matlab
function net = createNN(inputSize, numClasses)
% 创建神经网络结构
layers = [
featureInputLayer(inputSize, 'Name', 'input') % 输入层
fullyConnectedLayer(128, 'Name', 'fc1') % 全连接层1
batchNormalizationLayer('Name', 'bn1') % 批归一化
reluLayer('Name', 'relu1') % ReLU激活
dropoutLayer(0.3, 'Name', 'drop1') % Dropout层
fullyConnectedLayer(64, 'Name', 'fc2') % 全连接层2
batchNormalizationLayer('Name', 'bn2')
reluLayer('Name', 'relu2')
dropoutLayer(0.2, 'Name', 'drop2')
fullyConnectedLayer(32, 'Name', 'fc3') % 全连接层3
reluLayer('Name', 'relu3')
fullyConnectedLayer(numClasses, 'Name', 'output') % 输出层
softmaxLayer('Name', 'softmax') % Softmax分类
classificationLayer('Name', 'classification') % 分类层
];
% 网络选项
options = trainingOptions('adam', ...
'InitialLearnRate', 0.001, ...
'LearnRateSchedule', 'piecewise', ...
'LearnRateDropFactor', 0.5, ...
'LearnRateDropPeriod', 20, ...
'L2Regularization', 0.001, ...
'Shuffle', 'every-epoch', ...
'ValidationPatience', 10, ...
'ExecutionEnvironment', 'auto');
% 创建网络
net = layerGraph(layers);
end
5. 轴承故障信号生成(模拟)
matlab
function [normalSig, faultSigs] = generateBearingSignals(t, fs)
% 生成轴承正常和故障信号
% 输入: t - 时间向量, fs - 采样频率
% 输出: normalSig - 正常信号, faultSigs - 故障信号矩阵
% 基本参数
fn = 2000; % 轴转频 (Hz)
BPFO = 3.2*fn; % 外圈故障特征频率
BPFI = 4.8*fn; % 内圈故障特征频率
BSF = 2.1*fn; % 滚动体故障特征频率
% 正常信号(高斯白噪声 + 正弦波)
normalSig = 0.5*randn(size(t)) + 2*sin(2*pi*fn*t);
% 外圈故障信号
outerFault = 0.3*randn(size(t)) + 1.5*sin(2*pi*fn*t) + ...
0.8*sin(2*pi*BPFO*t) + 0.5*sin(2*pi*2*BPFO*t);
% 内圈故障信号
innerFault = 0.3*randn(size(t)) + 1.5*sin(2*pi*fn*t) + ...
0.7*sin(2*pi*BPFI*t) + 0.4*sin(2*pi*2*BPFI*t);
% 滚动体故障信号
ballFault = 0.3*randn(size(t)) + 1.5*sin(2*pi*fn*t) + ...
0.6*sin(2*pi*BSF*t) + 0.3*sin(2*pi*2*BSF*t);
% 添加冲击成分
impactInterval = 1/(2*fn); % 冲击间隔
impactTimes = 0:impactInterval:max(t);
for i = 1:length(impactTimes)
idx = find(t >= impactTimes(i), 1);
if ~isempty(idx) && idx < length(t)
% 外圈故障冲击
outerFault(idx:min(idx+10, end)) = outerFault(idx:min(idx+10, end)) + 3*exp(-50*(0:9));
% 内圈故障冲击
innerFault(idx:min(idx+10, end)) = innerFault(idx:min(idx+10, end)) + 3*exp(-50*(0:9));
% 滚动体故障冲击
ballFault(idx:min(idx+10, end)) = ballFault(idx:min(idx+10, end)) + 3*exp(-50*(0:9));
end
end
% 组合故障信号
faultSigs = [outerFault, innerFault, ballFault];
end
6. 结果可视化
matlab
function visualizeResults(signals, features, YTest, YPred, faultTypes)
% 可视化分析结果
figure('Position', [100, 100, 1200, 800]);
% 1. 原始信号示例
subplot(3, 2, [1, 2]);
plot(signals(:, 1));
hold on;
plot(signals(:, 2), 'r');
title('原始信号示例');
legend('正常信号', '故障信号');
xlabel('样本点');
ylabel('幅值');
% 2. IMF分量示例
subplot(3, 2, 3);
imfs = emd(signals(:, 1), 'MaxNumIMF', 4, 'Display', 0);
plot(imfs);
title('正常信号的IMF分量');
xlabel('样本点');
ylabel('幅值');
legend({'IMF1', 'IMF2', 'IMF3', 'IMF4', '残差'});
subplot(3, 2, 4);
imfs = emd(signals(:, 2), 'MaxNumIMF', 4, 'Display', 0);
plot(imfs);
title('故障信号的IMF分量');
xlabel('样本点');
ylabel('幅值');
% 3. 时频分析示例
subplot(3, 2, 5);
[instFreq, instAmp] = hilbertTransform(imfs, 10000);
imagesc(1:length(instAmp{1}), 1:length(instFreq{1}), abs([instFreq{:}]));
title('瞬时频率分布');
xlabel('时间');
ylabel('IMF分量');
colorbar;
subplot(3, 2, 6);
marginalSpec = zeros(50, size(imfs, 2));
for k = 1:size(imfs, 2)
[freqAxis, spec] = spectrogram(instAmp{k}, 64, 60, 64, 10000);
marginalSpec(:, k) = sum(abs(spec), 2);
end
imagesc(linspace(0, 5000, 50), 1:size(imfs, 2), marginalSpec);
title('边际谱');
xlabel('频率 (Hz)');
ylabel('IMF分量');
colorbar;
% 4. 特征重要性分析(使用随机森林)
figure;
allFeatures = cell2mat(features');
labelsAll = repelem([0; 1; 1; 1], size(signals, 2)); % 标签
rf = TreeBagger(50, allFeatures, categorical(labelsAll), ...
'Method', 'classification', 'OOBPredictorImportance', 'on');
imp = rf.OOBPermutedPredictorDeltaError;
bar(imp);
title('特征重要性排序');
xlabel('特征索引');
ylabel('重要性得分');
grid on;
% 5. 混淆矩阵(已在主程序中显示)
end
参考代码 把HHT和神经网络结合起来,识别出是否故障 www.youwenfan.com/contentcss/53366.html
三、关键技术解析
1. EMD分解优化
| 问题 | 解决方案 | MATLAB实现 |
|---|---|---|
| 端点效应 | 镜像延拓法 | signal = [flip(signal(1:50)); signal; flip(signal(end-49:end))] |
| 模态混叠 | 互补集合经验模态分解(CEEMDAN) | 添加正负白噪声集合平均 |
| 停止准则 | 标准差阈值法 | SD = sum((h_prev - h).^2)/sum(h_prev.^2) |
2. 特征选择与降维
matlab
function selectedFeatures = featureSelection(featureMatrix, labels)
% 特征选择与降维
% 1. 相关性分析
corrMatrix = corr(featureMatrix);
highCorrPairs = find(abs(corrMatrix) > 0.95 & triu(ones(size(corrMatrix)), 1));
% 2. 互信息筛选
mi = zeros(1, size(featureMatrix, 2));
for i = 1:size(featureMatrix, 2)
mi(i) = mutualInformation(featureMatrix(:, i), labels);
end
% 3. PCA降维
[coeff, score, latent] = pca(featureMatrix);
cumVar = cumsum(latent)/sum(latent);
numComponents = find(cumVar >= 0.95, 1); % 保留95%方差
selectedFeatures = score(:, 1:numComponents);
end
function mi = mutualInformation(x, y)
% 计算互信息
bins = 50;
px = histcounts(x, bins, 'Normalization', 'pdf');
py = histcounts(y, bins, 'Normalization', 'pdf');
pxy = histcounts2(x, y, bins, bins, 'Normalization', 'pdf');
mi = 0;
for i = 1:bins
for j = 1:bins
if pxy(i,j) > 0
mi = mi + pxy(i,j) * log2(pxy(i,j)/(px(i)*py(j)));
end
end
end
end
3. 神经网络优化技巧
-
学习率调度:
matlaboptions = trainingOptions('adam', ... 'LearnRateSchedule', 'piecewise', ... 'LearnRateDropFactor', 0.5, ... 'LearnRateDropPeriod', 20); -
正则化技术:
matlablayers = [ ... fullyConnectedLayer(128) batchNormalizationLayer() reluLayer() dropoutLayer(0.3) % 防止过拟合 ... ]; options = trainingOptions(..., 'L2Regularization', 0.001); -
早停机制:
matlaboptions = trainingOptions(..., 'ValidationPatience', 10, % 10次验证无改善则停止 'OutputFcn', @(info)stopIfAccuracyNotImproving(info, 0.98));
四、工业应用案例
1. 风力发电机齿轮箱故障诊断
matlab
% 实际数据加载与处理
load('windTurbineData.mat'); % 包含振动信号和故障标签
% 特征提取
featureMatrix = [];
for i = 1:size(vibrationData, 2)
signal = vibrationData(:, i);
imfs = emd(signal, 'MaxNumIMF', 6);
[instFreq, instAmp, marginalSpec] = hilbertTransform(imfs, 25000);
feat = extractFeatures(imfs, instFreq, instAmp, marginalSpec);
featureMatrix = [featureMatrix; feat];
end
% 添加工况特征
load('operatingConditions.mat'); % 转速、负载等
featureMatrix = [featureMatrix, operatingConditions];
% 训练诊断模型
net = createNN(size(featureMatrix, 2), 4); % 4种故障类型
trainedNet = trainNetwork(featureMatrix, labels, net, options);
% 部署到SCADA系统
save('gearboxDiagnosisModel.mat', 'trainedNet');
2. 变压器局部放电模式识别
matlab
% 局部放电信号处理
pdSignals = loadPDsignals(); % 局部放电信号
% 小波去噪
denoisedSignals = waveletDenoise(pdSignals, 'db4', 5);
% HHT分析
for i = 1:size(denoisedSignals, 2)
[imfs, res] = emd(denoisedSignals(:, i), 'MaxNumIMF', 5);
[hs, f, t] = hht(imfs, fs);
% 提取放电特征
pdFeatures(i, :) = extractPDfeatures(hs, f, t);
end
% 训练分类器
svmModel = fitcecoc(pdFeatures, dischargeTypes, 'Learners', 'svm');
五、系统部署与维护
1. 实时诊断系统架构
传感器
数据采集单元
边缘计算节点
HHT特征提取
神经网络推理
故障预警
云平台监控
2. 在线更新机制
matlab
function updateModel(newData, newLabels)
% 加载现有模型
load('currentModel.mat', 'net');
% 增量训练
updatedNet = trainNetwork(newData, newLabels, net, ...
'InitialLearnRate', 1e-4, ...
'MaxEpochs', 10);
% 模型验证
validationAccuracy = validateModel(updatedNet, validationSet);
% 版本管理
save(sprintf('model_v%d_%s.mat', datetime('now'), 'backup'), 'updatedNet');
% 部署更新
if validationAccuracy > bestAccuracy
deployModel(updatedNet);
bestAccuracy = validationAccuracy;
end
end
六、总结
1. 技术优势
-
强大的特征提取能力:HHT对非平稳信号的自适应分解优于传统FFT和小波分析
-
端到端的诊断流程:从原始信号到故障分类的完整解决方案
-
高兼容性:可与多种神经网络架构结合(CNN、LSTM、Transformer)
-
工业适用性:已在风电、轨交、电力等领域成功应用
2. 未来发展方向
-
多模态融合诊断:
matlab% 融合振动、温度、声音信号 fusedFeatures = [vibrationFeatures, temperatureFeatures, acousticFeatures]; -
深度学习增强:
matlab% 使用CNN自动学习特征 layers = [ imageInputLayer([size(imfs,1) size(imfs,2) 1]) convolution2dLayer(3, 16, 'Padding', 'same') reluLayer maxPooling2dLayer(2, 'Stride', 2) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer ]; -
数字孪生集成:
matlab% 构建设备数字孪生模型 digitalTwin = createDigitalTwin(deviceParameters); % 实时仿真与故障注入 [simulatedSignal, faultIndicators] = simulateFault(digitalTwin, faultType); % 与实际信号比对 residual = actualSignal - simulatedSignal;