此示例显示如何训练生成的对抗性网络(GAN)生成图像。
生成的对抗性网络(GaN)是一种深度学习网络,可以生成具有与输入实际数据相似特征的数据。
甘包括两个网络一起训练的网络:
发电机 - 给定随机值的向量(潜在输入)作为输入,该网络生成具有与训练数据相同结构的数据。
鉴别器 - 给定批次包含训练数据的观察的数据,并从生成器生成数据,这个网络试图将观察分类为“真实”或“生成”。
要训练甘甘,可以同时列出两个网络,以最大限度地提高两者的性能:
火车生成器生成“愚弄”鉴别者的数据。
培训鉴别器以区分实际和生成的数据。
为了优化发电机的性能,在给定的数据时最大化鉴别器的丢失。也就是说,发电机的目标是生成鉴别器将其分类为“Real”的数据。
为了优化鉴别器的性能,在给定批次的真实和生成数据时,最小化判别符的丢失。也就是说,鉴别者的目标是由发电机“被愚弄”。
理想地,这些策略导致发电机产生令人信服的现实数据和具有学习的强大特征表示的鉴别者,这些数据是培训数据的特征。
下载并提取花朵数据集[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);imds = imageageataStore(DataSetFolder,......'insertumbfolders',真的);
增强数据以包括随机水平翻转,并调整图像大小以具有64乘值64。
upmmenter = imagedataAugmenter('randxreflection',真的);Augimds = AugmentedimageDataStore([64 64],IMDS,'dataaugmentation',增强者);
定义以下网络架构,它生成从1乘100乘100个随机值数组的图像:
这个网络:
使用a将1×1-×100×10×7-of-128阵列转换为7-×7-by-128阵列项目和重塑层。
使用具有批量归一化和Relu层的一系列转换卷积层将产生的数组升高到64×64×3阵列。
将此网络架构定义为图层图并指定以下网络属性。
对于转置的卷积层,用每个层的过滤器数量减小,每个层的速度和每个边缘上的输出播种的步伐和每个边缘裁剪的5×5滤波器。
对于最终转置卷积层,指定与生成图像的三个RGB通道对应的三个5-5-5滤波器,以及前一层的输出大小。
在网络末尾,包括Tanh层。
要投影并重塑噪声输入,请使用自定义层ProjectAndreshapelayer.
,附加到该示例作为支持文件。万博1manbetx这ProjectAndreshapelayer.
使用完全连接的操作,层Upscales输入输入,并将输出重新装回指定大小。
filtersize = 5;numfilters = 64;numlattentinputs = 100;ProjectionSize = [4 4 512];tallersgenerator = [imageInputlayer([1 1 numlatentInputs],'正常化'那'没有'那'姓名'那'在')ProjectAndreshapelayer(Projectionsize,NumlattentInputs,'proj');TransposedConv2dlayer(过滤,4 * NumFilters,'姓名'那'tconv1'batchnormalizationlayer('姓名'那'bnorm1')剥离('姓名'那'relu1')TransposedConv2dlayer(过滤,2 * NumFilters,'走吧'2,'裁剪'那'相同的'那'姓名'那'tconv2'batchnormalizationlayer('姓名'那'bnorm2')剥离('姓名'那'relu2')TransposedConv2dlayer(过滤,NumFilters,'走吧'2,'裁剪'那'相同的'那'姓名'那'tconv3'batchnormalizationlayer('姓名'那'bnorm3')剥离('姓名'那'relu3')TransposedConv2dlayer(过滤,3,'走吧'2,'裁剪'那'相同的'那'姓名'那'tconv4')Tanhlayer('姓名'那'tanh')];Lgroggenerator = LayerGraph(层Generator);
要使用自定义训练循环训练网络并启用自动分化,将图层图转换为adlnetwork.
目的。
dlnetgenerator = dlnetwork(lgropgenerator);
定义以下网络,该网络分类真实和生成的64×64图像。
创建一个34×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')漏髓范围(秤,'姓名'那'lrelu1')卷积2dlayer(过滤,2 * numfilters,'走吧'2,'填充'那'相同的'那'姓名'那'conv2'batchnormalizationlayer('姓名'那'bn2')漏髓范围(秤,'姓名'那'lrelu2')卷积2dlayer(过滤,4 * numfilters,'走吧'2,'填充'那'相同的'那'姓名'那'conv3'batchnormalizationlayer('姓名'那'bn3')漏髓范围(秤,'姓名'那'lrelu3')卷积2dlayer(过滤,8 * numfilters,'走吧'2,'填充'那'相同的'那'姓名'那'conv4'batchnormalizationlayer('姓名'那'bn4')漏髓范围(秤,'姓名'那'lrelu4')卷积2dlayer(4,1,'姓名'那'conv5')];Lgraphdiscriminator = DaterGraph(LayersDiscriminator);
要使用自定义训练循环训练网络并启用自动分化,将图层图转换为adlnetwork.
目的。
dlnetdiscriminator = dlnetwork(lgraphdiscriminator);
创建功能MapicalGRADENTERS.
,列于模型梯度函数示例的一部分,它用作输入生成器和鉴别器网络,一个迷你输入数据,随机值阵列和翻转因子,并返回关于网络中的学习参数的丢失梯度两个网络的得分。
迷你批量大小为128的火车,500时代。对于较大的数据集,您可能不需要为尽可能多的时期训练。
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;
使用小公子
处理和管理迷你批次的图像。对于每个迷你批处理:
使用自定义迷你批处理预处理功能Preprocessminibatch.
(在此示例结束时定义)以重新缩放范围内的图像[-1,1]
。
丢弃任何具有少于128个观察的部分迷你批次。
使用维标签格式化图像数据'SSCB'
(空间,空间,频道,批量)。默认情况下,小公子
对象将数据转换为dlarray.
底层类型的对象单身的
。
在GPU上培训如果有一个可用的。当。。。的时候'outputenvironment'
选择小公子
是“汽车”
那小公子
将每个输出转换为aGPUArray.
如果可用GPU。使用GPU需要并行计算工具箱™和CUDA®已启用的NVIDIA®GPU,具有计算能力3.0或更高。
Augimds.minibatchsize =小匹匹匹匹配;executionenvironment =“汽车”;MBQ = Minibatchqueue(Augimds,......'minibatchsize',小匹马,......'partialminibatch'那'丢弃'那......'minibatchfcn',@preprocessminibatch,......'minibatchformat'那'SSCB'那......'outputenvironment',刽子毒环境;
使用自定义训练循环训练模型。在训练数据上循环并在每次迭代时更新网络参数。要监视培训进度,请使用一个随机值的一个随机值阵列显示一批生成的图像,以输入到发电机以及分数的曲线图。
初始化adam的参数。
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(“分数”) 网格在
训练甘。对于每个时代,将数据存储和循环播放和循环在迷你批量数据上。
对于每个迷你批处理:
使用模型梯度评估使用dlfeval.
和MapicalGRADENTERS.
功能。
使用使用的网络参数更新网络参数adamupdate.
功能。
绘制两个网络的分数。
毕竟验证频繁
迭代,显示一批生成的图像,用于固定的保持发生器输入。
培训可能需要一些时间来运行。
迭代= 0;start = tic;%循环epochs。为了epoch = 1:numepochs%重置和Shuffle数据存储。洗牌(MBQ);%循环在迷你批次。尽管Hasdata(MBQ)迭代=迭代+ 1;%读取迷你批次数据。DLX =下一个(MBQ);%为发电机网络生成潜在输入。转换成%dlarray并指定维标标签'sscb'(空间,%空间,频道,批量)。如果在GPU上培训,则转换GPUARRAY的%潜在输入。z = Randn(1,1,NumlattentInputs,尺寸(DLX,4),'单身的');dlz = dlarray(z,'SSCB');如果(execultenvironment ==.“汽车”&& canusegpu)||executionenvironment ==.“GPU”DLZ = GPUARRAY(DLZ);结尾%使用Model梯度和发电机状态进行评估%dlfeval和easturedients函数在结束时列出% 例子。[梯度总是,梯度分子剂,术语或级别,刻痕试验器,划分脉状物] =......dlfeval(@modelgradients,dlnetgenerator,dlnetdiscriminator,dlx,dlz,flipfactor);dlnetgenerator.state = stategenerator;%更新鉴别器网络参数。[DlnetDiscriminator,trailingavgdiscriminator,trailingavgsqdiscriminator] =......Adamupdate(DLNETDISCRIMINATOR,梯度DISCRIMINATOR,......TrailIghaVGDIscriminator,Trailingavgsqdiscriminator,迭代,......学习,梯度dayfactor,squaredgradientdecayfactor);%更新生成网络参数。[DlnetGenerator,TrailingAvggenerator,TrailingAvgsqgenerator] =......Adamupdate(DlnetGenerator,渐变的Generator,......Trailighavggenerator,trailighavgsqgenerator,迭代,......学习,梯度dayfactor,squaredgradientdecayfactor);每一个验证频率迭代,使用该次数显示生成的图像批次%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');标题(......“时代:”+ epoch +“,”+......“迭代:”+迭代+“,”+......“经过:”+字符串(d))绘制结尾结尾
这里,鉴别器已经学习了强大的特征表示,其识别生成图像之间的真实图像。反过来,发电机已经学习了类似强的特征表示,允许它生成现实的查找数据。
训练图显示了发电机和鉴别器网络的分数。了解有关如何解释网络分数的更多信息,请参阅监控GaN培训进度并确定常见的失败模式。
要生成新图像,请使用预测
用一个发电机的功能dlarray.
包含批次的1×1×100阵列随机值的对象。要将图像显示在一起,请使用inmtile.
使用函数并使用图像重新扫描图像rescale.
功能。
创建一个dlarray.
包含一批25个1×1-100-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.
应用sigmoid函数将其转换为概率。
功能[梯度总是,梯度分子剂,术语或级别,刻痕试验器,划分脉状物] =......ModelGRADENTERS(DLNETGENERATOR,DLNETDISCRIMINATOR,DLX,DLZ,FLIPFORTOR)%计算使用鉴别器网络的实际数据的预测。dlypry =前进(DlnetDiscriminator,DLX);%计算具有鉴别器网络的生成数据的预测。[dlxgenerated,stategenerator] =向前(DlnetGenerator,DLZ);dlypredgenerated =前进(dlnetdiscriminator,dlxgenerated);%将鉴别器输出转换为概率。probgenerated = sigmoid(dlypredgenerated);probreal = sigmoid(dlypred);%计算鉴别器的得分。划分((突起)+平均值(1-probgenerated))/ 2);%计算发电机的得分。刻录物=平均值(probgenerated);%随机翻转真实图像的标签的一部分。numobservations = size(probreal,4);idx = randperm(numobservations,backs(flipfactor * numobservations));%翻转标签probreal(::::,idx)= 1-probreal(::::,IDx);%计算GaN丢失。[损失Generator] = Ganloss(Probreal,Probgenerated);每个网络的%,相对于损耗计算梯度。梯度Generator = Dlgradient(LockGenerator,DlnetGenerator.Learnables,'etaindata',真的);梯度Discriminator = Dlgradient(LockDiscriminator,DLNetDiscriminator.Learnables);结尾
发电机的目的是生成鉴别器将其分类为“Real”的数据。为了最大化发电机的图像被鉴别器分类的概率,最小化负对数似函数。
鉴于输出 判别者:
输入图像属于“Real”类的概率是概率。
输入图像属于“生成”类的概率是概率。
请注意,SIGMOID操作
发生在MapicalGRADENTERS.
功能。发电机的损耗功能由
在哪里 包含生成的图像的鉴别器输出概率。
判别者的目标是由发电机“被愚弄”。为了最大化鉴别器在真实和生成的图像之间成功区分的概率,最小化相应的负对数似章的总和。
鉴别者的损失函数是给出的
在哪里 包含真实图像的鉴别器输出概率。
从0到1尺度测量发电机和鉴别者如何实现各自的目标,您可以使用分数概念。
发电机分数是与生成的图像的鉴别器输出对应的概率的平均值:
鉴别器分数是与真实和生成的图像的鉴别器输出对应的概率的平均值:
分数与损失成反比,但有效地包含相同的信息。
功能[损失Generator,损失Discriminator] = Ganloss(Probreal,Probenerated)%计算鉴别器网络的损失。loctDiscriminator = -mean(log(probreal))-mean(log(1-probenerated));%计算发电机网络的损耗。损失generator = -mean(log(probgenerated));结尾
这Preprocessminibatch.
函数使用以下步骤预处理数据:
从传入单元格数组中提取图像数据并将其连接到数字阵列中。
重新归类图像在范围内[-1,1]
。
功能x = preprocessminibatch(数据)%contenate mini-batchX = CAT(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.
|向前
|小公子
|预测