• 深度学习故障诊断之-使用条件生成对抗网络CGAN生成泵流量信号


    开始填坑

    MATLAB统计机器学习,深度学习,计算机视觉 - 哥廷根数学学派的文章 - 知乎 MATLAB统计机器学习,深度学习,计算机视觉 - 知乎

    之前写过在使用深度学习对机械系统或电气系统进行故障诊断时,如果没有大量的故障样本,可以使用Simulink 生成故障样本数据,还可以使用数字孪生技术等等

    深度学习故障诊断之-使用 Simulink 生成故障数据 - 哥廷根数学学派的文章 - 知乎 深度学习故障诊断之-使用 Simulink 生成故障数据 - 知乎

    本次讲解如何使用条件生成对抗网络CGAN生成泵流量信号

    完整代码链接

    🍞正在为您运送作品详情

    生成对抗网络 (GAN) 可用于生成近似真实数据的数据。 当模拟计算成本较高或实验成本较高时,GAN 非常有用。 条件 GAN(CGAN)可以在训练过程中使用数据标签来生成属于特定类别的数据。注意:本例将泵Simulink模型获得的模拟信号视为“真实”数据,当作CGAN 的训练数据集。 CGAN 使用一维卷积网络,此外本例使用主成分分析 (PCA) 直观地比较生成信号和真实信号的特征。三缸柱塞泵的Simulink模型如下,来源于mathworks大佬。

    再次强调:本例将泵Simulink模型获得的模拟信号视为“真实”数据,当作CGAN 的训练数据集

    下图为Simulink模型生成的“真实”泵流量信号

    接下来步入正题,CGAN 由两个作为“对手”一起训练的网络组成。

    生成器网络—给定一个标签和随机数组作为输入,该网络生成与对应于相同标签的训练数据相同结构的数据。 生成器的目标是生成鉴别器分类为“真实”的标记数据。

    判别器网络—给定一批标记数据,其中包含来自训练数据和生成器生成数据的观察结果,该网络尝试将观察结果分类为“真实”或“生成”。 判别器的目标是在给定批次的真实和生成的标记数据时不被生成器“愚弄”。

    导入数据

    模拟数据由 Simulink 模型生成。 Simulink 模型对3种类型的故障进行建模:气缸泄漏、进气口阻塞和轴承故障。 该数据集包含 1575 个泵输出流量信号,其中 760 个为健康信号,815 个为单个故障、两个故障的组合或三个故障的组合。 每个信号有 1201 个采样点,采样频率为 1000 Hz。.

    加载训练数据集并将信号进行标准化

    1. load(fullfile(saveFolder,'simulated.mat')) % 导入数据集
    2. meanFlow = mean(flow,2);
    3. flowNormalized = flow-meanFlow;
    4. stdFlow = std(flowNormalized(:));
    5. flowNormalized = flowNormalized/stdFlow;

    健康信号标记为 1,故障信号标记为 2。

    定义生成器网络,不再赘述,很容易看懂

    1. numFilters = 64;
    2. numLatentInputs = 100;
    3. projectionSize = [4 1 1024];
    4. numClasses = 2;
    5. embeddingDimension = 100;
    6. layersGenerator = [
    7. imageInputLayer([1 1 numLatentInputs],'Normalization','none','Name','in')
    8. projectAndReshapeLayer(projectionSize,numLatentInputs,'proj');
    9. concatenationLayer(3,2,'Name','cat');
    10. transposedConv2dLayer([5 1],8*numFilters,'Name','tconv1')
    11. batchNormalizationLayer('Name','bn1','Epsilon',5e-5)
    12. reluLayer('Name','relu1')
    13. transposedConv2dLayer([10 1],4*numFilters,'Stride',4,'Cropping',[1 0],'Name','tconv2')
    14. batchNormalizationLayer('Name','bn2','Epsilon',5e-5)
    15. reluLayer('Name','relu2')
    16. transposedConv2dLayer([12 1],2*numFilters,'Stride',4,'Cropping',[1 0],'Name','tconv3')
    17. batchNormalizationLayer('Name','bn3','Epsilon',5e-5)
    18. reluLayer('Name','relu3')
    19. transposedConv2dLayer([5 1],numFilters,'Stride',4,'Cropping',[1 0],'Name','tconv4')
    20. batchNormalizationLayer('Name','bn4','Epsilon',5e-5)
    21. reluLayer('Name','relu4')
    22. transposedConv2dLayer([7 1],1,'Stride',2,'Cropping',[1 0],'Name','tconv5')
    23. ];
    24. lgraphGenerator = layerGraph(layersGenerator);
    25. layers = [
    26. imageInputLayer([1 1],'Name','labels','Normalization','none')
    27. embedAndReshapeLayer(projectionSize(1:2),embeddingDimension,numClasses,'emb')];
    28. lgraphGenerator = addLayers(lgraphGenerator,layers);
    29. lgraphGenerator = connectLayers(lgraphGenerator,'emb','cat/in2');

    绘制生成器的网络结构

    将层图转换为 dlnetwork 对象,便于自动微分

    dlnetGenerator = dlnetwork(lgraphGenerator);

    类似地定义判别器网络

    1. scale = 0.2;
    2. inputSize = [1201 1 1];
    3. layersDiscriminator = [
    4. imageInputLayer(inputSize,'Normalization','none','Name','in')
    5. concatenationLayer(3,2,'Name','cat')
    6. convolution2dLayer([17 1],8*numFilters,'Stride',2,'Padding',[1 0],'Name','conv1')
    7. leakyReluLayer(scale,'Name','lrelu1')
    8. convolution2dLayer([16 1],4*numFilters,'Stride',4,'Padding',[1 0],'Name','conv2')
    9. leakyReluLayer(scale,'Name','lrelu2')
    10. convolution2dLayer([16 1],2*numFilters,'Stride',4,'Padding',[1 0],'Name','conv3')
    11. leakyReluLayer(scale,'Name','lrelu3')
    12. convolution2dLayer([8 1],numFilters,'Stride',4,'Padding',[1 0],'Name','conv4')
    13. leakyReluLayer(scale,'Name','lrelu4')
    14. convolution2dLayer([8 1],1,'Name','conv5')];
    15. lgraphDiscriminator = layerGraph(layersDiscriminator);
    16. layers = [
    17. imageInputLayer([1 1],'Name','labels','Normalization','none')
    18. embedAndReshapeLayer(inputSize,embeddingDimension,numClasses,'emb')];
    19. lgraphDiscriminator = addLayers(lgraphDiscriminator,layers);
    20. lgraphDiscriminator = connectLayers(lgraphDiscriminator,'emb','cat/in2');

    绘制判别器的网络结构

    同样将层图转换为 dlnetwork 对象便于自动微分

    dlnetDiscriminator = dlnetwork(lgraphDiscriminator);

    训练模型

    使用自定义训练循环训练 CGAN 模型。 对于每个mini-batch小批量数据:

    为生成器网络生成一个包含随机值数组的 dlarray 对象。

    对于 GPU 训练,将数据转换为 gpuArray 对象。

    使用 dlfeval 和函数 modelGradients计算模型梯度。

    指定训练参数

    1. params.numLatentInputs = numLatentInputs;
    2. params.numClasses = numClasses;
    3. params.sizeData = [inputSize length(labels)];
    4. params.numEpochs = 1000;
    5. params.miniBatchSize = 256;
    6. % 指定 Adam 优化器的选项
    7. params.learnRate = 0.0002;
    8. params.gradientDecayFactor = 0.5;
    9. params.squaredGradientDecayFactor = 0.999;

    设置执行环境以在 CPU 上运行 CGAN

    1. executionEnvironment = "cpu";
    2. params.executionEnvironment = executionEnvironment;

    网络训练

    1. [dlnetGenerator,dlnetDiscriminator] = trainGAN(dlnetGenerator, ...
    2. dlnetDiscriminator,flowNormalized,labels,params);

    下面的训练图显示了生成器和鉴别器网络的得分,在这个例子中,生成器和判别器的分数都收敛到接近 0.5,表明训练性能良好

    生成信号

    创建一个 dlarray 对象,其中包含一批 2000 个 1×1×100 的随机值数组,以输入到生成器网络中。 重置随机数生成器以获得可重复的结果。

    1. rng default
    2. numTests = 2000;
    3. ZNew = randn(1,1,numLatentInputs,numTests,'single');
    4. dlZNew = dlarray(ZNew,'SSCB');

    指定前 1000 个随机数组是健康的,其余都是故障的

    1. TNew = ones(1,1,1,numTests,'single');
    2. TNew(1,1,1,numTests/2+1:end) = single(2);
    3. dlTNew = dlarray(TNew,'SSCB');

    如果要使用 GPU 生成信号,将数据转换为 gpuArray 对象。

    1. if executionEnvironment == "gpu"
    2. dlZNew = gpuArray(dlZNew);
    3. dlTNew = gpuArray(dlTNew);
    4. end
    5. dlXGeneratedNew = predict(dlnetGenerator,dlZNew,dlTNew)*stdFlow+meanFlow;

    信号特征可视化

    与图像和音频信号不同,一般信号具有使人类感知难以区分的特征。 要比较真实信号和生成信号或健康信号和故障信号,可以将主成分分析PCA应用于真实信号的统计特征,然后将生成信号的特征投影到相同的 PCA 子空间。

    特征提取

    将真实信号和生成信号组合在一个数据矩阵中。 使用函数 extractFeatures 提取特征,包括常见的信号统计信息,例如均值和方差以及频谱特征。

    1. idxGenerated = 1:numTests;
    2. idxReal = numTests+1:numTests+size(flow,2);
    3. XGeneratedNew = squeeze(extractdata(gather(dlXGeneratedNew)));
    4. x = [XGeneratedNew single(flow)];
    5. features = zeros(size(x,2),14,'like',x);
    6. for ii = 1:size(x,2)
    7. features(ii,:) = extractFeatures(x(:,ii));
    8. end

    每行对应一个信号的特征。

    修改生成的健康和故障信号以及真实健康和故障信号的标签。

    L = [squeeze(TNew)+2;labels.'];

    标签的定义如下:

    1 — Generated healthy signals

    2 — Generated faulty signals

    3 — Real healthy signals

    4 — Real faulty signals

    主成分分析

    对真实信号的特征进行主成分分析,并将生成信号的特征投影到相同的主成分分析子空间。

    通过奇异值分解进行主成分分析

    1. featuresReal = features(idxReal,:);
    2. mu = mean(featuresReal,1);
    3. [~,S,W] = svd(featuresReal-mu);
    4. S = diag(S);
    5. Y = (features-mu)*W;

    前三个奇异值占99% 的能量。因此可以利用前三个主成分来可视化信号特征。

    sum(S(1:3))/sum(S)

    使用前3个主成分绘制所有信号的特征。 在 PCA 子空间中,生成信号的分布类似于真实信号的分布

    为了更好地捕捉真实信号和生成信号之间的差异,使用前两个主成分绘制子空间

    view(2)

    健康信号和故障信号无论是真实的还是生成的,都位于 PCA 子空间的同一区域,表明生成的信号具有与真实信号相似的特征。

    预测真实信号的标签

    为了进一步说明 CGAN 的性能,根据生成的信号训练 SVM 分类器,然后预测真实信号是健康的还是故障的。将生成的信号设置为训练数据集,将真实信号设置为测试数据集, 将数字标签更改为字符向量。

    1. LABELS = {'Healthy','Faulty'};
    2. strL = LABELS([squeeze(TNew);labels.']).';
    3. dataTrain = features(idxGenerated,:);
    4. dataTest = features(idxReal,:);
    5. labelTrain = strL(idxGenerated);
    6. labelTest = strL(idxReal);
    7. predictors = dataTrain;
    8. response = labelTrain;
    9. cvp = cvpartition(size(predictors,1),'KFold',5);

    使用生成的信号训练 SVM 分类器

    1. SVMClassifier = fitcsvm( ...
    2. predictors(cvp.training(1),:), ...
    3. response(cvp.training(1)),'KernelFunction','polynomial', ...
    4. 'PolynomialOrder',2, ...
    5. 'KernelScale','auto', ...
    6. 'BoxConstraint',1, ...
    7. 'ClassNames',LABELS, ...
    8. 'Standardize',true);

    使用经过训练的分类器获得真实信号的预测标签。 分类器实现了 90% 以上的预测准确率。

    1. actualValue = labelTest;
    2. predictedValue = predict(SVMClassifier,dataTest);
    3. 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 秒的时间来生成相同数量的数据。

  • 相关阅读:
    springboot家校共育平台-计算机毕业设计源码54235
    Spring框架在Bean中的管理(第十一课)
    2022世界杯La‘eeb肖像,python海龟实现啦
    办理广播电视节目制作许可证? 你需要知道这些
    JS高级 之 eventBus 事件总线
    win10 安装 oracle 19c 服务端 64 位和 PL/SQL Developer 连接工具
    如何自动生成一本epub电子书
    百度之星-新的阶乘提问
    windows上修改redis端口号
    java File类创建功能
  • 原文地址:https://blog.csdn.net/weixin_39402231/article/details/127110198