主要内容

このペ,ジの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。

条件付き敵対的生成ネットワ,ク(cgan)の学習

この例では,条件付き敵対的生成ネットワーク(CGAN)に学習させてイメージを生成する方法を説明します。

敵対的生成ネットワーク(GAN)は深層学習ネットワークの一種で,入力された学習データと類似の特性をもつデータを生成できます。

Ganは一緒に学習を行う2のネットワクで構成されています。

  1. ジェネレタ。ランダムな値で構成されるベクトルを入力として与えられ,学習デ,タと同じ構造のデ,タを生成します。

  2. ディスクリミネーター——このネットワークは,学習データとジェネレーターにより生成されたデータの両方からの観測値を含むデータのバッチを与えられ,その観測値が”実データ”か”生成データ”かの分類を試みます。

”“条件付き敵対的生成ネットワークは敵対的生成ネットワークの一種で,こちらも学習プロセス中にラベルを利用します。

  1. ジェネレタ。このネットワークは,ラベルと乱数の配列を入力として与えられ,同じラベルに対応する学習データの観測値と同じ構造のデータを生成します。

  2. ディスクリミネタ。学習データとジェネレーターにより生成されたデータの両方の観測値を含むラベル付きデータのバッチを与えられ,その観測値が”実データ”か”生成データ”かの分類を試みます。

条件付きGANに学習させる場合は,両方のネットワークの学習を同時に行うことで両者のパフォーマンスを最大化します。

  • ジェネレタに学習させて,ディスクリミネタを“騙す”デタを生成。

  • ディスクリミネ,タ,に学習させて,実デ,タと生成デ,タを区別。

ジェネレーターのパフォーマンスを最大化するには,生成されたラベル付きデータが与えられたときのディスクリミネーターの損失を最大化します。つまり,ジェネレーターの目的はディスクリミネーターが”実データ”と分類するようなラベル付きデータを生成することです。

ディスクリミネーターのパフォーマンスを最大化するには,ラベル付きの実データと生成データ両方のバッチが与えられたときのディスクリミネーターの損失を最小化します。“騙されない”ことです。

この方法の理想的な結果は,入力ラベルごとに実データに類似するデータをジェネレーターに生成させ,ラベルごとの学習データの特性を表す強い特徴表現をディスクリミネーターに学習させることです。

学習デ,タの読み込み

のデ,タセット[1]をダウンロ,ドし,解凍します。

url =“http://download.tensorflow.org/example_images/flower_photos.tgz”;downloadFolder = tempdir;文件名= fullfile(下载文件夹,“flower_dataset.tgz”);imageFolder = fullfile(下载文件夹,“flower_photos”);如果~存在(imageFolder“dir”) disp (“正在下载Flowers数据集(218 MB)…”) websave(文件名,url);解压(文件名,downloadFolder)结束

写真のメジデタストアを作成します。

datasetFolder = fullfile(imageFolder);imds = imageDatastore(数据文件夹,...“IncludeSubfolders”,真的,...“LabelSource”“foldernames”);

クラス数を表示します。

classes = categories(imds.Labels);numClasses = numel(类)
numClasses = 5

デ,タを拡張して水平方向にランダムに反転させ,ズを64 × 64に変更します。

augmenter = imageDataAugmenter(“RandXReflection”,真正的);augimds = augmentedImageDatastore([64 64],imds,“DataAugmentation”、增压器);

ジェネレ,タ,ネットワ,クの定義

乱数値の1 x 1 x 100の配列と対応するラベルを与えられてイメージを生成する,次の2入力ネットワークを定義します。

このネットワ,クは,次を行います。

  • ノesc escズの1 × 1 × 100の配列を4 × 4 × 1024の配列に変換します。

  • カテゴリカルラベルを埋め込みベクトルに変換して4行4列の配列に形状を変更します。

  • 2 .。出力は4 × 4 × 1025の配列です。

  • バッチ正規化とReLU層を用いた一連の転置畳み込み層を使用して,結果の配列を64 x 64 x 3の配列にスケールアップ。

このネットワ,クア,キテクチャを層グラフとして定義し,次のネットワ,クプロパティを指定します。

  • カテゴリカル入力では,50の埋め込み次元を使用します。

  • 転置畳み込み層では,5 x 5のフィルターを指定し,各層のフィルター数を減少させ,ストライドを2にし,出力を”同じく”トリミングするように設定します。

  • 最後の転置畳み込み層では,生成されたイメージの3つのRGBチャネルに対応する3つの5 x 5のフィルターを指定します。

  • ネットワ,クの最後に,tanh層を追加。

ノ▪▪ズ入力を投影して形状変更するには,この例にサポ▪▪トファ▪▪ルとして添付されている,カスタム層projectAndReshapeLayerを使用します。projectAndReshapeLayerオブジェクトは,全結合演算を使用して入力をスケールアップし,指定されたサイズに出力を形状変更します。

ラベルをネットワ,クに入力するには,imageInputLayerオブジェクトを使用し,etc / etc / etc / etc / etc / etc / etc / etcラベル入力を埋め込んで形状変更するには、この例にサポ、トファ、ルとして添付されている、カスタム層embedAndReshapeLayerを使用します。embedAndReshapeLayerオブジェクトは,埋め込みと全結合演算を使用して,カテゴリカルラベルを指定サイズの1チャネルのイメージに変換します。

numLatentInputs = 100;embeddingDimension = 50;numFilters = 64;filterSize = 5;projectionSize = [4 4 1024];layersGenerator = [imageInputLayer([1 1 numLatentInputs],“归一化”“没有”“名字”“噪音”) projectAndReshapeLayer (projectionSize numLatentInputs,“项目”);concatenationLayer (3 2“名字”“猫”);transposedConv2dLayer (filterSize 4 * numFilters,“名字”“tconv1”) batchNormalizationLayer (“名字”“bn1”) reluLayer (“名字”“relu1”) transposedConv2dLayer (2 * numFilters filterSize,“步”2,“种植”“相同”“名字”“tconv2”) batchNormalizationLayer (“名字”“bn2”) reluLayer (“名字”“relu2”) transposedConv2dLayer (filterSize numFilters,“步”2,“种植”“相同”“名字”“tconv3”) batchNormalizationLayer (“名字”“bn3”) reluLayer (“名字”“relu3”) transposedConv2dLayer (filterSize 3“步”2,“种植”“相同”“名字”“tconv4”) tanhLayer (“名字”的双曲正切));lgraphGenerator = layerGraph(layergenerator);图层= [imageInputLayer([1 1],“名字”“标签”“归一化”“没有”) embedAndReshapeLayer (projectionSize (1:2), embeddingDimension numClasses,“循证”));lgraphGenerator = addLayers(lgraphGenerator,layers);lgraphGenerator = connectLayers(lgraphGenerator,“循证”“猫/ in2”);

カスタム学習ル,プを使用してネットワ,クに学習させ,自動微分を有効にするには,層グラフをdlnetworkオブジェクトに変換します。

dlnetGenerator = dlnetwork(lgraphGenerator)
dlnetGenerator = dlnetwork with properties: Layers: [16×1 nnet.cnn.layer.Layer] Connections: [15×2 table] Learnables: [19×3 table] State: [6×3 table] InputNames: {'noise' 'labels'} OutputNames: {'tanh'}

ディスクリミネ,タ,ネットワ,クの定義

イメージのセットと対応するラベルを与えられて64 x 64の実イメージと生成イメージを分類する,次の2入力ネットワークを定義します。

64 x 64 x 1のイメージと対応するラベルを入力として受け取り,バッチ正規化層と漏ReLU層をもつ一連の畳み込み層を使用してスカラーの予測スコアを出力するネットワークを作成します。ドロップアウトを使用して,入力@ @ @ジにノ@ @ @ @ @ @ @

  • ドロップアウト層で,ドロップアウトの確率を0.75に設定。

  • 畳み込み層で,5 × 5のフィルタ,を指定し,各層でフィルタ,数を増やす。また,ストラaaplド2で出力の各エッジをパディングするように設定します。

  • 泄漏ReLU層で,スケ,ルを0.2に設定。

  • 最後の層で,4 × 4のフィルタをも畳み込み層を設定します。

dropoutProb = 0.75;numFilters = 64;量表= 0.2;inputSize = [64 64 3];filterSize = 5;layersDiscriminator = [imageInputLayer(inputSize,“归一化”“没有”“名字”“图片”) dropoutLayer (dropoutProb“名字”“辍学”) concatenationLayer (3 2“名字”“猫”) convolution2dLayer (filterSize numFilters,“步”2,“填充”“相同”“名字”“conv1”) leakyReluLayer(规模、“名字”“lrelu1”) convolution2dLayer (2 * numFilters filterSize,“步”2,“填充”“相同”“名字”“conv2”) batchNormalizationLayer (“名字”“bn2”) leakyReluLayer(规模、“名字”“lrelu2”) convolution2dLayer (filterSize 4 * numFilters,“步”2,“填充”“相同”“名字”“conv3”) batchNormalizationLayer (“名字”“bn3”) leakyReluLayer(规模、“名字”“lrelu3”) convolution2dLayer (filterSize 8 * numFilters,“步”2,“填充”“相同”“名字”“conv4”) batchNormalizationLayer (“名字”“bn4”) leakyReluLayer(规模、“名字”“lrelu4”1) convolution2dLayer(4日,“名字”“conv5”));lgraphDiscriminator = layerGraph(layersDiscriminator);图层= [imageInputLayer([1 1],“名字”“标签”“归一化”“没有”) embedAndReshapeLayer (inputSize embeddingDimension numClasses,“循证”));lgraphDiscriminator = addLayers(lgraphDiscriminator,layers);lgraphDiscriminator = connectLayers(lgraphDiscriminator,“循证”“猫/ in2”);

カスタム学習ル,プを使用してネットワ,クに学習させ,自動微分を有効にするには,層グラフをdlnetworkオブジェクトに変換します。

dlnetDiscriminator = dlnetwork(lgraphDiscriminator)
dlnetDiscriminator = dlnetwork with properties: Layers: [17×1 nnet.cnn.layer.Layer] Connections: [16×2 table] Learnables: [19×3 table] State: [6×3 table] InputNames: {'images' 'labels'} OutputNames: {'conv5'}

モデル勾配と損失関数の定義

この例のモデル勾配関数セクションにリストされている関数modelGradientsを作成します。この関数は,ジェネレーターおよびディスクリミネーターネットワーク,入力データのミニバッチ,およびランダムな値の配列を入力として受け取り,学習可能なネットワークパラメーターについての損失の勾配と,生成されたイメージの配列を返します。

学習オプションの指定

ミニバッチサesc escズを128として500エポック学習させます。

numEpochs = 500;miniBatchSize = 128;augimds。MiniBatchSize = MiniBatchSize;

亚当最適化のオプションを指定します。両方のネットワ,クで次を使用します。

  • 学習率0.0002

  • 勾配の減衰係数0.5

  • 2乗勾配の減衰係数0.999

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

Gpuが利用できる場合,Gpuで学習を行います。GPU を使用するには、Parallel Computing Toolbox™、および Compute Capability 3.0 以上の CUDA® 対応 NVIDIA® GPU が必要です。

executionEnvironment =“汽车”

100回の反復ごとに学習の進行状況プロットを更新します。

validationFrequency = 100;

実イメージと生成イメージとを区別するディスクリミネーターの学習速度が速すぎる場合,ジェネレーターの学習に失敗する可能性があります。ディスクリミネーターとジェネレーターの学習バランスを改善するために,実イメージの一部のラベルをランダムに反転します。反転係数を0.5に指定します。

flipFactor = 0.5;

モデルの学習

カスタム学習ル,プを使用してモデルに学習させます。学習デ,タ全体をル,プ処理し,各反復でネットワ,クパラメ,タ,を更新します。学習の進行状況を監視するには,ホールドアウトされたランダムな値の配列をジェネレーターに入力して得られた生成イメージのバッチと,ネットワークスコアのプロットを表示します。

亚当オプティマ。

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

学習の進行状況のプロットを初期化します。图を作成して幅が2倍になるようサescズ変更します。

F =数字;f.Position(3) = 2*f.Position(3);

生成された▪▪メ▪▪ジとスコアプロットのサブプロットを作成します。

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

スコアのプロットのアニメ,ションの線を初期化します。

lineScoreGenerator = animatedline(分数轴,“颜色”,[0 0.447 0.741]);lineScoreDiscriminator = animatedline(scoreAxes,“颜色”, [0.85 0.325 0.098]);

プロットの外観をカスタマ@ @ズします。

传奇(“发电机”鉴频器的);Ylim ([0 1]) xlabel(“迭代”) ylabel (“分数”网格)

学習の進行状況を監視するには,乱数値の1 x 1 xnumLatentInputsの配列25個を含むホールドアウトされたバッチと,対応する1から5のラベル(クラスに対応)を5回繰り返した集合を作成します。ここで,ラベルは配列の4番目の次元にあります。

numValidationImagesPerClass = 5;ZValidation = randn(1,1,numLatentInputs,numValidationImagesPerClass*numClasses,“单一”);TValidation = single(repmat(1:numClasses,[1 numValidationImagesPerClass]));TValidation = permute(TValidation,[1 3 4 2]);

デタをdlarrayオブジェクトに変換し,次元ラベル“SSCB”(空间,空间,通道,批次)を指定します。

dlZValidation = dlarray(ZValidation,“SSCB”);dlTValidation = dlarray(TValidation,“SSCB”);

Gpuで学習する場合,デ,タをgpuArrayオブジェクトに変換。

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

Ganに学習させます。各エポックにいて,デタをシャッフルしてデタのミニバッチをルプで回します。

各ミニバッチで次を行います。

  • ディスクリミネーターへの入力とジェネレーターの出力を確実に一致させるために,実イメージを再スケーリングしてピクセルが取る値を範囲[1]に収める。

  • 基となる型がdlarrayオブジェクトにメジデタとラベルを変換し,次元ラベルを“SSCB”(空间,空间,通道,批次)に指定。

  • ジェネレ,タ,ネットワ,ク用の乱数値の配列を含むdlarrayオブジェクトを生成。

  • Gpuで学習する場合,デ,タをgpuArrayオブジェクトに変換。

  • 関数dlfevalおよびmodelGradientsを使用してモデルの勾配を評価します。

  • 関数adamupdateを使用してネットワ,クパラメ,タ,を更新。

  • 2 .のネットワ,クのスコアをプロット。

  • validationFrequencyの反復がすべて終了した後で,ホールドアウトされた固定ジェネレーター入力の生成イメージのバッチを表示。

学習を行うのに時間がかかる場合があります。

迭代= 0;开始= tic;%遍历epoch。epoch = 1:numEpochs重置和洗牌数据存储。重置(augimds);Augimds = shuffle(Augimds);在小批上循环。Hasdata (augimds)迭代=迭代+ 1;读取小批数据并生成潜在输入%发电机网络。Data = read(augimds);忽略纪元的最后一个部分小批。如果size(data,1) < miniBatchSize继续结束X = cat(4,data{:,1}{:});X =单(X);T = single(data.response);T = permute(T,[2 3 4 1]);Z = randn(1,1,numLatentInputs,miniBatchSize,“单一”);重新缩放范围为[-1 1]的图像。X = rescale(X,-1,1,“InputMin”0,“InputMax”, 255);将小批量数据转换为dlarray并指定尺寸标签% 'SSCB'(空间,空间,通道,批处理)。dlX = dlarray(X,“SSCB”);dlZ = dlarray(Z,“SSCB”);dlT = darray (T,“SSCB”);如果在GPU上训练,则将数据转换为gpuArray。如果(executionEnvironment = =“汽车”&& canUseGPU) || executionEnvironment ==“图形”dlX = gpuArray(dlX);dlZ = gpuArray(dlZ);dlT = gpuArray(dlT);结束使用评估模型梯度和发电机状态的末尾列出的modelGradients函数%的例子。[gradientsGenerator, gradientsDiscriminator, stateGenerator, scoreGenerator, scoreDiscriminator] =...dlfeval(@modelGradients, dlnetGenerator, dlnetDiscriminator, dlX, dlT, dlZ, flipFactor);dlnetGenerator。状态=状态生成器;更新鉴别器网络参数。[dlnetDiscriminator, trailingAvgDiscriminator trailingAvgSqDiscriminator] =...adamupdate (dlnetDiscriminator gradientsDiscriminator,...trailingAvgDiscriminator, trailingAvgSqDiscriminator,迭代,...learnRate, gradientDecayFactor, squaredGradientDecayFactor);更新发电机网络参数。[dlnetGenerator, trailingAvgGenerator trailingAvgSqGenerator] =...adamupdate (dlnetGenerator gradientsGenerator,...trailingAvgGenerator, trailingAvgSqGenerator,迭代,...learnRate, gradientDecayFactor, squaredGradientDecayFactor);%每次验证频率迭代,显示批生成的图像使用%保留的发电机输入。如果mod(迭代,validationFrequency) == 0 ||迭代== 1使用保留的生成器输入生成图像。dlXGeneratedValidation = predict(dlnetGenerator,dlZValidation,dlTValidation);平铺和重新缩放范围[0 1]的图像。I = imtile(extractdata(dlXGeneratedValidation),...“GridSize”, (numValidationImagesPerClass numClasses]);I = rescale(I);显示图片。次要情节(1、2、1);图像(imageAxes,我)xticklabels ([]);yticklabels ([]);标题(“生成的图像”);结束更新分数图次要情节(1、2、2)addpoints (lineScoreGenerator,迭代,...双(收集(extractdata (scoreGenerator))));addpoints (lineScoreDiscriminator迭代,...双(收集(extractdata (scoreDiscriminator))));用培训进度信息更新标题。。D = duration(0,0,toc(start),“格式”“hh: mm: ss”);标题(...”时代:“+ epoch +”、“+...“迭代:“+迭代+”、“+...”经过:“+字符串(D))现在绘制结束结束

ここでは,ディスクリミネーターは生成イメージの中から実イメージを識別する強い特徴表現を学習しました。それに対し,ジェネレーターは実データのように見えるデータを生成できるように,同様に強い特徴表現を学習しました。各列は1のクラスに対応します。

学習プロットは,ジェネレタおよびディスクリミネタのネットワクのスコアを示しています。ネットワクのスコアを解釈する方法の詳細にいては,Ganの学習過程の監視と一般的な故障モ,ドの識別を参照してください。

新しい▪▪メ▪▪ジの生成

特定のクラスの新しいメジを生成するには,ジェネレタに対して関数预测を使用し,dlarrayオブジェクトを指定します。このオブジェクトには,乱数値の1 x 1 xnumLatentInputsの配列のバッチと,目的のクラスに対応するラベルの配列が含まれています。デタをdlarrayオブジェクトに変換し,次元ラベル“SSCB”(空间,空间,通道,批次)を指定します。Gpuでの予測のために,デ,タをgpuArrayに変換します。メ,ジを並べて表示するには関数imtileを使用し,関数重新调节を使ってメジを再スケリングします。

1番目のクラスに対応する,乱数値から成る36ベクトルの配列を作成します。

numObservationsNew = 36;idxClass = 1;Z = randn(1,1,numLatentInputs,numObservationsNew,“单一”);T = repmat(single(idxClass),[1 1 1 numObservationsNew]);

デ,タを次元ラベル“SSCB”(空间,空间,通道,批次)付きのdlarrayオブジェクトに変換します。

dlZ = dlarray(Z,“SSCB”);dlT = darray (T,“SSCB”);

Gpuを使用してaapl . exe,デaapl . exe,デaapl . exegpuArrayオブジェクトにも変換します。

如果(executionEnvironment = =“汽车”&& canUseGPU) || executionEnvironment ==“图形”dlZ = gpuArray(dlZ);dlT = gpuArray(dlT);结束

ジェネレ,タ,ネットワ,クに対して関数预测を使用し,。

dlXGenerated = predict(dlnetGenerator,dlZ,dlT);

生成された▪▪メ▪▪ジをプロットに表示します。

figure I = imtile(extractdata(dlXGenerated));I = rescale(I);imshow (I)标题(”类:“+类(idxClass))

ここで,ジェネレタネットワクは指定のクラスで条件付けされたメジを生成します。

モデル勾配関数

関数modelGradientsは,ジェネレ,タ,およびディスクリミネ,タ,のdlnetworkオブジェクトdlnetGeneratorおよびdlnetDiscriminator,入力デ,タdlXのミニバッチ,対応するラベルdlT,およびランダムな値の配列dlZを入力として受け取り,学習可能なネットワークパラメーターについての損失の勾配,ジェネレーターの状態,およびネットワークのスコアを返します。

実イメージと生成イメージとを区別するディスクリミネーターの学習速度が速すぎる場合,ジェネレーターの学習に失敗する可能性があります。ディスクリミネーターとジェネレーターの学習バランスを改善するために,実イメージの一部のラベルをランダムに反転します。

函数[gradientsGenerator, gradientsDiscriminator, stateGenerator, scoreGenerator, scoreDiscriminator] =...modelGradients(dlnetGenerator, dlnetDiscriminator, dlX, dlT, dlZ, flipFactor)用鉴别器网络计算真实数据的预测。。dlYPred = forward(dlnetDiscriminator, dlX, dlT);用鉴别器网络计算生成数据的预测。[dlXGenerated,stateGenerator] = forward(dlnetGenerator, dlZ, dlT);dlYPredGenerated = forward(dlnetDiscriminator, dlXGenerated, dlT);计算概率。probGenerated = sigmoid(dlYPredGenerated);probReal = sigmoid(dlYPred);计算生成器和鉴别器得分scoreGenerator = mean(probGenerated);scoreDiscriminator = (mean(probReal) + mean(1-probGenerated)) / 2;翻转标签。numObservations = size(dlYPred,4);idx = randperm(numObservations,floor(flipFactor * numObservations));probReal(:,:,:,idx) = 1 - probReal(:,:,:,idx);计算GAN损耗。[lossGenerator, lossDiscriminator] = ganLoss(probReal, probGenerated);对于每个网络,计算与损失相关的梯度。gradientsGenerator = dlgradient(lossGenerator, dlnetGenerator。可学的,“RetainData”,真正的);gradientsDiscriminator = dlgradient(lossDiscriminator, dlnetDiscriminator.Learnables);结束

Ganの損失関数

ジェネレーターの目的はディスクリミネーターが”実データ”に分類するようなデータを生成することです。ジェネレーターが生成したイメージをディスクリミネーターが実データとして分類する確率を最大化するには,負の対数尤度関数を最小化します。

ディスクリミネ,タ,の出力 Y が与えられた場合,次のようになります。

  • Y ˆ σ Y は,入力メジが“実”クラスに属する確率です。

  • 1 - Y ˆ は,入力メジが“生成”クラスに属している確率です。

シグモ@ @ド演算 σ は関数modelGradientsで行われる点に注意してください。ジェネレ,タ,の損失関数は次の式で表されます。

lossGenerator - 的意思是 日志 Y ˆ 生成的

ここで, Y ˆ G e n e r 一个 t e d は生成メジに対するディスクリミネタの出力確率を表しています。

ディスクリミネタの目的はジェネレタに“騙されない”ことです。ディスクリミネーターが実イメージと生成イメージを正しく区別する確率を最大化するには,対応する負の対数尤度関数の和を最小化します。ディスクリミネ,タ,の損失関数は次の式で表されます。

lossDiscriminator - 的意思是 日志 Y ˆ 真正的 - 的意思是 日志 1 - Y ˆ 生成的

ここで, Y ˆ R e 一个 l は実メジに対するディスクリミネタの出力確率を表しています。

函数[lossGenerator, lossDiscriminator] = ganLoss(scoresReal,scoresGenerated)计算鉴别器网络的损失。lossGenerated = -mean(1 - scoresGenerated));lossReal = -mean(log(scoresReal));%组合鉴别器网络的损失。lossDiscriminator = lossReal + lossGenerated;计算发电机网络的损失。lossGenerator = -mean(log(scoresGenerated));结束

参考文献

参考

||||||

関連するトピック