使用实验管理器训练生成对抗网络(甘斯)
这个例子展示了如何创建一个定制的培训实验训练生成敌对的网络(GAN)生成图片的花。自定义训练实验,您显式地定义所使用的训练过程实验管理器。在本例中,您实现一个自定义甘训练循环训练,一种深度学习网络,可以生成具有类似特征的数据作为输入实际数据。氮化镓由火车在一起的两个网络:
发电机-给定的向量随机值(潜在的输入)作为输入,这个网络生成数据具有相同结构作为训练数据。
鉴别器——鉴于批次的数据包含从训练数据的观察,从发电机和生成的数据,这个网络尝试分类观察“真实”或“产生”。
GAN火车,火车两个网络同时最大化两个网络的性能:
火车生成器来生成“傻瓜”鉴别器的数据。发电机的性能优化,最大化的损失时鉴别器生成的数据。换句话说,发电机的目的是生成数据,鉴别器分类为“真正的”。
培养鉴别器区分真实和生成数据。优化鉴别器的性能,减少损失的鉴别器当批次的真实和生成数据。换句话说,鉴频器的目的是不要被“骗”发电机。
理想情况下,这些策略导致发电机产生令人信服的真实数据和鉴频器已经学会强大特性表征,是训练数据的特征。有关更多信息,请参见火车生成对抗网络(甘)。
开放实验
首先,打开示例。实验管理器加载一个预配置实验的项目,你可以检查和运行。开放实验,实验的浏览器面板,双击实验的名称(ImageGenerationExperiment
)。
定制培训实验由一个描述,hyperparameters表和培训功能。有关更多信息,请参见配置自定义训练实验。
的描述字段包含的文本描述的实验。对于这个例子,描述是:
火车生成敌对的网络(GAN)生成图片的花。使用hyperparameters指定:*辍学层鉴别器网络的概率*实际标签的一部分翻转而鉴别器网络培训
的Hyperparameters部分指定策略(详尽的扫描
)和hyperparameter值用于实验。当您运行实验,实验管理器使用每一列车网络的组合hyperparameter hyperparameter表中指定的值。这个示例使用两个hyperparameters:
dropoutProb
集的概率中的辍学层鉴别器网络。默认情况下,这个hyperparameter指定的值(0.25 0.5 0.75)
。flipFactor
设置真实的分数标签翻转时火车鉴别器网络。实验使用这个hyperparameter添加噪声的实际数据和更好的平衡学习鉴别器和生成器。否则,如果鉴别器学会区分真正的过快和生成图像,然后生成器可以没有火车。这个hyperparameter被指定为值(0.1 0.3 0.5)
。
的培训功能指定了训练数据、网络架构、培训方案和培训过程中使用的实验。训练的输入函数是一个结构从hyperparameter表和字段experiments.Monitor
对象,您可以使用它来跟踪培训的进度,记录值的指标使用的培训,和生产培训的阴谋。训练函数返回一个包含训练发生器结构网络,训练有素的鉴别器网络,用于训练和执行环境。实验管理器保存此输出,所以你可以出口到MATLAB工作区当培训完成。训练函数有六个部分。
初始化输出网络的初始值设置为空数组来表示训练还没有开始。实验设置执行环境
“汽车”
,所以列车网络的GPU如果一个是可用的。使用GPU需要并行计算工具箱™和支持GPU设备。万博1manbetx有关更多信息,请参见GPU计算的需求(并行计算工具箱)。
输出。发电机= [];输出。鉴频器= [];输出。executionEnvironment =“汽车”;
负荷训练数据作为一个定义了训练数据的实验
imageDatastore
对象。实验使用鲜花数据集,其中包含3670张图片的鲜花和大约218 MB。在这个数据集的更多信息,参见图像数据集。
班长。状态=“加载数据”;
url =“http://download.tensorflow.org/example_images/flower_photos.tgz”;downloadFolder = tempdir;文件名= fullfile (downloadFolder,“flower_dataset.tgz”);
imageFolder = fullfile (downloadFolder,“flower_photos”);如果~存在(imageFolder“dir”)websave(文件名,url);解压(文件名,downloadFolder)结束
datasetFolder = fullfile (imageFolder);imdsTrain = imageDatastore (datasetFolder,…IncludeSubfolders = true);
增量= imageDataAugmenter (RandXReflection = true);augimdsTrain = augmentedImageDatastore (imdsTrain (64 64),…DataAugmentation =增压器);
定义发电机网络将发电机网络的架构定义为图像生成一层图从1 -通过- 1 - 100随机值的数组。训练网络使用一个自定义训练循环和启用自动分化,训练函数转换层图
dlnetwork
对象。发电机网络这个架构。
班长。状态=“创建生成器”;
filterSize = 5;numFilters = 64;numLatentInputs = 100;projectionSize = (512 4);
layersGenerator = [featureInputLayer (numLatentInputs) projectAndReshapeLayer (projectionSize numLatentInputs) transposedConv2dLayer (filterSize 4 * numFilters) batchNormalizationLayer reluLayer transposedConv2dLayer (2 * numFilters filterSize,跨步= 2,裁剪=“相同”)batchNormalizationLayer reluLayer transposedConv2dLayer (filterSize numFilters,跨步= 2,裁剪=“相同”)batchNormalizationLayer reluLayer transposedConv2dLayer (filterSize 3步= 2,裁剪=“相同”)tanhLayer);
lgraphGenerator = layerGraph (layersGenerator);输出。发电机= dlnetwork (lgraphGenerator);
定义鉴别器网络鉴频器网络的架构定义为一层图,把真实和生成64 - - 64 - 3的图片。辍学层使用辍学概率hyperparameter表中定义。训练网络使用一个自定义训练循环和启用自动分化,训练函数转换层图
dlnetwork
对象。鉴频器网络这个架构。
班长。状态=“创建鉴别器”;
filterSize = 5;numFilters = 64;inputSize = (64 64 3);dropoutProb = params.dropoutProb;规模= 0.2;
layersDiscriminator = [imageInputLayer (inputSize正常化=“没有”)dropoutLayer (dropoutProb) convolution2dLayer (filterSize numFilters,跨步= 2,填充=“相同”)leakyReluLayer(规模)convolution2dLayer (2 * numFilters filterSize,跨步= 2,填充=“相同”)batchNormalizationLayer leakyReluLayer(规模)convolution2dLayer (4 * numFilters filterSize,跨步= 2,填充=“相同”)batchNormalizationLayer leakyReluLayer(规模)convolution2dLayer (filterSize 8 * numFilters,跨步= 2,填充=“相同”)batchNormalizationLayer leakyReluLayer(规模)convolution2dLayer (4,1) sigmoidLayer];
lgraphDiscriminator = layerGraph (layersDiscriminator);输出。鉴频器= dlnetwork (lgraphDiscriminator);
指定培训选项定义使用的培训选择实验。在这个例子中,实验经理列车网络mini-batch大小128 50时代使用的初始学习速率0.0002,渐变衰减系数为0.5,平方梯度衰减系数为0.999。
numEpochs = 50;miniBatchSize = 128;learnRate = 0.0002;gradientDecayFactor = 0.5;squaredGradientDecayFactor = 0.999;trailingAvgG = [];trailingAvgSqG = [];trailingAvgD = [];trailingAvgSqD = [];flipFactor = params.flipFactor;
火车模型定义了自定义训练循环使用的实验。自定义训练循环使用
minibatchqueue
处理和管理mini-batches图像。对于每个mini-batch,minibatchqueue
对象重新调节图像的范围[1],丢弃任何偏mini-batches少于128的观察,和格式的图像数据维度标签“SSCB”
(空间、空间、通道、批)。默认情况下,minibatchqueue
把数据转换为对象dlarray
对象与基本类型单
。对于每一个时代,自定义训练循环打乱数据存储和循环遍历mini-batches的数据。如果你训练GPU,数据转换为gpuArray
(并行计算工具箱)对象。然后,训练函数评价模型梯度并更新鉴别器和生成器网络参数。自定义训练循环的每次迭代后,培训功能节省了培训网络和更新进展。
班长。指标= [“scoreGenerator”,“scoreDiscriminator”,“scoreCombined”];班长。包含=“迭代”;groupSubPlot(监控,“综合评分”,“scoreCombined”);groupSubPlot(监控,“发电机和鉴别器分数”,…(“scoreGenerator”,“scoreDiscriminator”]);班长。状态=“培训”;
augimdsTrain。MiniBatchSize = MiniBatchSize;兆贝可= minibatchqueue (augimdsTrain,…MiniBatchSize = MiniBatchSize,…PartialMiniBatch =“丢弃”,…MiniBatchFcn = @preprocessMiniBatch,…MiniBatchFormat =“SSCB”,…OutputEnvironment = output.executionEnvironment);
迭代= 0;为时代= 1:numEpochs shuffle(兆贝可);而hasdata(兆贝可)迭代=迭代+ 1;X =下一个(兆贝可);Z = randn (numLatentInputs miniBatchSize,“单身”);Z = dlarray (Z,“CB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |…输出。executionEnvironment = =“图形”Z = gpuArray (Z);结束[~,~,gradientsG、gradientsD stateG, scoreG,得分)=…dlfeval (@modelLoss output.generator output.discriminator X, Z, flipFactor);output.generator。状态= stateG;(输出。鉴频器、trailingAvgD trailingAvgSqD] = adamupdate (…output.discriminator gradientsD,…trailingAvgD trailingAvgSqD,迭代,…learnRate、gradientDecayFactor squaredGradientDecayFactor);(输出。发电机、trailingAvgG trailingAvgSqG] = adamupdate (…output.generator gradientsG,…trailingAvgG trailingAvgSqG,迭代,…learnRate、gradientDecayFactor squaredGradientDecayFactor);scoreG =双(收集(extractdata (scoreG)));得分=双(收集(extractdata(得分)));scoreCombinedValue = 1 - 2 *马克斯(abs(- 0.5分),abs (scoreg - 0.5));recordMetrics(监控、迭代…scoreGenerator = scoreG,…scoreDiscriminator =得分,…scoreCombined = scoreCombinedValue);如果班长。停止| | isnan (scoreG) | | isnan(得分)返回;结束结束班长。进步=(时代/ numEpochs) * 100;结束
培训甘斯可能是一项富有挑战的任务,因为发电机和鉴别器网络培训期间互相竞争。如果一个网络学习过快,那么其他网络可以从失败中学习。帮助您诊断问题和监控发电机和鉴别器实现各自的目标,这个实验显示一对训练成绩的阴谋。发电机分数scoreGenerator
措施的可能性鉴别器能正确区分生成图像。鉴频器的分数scoreDiscriminator
措施的可能性鉴别器能正确区分所有输入图像,假设实际的数量和生成图像传递到鉴频器是相等的。在理想的情况下,分数都是0.5。分数太接近于零或一个可以表明一个网络占主导地位。看到监测GAN培训进展并确定常见的失效模式。
来帮助你决定哪些试验产生最好的结果,这个实验结合发电机分数和鉴别器分数成一个单一的数值,scoreCombined
。这个指标使用l——∞范数来确定关闭两个网络是理想的场景。需要一个如果两个网络的价值分数等于0.5,和零如果其中一个网络分数等于0或1。
检查培训功能,培训功能,点击编辑。MATLAB®编辑器中打开的训练函数。此外,训练函数的代码出现在附录1最后这个例子。
运行实验
当您运行实验,实验管理列车网络多次训练函数定义的。每个试验使用不同的组合hyperparameter值。默认情况下,实验管理器运行一个审判。如果你有并行计算工具箱,您可以同时运行多个试验或卸载实验作为批处理作业在一个集群中。
运行一个审判的一次实验,在实验管理器将来发布,在模式中,选择
顺序
并点击运行。同时,运行多个试验模式中,选择
同时
并点击运行。如果没有当前并行池、实验管理器启动一个集群使用默认配置文件。实验管理器然后运行尽可能多的同时试验有工人在你平行池。为达到最佳效果,在你运行你的实验,开始与尽可能多的工人gpu并行池。有关更多信息,请参见并行使用实验管理器来训练网络和GPU计算的需求(并行计算工具箱)。将实验作为批处理作业,模式中,选择
批处理顺序
或批处理同时
,指定你集群和池大小,然后单击运行。有关更多信息,请参见卸载实验作为集群的批处理作业。
一个表显示的结果为每个审判训练和验证精度损失。
显示培训策划和跟踪每个试验的进展在实验时,审查结果,点击培训策划。
评估结果
为你的实验,找到最佳结果使用综合得分排序结果的表。
指出scoreCombined列。
点击三角形图标。
选择按照降序排列。
综合得分最高的审判出现在顶部的结果表。
评估质量的氮化镓生成和检查训练发生器产生的图像。
选择试验综合得分最高的。
在实验管理器将来发布,点击出口>训练输出。
在对话框窗口中,输入导出的培训工作空间变量的名称输出。默认的名称是
trainingOutput
。测试训练网络通过调用生成器
generateTestImages
功能,这是上市附录3最后这个例子。使用导出的训练函数作为输入输出。例如,在MATLAB命令窗口中,输入:
generateTestImages (trainingOutput)
25个随机向量的函数创建一个批处理生成器的输入网络,并显示生成的图像。
利用综合得分排序结果可能不确定最好的试验在所有情况下。为达到最佳效果,重复这个过程对于每个试验综合得分高的,视觉上检查发电机产生了各种各样的图片没有很多重复。如果图像没有多样性,其中一些是几乎相同的,那么你的发电机可能影响模式崩溃。有关更多信息,请参见模式崩溃。
记录对你的实验的结果,添加一个注释。
在结果表中,右键单击scoreCombined细胞最好的审判。
选择添加注释。
在注释窗格中,在文本框中输入你的观察。
有关更多信息,请参见排序、过滤和注释的实验结果。
重新运行实验
识别后的组合hyperparameters产生最好的图片,第二次运行实验训练网络更长一段时间。
回到实验定义面板中。
hyperparameter表,输入hyperparameter值最好的试验。例如,使用值试验3,改变的价值
dropoutProb
来0.75
和flipFactor
来0.1
。打开训练函数,指定一个较长的训练时间。下指定培训选项,改变的价值
numEpochs
来500年
。使用新的hyperparameter值运行实验和培训功能。实验管理器运行一个审判。培训大约需要10倍的时间比之前的试验。
当实验结束时,出口培训输出并运行
generateTestImages
函数来测试新发电机网络。和之前一样,视觉检查发电机产生各种各样的图片没有很多重复。
关闭实验
在实验的浏览器窗格中,右键单击项目并选择的名称关闭项目。实验管理器关闭所有的实验和结果包含在项目中。
附录1:培训功能
这个函数指定了训练数据、网络架构、培训方案和培训过程中使用的实验。
输入
参数个数
从实验管理器是一个结构字段hyperparameter表。监控
是一个experiments.Monitor
对象,您可以使用它来跟踪培训的进展,在结果表中更新信息字段,记录值的指标使用的培训,和生产培训的阴谋。
输出
输出
是一个结构,包含训练生成器网络,训练有素的鉴别器网络,用于训练和执行环境。实验管理器保存此输出,所以你可以出口到MATLAB工作区当培训完成。
函数输出= ImageGenerationExperiment_training1(参数、监控)输出。发电机= [];输出。鉴频器= [];输出。executionEnvironment =“汽车”;班长。状态=“加载数据”;url =“http://download.tensorflow.org/example_images/flower_photos.tgz”;downloadFolder = tempdir;文件名= fullfile (downloadFolder,“flower_dataset.tgz”);imageFolder = fullfile (downloadFolder,“flower_photos”);如果~存在(imageFolder“dir”)websave(文件名,url);解压(文件名,downloadFolder)结束datasetFolder = fullfile (imageFolder);imdsTrain = imageDatastore (datasetFolder,…IncludeSubfolders = true);增量= imageDataAugmenter (RandXReflection = true);augimdsTrain = augmentedImageDatastore (imdsTrain (64 64),…DataAugmentation =增压器);班长。状态=“创建生成器”;filterSize = 5;numFilters = 64;numLatentInputs = 100;projectionSize = (512 4);layersGenerator = [featureInputLayer (numLatentInputs) projectAndReshapeLayer (projectionSize numLatentInputs) transposedConv2dLayer (filterSize 4 * numFilters) batchNormalizationLayer reluLayer transposedConv2dLayer (2 * numFilters filterSize,跨步= 2,裁剪=“相同”)batchNormalizationLayer reluLayer transposedConv2dLayer (filterSize numFilters,跨步= 2,裁剪=“相同”)batchNormalizationLayer reluLayer transposedConv2dLayer (filterSize 3步= 2,裁剪=“相同”)tanhLayer);lgraphGenerator = layerGraph (layersGenerator);输出。发电机= dlnetwork (lgraphGenerator);班长。状态=“创建鉴别器”;filterSize = 5;numFilters = 64;inputSize = (64 64 3);dropoutProb = params.dropoutProb;规模= 0.2;layersDiscriminator = [imageInputLayer (inputSize正常化=“没有”)dropoutLayer (dropoutProb) convolution2dLayer (filterSize numFilters,跨步= 2,填充=“相同”)leakyReluLayer(规模)convolution2dLayer (2 * numFilters filterSize,跨步= 2,填充=“相同”)batchNormalizationLayer leakyReluLayer(规模)convolution2dLayer (4 * numFilters filterSize,跨步= 2,填充=“相同”)batchNormalizationLayer leakyReluLayer(规模)convolution2dLayer (filterSize 8 * numFilters,跨步= 2,填充=“相同”)batchNormalizationLayer leakyReluLayer(规模)convolution2dLayer (4,1) sigmoidLayer];lgraphDiscriminator = layerGraph (layersDiscriminator);输出。鉴频器= dlnetwork (lgraphDiscriminator);numEpochs = 50;miniBatchSize = 128;learnRate = 0.0002;gradientDecayFactor = 0.5;squaredGradientDecayFactor = 0.999;trailingAvgG = []; trailingAvgSqG = []; trailingAvgD = []; trailingAvgSqD = []; flipFactor = params.flipFactor; monitor.Metrics = [“scoreGenerator”,“scoreDiscriminator”,“scoreCombined”];班长。包含=“迭代”;groupSubPlot(监控,“综合评分”,“scoreCombined”);groupSubPlot(监控,“发电机和鉴别器分数”,…(“scoreGenerator”,“scoreDiscriminator”]);班长。状态=“培训”;augimdsTrain。MiniBatchSize = MiniBatchSize;兆贝可= minibatchqueue (augimdsTrain,…MiniBatchSize = MiniBatchSize,…PartialMiniBatch =“丢弃”,…MiniBatchFcn = @preprocessMiniBatch,…MiniBatchFormat =“SSCB”,…OutputEnvironment = output.executionEnvironment);迭代= 0;为时代= 1:numEpochs shuffle(兆贝可);而hasdata(兆贝可)迭代=迭代+ 1;X =下一个(兆贝可);Z = randn (numLatentInputs miniBatchSize,“单身”);Z = dlarray (Z,“CB”);如果(输出。executionEnvironment = =“汽车”& & canUseGPU) | |…输出。executionEnvironment = =“图形”Z = gpuArray (Z);结束[~,~,gradientsG、gradientsD stateG, scoreG,得分)=…dlfeval (@modelLoss output.generator output.discriminator X, Z, flipFactor);output.generator。状态= stateG;(输出。鉴频器、trailingAvgD trailingAvgSqD] = adamupdate (…output.discriminator gradientsD,…trailingAvgD trailingAvgSqD,迭代,…learnRate、gradientDecayFactor squaredGradientDecayFactor);(输出。发电机、trailingAvgG trailingAvgSqG] = adamupdate (…output.generator gradientsG,…trailingAvgG trailingAvgSqG,迭代,…learnRate、gradientDecayFactor squaredGradientDecayFactor);scoreG =双(收集(extractdata (scoreG)));得分=双(收集(extractdata(得分)));scoreCombinedValue = 1 - 2 *马克斯(abs(- 0.5分),abs (scoreg - 0.5));recordMetrics(监控、迭代…scoreGenerator = scoreG,…scoreDiscriminator =得分,…scoreCombined = scoreCombinedValue);如果班长。停止| | isnan (scoreG) | | isnan(得分)返回;结束结束班长。进步=(时代/ numEpochs) * 100;结束结束
附录2:定制培训辅助函数
这个函数需要作为输入生成器和鉴频器dlnetwork
对象(netG
和netD
),输入数据的mini-batch (X
),一个随机值数组(Z
),实际的百分比标签翻转(flipProb
),并返回值损失,损失值的梯度对可学的网络参数,发电机状态,和两个网络的分数。
函数[lossG, lossD gradientsG、gradientsD stateG, scoreG,得分)=…modelLoss (netG,经济技术开发区X, Z, flipProb) YReal =前进,经济技术开发区(X);向前(XGenerated stateG] = (netG, Z);YGenerated =前进(,经济技术开发区XGenerated);得分=(意思(YReal) + (1-YGenerated)) / 2;scoreG =意味着(YGenerated);numObservations =大小(YReal 4);numObservations idx =兰德(1)< flipProb;YReal (:,:,:, idx) = 1 - YReal (:,:,:, idx);[lossG, lossD] = GANLoss (YReal YGenerated);gradientsG = dlgradient (lossG、netG.Learnables RetainData = true); gradientsD = dlgradient(lossD,netD.Learnables);结束
这个函数返回鉴别器和机组的损失。
函数[lossG, lossD] = GANLoss (YReal YGenerated) lossD =意味着(日志(YReal))的意思是(日志(1-YGenerated));lossG =意味着(日志(YGenerated));结束
这个函数使用以下步骤:预处理数据
提取图像数据从传入单元阵列和连接到一个数字数组。
重新调节图像的范围[1]。
函数X = preprocessMiniBatch(数据)X =猫(4、数据{:});X =重新调节(X, 1, 1, InputMin = 0, InputMax = 255);结束
附录3:生成测试图像
这个函数创建一批25个随机向量生成器的输入网络,显示生成的图像。使用这个函数视觉检查发电机产生的各种各样的图片没有很多重复。如果图像没有多样性,其中一些是几乎相同的,那么你的发电机可能影响模式崩溃。
函数generateTestImages (trainingOutput)发电机= trainingOutput.generator;executionEnvironment = trainingOutput.executionEnvironment;numLatentInputs = 100;numTestImages = 25;中兴通讯= randn (numLatentInputs numTestImages,“单身”);中兴通讯= dlarray(中兴通讯,“CB”);如果(executionEnvironment = =“汽车”& & canUseGPU) | | executionEnvironment = =“图形”中兴通讯= gpuArray(中兴);结束XGenTest =预测(发电机,中兴通讯);我= imtile (extractdata (XGenTest));I =重新调节(我);数字图像(I)轴从标题(“生成的图像”)结束