此示例显示如何训练生成的对抗性网络(GAN)生成图像。
生成的对抗性网络(GaN)是一种深度学习网络,可以生成具有与输入实际数据相似特征的数据。
阿甘由两个网络,在一起训练的:
发电机 - 给定随机值的向量(潜在输入)作为输入,该网络生成具有与训练数据相同结构的数据。
鉴别器——给定一批包含训练数据和生成器生成数据的观测数据,该网络试图将这些观测数据分类为“真实”或“生成”。
为了训练一个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(文件名,url);解压(文件名,downloadFolder)结束
创建一个包含花的照片的图像数据存储。
datasetFolder =完整文件(imageFolder);IMDS = imageDatastore(datasetFolder,......'insertumbfolders',真正的);
增强数据以包括随机水平翻转,并调整图像大小以具有64乘值64。
增强因子= imageDataAugmenter('randxreflection',真正的);augimds = augmentedImageDatastore([64 64],IMDS,“DataAugmentation”,增强者);
定义下面的网络体系结构,其产生从1 * 1 * 100阵列的随机值的图像:
该网络:
使用a将1×1-×100×10×7-of-128阵列转换为7-×7-by-128阵列项目与重塑层。
使用具有批量归一化和Relu层的一系列转换卷积层将产生的数组升高到64×64×3阵列。
定义该网络体系结构作为层图形和指定以下网络属性。
对于转置卷积层,指定5 × 5滤波器,每个层的滤波器数量减少,步幅为2,并裁剪每个边缘的输出。
对于最终转置卷积层,指定与生成图像的三个RGB通道对应的三个5-5-5滤波器,以及前一层的输出大小。
在网络的端部,包括一个双曲正切层。
要投影并重塑噪声输入,请使用自定义层ProjectAndreshapelayer.
,附加到该示例作为支持文件。金宝app的ProjectAndreshapelayer.
层使用完全连接的操作放大输入,并将输出重塑为指定的大小。
filtersize = 5;numfilters = 64;numlattentinputs = 100;ProjectionSize = [4 4 512];tallersgenerator = [imageInputlayer([1 1 numlatentInputs],'正常化','没有',“名字”,“在”) projectAndReshapeLayer (projectionSize numLatentInputs,“项目”);transposedConv2dLayer(filterSize,4个* numFilters,“名字”,'tconv1'batchnormalizationlayer(“名字”,'bnorm1') reluLayer (“名字”,'relu1')TransposedConv2dlayer(过滤,2 * NumFilters,“步”2,'裁剪','同样',“名字”,'tconv2'batchnormalizationlayer(“名字”,'bnorm2') reluLayer (“名字”,'relu2')transposedConv2dLayer(filterSize,numFilters,“步”2,'裁剪','同样',“名字”,'tconv3'batchnormalizationlayer(“名字”,'bnorm3') reluLayer (“名字”,'relu3')transposedConv2dLayer(filterSize,3,“步”2,'裁剪','同样',“名字”,'tconv4')Tanhlayer(“名字”,'tanh')];Lgroggenerator = LayerGraph(层Generator);
为了使用自定义的训练循环来训练网络并使其能够自动区分,将层图转换为dlnetwork.
对象。
dlnetgenerator = dlnetwork(lgropgenerator);
定义以下网络,该网络分类真实和生成的64×64图像。
创建一个网络,它采用64通过-64×3的图像,并返回使用具有批标准化和漏RELU层的一系列卷积层的标量预测得分。噪声添加到使用辍学输入图像。
对于退出层,指定退出概率为0.5。
对于卷积图层,为每个层的滤波器数量越来越多地指定5×5滤波器。还指定了2的步幅和输出的填充。
对于泄漏的Relu层,指定0.2的等级。
对于最终图层,用一个4×4滤波器指定卷积层。
为了输出在范围[0,1]的概率,使用sigmoid.
功能在模型梯度函数.
dropoutprob = 0.5;numfilters = 64;Scale = 0.2;InputSize = [64 64 3];filtersize = 5;LayersDiscriminator = [ImageInputLayer(输入,'正常化','没有',“名字”,“在”)DropoutLayer(0.5,“名字”,'辍学')卷积2dlayer(过滤,numfilters,“步”2,'填充','同样',“名字”,'conv1') leakyReluLayer(规模、“名字”,'lrelu1')卷积2dlayer(过滤,2 * numfilters,“步”2,'填充','同样',“名字”,'conv2'batchnormalizationlayer(“名字”,'BN2') leakyReluLayer(规模、“名字”,'lrelu2')卷积2dlayer(过滤,4 * numfilters,“步”2,'填充','同样',“名字”,'conv3'batchnormalizationlayer(“名字”,'BN3') leakyReluLayer(规模、“名字”,'lrelu3')卷积2dlayer(过滤,8 * numfilters,“步”2,'填充','同样',“名字”,'CONV4'batchnormalizationlayer(“名字”,'BN4') leakyReluLayer(规模、“名字”,'lrelu4')convolution2dLayer(4,1,“名字”,'conv5')];Lgraphdiscriminator = DaterGraph(LayersDiscriminator);
为了使用自定义的训练循环来训练网络并使其能够自动区分,将层图转换为dlnetwork.
对象。
dlnetDiscriminator = dlnetwork (lgraphDiscriminator);
创建功能MapicalGRADENTERS.
,列于模型梯度函数的示例的部分,该部分作为输入发电机和鉴别网络中,小批量的输入数据,随机值的阵列和翻盖因子,并返回损失的梯度的相对于所述可学习参数在网络和两个网络的分数。
500个纪元的128个小批量列车。对于更大的数据集,您可能不需要训练那么多的纪元。
numEpochs = 500;miniBatchSize = 128;
指定ADAM优化选项。对于两个网络,指定
学习率为0.0002
梯度衰减因子0.5
平方梯度衰减因子为0.999
学习= 0.0002;梯度Dayfactor = 0.5;squaredgradientdecayfactor = 0.999;
如果鉴别者学会过度地区分真实和生成的图像,则发电机可能无法训练。为了更好地平衡鉴别器和发电机的学习,通过随机翻转标签将噪声添加到真实数据。
指定翻转30%的真实标签。这意味着在培训期间翻转15%的标签总数。请注意,由于所有生成的图像仍然正确标记,这不会损害发电机。
flipFactor = 0.3;
每100次迭代显示生成的验证图像。
验证频率= 100;
使用minibatchqueue
处理和管理迷你批次的图像。为每个mini-batch:
使用自定义小批量预处理功能preprocessMiniBatch
(在此示例结束时定义)以重新缩放范围内的图像[-1,1]
.
丢弃任何小于128个观测值的部分小批。
格式尺寸标签的图像数据'SSCB'
(空间,空间信道,批次)。默认情况下,minibatchqueue
对象将数据转换为dlarray.
底层类型的对象单身
.
在GPU上培训如果有一个可用的。什么时候'outputenvironment'
选择minibatchqueue
是“自动”
,minibatchqueue
将每个输出到GPUArray.
如果GPU可用。使用GPU需要并行计算工具箱™和启用CUDA®GPUNVIDIA®计算能力3.0或更高版本。
Augimds.minibatchsize =小匹匹匹匹配;executionenvironment =“自动”;活度= minibatchqueue(augimds,......'minibatchsize',小匹马,......'partialminibatch','丢弃',......'MiniBatchFcn',@preprocessminibatch,......'MiniBatchFormat','SSCB',......'outputenvironment',刽子毒环境;
使用自定义训练循环训练模型。在训练数据上循环并在每次迭代时更新网络参数。要监视培训进度,请使用一个随机值的一个随机值阵列显示一批生成的图像,以输入到发电机以及分数的曲线图。
初始化为亚当的参数。
trailingAvgGenerator = [];trailingAvgSqGenerator = [];trailingAvgDiscriminator = [];trailingAvgSqDiscriminator = [];
为了监控训练进展,使用输入到生成器中的固定数组的随机值来显示生成的一批图像,并绘制网络分数。
创建举行出的随机值的数组。
numValidationImages = 25;ZValidation = randn(1,1,numLatentInputs,numValidationImages,“单身”);
将数据转换为dlarray.
对象并指定维度标签'SSCB'
(空间,空间信道,批次)。
dlZValidation = dlarray (ZValidation,'SSCB');
对于GPU培训,将数据转换为GPUArray.
对象。
如果(execultenvironment ==.“自动”&& canUseGPU) || executionEnvironment ==“GPU”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(“得分”)网格上
训练甘。对于每个时代,将数据存储和循环播放和循环在迷你批量数据上。
为每个mini-batch:
使用模型梯度评估使用dlfeval
和MapicalGRADENTERS.
函数。
使用使用的网络参数更新网络参数adamupdate.
函数。
绘制两个网络的分数。
毕竟validationFrequency
迭代,显示一批生成的图像,用于固定的保持发生器输入。
培训可能需要一些时间来运行。
迭代= 0;start = tic;%循环epochs。为历元= 1:numEpochs%重置和洗牌的数据存储。洗牌(MBQ);%循环在迷你批次。而Hasdata(MBQ)迭代=迭代+ 1;%读取迷你批次数据。dlX =下一个(兆贝可);%为发电机网络生成潜在输入。转换为%dlarray并指定维标标签'sscb'(空间,%的空间,通道,批次)。如果在GPU训练,然后将其转换%潜在输入到gpuArray。z = Randn(1,1,NumlattentInputs,尺寸(DLX,4),“单身”);dlz = dlarray(z,'SSCB');如果(execultenvironment ==.“自动”&& canUseGPU) || executionEnvironment ==“GPU”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迭代,显示批次使用所生成的图像的%HOLD-OUT发电机输入如果mod(迭代,验证频率)== 0 ||迭代== 1%使用保持的发电机输入生成图像。dlxgeneratedValidation =预测(DlnetGenerator,DLZValidation);%瓷砖并重新归类范围的图像[0 1]。i = Imtile(提取数据(DLXGeneratedValidation));我= Rescale(i);%显示图像。副区(1,2,1);图像(imageAxes,I)xticklabels([]);yticklabels([]);标题(“生成的图像”);结束%更新分数图副区(1,2,2)addpoints(lineScoreGenerator,迭代,......双(收集(摘录(刻度))))));addpoints(LineScoredIscriminator,迭代,......双(收集(提取物)));%更新标题与训练进度信息。d =持续时间(0,0,toc(start),'格式','hh:mm:ss');标题(......“时代”+时代+“,”+......“迭代:”+迭代+“,”+......“经历:”+字符串(d))绘制结束结束
这里,鉴别器已经学习了强大的特征表示,其识别生成图像之间的真实图像。反过来,发电机已经学习了类似强的特征表示,允许它生成现实的查找数据。
训练图显示了生成器和鉴别器网络的得分。要了解更多关于如何解释网络分数,请看监视器甘训练进程,并确定共同的故障模式.
要生成新的图像,使用预测
在具有发电机功能dlarray.
对象,该对象包含一批1 × 1 × 100的随机值数组。要同时显示图像,请使用imtile
使用函数并使用图像重新扫描图像rescale.
函数。
创建A.dlarray.
对象,该对象包含25个1 × 1 × 100的随机值数组,以输入到生成器网络。
ZNew = randn(1,1,numLatentInputs,25,“单身”);dlZNew = dlarray(ZNew,'SSCB');
要使用GPU生成图像,还需要将数据转换为GPUArray.
对象。
如果(execultenvironment ==.“自动”&& canUseGPU) || executionEnvironment ==“GPU”dlZNew = gpuArray(dlZNew);结束
生成新的图像使用预测
使用发电机和输入数据。
dlxgeneratednew =预测(Dlnetgenerator,dlznew);
显示图像。
i = Imtile(提取数据(DLXGeneratedNew));我= Rescale(i);图图像(i)轴关闭标题(“生成的图像”)
功能MapicalGRADENTERS.
将生成器和鉴别器作为输入dlnetwork.
对象dlnetGenerator
和dlnetdiscriminator
,迷你批次输入数据dlX
,随机值的阵列dlZ
和翻转真实标签的百分比Flipfactor,
并返回损失相对于网络中可学习参数、生成器状态和两个网络的分数的梯度。因为鉴别器输出不在[0,1]范围内,MapicalGRADENTERS.
应用双曲线函数将其转换成概率。
功能[梯度总是,梯度分子剂,术语或级别,刻痕试验器,划分脉状物] =......modelGradients(dlnetGenerator,dlnetDiscriminator,DLX,DLZ,flipFactor)%计算使用鉴别器网络的实际数据的预测。dlYPred = forward(dlnetDiscriminator, dlX);%计算具有鉴别器网络的生成数据的预测。向前(dlXGenerated stateGenerator] = (dlnetGenerator, dlZ);dlYPredGenerated = forward(dlnetDiscriminator, dlXGenerated);%转换鉴别器输出到概率。probGenerated =乙状结肠(dlYPredGenerated);probReal =乙状结肠(dlYPred);%计算鉴别器的得分。scoreDiscriminator =((意思(probReal) + (1-probGenerated)) / 2);%计算发电机的得分。刻录物=平均值(probgenerated);%随机翻转真实图像的标签的一部分。numObservations =尺寸(probReal,4);IDX = randperm(numObservations,地板(flipFactor * numObservations));%翻转标签probReal(:,:,:,IDX)= 1-probReal(:,:,:,IDX);%计算GaN丢失。[lossGenerator, lossDiscriminator] = ganLoss(probReal,probGenerated);%对于每个网络,计算梯度相对于损失。gradientsGenerator = dlgradient(lossGenerator,dlnetGenerator.Learnables,'etaindata',真正的);gradientsDiscriminator = dlgradient(lossDiscriminator, dlnetDiscriminator.Learnables);结束
发电机的目的是生成数据鉴别归类为“真正的”。为了最大限度地从发电机图像被鉴别归类为真正的概率,尽量减少负面数似然函数。
鉴于输出 判别者:
是输入图像属于类“真实”的概率。
输入图像属于“生成”类的概率是概率。
请注意,SIGMOID操作
发生在MapicalGRADENTERS.
函数。为发电机的损失函数为
在哪里 包含生成的图像的鉴别器输出概率。
鉴别器的目的是不被生成器“愚弄”。为了最大限度地提高鉴别器在真实图像和生成图像之间成功鉴别的概率,最小化相应的负对数似然函数的和。
用于鉴别的损失函数为
在哪里 包含了真实图像鉴别器输出概率。
从0到1尺度测量发电机和鉴别者如何实现各自的目标,您可以使用分数概念。
发电机得分是平均对应于所述鉴别器输出所生成的图像的概率的:
鉴别器分数是与真实和生成的图像的鉴别器输出对应的概率的平均值:
分数与损失成反比,但有效地包含相同的信息。
功能[损失Generator,损失Discriminator] = Ganloss(Probreal,Probenerated)%计算的亏损为鉴别网络。lossDiscriminator = -mean(日志(probReal))-mean(日志(1- probGenerated));%计算发电机网络的损耗。损失generator = -mean(log(probgenerated));结束
的preprocessMiniBatch
函数使用以下步骤预处理数据:
从传入单元格数组中提取图像数据并将其连接到数字阵列中。
重新调整图像的范围[-1,1]
.
功能x = preprocessminibatch(数据)%contenate mini-batchX =猫(4,数据{:});%重新归类范围[-1 1]中的图像。x = Rescale(x,-1,1,'Inputmin',0,'inputmax',255);结束
TensoRflow团队。花http://download.tensorflow.org/example_images/flower_photos.tgz
Radford,Alec,Luke Metz和Soumith Chintala。“用深卷积生成的对抗网络进行无监督的代表学习。”预印本的arXiv的arXiv:1511.06434(2015)。
adamupdate.
|dlarray.
|dlfeval
|Dlgradient.
|dlnetwork.
|前进
|minibatchqueue
|预测