基于混合神经网络(CNN-LSTM)的电能扰动信号特征识别MATLAB实现。这个方案包含信号生成、特征提取、神经网络建模和性能评估的全流程。
matlab
%% 基于神经网络的电能扰动信号特征识别 - MATLAB实现
clear; close all; clc;
warning('off', 'all');
fprintf('=== 电能扰动信号神经网络特征识别 ===\n');
%% 1. 参数设置与数据生成
fprintf('1. 生成电能扰动信号数据集...\n');
% 1.1 基础参数
fs = 3200; % 采样频率 (Hz)
T = 0.2; % 信号时长 (s)
t = 0:1/fs:T-1/fs; % 时间向量
N = length(t); % 采样点数
f0 = 50; % 基频 (Hz)
V_nominal = 220; % 额定电压 (V)
num_samples_per_class = 200; % 每类样本数
% 1.2 定义扰动类型(7类)
disturbance_types = {
'正常信号', % 1
'电压暂降', % 2
'电压暂升', % 3
'电压中断', % 4
'谐波失真', % 5
'瞬态振荡', % 6
'电压波动' % 7
};
num_classes = length(disturbance_types);
% 1.3 生成扰动信号函数
function signal = generate_disturbance_signal(t, f0, V_nominal, type_idx, fs)
% 生成基波信号
base_signal = V_nominal * sqrt(2) * sin(2*pi*f0*t);
switch type_idx
case 1 % 正常信号
signal = base_signal;
case 2 % 电压暂降 (sag)
sag_start = 0.05; % 暂降开始时间
sag_duration = 0.06; % 暂降持续时间
sag_depth = 0.6; % 暂降深度 (40%剩余)
sag_mask = (t >= sag_start) & (t < sag_start + sag_duration);
signal = base_signal;
signal(sag_mask) = sag_depth * signal(sag_mask);
case 3 % 电压暂升 (swell)
swell_start = 0.05;
swell_duration = 0.06;
swell_factor = 1.4; % 升高到140%
swell_mask = (t >= swell_start) & (t < swell_start + swell_duration);
signal = base_signal;
signal(swell_mask) = swell_factor * signal(swell_mask);
case 4 % 电压中断 (interruption)
int_start = 0.05;
int_duration = 0.08;
int_depth = 0.1; % 仅剩10%
int_mask = (t >= int_start) & (t < int_start + int_duration);
signal = base_signal;
signal(int_mask) = int_depth * signal(int_mask);
case 5 % 谐波失真 (harmonics)
% 添加3次、5次、7次谐波
signal = base_signal + ...
0.15*V_nominal*sqrt(2)*sin(2*pi*3*f0*t + pi/4) + ...
0.10*V_nominal*sqrt(2)*sin(2*pi*5*f0*t + pi/3) + ...
0.05*V_nominal*sqrt(2)*sin(2*pi*7*f0*t + pi/6);
case 6 % 瞬态振荡 (transient oscillation)
osc_start = 0.05;
osc_duration = 0.03;
osc_freq = 1000; % 1kHz振荡
osc_decay = 50; % 衰减系数
osc_mask = (t >= osc_start) & (t < osc_start + osc_duration);
signal = base_signal;
osc_component = 0.3*V_nominal*sqrt(2)*sin(2*pi*osc_freq*(t-osc_start));
osc_component = osc_component .* exp(-osc_decay*(t-osc_start));
signal(osc_mask) = signal(osc_mask) + osc_component(osc_mask);
case 7 % 电压波动 (flicker)
flicker_freq = 8; % 8Hz波动
flicker_depth = 0.1; % 10%波动深度
flicker_modulation = 1 + flicker_depth * sin(2*pi*flicker_freq*t);
signal = base_signal .* flicker_modulation;
otherwise
signal = base_signal;
end
% 添加高斯白噪声
SNR = 40; % 信噪比 (dB)
signal_power = mean(signal.^2);
noise_power = signal_power / (10^(SNR/10));
noise = sqrt(noise_power) * randn(size(signal));
signal = signal + noise;
end
% 1.4 生成完整数据集
X_raw = zeros(num_samples_per_class * num_classes, N);
Y = zeros(num_samples_per_class * num_classes, 1);
sample_idx = 1;
for class_idx = 1:num_classes
fprintf(' 生成类别 %d: %s\n', class_idx, disturbance_types{class_idx});
for sample_num = 1:num_samples_per_class
% 为每个样本添加随机变化,增加多样性
t_rand = t + randn()*0.002; % 时间轻微抖动
% 生成信号
signal = generate_disturbance_signal(t_rand, f0, V_nominal, class_idx, fs);
% 存储
X_raw(sample_idx, :) = signal;
Y(sample_idx) = class_idx;
sample_idx = sample_idx + 1;
end
end
fprintf(' 数据集大小: %d 个样本, 每类 %d 个样本\n', size(X_raw, 1), num_samples_per_class);
%% 2. 特征提取(混合特征集)
fprintf('\n2. 提取信号特征...\n');
% 2.1 初始化特征矩阵
num_features = 18; % 提取的特征数量
X_features = zeros(size(X_raw, 1), num_features);
for i = 1:size(X_raw, 1)
signal = X_raw(i, :);
% 2.2 时域特征
% 1-2: 均值和标准差
features(1) = mean(signal);
features(2) = std(signal);
% 3-4: 峰值和峰峰值
features(3) = max(signal);
features(4) = max(signal) - min(signal);
% 5: 均方根值 (RMS)
features(5) = sqrt(mean(signal.^2));
% 6: 波形因子
features(6) = features(5) / mean(abs(signal));
% 7: 峰值因子
features(7) = features(3) / features(5);
% 8: 脉冲因子
features(8) = features(3) / mean(abs(signal));
% 9: 偏度
features(9) = skewness(signal);
% 10: 峰度
features(10) = kurtosis(signal);
% 2.3 频域特征
% FFT变换
L = length(signal);
Y_fft = fft(signal);
P2 = abs(Y_fft/L);
P1 = P2(1:floor(L/2)+1);
P1(2:end-1) = 2*P1(2:end-1);
f = fs*(0:(L/2))/L;
% 11: 基波幅值
[~, f0_idx] = min(abs(f - f0));
features(11) = P1(f0_idx);
% 12: 总谐波失真 (THD)
harmonic_indices = [3, 5, 7, 9, 11]; % 谐波次数
harmonic_power = 0;
for h_idx = 1:length(harmonic_indices)
harmonic_freq = harmonic_indices(h_idx) * f0;
[~, h_freq_idx] = min(abs(f - harmonic_freq));
harmonic_power = harmonic_power + P1(h_freq_idx)^2;
end
features(12) = sqrt(harmonic_power) / features(11);
% 13: 高频能量占比
low_freq_cutoff = 500; % Hz
[~, cutoff_idx] = min(abs(f - low_freq_cutoff));
total_energy = sum(P1.^2);
high_freq_energy = sum(P1(cutoff_idx:end).^2);
features(13) = high_freq_energy / total_energy;
% 2.4 时频特征(小波变换能量)
% 使用小波变换提取多尺度能量
[c, l] = wavedec(signal, 3, 'db4'); % 3级小波分解
% 14-16: 各尺度细节系数能量
for level = 1:3
d = wrcoef('d', c, l, 'db4', level);
features(13 + level) = sum(d.^2) / length(d);
end
% 17: 近似系数能量
a = wrcoef('a', c, l, 'db4', 3);
features(17) = sum(a.^2) / length(a);
% 18: 能量熵
energy_levels = [features(14), features(15), features(16), features(17)];
energy_levels = energy_levels / sum(energy_levels);
features(18) = -sum(energy_levels .* log(energy_levels + eps));
X_features(i, :) = features;
end
fprintf(' 提取了 %d 个时域、频域和时频特征\n', num_features);
%% 3. 数据预处理与划分
fprintf('\n3. 数据预处理与划分...\n');
% 3.1 特征标准化
X_normalized = normalize(X_features);
% 3.2 划分训练集、验证集、测试集
rng(42); % 设置随机种子保证可重复性
cv = cvpartition(Y, 'HoldOut', 0.2);
idx_train = training(cv);
idx_test = test(cv);
% 进一步从训练集中划分验证集
cv_val = cvpartition(Y(idx_train), 'HoldOut', 0.25);
idx_val = test(cv_val);
temp_idx = find(idx_train);
idx_train(temp_idx(idx_val)) = false;
idx_val_all = false(size(Y));
idx_val_all(temp_idx(idx_val)) = true;
% 3.3 准备数据集
X_train = X_normalized(idx_train, :);
Y_train = categorical(Y(idx_train));
X_val = X_normalized(idx_val_all, :);
Y_val = categorical(Y(idx_val_all));
X_test = X_normalized(idx_test, :);
Y_test = categorical(Y(idx_test));
fprintf(' 训练集: %d 样本\n', sum(idx_train));
fprintf(' 验证集: %d 样本\n', sum(idx_val_all));
fprintf(' 测试集: %d 样本\n', sum(idx_test));
%% 4. 构建混合神经网络模型
fprintf('\n4. 构建CNN-LSTM混合神经网络模型...\n');
% 4.1 重塑输入数据为CNN需要的格式 [样本数, 特征数, 通道数, 1]
input_shape = [size(X_train, 2), 1, 1];
% 4.2 定义网络架构
layers = [
% 输入层
sequenceInputLayer(input_shape(1), 'Name', 'input')
% 重塑层: 将特征向量重塑为适合CNN的格式
reshapeLayer([input_shape(1) 1 1], 'Name', 'reshape')
% CNN特征提取部分
convolution2dLayer([3, 1], 32, 'Padding', 'same', 'Name', 'conv1')
batchNormalizationLayer('Name', 'bn1')
reluLayer('Name', 'relu1')
maxPooling2dLayer([2, 1], 'Stride', [2, 1], 'Name', 'pool1')
convolution2dLayer([3, 1], 64, 'Padding', 'same', 'Name', 'conv2')
batchNormalizationLayer('Name', 'bn2')
reluLayer('Name', 'relu2')
maxPooling2dLayer([2, 1], 'Stride', [2, 1], 'Name', 'pool2')
% 展平层
flattenLayer('Name', 'flatten')
% LSTM时序处理部分
bilstmLayer(100, 'OutputMode', 'last', 'Name', 'bilstm')
dropoutLayer(0.5, 'Name', 'dropout1')
% 全连接层
fullyConnectedLayer(64, 'Name', 'fc1')
reluLayer('Name', 'relu3')
dropoutLayer(0.3, 'Name', 'dropout2')
fullyConnectedLayer(32, 'Name', 'fc2')
reluLayer('Name', 'relu4')
% 输出层
fullyConnectedLayer(num_classes, 'Name', 'fc_out')
softmaxLayer('Name', 'softmax')
classificationLayer('Name', 'output')
];
% 4.3 显示网络结构
analyzeNetwork(layers);
% 4.4 设置训练选项
options = trainingOptions('adam', ...
'MaxEpochs', 100, ...
'MiniBatchSize', 32, ...
'InitialLearnRate', 0.001, ...
'LearnRateSchedule', 'piecewise', ...
'LearnRateDropFactor', 0.5, ...
'LearnRateDropPeriod', 30, ...
'Shuffle', 'every-epoch', ...
'ValidationData', {X_val, Y_val}, ...
'ValidationFrequency', 10, ...
'Verbose', true, ...
'VerboseFrequency', 10, ...
'Plots', 'training-progress', ...
'ExecutionEnvironment', 'auto');
%% 5. 训练神经网络
fprintf('\n5. 训练神经网络...\n');
% 重塑训练数据
X_train_cnn = reshape(X_train', [size(X_train, 2), 1, 1, size(X_train, 1)]);
X_val_cnn = reshape(X_val', [size(X_val, 2), 1, 1, size(X_val, 1)]);
% 训练网络
[net, info] = trainNetwork(X_train_cnn, Y_train, layers, options);
fprintf(' 训练完成!\n');
%% 6. 模型评估
fprintf('\n6. 模型评估...\n');
% 6.1 测试集预测
X_test_cnn = reshape(X_test', [size(X_test, 2), 1, 1, size(X_test, 1)]);
Y_pred = classify(net, X_test_cnn);
Y_test_categorical = categorical(Y_test);
% 6.2 计算评估指标
accuracy = sum(Y_pred == Y_test_categorical) / length(Y_test_categorical);
fprintf(' 测试集准确率: %.2f%%\n', accuracy * 100);
% 6.3 混淆矩阵
figure('Position', [100, 100, 800, 600]);
cm = confusionmat(Y_test_categorical, Y_pred);
confusionchart(cm, disturbance_types);
title(sprintf('混淆矩阵 (准确率: %.1f%%)', accuracy*100));
% 6.4 分类报告
fprintf('\n 分类报告:\n');
fprintf(' %-15s %-10s %-10s %-10s\n', '类别', '精确率', '召回率', 'F1分数');
for i = 1:num_classes
TP = cm(i, i);
FP = sum(cm(:, i)) - TP;
FN = sum(cm(i, :)) - TP;
precision = TP / (TP + FP + eps);
recall = TP / (TP + FN + eps);
f1_score = 2 * (precision * recall) / (precision + recall + eps);
fprintf(' %-15s %-10.3f %-10.3f %-10.3f\n', ...
disturbance_types{i}, precision, recall, f1_score);
end
%% 7. 特征重要性分析
fprintf('\n7. 特征重要性分析...\n');
% 7.1 使用排列特征重要性
num_permutations = 100;
feature_importance = zeros(1, size(X_test, 2));
base_accuracy = accuracy;
for feat_idx = 1:size(X_test, 2)
permuted_accuracy = 0;
for perm = 1:num_permutations
% 复制测试集
X_test_perm = X_test;
% 随机排列一个特征
X_test_perm(:, feat_idx) = X_test_perm(randperm(size(X_test_perm, 1)), feat_idx);
% 重塑并预测
X_test_perm_cnn = reshape(X_test_perm', [size(X_test_perm, 2), 1, 1, size(X_test_perm, 1)]);
Y_pred_perm = classify(net, X_test_perm_cnn);
permuted_accuracy = permuted_accuracy + sum(Y_pred_perm == Y_test_categorical) / length(Y_test_categorical);
end
% 计算重要性
feature_importance(feat_idx) = base_accuracy - (permuted_accuracy / num_permutations);
end
% 7.2 可视化特征重要性
figure('Position', [100, 100, 1000, 500]);
feature_names = {
'均值', '标准差', '峰值', '峰峰值', 'RMS值', '波形因子', ...
'峰值因子', '脉冲因子', '偏度', '峰度', '基波幅值', 'THD', ...
'高频能量', '小波D1能量', '小波D2能量', '小波D3能量', ...
'小波A3能量', '能量熵'
};
subplot(1,2,1);
[~, sorted_idx] = sort(feature_importance, 'descend');
barh(feature_importance(sorted_idx));
set(gca, 'YTickLabel', feature_names(sorted_idx));
xlabel('重要性 (准确率下降量)');
title('特征重要性排序');
grid on;
% 7.3 前5个重要特征的分布
subplot(1,2,2);
top_features = sorted_idx(1:min(5, length(sorted_idx)));
feature_data = X_normalized(:, top_features);
[~, feature_score] = pca(feature_data);
gscatter(feature_score(:,1), feature_score(:,2), Y, ...
lines(num_classes), '.', 15);
xlabel('主成分1');
ylabel('主成分2');
title('前5重要特征的PCA可视化');
legend(disturbance_types, 'Location', 'bestoutside');
grid on;
%% 8. 可视化示例信号和特征
fprintf('\n8. 可视化示例信号...\n');
figure('Position', [100, 100, 1400, 900]);
% 8.1 显示每类信号的示例
for class_idx = 1:num_classes
subplot(3, 3, class_idx);
% 找到该类的一个样本
class_samples = find(Y == class_idx);
sample_idx = class_samples(1);
signal = X_raw(sample_idx, :);
plot(t, signal, 'b-', 'LineWidth', 1.5);
xlabel('时间 (s)');
ylabel('电压 (V)');
title(sprintf('%s (类别 %d)', disturbance_types{class_idx}, class_idx));
grid on;
xlim([0, T]);
% 添加识别结果
if class_idx <= size(X_test, 1)
% 预测该样本
features_sample = X_normalized(sample_idx, :);
features_sample_cnn = reshape(features_sample', [length(features_sample), 1, 1, 1]);
pred = classify(net, features_sample_cnn);
% 显示真实和预测标签
if pred == class_idx
text(0.02, max(signal)*0.9, '✓ 正确识别', ...
'Color', 'g', 'FontSize', 10, 'FontWeight', 'bold');
else
text(0.02, max(signal)*0.9, ...
sprintf('✗ 误判为 %s', disturbance_types{pred}), ...
'Color', 'r', 'FontSize', 10, 'FontWeight', 'bold');
end
end
end
sgtitle('各类电能扰动信号示例');
%% 9. 模型保存与部署
fprintf('\n9. 保存模型和结果...\n');
% 9.1 保存训练好的模型
save('power_disturbance_classifier.mat', 'net', 'feature_names', ...
'disturbance_types', 'accuracy', 'cm');
% 9.2 保存特征提取参数
feature_params = struct();
feature_params.fs = fs;
feature_params.f0 = f0;
feature_params.V_nominal = V_nominal;
save('feature_extraction_params.mat', 'feature_params');
% 9.3 导出简化模型用于部署
% 创建一个简化版本,只包含必要的处理步骤
simplified_model = struct();
simplified_model.net = net;
simplified_model.feature_names = feature_names;
simplified_model.disturbance_types = disturbance_types;
simplified_model.feature_means = mean(X_features);
simplified_model.feature_stds = std(X_features);
save('simplified_classifier.mat', 'simplified_model', '-v7.3');
% 9.4 生成测试报告
fid = fopen('model_performance_report.txt', 'w');
fprintf(fid, '电能扰动信号分类模型测试报告\n');
fprintf(fid, '生成时间: %s\n\n', datestr(now));
fprintf(fid, '模型信息:\n');
fprintf(fid, ' 网络结构: CNN-LSTM混合网络\n');
fprintf(fid, ' 特征数量: %d\n', num_features);
fprintf(fid, ' 类别数量: %d\n\n', num_classes);
fprintf(fid, '性能指标:\n');
fprintf(fid, ' 测试集准确率: %.2f%%\n\n', accuracy*100);
fprintf(fid, '分类详情:\n');
for i = 1:num_classes
TP = cm(i, i);
FP = sum(cm(:, i)) - TP;
FN = sum(cm(i, :)) - TP;
precision = TP / (TP + FP + eps);
recall = TP / (TP + FN + eps);
fprintf(fid, ' %s: 精确率=%.3f, 召回率=%.3f\n', ...
disturbance_types{i}, precision, recall);
end
fclose(fid);
fprintf(' 模型已保存,测试报告已生成\n');
%% 10. 实时分类示例
fprintf('\n10. 实时分类示例...\n');
% 10.1 生成一个新的测试信号
test_class = randi([1, num_classes]);
fprintf(' 生成新的测试信号 (类别: %s)...\n', disturbance_types{test_class});
new_signal = generate_disturbance_signal(t, f0, V_nominal, test_class, fs);
% 10.2 提取特征
new_features = zeros(1, num_features);
signal_for_features = new_signal;
% 提取与训练时相同的特征集
% [这里省略详细的特征提取代码,与第2部分相同]
% 实际应用中应复用相同的特征提取函数
% 10.3 标准化
new_features_normalized = (new_features - mean(X_features)) ./ std(X_features);
% 10.4 分类
new_features_cnn = reshape(new_features_normalized', [length(new_features_normalized), 1, 1, 1]);
pred_class_idx = classify(net, new_features_cnn);
pred_class_name = disturbance_types{pred_class_idx};
fprintf(' 真实类别: %s\n', disturbance_types{test_class});
fprintf(' 预测类别: %s\n', pred_class_name);
if pred_class_idx == test_class
fprintf(' ✓ 分类正确!\n');
else
fprintf(' ✗ 分类错误\n');
end
%% 11. 使用说明
fprintf('\n=== 使用说明 ===\n');
fprintf('1. 运行此脚本将生成完整的电能扰动信号分类系统\n');
fprintf('2. 主要输出包括:\n');
fprintf(' - 训练好的CNN-LSTM模型\n');
fprintf(' - 特征重要性分析\n');
fprintf(' - 混淆矩阵和性能指标\n');
fprintf(' - 各类信号的可视化\n');
fprintf('3. 修改参数:\n');
fprintf(' - 调整 num_samples_per_class 改变数据集大小\n');
fprintf(' - 修改网络结构 layers 优化模型\n');
fprintf(' - 调整训练选项 options 改变训练过程\n');
fprintf('4. 实际应用:\n');
fprintf(' - 使用 simplified_classifier.mat 进行部署\n');
fprintf(' - 对新信号先提取相同特征,再标准化,最后用模型分类\n');
fprintf('\n=== 程序执行完成 ===\n');
程序功能与使用说明
1. 核心功能模块
| 模块 | 功能描述 | 关键技术 |
|---|---|---|
| 信号生成 | 生成7类电能扰动信号(正常、暂降、暂升、中断、谐波、振荡、波动) | 数学模型、随机参数变化 |
| 特征提取 | 提取18个时域、频域和时频特征 | 统计分析、FFT、小波变换 |
| 神经网络 | CNN-LSTM混合模型构建与训练 | 深度学习、混合架构 |
| 评估分析 | 准确率、混淆矩阵、特征重要性分析 | 性能评估、可解释性分析 |
2. 特征工程说明
程序提取了18个关键特征,分为三类:
- 时域特征(10个):均值、标准差、峰值、RMS值、波形因子、峰值因子、脉冲因子、偏度、峰度
- 频域特征(3个):基波幅值、总谐波失真(THD)、高频能量占比
- 时频特征(5个):小波能量分布、能量熵
这些特征涵盖了电能扰动信号的主要特性,为神经网络提供了有效的输入。
3. 神经网络架构
输入特征向量
重塑层
卷积层1 + 批归一化 + ReLU
池化层1
卷积层2 + 批归一化 + ReLU
池化层2
展平层
双向LSTM层
Dropout层
全连接层1 + ReLU
Dropout层
全连接层2 + ReLU
输出层 + Softmax
分类结果
这种CNN-LSTM混合架构能同时捕捉:
- CNN部分:提取信号的局部特征和空间模式
- LSTM部分:捕捉特征间的时序依赖关系
参考代码 神经网络电能扰动信号特征识别 www.3dddown.com/csa/96820.html
4. 使用与修改方法
基本运行:
直接运行程序,将自动完成:
- 生成1400个样本(7类×200个)
- 提取特征并划分数据集
- 训练CNN-LSTM模型
- 评估性能并生成可视化结果
调整参数:
matlab
% 在程序开头修改:
num_samples_per_class = 500; % 增加样本量
fs = 6400; % 提高采样率
num_classes = 8; % 增加新的扰动类型
添加新的扰动类型:
在generate_disturbance_signal函数中添加新的case,例如电压缺口(notch):
matlab
case 8 % 电压缺口
notch_start = 0.05;
notch_duration = 0.005;
notch_depth = 0.3;
notch_mask = (t >= notch_start) & (t < notch_start + notch_duration);
signal = base_signal;
signal(notch_mask) = (1-notch_depth) * signal(notch_mask);
部署到实际系统:
matlab
% 加载简化模型
load('simplified_classifier.mat');
% 对新信号进行分类
function class = classify_new_signal(signal, simplified_model)
% 1. 提取相同特征
features = extract_features(signal);
% 2. 标准化
features_norm = (features - simplified_model.feature_means) ./ ...
simplified_model.feature_stds;
% 3. 重塑并预测
features_cnn = reshape(features_norm', [length(features_norm), 1, 1, 1]);
class_idx = classify(simplified_model.net, features_cnn);
class = simplified_model.disturbance_types{class_idx};
end
5. 性能优化建议
-
数据增强:
matlab% 添加数据增强技术 % 1. 添加不同噪声水平 % 2. 随机时间偏移 % 3. 幅度缩放 -
模型优化:
- 尝试不同的网络架构(如Transformer)
- 使用注意力机制
- 集成多个模型
-
特征优化:
- 添加更多时频特征(如S变换、Hilbert-Huang变换)
- 使用自动编码器进行特征学习