前言:
如今同学们对“小波自适应算法”可能比较珍视,同学们都想要知道一些“小波自适应算法”的相关内容。那么小编在网络上收集了一些有关“小波自适应算法””的相关知识,希望我们能喜欢,朋友们一起来了解一下吧!代码如下
本文简单地演示一下如何使用连续小波变换 (CWT) 和深度卷积神经网络 (CNN) 对人体心电图 (ECG) 信号进行分类,并进行特征可视化便于以后的深入分析。由于从头训练深度 CNN 的计算成本很高,并且需要大量的训练数据,在很多应用中并没有足够数量的训练数据可用,因此本文采用迁移学习方法(GoogLeNet 和 SqueezeNet)对ECG波形的CWT时频谱图进行分类,所用的编程环境为MATLAB R2021B。
在本文中,使用的ECG数据分为3种:心律失常(ARR)、充血性心力衰竭(CHF) 和正常窦性心律(NSR),分别来自MIT-BIH Arrhythmia数据库、MIT-BIH Normal Sinus Rhythm数据库和BIDMC Congestive Heart Failure数据库,下载完成后,首先看一下这3种波形的样子。
创建CWT时频谱图
要创建CWT时频谱图,首先设置一个CWT滤波器组。
Fs = 128;fb = cwtfilterbank('SignalLength',1000,... 'SamplingFrequency',Fs,... 'VoicesPerOctave',12);
然后看一下CWT时频谱图
sig = ECGData.Data(1,1:1000);[cfs,frq] = wt(fb,sig);t = (0:999)/Fs;figure;pcolor(t,frq,abs(cfs))set(gca,'yscale','log');shading interp;axis tight;title('Scalogram');xlabel('Time (s)');ylabel('Frequency (Hz)')
然后将CWT时频谱图创建为RGB图像,并调整至224×224×3大小。
将CWT时频谱图像加载为图像数据存储,imageDatastore函数自动根据文件夹名称对图像加标签,并将数据存储为 ImageDatastore 对象。通过图像数据存储可以存储大图像数据,包括无法放入内存的数据,并在 CNN 的训练过程中高效分批读取图像
allImages = imageDatastore(fullfile(parentDir,dataDir),... 'IncludeSubfolders',true,... 'LabelSource','foldernames');
将图像随机分成两组,一组用于训练,另一组用于验证。使用 80%的图像进行训练,其余的用于验证。为了可复现,设置随机种子
rng default[imgsTrain,imgsValidation] = splitEachLabel(allImages,0.8,'randomized');
加载预训练的 GoogLeNet网络,如果未安装 Deep Learning Toolbox™ Model for GoogLeNet Network 支持包,软件将在附加功能资源管理器中提供所需支持包的链接
net = googlenet;
显示网络的层次图
lgraph = layerGraph(net);numberOfLayers = numel(lgraph.Layers);figure('Units','normalized','Position',[0.1 0.1 0.8 0.8]);plot(lgraph)title(['GoogLeNet Layer Graph: ',num2str(numberOfLayers),' Layers']);
检查网络层属性的第一个元素,确认 GoogLeNet 需要大小为 224×224×3 的 RGB 图像
net.Layers(1)ans = ImageInputLayer with properties: Name: 'data' InputSize: [224 224 3] Hyperparameters DataAugmentation: 'none' Normalization: 'zerocenter' Mean: [224×224×3 single]
修改 GoogLeNet 网络参数
网络架构中的每层都可以视为一个滤波器,较浅的层识别图像的更常见特征,如斑点、边缘和颜色,后续层侧重于更具体的特征,以便区分类别。GoogLeNet 经训练可将图像分类至 1000 个目标类别。对于我们的 ECG 分类问题,必须重新训练 GoogLeNet。为防止过拟合,使用了dropout层,dropout概率为 0.5。将网络中的最终dropout层 'pool5-drop_7x7_s1' 替换为概率为 0.6 的dropout层
newDropoutLayer = dropoutLayer(0.6,'Name','new_Dropout');lgraph = replaceLayer(lgraph,'pool5-drop_7x7_s1',newDropoutLayer);
GoogLeNet 中的 'loss3-classifier' 和 'output' 这两个层包含将网络提取的特征合并为类概率、损失值和预测标签的信息,要重新训练 GoogLeNet 以对CWT时频谱RGB图像进行分类,将这两个层替换为适合数据的新层。将全连接层 'loss3-classifier' 替换为新的全连接层,其中滤波器的数量等于类的数量,要使新层中的学习速度快于迁移的层,要增大全连接层的学习率
numClasses = numel(categories(imgsTrain.Labels));newConnectedLayer = fullyConnectedLayer(numClasses,'Name','new_fc',... 'WeightLearnRateFactor',5,'BiasLearnRateFactor',5);lgraph = replaceLayer(lgraph,'loss3-classifier',newConnectedLayer);newClassLayer = classificationLayer('Name','new_classoutput');lgraph = replaceLayer(lgraph,'output',newClassLayer);
设置训练选项并训练GoogLeNet
训练神经网络是一个使损失函数最小的迭代过程。要使损失函数最小,一般使用梯度下降算法。在每次迭代中,会评估损失函数的梯度并更新权重参数。可以通过设置各种选项来调整训练。InitialLearnRate 指定损失函数负梯度方向的初始步长大小,MiniBatchSize 指定在每次迭代中使用的训练集子集的大小,一轮指对整个训练集完整运行一遍训练算法,MaxEpochs 指定用于训练的最大轮数,选择正确的轮数至关重要,减少轮数会导致模型欠拟合,而增加轮数会导致过拟合。
使用 trainingOptions 函数指定训练选项。将 MiniBatchSize 设置为 10,MaxEpochs 置为 10,InitialLearnRate 置为 0.0001。通过将 Plots 设置为 training-progress 来可视化训练进度。使用带动量的随机梯度下降优化器。默认情况下,训练在 GPU(如果有)上进行。使用 GPU 需要 Parallel Computing Toolbox™。为了实现可复现性,将 ExecutionEnvironment 设置为 cpu,以使 trainNetwork 使用 CPU。将随机种子设置为默认值
options = trainingOptions('sgdm',... 'MiniBatchSize',15,... 'MaxEpochs',20,... 'InitialLearnRate',1e-4,... 'ValidationData',imgsValidation,... 'ValidationFrequency',10,... 'Verbose',1,... 'ExecutionEnvironment','cpu',... 'Plots','training-progress');rng default
开始训练网络
trainedGN = trainNetwork(imgsTrain,lgraph,options);
查看经过训练的网络的最后一层,确认分类输出层包括3个类
trainedGN.Layers(end)ans = ClassificationOutputLayer with properties: Name: 'new_classoutput' Classes: [ARR CHF NSR] OutputSize: 3 Hyperparameters LossFunction: 'crossentropyex'
评估 GoogLeNet 准确度
[YPred,probs] = classify(trainedGN,imgsValidation);accuracy = mean(YPred==imgsValidation.Labels);disp(['GoogLeNet Accuracy: ',num2str(100*accuracy),'%'])
GoogLeNet Accuracy: 96.875%
GoogLeNet的每层都对输入图像产生响应或激活,然而,GoogLeNet内只有少数几个层适合图像特征提取,开始的几个层捕获基本的图像特征,如边缘等,可视化第一个卷积层的网络滤波器权重
通过将激活区域与原始图像进行比较,可以检查激活区域并查看GoogLeNet网络学习的特征,本文查看卷积层中的哪些区域在来自ARR类的图像的激活,并与原始图像中的对应区域进行比较。限于篇幅,仅查看第一个卷积层 'conv1-7x7_s2' 的输出激活区域
将最强通道与原始图像进行比较
至于进行特征可视化的好处,一是可以重点针对激活区域进行分析,看看哪个频段对于分类贡献最大;二是可以有针对性的选择相关频段作为CNN的输入,避免全频段输入,增强网络的处理效率,因此可以选择频率切片小波变换,如下:
Ricker小波及其频率切片小波变换 - 哥廷根数学学派的文章 - 知乎
此外,实际中采集的ECG等信号受噪声干扰较大,因此可以进行降噪前处理,一方面能提高网络的识别准确率,二方面可以提高网络的收敛速度,可视化可读性更好,比如采用基于Cycle Spinning的移不变小波去噪方法:
基于Cycle Spinning的移不变小波去噪 - 哥廷根数学学派的文章 - 知乎
还可以使用小波分解方法对心电信号ECG进行降噪
简单的基于小波分解的心电信号ECG降噪 - 哥廷根数学学派的文章 - 知乎
小波降噪基础-python版本 - 哥廷根数学学派的文章 - 知乎
或者采用基于自编码器的方法进行降噪
基于自编码器的语音信号降噪 - 哥廷根数学学派的文章 - 知乎
还可以使用更优秀的时频分析方法代替普通的CWT时频谱(虽然并不普通)
时间序列信号处理系列-基于Python的同步压缩变换 - 哥廷根数学学派的文章 - 知乎
时间重分配多重同步压缩变换(TMSST)在信号处理中的应用 - 哥廷根数学学派的文章 - 知乎
多重同步压缩变换multisynchrosqueezing transform(MSST)在信号处理中的应用 - 哥廷根数学学派的文章 - 知乎
改进多重同步压缩变换improved multisynchrosqueezing transform(IMSST)在信号处理中的应用 - 哥廷根数学学派的文章 - 知乎
还可以使用各种模态分解方法,只提取某几个模态分类进行输入
基于自适应Chirp模态分解的滚动承故障诊断方法 - 哥廷根数学学派的文章 - 知乎
基于离散小波变换的滚动轴承故障诊断 - 哥廷根数学学派的文章 - 知乎
还可以使用其他优秀的特征可视化方法
关于深度学习可解释性 - 哥廷根数学学派的文章 - 知乎
使用深度学习通过脑部MRI进行年龄分类 - 哥廷根数学学派的文章 - 知乎
AlexNet 网络deepdream可视化 - 哥廷根数学学派的文章 - 知乎
使用 Score-CAM方法解释深度学习分类结果 - 哥廷根数学学派的文章 - 知乎
还有各种网络的魔改之类的,我就暂时不讲了,以后有时间讲几个
详细文章
基于小波分析和深度学习的时间序列分类并可视化相关特征 - 哥廷根数学学派的文章 - 知乎
标签: #小波自适应算法