Matlab使用CNN对一维信号进行二分类或多分类源程序

张开发
2026/4/15 3:10:57 15 分钟阅读

分享文章

Matlab使用CNN对一维信号进行二分类或多分类源程序
Matlab使用CNN(卷积神经网络)对一维信号(如语音信号、心电图信号)进行二分类源程序。 也可以改成多分类。 会提供原始数据数据可直接替换为自己的数据运行注释详细 工作如下 1、加载数据一共为200个正常样本和200个异常样本训练集为80%即160正常和160异常一共320条数据测试集为40正常和40异常一共80条数据。 2、构建一维CNN架构层数为两层。 3、构建options。 4、训练。 5、测试并绘制混淆矩阵。 注考虑到使用Matlab对一维信号进行CNN分类的教程较少此程序是为了方便学习怎么搭建网络、测试等等使用的数据量较少并且数据本身也易于分类自己换成自己的数据时可能需要根据实际情况调整网络。最近在折腾一维信号的分类问题发现用Matlab搞CNN分类的现成代码确实不多。正好手头有个自用的基础框架拿过来改改就能跑特别适合刚入门的同学理解整个流程。下面直接上硬货咱们边看代码边聊注意事项。先准备数据这事儿挺关键。假设你的数据已经整理成【样本数×信号长度】的矩阵比如每个样本是1000个采样点的一维信号% 加载数据这里假装已经load好了 normal_data randn(200, 1000); % 200个正常样本 abnormal_data randn(200, 1000); % 200个异常样本 % 打乱顺序防止批次偏差 shuffled_idx randperm(400); all_data [normal_data; abnormal_data]; all_labels [ones(200,1); zeros(200,1)]; all_data all_data(shuffled_idx, :); all_labels all_labels(shuffled_idx, :); % 切分训练测试集 train_x all_data(1:320, :); train_y all_labels(1:320, :); test_x all_data(321:end, :); test_y all_labels(321:end, :); % 转成matlab需要的格式样本数×1×长度×通道数 train_x reshape(train_x, [320,1,1000,1]); test_x reshape(test_x, [80,1,1000,1]);这里有个坑要注意如果你的信号长度不一致得先做插值或者截断对齐。我之前处理心电信号时就遇到过这个问题最后用动态时间规整解决的。接下来是网络结构搭建这里用两层卷积池化的经典组合layers [ imageInputLayer([1 1000 1], Name, input) % 输入层 convolution2dLayer([1 15], 16, Padding, same, Name, conv1) % 一维卷积 batchNormalizationLayer reluLayer maxPooling2dLayer([1 5], Stride, [1 3], Name, pool1) % 一维池化 convolution2dLayer([1 10], 32, Padding, same, Name, conv2) batchNormalizationLayer reluLayer maxPooling2dLayer([1 5], Stride, [1 3], Name, pool2) globalAveragePooling2dLayer fullyConnectedLayer(2) softmaxLayer classificationLayer];这里有两个骚操作用imageInputLayer处理一维信号本质是把单通道当作二维的特殊情况全局平均池化替代全连接层实测能有效防止过拟合尤其在小样本场景下训练参数配置直接影响收敛速度新手建议先用默认参数试水options trainingOptions(adam, ... MaxEpochs, 30, ... MiniBatchSize, 32, ... ValidationData, {test_x, categorical(test_y)}, ... ValidationFrequency, 10, ... Verbose, true, ... Plots, training-progress);重点说下ValidationFrequency设置。当你的训练集很大时可以适当调高这个值加快训练。但咱们这个例子数据量小设为10刚好能在每个epoch验证两次。Matlab使用CNN(卷积神经网络)对一维信号(如语音信号、心电图信号)进行二分类源程序。 也可以改成多分类。 会提供原始数据数据可直接替换为自己的数据运行注释详细 工作如下 1、加载数据一共为200个正常样本和200个异常样本训练集为80%即160正常和160异常一共320条数据测试集为40正常和40异常一共80条数据。 2、构建一维CNN架构层数为两层。 3、构建options。 4、训练。 5、测试并绘制混淆矩阵。 注考虑到使用Matlab对一维信号进行CNN分类的教程较少此程序是为了方便学习怎么搭建网络、测试等等使用的数据量较少并且数据本身也易于分类自己换成自己的数据时可能需要根据实际情况调整网络。训练启动就一行代码net trainNetwork(train_x, categorical(train_y), layers, options);跑起来后盯着训练曲线看如果验证集准确率早早就到95%以上但训练集还在涨八成是过拟合了。这时候可以试试在卷积层后面加Dropout层比如设置0.5的丢弃率。测试环节要关注实际应用场景的需求% 预测并计算指标 pred_labels classify(net, test_x); accuracy sum(pred_labels categorical(test_y))/numel(test_y) % 混淆矩阵可视化 plotconfusion(categorical(test_y), pred_labels) set(gca, XTickLabel, {正常,异常}) set(gca, YTickLabel, {正常,异常}) % 计算ROC曲线需要深度学习工具箱 [~,scores] predict(net,test_x); [X,Y,T,AUC] perfcurve(test_y, scores(:,2), 1); figure; plot(X,Y); xlabel(假阳性率); ylabel(真阳性率)遇到过特别有意思的情况某次测试准确率高达99%但实际部署时效果差后来发现是测试集分布和真实场景不一致。所以建议在代码里预留数据增强的接口比如加噪声、时移等操作。最后说说工程化改进方向改用小波变换后的特征作为输入对非平稳信号效果更好在第一个卷积层后加残差连接处理长程依赖用贝叶斯优化自动调参部署时改用C接口加速推理这个框架改成多分类也简单把最后的全连接层输出改成类别数损失函数换成交叉熵就行。完整代码已打包放在Github假装有链接换自己的数据时注意调整输入层的信号长度参数。遇到问题欢迎评论区交流看到都会回~

更多文章