大家好,欢迎来到IT知识分享网。
开始填坑
MATLAB统计机器学习,深度学习,计算机视觉 – 哥廷根数学学派的文章 – 知乎 https://zhuanlan.zhihu.com/p/
之前写过在使用深度学习对机械系统或电气系统进行故障诊断时,如果没有大量的故障样本,可以使用Simulink 生成故障样本数据,还可以使用数字孪生技术等等
深度学习故障诊断之-使用 Simulink 生成故障数据 – 哥廷根数学学派的文章 – 知乎 https://zhuanlan.zhihu.com/p/
本次讲解如何使用条件生成对抗网络CGAN生成泵流量信号
完整版代码链接如下
https://mianbaoduo.com/o/bread/Y5iak5Zu
生成对抗网络 (GAN) 可用于生成近似真实数据的数据。 当模拟计算成本较高或实验成本较高时,GAN 非常有用。 条件 GAN(CGAN)可以在训练过程中使用数据标签来生成属于特定类别的数据。注意:本例将泵Simulink模型获得的模拟信号视为“真实”数据,当作CGAN 的训练数据集。 CGAN 使用一维卷积网络,此外本例使用主成分分析 (PCA) 直观地比较生成信号和真实信号的特征。三缸柱塞泵的Simulink模型如下,来源于mathworks大佬。
再次强调:本例将泵Simulink模型获得的模拟信号视为“真实”数据,当作CGAN 的训练数据集
下图为Simulink模型生成的“真实”泵流量信号
接下来步入正题,CGAN 由两个作为“对手”一起训练的网络组成。
生成器网络—给定一个标签和随机数组作为输入,该网络生成与对应于相同标签的训练数据相同结构的数据。 生成器的目标是生成鉴别器分类为“真实”的标记数据。
判别器网络—给定一批标记数据,其中包含来自训练数据和生成器生成数据的观察结果,该网络尝试将观察结果分类为“真实”或“生成”。 判别器的目标是在给定批次的真实和生成的标记数据时不被生成器“愚弄”。
导入数据
模拟数据由 Simulink 模型生成。 Simulink 模型对3种类型的故障进行建模:气缸泄漏、进气口阻塞和轴承故障。 该数据集包含 1575 个泵输出流量信号,其中 760 个为健康信号,815 个为单个故障、两个故障的组合或三个故障的组合。 每个信号有 1201 个采样点,采样频率为 1000 Hz。.
加载训练数据集并将信号进行标准化
load(fullfile(saveFolder,'simulated.mat')) % 导入数据集 meanFlow = mean(flow,2); flowNormalized = flow-meanFlow; stdFlow = std(flowNormalized(:)); flowNormalized = flowNormalized/stdFlow;
健康信号标记为 1,故障信号标记为 2。
定义生成器网络,不再赘述,很容易看懂
numFilters = 64; numLatentInputs = 100; projectionSize = [4 1 1024]; numClasses = 2; embeddingDimension = 100; layersGenerator = [ imageInputLayer([1 1 numLatentInputs],'Normalization','none','Name','in') projectAndReshapeLayer(projectionSize,numLatentInputs,'proj'); concatenationLayer(3,2,'Name','cat'); transposedConv2dLayer([5 1],8*numFilters,'Name','tconv1') batchNormalizationLayer('Name','bn1','Epsilon',5e-5) reluLayer('Name','relu1') transposedConv2dLayer([10 1],4*numFilters,'Stride',4,'Cropping',[1 0],'Name','tconv2') batchNormalizationLayer('Name','bn2','Epsilon',5e-5) reluLayer('Name','relu2') transposedConv2dLayer([12 1],2*numFilters,'Stride',4,'Cropping',[1 0],'Name','tconv3') batchNormalizationLayer('Name','bn3','Epsilon',5e-5) reluLayer('Name','relu3') transposedConv2dLayer([5 1],numFilters,'Stride',4,'Cropping',[1 0],'Name','tconv4') batchNormalizationLayer('Name','bn4','Epsilon',5e-5) reluLayer('Name','relu4') transposedConv2dLayer([7 1],1,'Stride',2,'Cropping',[1 0],'Name','tconv5') ]; lgraphGenerator = layerGraph(layersGenerator); layers = [ imageInputLayer([1 1],'Name','labels','Normalization','none') embedAndReshapeLayer(projectionSize(1:2),embeddingDimension,numClasses,'emb')]; lgraphGenerator = addLayers(lgraphGenerator,layers); lgraphGenerator = connectLayers(lgraphGenerator,'emb','cat/in2');
绘制生成器的网络结构
将层图转换为 dlnetwork 对象,便于自动微分
dlnetGenerator = dlnetwork(lgraphGenerator);
类似地定义判别器网络
scale = 0.2; inputSize = [1201 1 1]; layersDiscriminator = [ imageInputLayer(inputSize,'Normalization','none','Name','in') concatenationLayer(3,2,'Name','cat') convolution2dLayer([17 1],8*numFilters,'Stride',2,'Padding',[1 0],'Name','conv1') leakyReluLayer(scale,'Name','lrelu1') convolution2dLayer([16 1],4*numFilters,'Stride',4,'Padding',[1 0],'Name','conv2') leakyReluLayer(scale,'Name','lrelu2') convolution2dLayer([16 1],2*numFilters,'Stride',4,'Padding',[1 0],'Name','conv3') leakyReluLayer(scale,'Name','lrelu3') convolution2dLayer([8 1],numFilters,'Stride',4,'Padding',[1 0],'Name','conv4') leakyReluLayer(scale,'Name','lrelu4') convolution2dLayer([8 1],1,'Name','conv5')]; lgraphDiscriminator = layerGraph(layersDiscriminator); layers = [ imageInputLayer([1 1],'Name','labels','Normalization','none') embedAndReshapeLayer(inputSize,embeddingDimension,numClasses,'emb')]; lgraphDiscriminator = addLayers(lgraphDiscriminator,layers); lgraphDiscriminator = connectLayers(lgraphDiscriminator,'emb','cat/in2');
绘制判别器的网络结构
同样将层图转换为 dlnetwork 对象便于自动微分
dlnetDiscriminator = dlnetwork(lgraphDiscriminator);
训练模型
使用自定义训练循环训练 CGAN 模型。 对于每个mini-batch小批量数据:
为生成器网络生成一个包含随机值数组的 dlarray 对象。
对于 GPU 训练,将数据转换为 gpuArray 对象。
使用 dlfeval 和函数 modelGradients计算模型梯度。
指定训练参数
params.numLatentInputs = numLatentInputs; params.numClasses = numClasses; params.sizeData = [inputSize length(labels)]; params.numEpochs = 1000; params.miniBatchSize = 256; % 指定 Adam 优化器的选项 params.learnRate = 0.0002; params.gradientDecayFactor = 0.5; params.squaredGradientDecayFactor = 0.999;
设置执行环境以在 CPU 上运行 CGAN
executionEnvironment = "cpu"; params.executionEnvironment = executionEnvironment;
网络训练
[dlnetGenerator,dlnetDiscriminator] = trainGAN(dlnetGenerator, ... dlnetDiscriminator,flowNormalized,labels,params);
下面的训练图显示了生成器和鉴别器网络的得分,在这个例子中,生成器和判别器的分数都收敛到接近 0.5,表明训练性能良好
生成信号
创建一个 dlarray 对象,其中包含一批 2000 个 1×1×100 的随机值数组,以输入到生成器网络中。 重置随机数生成器以获得可重复的结果。
rng default numTests = 2000; ZNew = randn(1,1,numLatentInputs,numTests,'single'); dlZNew = dlarray(ZNew,'SSCB');
指定前 1000 个随机数组是健康的,其余都是故障的
TNew = ones(1,1,1,numTests,'single'); TNew(1,1,1,numTests/2+1:end) = single(2); dlTNew = dlarray(TNew,'SSCB');
如果要使用 GPU 生成信号,将数据转换为 gpuArray 对象。
if executionEnvironment == "gpu" dlZNew = gpuArray(dlZNew); dlTNew = gpuArray(dlTNew); end dlXGeneratedNew = predict(dlnetGenerator,dlZNew,dlTNew)*stdFlow+meanFlow;
信号特征可视化
与图像和音频信号不同,一般信号具有使人类感知难以区分的特征。 要比较真实信号和生成信号或健康信号和故障信号,可以将主成分分析PCA应用于真实信号的统计特征,然后将生成信号的特征投影到相同的 PCA 子空间。
特征提取
将真实信号和生成信号组合在一个数据矩阵中。 使用函数 extractFeatures 提取特征,包括常见的信号统计信息,例如均值和方差以及频谱特征。
idxGenerated = 1:numTests; idxReal = numTests+1:numTests+size(flow,2); XGeneratedNew = squeeze(extractdata(gather(dlXGeneratedNew))); x = [XGeneratedNew single(flow)]; features = zeros(size(x,2),14,'like',x); for ii = 1:size(x,2) features(ii,:) = extractFeatures(x(:,ii)); end
每行对应一个信号的特征。
修改生成的健康和故障信号以及真实健康和故障信号的标签。
L = [squeeze(TNew)+2;labels.'];
标签的定义如下:
1 — Generated healthy signals
2 — Generated faulty signals
3 — Real healthy signals
4 — Real faulty signals
主成分分析
对真实信号的特征进行主成分分析,并将生成信号的特征投影到相同的主成分分析子空间。
通过奇异值分解进行主成分分析
featuresReal = features(idxReal,:); mu = mean(featuresReal,1); [~,S,W] = svd(featuresReal-mu); S = diag(S); Y = (features-mu)*W;
前三个奇异值占99% 的能量。因此可以利用前三个主成分来可视化信号特征。
sum(S(1:3))/sum(S)
使用前3个主成分绘制所有信号的特征。 在 PCA 子空间中,生成信号的分布类似于真实信号的分布
为了更好地捕捉真实信号和生成信号之间的差异,使用前两个主成分绘制子空间
view(2)
健康信号和故障信号无论是真实的还是生成的,都位于 PCA 子空间的同一区域,表明生成的信号具有与真实信号相似的特征。
预测真实信号的标签
为了进一步说明 CGAN 的性能,根据生成的信号训练 SVM 分类器,然后预测真实信号是健康的还是故障的。将生成的信号设置为训练数据集,将真实信号设置为测试数据集, 将数字标签更改为字符向量。
LABELS = {'Healthy','Faulty'}; strL = LABELS([squeeze(TNew);labels.']).'; dataTrain = features(idxGenerated,:); dataTest = features(idxReal,:); labelTrain = strL(idxGenerated); labelTest = strL(idxReal); predictors = dataTrain; response = labelTrain; cvp = cvpartition(size(predictors,1),'KFold',5);
使用生成的信号训练 SVM 分类器
SVMClassifier = fitcsvm( ... predictors(cvp.training(1),:), ... response(cvp.training(1)),'KernelFunction','polynomial', ... 'PolynomialOrder',2, ... 'KernelScale','auto', ... 'BoxConstraint',1, ... 'ClassNames',LABELS, ... 'Standardize',true);
使用经过训练的分类器获得真实信号的预测标签。 分类器实现了 90% 以上的预测准确率。
actualValue = labelTest; predictedValue = predict(SVMClassifier,dataTest); predictAccuracy = mean(cellfun(@strcmp,actualValue,predictedValue))
查看混淆矩阵
比较真实信号和生成信号的频谱特性
泵电机转速为 950 rpm,即15.833 Hz,由于泵具有三个气缸,因此预计流量的基波频率为 15.833 Hz 或 47.5 Hz 的 3 倍,谐波频率为 47.5 Hz 的倍数。 从真实和生成的健康信号的频谱图中可以看出,生成的健康信号在 47.5 Hz 和 2 倍 47.5 Hz 处具有较高的功率值,与真实健康信号相同。
如果存在故障,将在泵电机速度 15.833 Hz 及其谐波处发生共振。 绘制真实和生成的故障信号的频谱。 生成的信号在 15.833 Hz 及其谐波附近具有较高的功率值,与真正的故障信号相似。
绘制另一种真实和生成的故障信号的频谱。 产生的故障信号的频谱特征与理论分析的匹配度不高,与真实故障信号存在差异。 CGAN 仍然可以通过调整网络结构或超参数来改进。
计算时间
Simulink 仿真需要大约 14 小时才能生成 2000 个泵流量信号。 如果有 Parallel Computing Toolbox工具箱,则时间可以减少到大约 1.7 小时,使用 8 个并行工作器。使用 NVIDIA Titan V GPU,CGAN 需要 1.5 小时的训练时间和 70 秒的时间来生成相同数量的数据。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/94412.html