主要内容

训练生成对抗网络(GAN)

这个例子展示了如何训练生成对抗网络来生成图像。

生成的对抗性网络(GaN)是一种深度学习网络,可以生成具有与输入实际数据相似特征的数据。

一个GAN由两个一起训练的网络组成:

  1. 发电机 - 给定随机值的向量(潜在输入)作为输入,该网络生成具有与训练数据相同结构的数据。

  2. 鉴别者 - 给定批次包含训练数据的观察的数据,并从发电机生成数据,这个网络试图将观察分类为“真正的”“生成”

为了训练一个GAN,同时训练两个网络,以使两者的性能最大化:

  • 训练生成器生成“愚弄”鉴别器的数据。

  • 培训鉴别器以区分实际和生成的数据。

为了优化生成器的性能,当给定生成数据时,最大限度地增加鉴别器的损失。也就是说,生成器的目标是生成鉴别器分类为的数据“真正的”

为了优化鉴别器的性能,在给定批次的真实和生成数据时,最小化判别符的丢失。也就是说,鉴别者的目标是由发电机“被愚弄”。

理想情况下,这些策略会产生一个生成令人信服的真实数据的生成器和一个学习了训练数据特征的强特征表示的鉴别器。

负载培训数据

下载并提取数据集[1]。

url ='http://download.tensorflow.org/example_images/flower_photos.tgz';downloadfolder = tempdir;filename = fullfile(downloadFolder,'flower_dataset.tgz');imageFolder = fullfile (downloadFolder,“flower_photos”);如果~存在(imageFolder'dir')disp('下载鲜花数据集(218 MB)......')Websave(Filename,URL);Untar(文件名,DownloadFolder)结尾

创建一个包含花的照片的图像数据存储。

datasetFolder = fullfile (imageFolder);imd = imageDatastore (datasetFolder,...'insertumbfolders',真正的);

增加数据以包括随机水平翻转,并将图像大小调整为64 * 64。

增量= imageDataAugmenter ('randxreflection',真正的);= augmentedImageDatastore([64 64],imds,“DataAugmentation”、增压器);

定义生成器网络

定义以下网络架构,从大小100的随机向量生成图像。

这个网络:

  • 使用a将大小100到7-ob-7-by-128阵列的随机向量转换为项目和重塑层。

  • 使用一系列带批归一化的转置卷积层和ReLU层将生成的数组升级为64 × 64 × 3数组。

将此网络体系结构定义为一个层图,并指定以下网络属性。

  • 对于转置的卷积层,指定5 × 5滤波器,每层滤波器数量减少,步长为2,并在每条边缘上裁剪输出。

  • 对于最后的转置卷积层,指定三个5 × 5滤波器对应生成图像的三个RGB通道,以及前一层的输出大小。

  • 在网络的末端,包括一个tanh层。

要投影并重塑噪声输入,请使用自定义层projectAndReshapeLayer,作为支持文件附加到此示例中。金宝app的projectAndReshapeLayerObject使用完全连接的操作Upscales输入,并将输出重新插入指定大小。

filtersize = 5;numfilters = 64;numlattentinputs = 100;ProjectionSize = [4 4 512];tallersgenerator = [featureinputlayer(numlatentinputs,“名字”“在”) projectAndReshapeLayer (projectionSize numLatentInputs,“名字”“项目”);transposedConv2dLayer (filterSize 4 * numFilters,“名字”'tconv1') batchNormalizationLayer (“名字”“bnorm1”) reluLayer (“名字”“relu1”) transposedConv2dLayer (2 * numFilters filterSize,“步”2,“种植”“相同”“名字”'tconv2') batchNormalizationLayer (“名字”“bnorm2”) reluLayer (“名字”“relu2”) transposedConv2dLayer (filterSize numFilters,“步”2,“种植”“相同”“名字”'tconv3') batchNormalizationLayer (“名字”“bnorm3”) reluLayer (“名字”“relu3”) transposedConv2dLayer (filterSize 3“步”2,“种植”“相同”“名字”“tconv4”)Tanhlayer(“名字”'tanh'));lgraphGenerator = layerGraph (layersGenerator);

要使用自定义训练循环训练网络并实现自动区分,请将层图转换为dlnetwork对象。

dlnetgenerator = dlnetwork(lgropgenerator);

定义鉴别器网络

定义以下网络,对真实和生成的64 × 64图像进行分类。

创建一个网络,获取64 × 64 × 3的图像,并使用一系列卷积层和批量归一化和泄漏的ReLU层返回标量预测得分。使用dropout为输入图像添加噪声。

  • 对于dropout层,指定dropout概率为0.5。

  • 对于卷积层,指定5 × 5滤波器,每一层的滤波器数量要不断增加。还要指定输出的步幅为2和填充。

  • 对于泄漏的ReLU层,指定0.2的刻度。

  • 对于最终图层,用一个4×4滤波器指定卷积层。

要输出范围[0,1]内的概率,请使用乙状结肠功能MapicalGRADENTERS.功能,列出模型梯度函数示例的一部分。

dropoutprob = 0.5;numfilters = 64;Scale = 0.2;InputSize = [64 64 3];filtersize = 5;LayersDiscriminator = [ImageInputLayer(输入,“归一化”'没有任何'“名字”“在”) dropoutLayer (dropoutProb“名字”“辍学”)卷积2dlayer(过滤,numfilters,“步”2,“填充”“相同”“名字”'conv1') leakyReluLayer(规模、“名字”'lrelu1') convolution2dLayer (2 * numFilters filterSize,“步”2,“填充”“相同”“名字”'conv2') batchNormalizationLayer (“名字”“bn2”) leakyReluLayer(规模、“名字”“lrelu2”)卷积2dlayer(过滤,4 * numfilters,“步”2,“填充”“相同”“名字”'conv3') batchNormalizationLayer (“名字”“bn3”) leakyReluLayer(规模、“名字”“lrelu3”)卷积2dlayer(过滤,8 * numfilters,“步”2,“填充”“相同”“名字”“conv4”) batchNormalizationLayer (“名字”“bn4”) leakyReluLayer(规模、“名字”“lrelu4”1) convolution2dLayer(4日,“名字”“conv5”));lgraphDiscriminator = layerGraph (layersDiscriminator);

要使用自定义训练循环训练网络并实现自动区分,请将层图转换为dlnetwork对象。

dlnetDiscriminator = dlnetwork (lgraphDiscriminator);

定义模型梯度和损失函数

创建函数MapicalGRADENTERS.,列于模型梯度函数示例的一部分,它以发电机和鉴别器网络为输入,一个迷你输入数据,随机值阵列和翻转因子,并返回到网络中的学习参数的损失梯度和两个网络的分数。

指定培训选项

在500个epoch中使用128个小批量的火车。对于更大的数据集,您可能不需要训练那么多的时代。

numEpochs = 500;miniBatchSize = 128;

指定Adam优化的选项。对于两个网络,请指定:

  • 学习率为0.0002

  • 梯度衰减系数为0.5

  • 平方梯度衰减因子为0.999

learnRate = 0.0002;gradientDecayFactor = 0.5;squaredGradientDecayFactor = 0.999;

如果鉴别器太快地学会区分真实图像和生成图像,那么发生器就可能无法训练。为了更好地平衡鉴别器和生成器的学习,通过随机翻转标签向真实数据添加噪声。

指定一个flipFactor值为0.3,以翻转30%的真实标签(占总标签的15%)。请注意,由于所有生成的图像仍然正确标记,这不会损害发电机。

flipFactor = 0.3;

每100次迭代显示生成的验证图像。

验证频率= 100;

火车模型

minibatchqueue处理和管理小批映像。对于每个迷你批处理:

  • 使用自定义小批量预处理功能preprocessMiniBatch(在此示例结束时定义)以重新缩放范围内的图像[1]

  • 丢弃任何小于128次的部分小批次。

  • 使用尺寸标签格式化图像数据“SSCB”(空间、空间、通道、批处理)。默认情况下,minibatchqueue对象将数据转换为dlarray.底层类型的对象

  • 在GPU上培训如果有一个可用的。当。。。的时候“OutputEnvironment”选择minibatchqueue“汽车”minibatchqueue将每个输出转换为gpuArray图形处理器是否可用。使用GPU需要并行计算工具箱™和使用CUDA®的NVIDIA®GPU,具有3.0或更高的计算能力。

Augimds.minibatchsize =小匹匹匹匹配;executionenvironment =“汽车”;兆贝可= minibatchqueue (augimds,...“MiniBatchSize”miniBatchSize,...'partialminibatch'“丢弃”...“MiniBatchFcn”@preprocessMiniBatch,...“MiniBatchFormat”“SSCB”...“OutputEnvironment”,刽子毒环境;

使用自定义培训循环训练模型。循环遍历训练数据并在每次迭代时更新网络参数。为了监控训练进度,可以显示一批生成的图像,使用一个固定的随机值数组输入生成器,以及一个分数图。

初始化Adam的参数。

trailingAvgGenerator = [];trailingAvgSqGenerator = [];trailingAvgDiscriminator = [];trailingAvgSqDiscriminator = [];

为了监视培训进度,使用进入发电机的固定随机向量显示一批生成的图像并绘制网络分数。

创建一个保留的随机值数组。

numValidationImages = 25;ZValidation = randn (numLatentInputs numValidationImages,“单一”);

将数据转换为dlarray.对象,并指定维度标签“CB”(频道,批处理)。

dlZValidation = dlarray (ZValidation,“CB”);

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

如果(executionEnvironment = =“汽车”&& canUseGPU) || executionEnvironment ==“图形”dlZValidation = gpuArray (dlZValidation);结尾

初始化培训进度图。创建一个图形并将其大小调整为宽度的两倍。

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

为生成的图像和网络分数创建一个子图。

imageAxes =情节(1、2、1);scoreAxes =情节(1、2、2);

初始化Scores Plot的动画行。

lineScoreGenerator = animatedline (scoreAxes,“颜色”,[0 0.447 0.741]);LineScoredIscriminator = AnimatedLine(Scoreaxes,“颜色”, [0.85 0.325 0.098];传奇('发电机'鉴频器的);ylim([01])xlabel(“迭代”) ylabel (“分数”网格)

训练甘。对于每个时代,将数据存储和循环播放和循环在迷你批量数据上。

对于每个迷你批处理:

  • 使用模型梯度评估使用dlfevalMapicalGRADENTERS.函数。

  • 使用使用的网络参数更新网络参数adamupdate.函数。

  • 绘制两个网络的分数。

  • 在每一个validationFrequency迭代,为固定的生成器输入显示一批生成的图像。

培训可能需要一些时间来运行。

迭代= 0;开始=抽搐;%遍历纪元。时代= 1:numEpochs%重置和洗牌数据存储。洗牌(兆贝可);%循环小批处理。尽管Hasdata (mbq)迭代=迭代+ 1;%读取小批数据。dlX =下一个(兆贝可);%为发电机网络生成潜在输入。转换成% dlarray并指定维度标签'CB' (channel, batch)。%如果在GPU上训练,那么将潜在输入转换为gpuArray。Z = randn (numLatentInputs miniBatchSize,“单一”);dlz = dlarray(z,“CB”);如果(executionEnvironment = =“汽车”&& canUseGPU) || executionEnvironment ==“图形”DLZ = GPUARRAY(DLZ);结尾%使用评估模型梯度和发电机状态%dlfeval和easturedients函数在结束时列出%的例子。[梯度总是,梯度分子剂,术语或级别,刻痕试验器,划分脉状物] =...dlfeval(@modelgradients,dlnetgenerator,dlnetdiscriminator,dlx,dlz,flipfactor);dlnetgenerator.state = stategenerator;%更新鉴别器网络参数。[dlnetDiscriminator, trailingAvgDiscriminator trailingAvgSqDiscriminator] =...adamupdate (dlnetDiscriminator gradientsDiscriminator,...trailingAvgDiscriminator trailingAvgSqDiscriminator,迭代,...learnRate、gradientDecayFactor squaredGradientDecayFactor);%更新发电机网络参数。[DlnetGenerator,TrailingAvggenerator,TrailingAvgsqgenerator] =...adamupdate (dlnetGenerator gradientsGenerator,...trailingAvgGenerator trailingAvgSqGenerator,迭代,...learnRate、gradientDecayFactor squaredGradientDecayFactor);%每次validationFrequency迭代时,使用%保持发电机输入。如果mod(迭代,验证频率)== 0 ||迭代== 1%使用保留的生成器输入生成图像。dlXGeneratedValidation =预测(dlnetGenerator dlZValidation);%瓷砖并重新归类范围的图像[0 1]。i = Imtile(提取数据(DLXGeneratedValidation));I =重新调节(我);%显示图像。次要情节(1、2、1);图像(imageAxes,我)xticklabels ([]);yticklabels ([]);标题(“生成的图像”);结尾%更新分数绘图。次要情节(1、2、2)addpoints (lineScoreGenerator,迭代,...双(收集(extractdata (scoreGenerator))));addpoints (lineScoreDiscriminator迭代,...双(收集(extractdata (scoreDiscriminator))));%使用培训进度信息更新标题。d =持续时间(0,0,toc(start),“格式”“hh: mm: ss”);标题(...”时代:“+时代+", "+...“迭代:“+迭代+", "+...”经过:“+字符串(d))绘制结尾结尾

在这里,鉴别器学习了一个强大的特征表示,在生成的图像中识别真实图像。反过来,生成器也学习了类似的强特征表示,允许它生成类似于训练数据的图像。

训练图显示了产生器和鉴别器网络的分数。要了解更多关于如何解释网络分数的信息,请参见监控GAN培训进度,识别常见故障模式

生成新的图片

要生成新的图像,请使用预测功能上的发电机与dlarray.对象,该对象包含一批随机向量。若要一起显示图像,请使用imtile使用函数并使用图像重新扫描图像重新调节函数。

创建一个dlarray.对象,该对象包含一批要输入到生成器网络的25个随机向量。

numObservations = 25;ZNew = randn (numLatentInputs numObservations,“单一”);dlZNew = dlarray (ZNew,“CB”);

要使用GPU生成图像,也要将数据转换为gpuArray对象。

如果(executionEnvironment = =“汽车”&& canUseGPU) || executionEnvironment ==“图形”dlZNew = gpuArray (dlZNew);结尾

控件生成新的映像预测函数与生成器和输入数据。

dlxgeneratednew =预测(Dlnetgenerator,dlznew);

显示图像。

我= imtile (extractdata (dlXGeneratedNew));I =重新调节(我);数字图像(I)轴离开标题(“生成的图像”

模型梯度函数

这个函数MapicalGRADENTERS.以发生器和鉴别器作为输入dlnetwork对象dlnetGeneratordlnetdiscriminator,一小批输入数据dlX,一个随机值数组DLZ.以及真正的标签所占的比例flipFactor,返回损失相对于网络中可学习参数的梯度、发电机状态和两个网络的得分。由于鉴别器输出不在[0,1]范围内,因此MapicalGRADENTERS.函数应用sigmoid函数将其转换为概率。

功能[梯度总是,梯度分子剂,术语或级别,刻痕试验器,划分脉状物] =...modelGradients(dlnetGenerator, dlnetDiscriminator, dlX, dlZ, flipFactor)%计算使用鉴别器网络的实际数据的预测。dlYPred = forward(dlnetDiscriminator, dlX);%利用鉴别器网络计算生成数据的预测。向前(dlXGenerated stateGenerator] = (dlnetGenerator, dlZ);dlYPredGenerated = forward(dlnetDiscriminator, dlXGenerated);将鉴别器输出转换为概率。probGenerated =乙状结肠(dlYPredGenerated);probReal =乙状结肠(dlYPred);%计算鉴别器的得分。scoreDiscriminator = (mean(probReal) + mean(1-probGenerated)) / 2;%计算生成器的分数。scoreGenerator =意味着(probGenerated);%随机翻转真实图像的标签的一部分。numObservations =大小(probReal 4);idx = randperm(numObservations,floor(flipFactor * numObservations));%翻转标签。probReal(:,:,:,idx) = 1 - probReal(:,:,:,idx);%计算GAN损失。[lossGenerator, lossDiscriminator] = ganLoss(probReal,probGenerated);%对于每个网络,计算相对于损失的梯度。= dlgradient(lossGenerator, dlnetGenerator. dll)可学的,“RetainData”,真正的);gradientsDiscriminator = dlgradient(lossDiscriminator, dlnetDiscriminator.Learnables);结尾

GAN损失函数和分数

发电机的目的是生成鉴别器分类为的数据“真正的”.为了使来自生成器的图像被鉴别器分类为真实的概率最大化,请最小化负对数似然函数。

鉴于输出 Y 判别者:

  • Y ˆ σ. Y 输入图像属于类的概率是多少“真正的”

  • 1 - Y ˆ 输入图像属于类的概率是多少“生成”

请注意,SIGMOID操作 σ. 发生在MapicalGRADENTERS.函数。发电机的损耗函数由

lossGenerator - 吝啬的 日志 Y ˆ 生成的

在哪里 Y ˆ G e n e r 一个 t e d 包含生成的图像的鉴别器输出概率。

鉴别器的目的是不被生成器“愚弄”。为了最大化鉴别器成功鉴别真实图像和生成图像的概率,将相应的负对数似然函数的和最小化。

鉴别器的损失函数由

损失Discriminator. - 吝啬的 日志 Y ˆ 真实的 - 吝啬的 日志 1 - Y ˆ 生成的

在哪里 Y ˆ R e 一个 l 包含真实图像的鉴别器输出概率。

为了从0到1来衡量生成器和鉴别器实现各自目标的程度,你可以使用分数的概念。

生成器得分是所生成图像的鉴别器输出对应概率的平均值:

scoreGenerator 吝啬的 Y ˆ 生成的

鉴别器分数是与真实和生成的图像的鉴别器输出对应的概率的平均值:

scoreDiscriminator 1 2 吝啬的 Y ˆ 真实的 + 1 2 吝啬的 1 - Y ˆ 生成的

分数与损失成反比,但实际上包含相同的信息。

功能[损失Generator,损失Discriminator] = Ganloss(Probreal,Probenerated)%计算鉴别器网络的损失。lossDiscriminator = -mean(log(probReal)) -mean(log(1-probGenerated));%计算发电网络的损耗。损失generator = -mean(log(probgenerated));结尾

Mini-Batch预处理功能

preprocessMiniBatch函数使用以下步骤对数据进行预处理:

  1. 从传入单元格数组中提取图像数据并将其连接到数字阵列中。

  2. 将图像缩放到范围内[1]

功能x = preprocessminibatch(数据)%contenate mini-batchX =猫(4、数据{:});%缩放范围[-1 1]的图像。x = Rescale(x,-1,1,“InputMin”0,'inputmax',255);结尾

参考

  1. TensorFlow团队。http://download.tensorflow.org/example_images/flower_photos.tgz

  2. 雷德福,亚历克,卢克·梅茨,还有苏密斯·金塔拉。“基于深度卷积生成对抗网络的无监督表示学习”预印本,2015年11月19日提交。http://arxiv.org/abs/1511.06434。

另请参阅

|||||||

相关的话题