MATLAB实战 利用1D-DCGAN生成光谱或信号数据

news2024/11/16 1:37:36

0.前言

        在光谱学或信号处理领域,获取大量高质量的数据可能是一项挑战。利用DCGAN进行“迁移学习”,对抗性地生成光谱或信号数据,具有强化、泛化样本特征的应用潜力。

        该实战项目提供了所有源代码与测试数据,旨在帮助学者快速地掌握了解利用DCGAN对1维数据的生成。

建议开始本项目前提前了解和掌握以下内容:MATLAB代码解析:利用DCGAN实现图像数据的生成 全网最细&DCGAN设计-训练入门

项目参考文献:

光谱技术结合水分校正与样本增广的棉田土壤盐分精准反演 - 中国知网

1.训练效果、脚本与文件

1.1训练效果

 训练8个周期

 训练36个周期

训练115个周期

充分训练后

1.2脚本代码

1.2.1主程序

数据获取
clear all
clc
load("TestData.mat");
%返回相同的数据类型,以行为分配样本
%'IterationDimension'=1以第一个维度划分样本(行),2为第二个维度,以此类推;
ADataStore = arrayDatastore(DataMat,'IterationDimension',1,'OutputType', 'cell');
%%构建生成器
numLatentInputs=200;%输入随机数大小
netG=Creat_1D_Gener(numLatentInputs);
%%判别器
netD=Creat_1D_Discri();
%%指定训练选项
dropoutProb = 0.25;%泄露率
scale = 0.2;
numEpochs = 2000;%训练周期
miniBatchSize = 256;%最小批次
learnRate = 0.00002;
learnRateD=0.00002;
gradientDecayFactor = 0.45;
squaredGradientDecayFactor = 0.999;
flipProb = 0.15;%翻转概率
validationFrequency = 100;%验证频率
%%训练模型
mbq = minibatchqueue(ADataStore, ...
    MiniBatchSize=miniBatchSize, ...
    MiniBatchFcn=@preprocessMiniBatch12_2D, ...%预处理方法,与采集的数据类型对应
    PartialMiniBatch="discard", ...
    MiniBatchFormat="SCB");

trailingAvgG = [];
trailingAvgSqG = [];
trailingAvg = [];
trailingAvgSqD = [];
numValidationImages = 4;
ZValidation = randn(numLatentInputs,numValidationImages,"single");
ZValidation = dlarray(ZValidation,"CB");
if canUseGPU
    ZValidation = gpuArray(ZValidation);
end

f = figure;
f.Position(3) = 2*f.Position(3);

imageAxes = subplot(1,2,1);
scoreAxes = subplot(1,2,2);

C = colororder;
lineScoreG = animatedline(scoreAxes,Color=C(1,:));
lineScoreD = animatedline(scoreAxes,Color=C(2,:));
legend("Generator","Discriminator");
ylim([0 1])
xlabel("Iteration")
ylabel("Score")
grid on

iteration = 0;
start = tic;

% Loop over epochs.
for epoch = 1:numEpochs

    % Reset and shuffle datastore.
    shuffle(mbq);

    % Loop over mini-batches.
    while hasdata(mbq)
        iteration = iteration + 1;
        
        % Read mini-batch of data.
        X = next(mbq);

        % Generate latent inputs for the generator network. Convert to
        % dlarray and specify the format "CB" (channel, batch). If a GPU is
        % available, then convert latent inputs to gpuArray.
        Z = randn(numLatentInputs,miniBatchSize,"single");
        Z = dlarray(Z,"CB");

        if canUseGPU
            Z = gpuArray(Z);
        end

        % Evaluate the gradients of the loss with respect to the learnable
        % parameters, the generator state, and the network scores using
        % dlfeval and the modelLoss function.
        [~,~,gradientsG,gradientsD,stateG,scoreG,scoreD] = ...
            dlfeval(@modelLoss,netG,netD,X,Z,flipProb);
        netG.State = stateG;  

        %%show data
        %"epoch"
        %epoch
        %"scoreG-D"
        %[scoreG,scoreD]
        
        
        % Update the discriminator network parameters.
        [netD,trailingAvg,trailingAvgSqD] = adamupdate(netD, gradientsD, ...
            trailingAvg, trailingAvgSqD, iteration, ...
            learnRateD, gradientDecayFactor, squaredGradientDecayFactor);
        

        % Update the generator network parameters.
        [netG,trailingAvgG,trailingAvgSqG] = adamupdate(netG, gradientsG, ...
            trailingAvgG, trailingAvgSqG, iteration, ...
            learnRate, gradientDecayFactor, squaredGradientDecayFactor);
        % Every validationFrequency iterations, display batch of generated
        % images using the held-out generator input.
        if mod(iteration,validationFrequency) == 0 || iteration == 1
            % Generate images using the held-out generator input.
            XGeneratedValidation = predict(netG,ZValidation);

            % Tile and rescale the images in the range [0 1].
            I = imtile(extractdata(XGeneratedValidation));
            I = rescale(I);
            % Display the images.
            subplot(1,2,1);
            plot(I,'DisplayName','I')
            % xticklabels([0 900]);
            % yticklabels([-1 1]);
            title("Generated Curve");
            % Update the scores plot.
            subplot(1,2,2)
            scoreGV = double(extractdata(scoreG));
            addpoints(lineScoreG,iteration,scoreGV);

            scoreDV = double(extractdata(scoreD));
            addpoints(lineScoreD,iteration,scoreDV);

            % Update the title with training progress information.
            D = duration(0,0,toc(start),Format="hh:mm:ss");
            title(...
                "Epoch: " + epoch + ", " + ...
                "Iteration: " + iteration + ", " + ...
                "Elapsed: " + string(D))

            drawnow
            %周期性保存数据
            if mod(iteration,validationFrequency*100)==0
                %save GANmodel_test.mat netG netD trailingAvg trailingAvgSqD iteration
            end
        end

    end
end
%%生成新图像  
numLatentInputs = 50;
numObservations = 1;
ZNew = randn(numLatentInputs,numObservations,"single");
ZNew = dlarray(ZNew,"CB");
if canUseGPU
    ZNew = gpuArray(ZNew);
end

XGeneratedNew = predict(netG,ZNew);

I = imtile(extractdata(XGeneratedNew));
I=rescale(I)
figure
plot(I,'DisplayName','I')
axis off
title("Generated Images")


该代码内容与之前图像生成的思路[1]基本一致,主要变动在于生成器、判别器、数据库构建和数据预处的区别。

[1] https://blog.csdn.net/m0_47787372/article/details/141791275?spm=1001.2014.3001.5501

首先是数据格式的变动,由于1D数据较小,这里直接用内存载入训练。

         该程序提供的示例数据为2维的doule类型(每行为1个样本),数据量3658、单样本长度128。这里利用"arrayDatastore"函数直接从内存读取该数据作为深度学习的训练样本,'IterationDimension'为样本分割的维数,这里按行分割样本,固其值设置为1;OutputType设置成same或cell都可以。

ADataStore = arrayDatastore(DataMat,'IterationDimension',1,'OutputType', 'cell');

如果这里不使用arrayDatastore类函数,将无法使用minibatchqueue函数将数据拆分成多个训练批次。后者仅支持datastore数据类型,当然你使用imaginedatastore等其他函数也是可以的(把1维数据变成图像再训练),但这本质上属于还是未对matlab数据类型的实现精准掌握。

1.2.2 生成器 


function net=Creat_2D_Gener(numLatentInputs)
net = dlnetwork;

Add branches to the dlnetwork. Each branch is a linear array of layers.
tempNet = [
    featureInputLayer(numLatentInputs,"Name","input")
    projectAndReshapeLayer([8 2048])
    transposedConv1dLayer(3,1024,"Name","transposed-conv1d","Cropping","same","Stride",2)
    instanceNormalizationLayer("Name","instancenorm")
    reluLayer("Name","relu")
    transposedConv1dLayer(3,512,"Name","transposed-conv1d_1","Cropping","same","Stride",2)
    instanceNormalizationLayer("Name","instancenorm_1")
    reluLayer("Name","relu_1")
    transposedConv1dLayer(3,256,"Name","transposed-conv1d_2","Cropping","same")
    instanceNormalizationLayer("Name","instancenorm_2")
    reluLayer("Name","relu_3")
    transposedConv1dLayer(3,128,"Name","transposed-conv1d_3","Cropping","same","Stride",2)
    instanceNormalizationLayer("Name","instancenorm_3")
    reluLayer("Name","relu_2")
    transposedConv1dLayer(3,64,"Name","transposed-conv1d_4","Cropping","same","Stride",2)
    instanceNormalizationLayer("Name","instancenorm_3_1")
    reluLayer("Name","relu_2_1")
    transposedConv1dLayer(1,1,"Name","transposed-conv1d_5","Cropping","same")
    tanhLayer("Name","tanh")];
net = addLayers(net,tempNet);

clear tempNet;

net = initialize(net);

plot(net);

end

生成器用的是1维转置卷积层,输入200个随机数,通过自定义的全连接reshape层将数据转化为8*2048的大小。利用Matlab的DL designer工具包进行分析,通过观察Activation属性,我们可以很快的了解数据在生成器中的变化。其中S为空间维度,C为通道维度,B为批次量(根据训练设置变化)。这里的设计的思路就是利用噪声生成一个通道数高的带加工样本,之后每次一维转置卷积中通道维度每减半、空间维度翻倍。最后加工为128*1(C)的1维数据。

其中,rehape自定义层代码如下,和图像生成的项目基本一致,但是输出格式进行了调整(SCB),该层就是将200个输入噪声通过全连接层变为8*2048长度的数据,再reshape成8*2048*1的SCB格式数据。

classdef projectAndReshapeLayer < nnet.layer.Layer ...
        & nnet.layer.Formattable ...
        & nnet.layer.Acceleratable

    properties
        % Layer properties.
        OutputSize
    end

    properties (Learnable)
        % Layer learnable parameters.

        Weights
        Bias
    end

    methods
        function layer = projectAndReshapeLayer(outputSize,NameValueArgs)
            % layer = projectAndReshapeLayer(outputSize)
            % creates a projectAndReshapeLayer object that projects and
            % reshapes the input to the specified output size.
            %
            % layer = projectAndReshapeLayer(outputSize,Name=name)
            % also specifies the layer name.

            % Parse input arguments.
            arguments
                outputSize
                NameValueArgs.Name = "";
            end

            % Set layer name.
            name = NameValueArgs.Name;
            layer.Name = name;

            % Set layer description.
            layer.Description = "Project and reshape to size " + ...
                join(string(outputSize));

            % Set layer type.
            layer.Type = "Project and Reshape";

            % Set output size.
            layer.OutputSize = outputSize;
        end

        function layer = initialize(layer,layout)
            % layer = initialize(layer,layout) initializes the layer
            % learnable parameters.
            %
            % Inputs:
            %         layer  - Layer to initialize
            %         layout - Data layout, specified as a 
            %                  networkDataLayout object
            %
            % Outputs:
            %         layer - Initialized layer

            % Layer output size.
            outputSize = layer.OutputSize;

            % Initialize fully connect weights.
            if isempty(layer.Weights)

                % Find number of channels.
                idx = finddim(layout,"C");
                numChannels = layout.Size(idx);

                % Initialize using Glorot.
                sz = [prod(outputSize) numChannels];
                numOut = prod(outputSize);
                numIn = numChannels;
                layer.Weights = initializeGlorot(sz,numOut,numIn);
            end

            % Initialize fully connect bias.
            if isempty(layer.Bias)

                % Initialize with zeros.
                layer.Bias = initializeZeros([prod(outputSize) 1]);
            end
        end

        function Z = predict(layer, X)
            % Forward input data through the layer at prediction time and
            % output the result.
            %
            % Inputs:
            %         layer - Layer to forward propagate through
            %         X     - Input data, specified as a formatted dlarray
            %                 with a "C" and optionally a "B" dimension.
            % Outputs:
            %         Z     - Output of layer forward function returned as
            %                 a formatted dlarray with format "SSCB".

            % Fully connect.
            weights = layer.Weights;
            bias = layer.Bias;
            X = fullyconnect(X,weights,bias);

            % Reshape.
            outputSize = layer.OutputSize;
            Z = reshape(X,outputSize(1),outputSize(2),[]);
            Z = dlarray(Z,"SCB");
        end
    end
end

1.2.3 判别器

判别器基本与生成器对称,用1维卷积核, 代码如下:


function net=Creat_1D_Discri(droprate,scale)
net = dlnetwork;

tempNet = [
    inputLayer([128 1 NaN],"SCB","Name","input")
    dropoutLayer(droprate,"Name","dropout")
    convolution1dLayer(3,32,"Name","conv1d","Padding","same","Stride",2)
    leakyReluLayer(scale,"Name","leakyrelu_1")
    convolution1dLayer(3,64,"Name","conv1d_1","Padding","same","Stride",2)
    batchNormalizationLayer("Name","batchnorm")
    leakyReluLayer(scale,"Name","leakyrelu_2")
    convolution1dLayer(3,128,"Name","conv1d_2","Padding","same","Stride",2)
    batchNormalizationLayer("Name","batchnorm_1")
    leakyReluLayer(scale,"Name","leakyrelu_3")
    convolution1dLayer(3,256,"Name","conv1d_3","Padding","same","Stride",2)
    batchNormalizationLayer("Name","batchnorm_1_1")
    leakyReluLayer(scale,"Name","leakyrelu_3_1")
    convolution1dLayer(3,512,"Name","conv1d_4","Padding","same","Stride",2)
    batchNormalizationLayer("Name","batchnorm_1_2")
    leakyReluLayer(scale,"Name","leakyrelu_3_2")
    convolution1dLayer(5,1,"Name","conv1d_5","Padding","same","Stride",4)
    sigmoidLayer("Name","layer")];
net = addLayers(net,tempNet);

% clean up helper variable
clear tempNet;

net = initialize(net);

plot(net);

具体参数如下

1.2.3数据预处理函数

 预处理函数有比较明显的改动,1个是本次示例数据是int12的格式,所以我们这里归一化范围修改了。其次是样本凭借的维度(批次维度)为3,需要注意。同时我们需要调整数据的维度顺序,因为arraydatastore按第一个维度分割样本后的数据格式为1*128*1(CSB),为了对应深度学习模型的输入维度(SCB),在预处理前利用permute函数进行维度调整。

function X = preprocessMiniBatch12_2D(data)

% Concatenate mini-batch
X = cat(3,data{:});

%调整矩阵的维度,让数值回到空间通道中,通道在第二位置;
X=permute(X, [2, 1, 3]); 
% Rescale the images in the range [-1 1].
X = rescale(X,-1,1,InputMin=0,InputMax=2^12);

end

1.2.4 损失函数

无大变化:

反向传播与梯度计算

function [lossG,lossD,gradientsG,gradientsD,stateG,scoreG,scoreD] = ...
    modelLoss(netG,netD,X,Z,flipProb)

% Calculate the predictions for real data with the discriminator network.
YReal = forward(netD,X);
% Calculate the predictions for generated data with the discriminator
% network.
[XGenerated,stateG] = forward(netG,Z);
YGenerated = forward(netD,XGenerated);

% Calculate the score of the discriminator.
scoreD = (mean(YReal) + mean(1-YGenerated)) / 2;

% Calculate the score of the generator.
scoreG = mean(YGenerated);

% Randomly flip the labels of the real images.
numObservations = size(YReal,4);
idx = rand(1,numObservations) < flipProb;
YReal(:,:,:,idx) = 1 - YReal(:,:,:,idx);

% Calculate the GAN loss.
[lossG, lossD] = ganLoss(YReal,YGenerated);

% For each network, calculate the gradients with respect to the loss.
gradientsG = dlgradient(lossG,netG.Learnables,RetainData=true);
gradientsD = dlgradient(lossD,netD.Learnables);

end

损失函数:

function [lossG,lossD] = ganLoss(YReal,YGenerated)

% Calculate the loss for the discriminator network.
lossD = -mean(log(YReal)) - mean(log(1-YGenerated));

% Calculate the loss for the generator network.
lossG = -mean(log(YGenerated));

end

1.3 资源下载

脚本、函数文件与示例数据如下:

通过网盘分享的文件:24-1D_DCGAN_EXAMPLE.zip
链接: https://pan.baidu.com/s/1kxQ4Q3RCzLeeAgdQBWl9KQ?pwd=3wgy 提取码: 3wgy 

2.总结

   从信息论的角度进行分析,DCGAN 在基于先验知识(真实样本)的条件下尽可能地生成接 近真实的样本,这一过程并不会创造新信息,无法通过对抗过程来增加训练集基本特征的多样性。但对于样本 多样性而言,DCGAN具有基于现有特征进行缩放及组 合以形成更多具有特异性高级特征的能力,因此它具有强化预测模型的泛化能力的潜力,提高模型对特征挖掘和学习能力,但这也导致DCGAN在过少的训练集(基本特征不足)或足够丰富的训练集(高级特征充足)的场景下, 很难带来显著的预测性能效果提升[2].  

[2] 光谱技术结合水分校正与样本增广的棉田土壤盐分精准反演 - 中国知网

   该项目详细展示和分析了在MATLAB中利用DCGAN生成1D数据的方法和注意事项,欢迎大家进行交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2241184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

react + ts定义接口类型写法

接口&#xff08;未进行ts定义&#xff09; export async function UserList(params: {// keyword?: string;current?: number;pageSize?: number;},// options?: { [key: string]: any }, ) {return request<API1.UserList>(http://geek.itheima.net/v1_0/mp/artic…

uniapp luch-request 使用教程+响应对象创建

1. 介绍 luch-request 是一个基于 Promise 开发的 uni-app 跨平台、项目级别的请求库。它具有更小的体积、易用的 API 和方便简单的自定义能力。luch-request 支持请求和响应拦截、全局挂载、多个全局配置实例、自定义验证器、文件上传/下载、任务操作、自定义参数以及多拦截器…

RHCE-DNS域名解析服务器

一、DNS简介 DNS &#xff08; Domain Name System &#xff09;是互联网上的一项服务&#xff0c;它作为将域名和 IP 地址相互映射的一个分布式 数据库&#xff0c;能够使人更方便的访问互联网。 DNS 系统使用的是网络的查询&#xff0c;那么自然需要有监听的 port 。 DNS 使…

Unity中HDRP设置抗锯齿

一、以前抗锯齿的设置方式 【Edit】——>【Project Settings】——>【Quality】——>【Anti-aliasing】 二、HDRP项目中抗锯齿的设置方式 在Hierarchy中——>找到Camera对象——>在Inspector面板上——>【Camera组件】——>【Rendering】——>【Pos…

电子工牌独立双通道定向拾音方案(有视频演示)

现在一些行业的客服人员在面对客户都要求使用电子工牌分别记录客服和顾客的声音,我们利用双麦克风阵列双波束拾音的方案设计了一个电子工牌方案.可以有效分别记录客服和顾客的声音. 方案思路: 我们采用了一个双麦阵列波束拾音的模块A-59,此模块可以利用2个麦克风组成阵列进行双…

Redis下载历史版本

Linux版本&#xff1a; https://download.redis.io/releases/ Windows版本&#xff1a; https://github.com/tporadowski/redis/releases Linux Redis对应gcc版本

Mysql篇-三大日志

概述 undo log&#xff08;回滚日志&#xff09;&#xff1a;是 Innodb 存储引擎层生成的日志&#xff0c;实现了事务中的原子性&#xff0c;主要用于事务回滚和 MVCC。 redo log&#xff08;重做日志&#xff09;&#xff1a;是 Innodb 存储引擎层生成的日志&#xff0c;实现…

MFC工控项目实例三十实现一个简单的流程

启动按钮夹紧 密闭&#xff0c;时间0到平衡 进气&#xff0c;时间1到进气关&#xff0c;时间2到平衡关 检测&#xff0c;时间3到平衡 排气&#xff0c;时间4到夹紧开、密闭开、排气关。 相关代码 void CSEAL_PRESSUREDlg::OnTimer_2(UINT nIDEvent_2) {// if (nIDEvent_21 &am…

通过 SSH 隧道将本地端口转发到远程主机

由于服务器防火墙,只开放了22端口,想要通过5901访问服务器上的远程桌面,可以通过下面的方式进行隧道转发。 一、示例命令 这条代码的作用是通过 SSH 创建一个 本地端口转发,将你本地的端口(5901)通过加密的 SSH 隧道连接到远程服务器上的端口(5901)。这种方式通常用于在…

docker——项目部署

什么是Docker&#xff1f; Docker是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可抑制的容器中&#xff0c;然后发布到任何流行的Linux机器上&#xff0c;也可以实现虚拟化。容器完全使用沙盒机制&#xff0c;相互之间不会存在任何接口。几…

LabVIEW-TestExec SL

文章目录 新建LabVIEW .llb库链接vi至TestExec SLTestPlan调用调用自定义动作创建变量配置动作参数 注意事项 新建LabVIEW .llb库 创建一个文件夹用来存放文件。在此文件夹下创建两个文件夹&#xff0c;分别命名为Actions和Bin。其中&#xff0c;Actions用于存放动作&#xff…

数据结构--数组

一.线性和非线性 线性&#xff1a;除首尾外只有一个唯一的前驱和后继。eg&#xff1a;数组&#xff0c;链表等。 非线性&#xff1a;不是线性的就是非线性。 二.数组是什么&#xff1f; 数组是一个固定长度的存储相同数据类型的数据结构&#xff0c;数组中的元素被存储在一…

NFS-Ganesha 核心架构解读

NFSv4 简要概述 NFS 这个协议( NFSv2 )最初由 Sun Microsystems 在 1984 年设计提出&#xff0c;由于存在一些不足&#xff0c;因此在随后由几家公司联合推出了 NFSv3。到了 NFSv4 时&#xff0c;开发完全由 IETF 主导&#xff0c;设计目标是&#xff1a; 提高互联下的 NFS 访…

Simulink对仿真数据进行FFT频谱分析

1 问题引入 在仿真阶段&#xff0c;经常会遇到有些仿真结果的数据需要进行频谱分析&#xff0c;如何快速便捷地操作&#xff0c;这里介绍其中一种简单的方法。主要利用 Simulink 中 Scope 显示的数据进行保存并进行 FFT 频谱分析&#xff0c;按下文操作即可。 2 实战 2.1 将…

Python实现贪吃蛇 经典解压小游戏!附源码

大家应该都玩过诺基亚上面的贪吃蛇吧&#xff0c;那是一段美好的童年回忆&#xff0c;本文将带你一步步用python语言实现一个snake小游戏&#xff01; 基础环境必备 版本&#xff1a;Python3 ●系统&#xff1a;Windows ●相关模块&#xff1a;pygame pip install pygame安…

Taro React-Native IOS 打包发布

http网络请求不到 配置 fix react-native facebook::flipper::SocketCertificateProvider‘ (aka ‘int‘) is not a function or func_rn运行debug提示flipper-CSDN博客 Xcode 15&#xff08;iOS17&#xff09;编译适配报错_no template named function in namespace std-CS…

Chrome使用IE内核

Chrome使用IE内核 1.下载扩展程序IE Tab 2.将下载好的IE Tab扩展程序拖拽到扩展程序界面&#xff0c;之后重启chrome浏览器即可

C++基础:Pimpl设计模式的实现

2024/11/14: 在实现C17的Any类时偶然接触到了嵌套类的实现方法以及Pimpl设计模式&#xff0c;遂记录。 PIMPL &#xff08; Private Implementation 或 Pointer to Implementation &#xff09;是通过一个私有的成员指针&#xff0c;将指针所指向的类的内部实现数据进行隐藏。 …

深入理解AIGC背后的核心算法:GAN、Transformer与Diffusion Models

深入理解AIGC背后的核心算法&#xff1a;GAN、Transformer与Diffusion Models 前言 随着人工智能技术的发展&#xff0c;AIGC&#xff08;AI Generated Content&#xff0c;人工智能生成内容&#xff09;已经不再是科幻电影中的幻想&#xff0c;而成为了现实生活中的一种新兴力…

LeetCode面试经典150题C++实现,更新中

用C实现下面网址的题目 https://leetcode.cn/problems/merge-sorted-array/?envTypestudy-plan-v2&envIdtop-interview-150 1、数组\字符串 88合并两个有序数组 以下是使用 C 实现合并两个有序数组的代码及测试用例 C代码实现 #include <iostream> #include &l…