Main Content

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

생성적 적대 신경망(GAN) 훈련시키기

이 예제에서는 생성적 적대 신경망(GAN)을 훈련시켜서 영상을 생성하는 방법을 보여줍니다.

생성적 적대 신경망(GAN)은 입력값인 실제 데이터와 비슷한 특징을 갖는 데이터를 생성할 수 있는 딥러닝 신경망의 한 종류입니다.

GAN은 함께 훈련되는 다음과 같은 두 개의 신경망으로 구성됩니다.

  1. 생성기 — 입력값으로 난수로 구성된 벡터(잠재 입력값)가 주어지면 이 신경망은 훈련 데이터와 동일한 구조를 갖는 데이터를 생성합니다.

  2. 판별기 — 두 훈련 데이터의 관측값을 포함하는 데이터의 배치(batch)와 생성기에서 생성된 데이터가 주어지면 이 신경망은 관측값을 "real"과 "generated"로 분류하려고 시도합니다.

GAN을 훈련시키려면 두 신경망의 성능을 극대화할 수 있도록 다음과 같이 두 신경망을 동시에 훈련시키십시오.

  • 판별기를 "속이는" 데이터를 생성하도록 생성기를 훈련시킵니다.

  • 실제 데이터와 생성된 데이터를 구분하도록 판별기를 훈련시킵니다.

생성기의 성능을 최적화하려면, 생성된 데이터가 주어졌을 때의 판별기 손실을 최대화하십시오. 즉, 생성기의 목적은 판별기가 "real"로 분류하는 데이터를 생성하는 것입니다.

판별기의 성능을 최적화하려면, 실제 데이터의 배치와 생성된 데이터의 배치가 둘 다 주어졌을 때의 판별기 손실을 최소화하십시오. 즉, 판별기의 목적은 생성기에 "속지" 않는 것입니다.

이상적으로는 이 전략의 결과로 실제처럼 보이는 그럴싸한 데이터를 생성하는 생성기와 훈련 데이터의 특징인 강한 특징 표현을 학습한 판별기가 생성됩니다.

훈련 데이터 불러오기

Flowers 데이터 세트[1]를 다운로드하여 추출합니다.

url = 'http://download.tensorflow.org/example_images/flower_photos.tgz';
downloadFolder = tempdir;
filename = fullfile(downloadFolder,'flower_dataset.tgz');

imageFolder = fullfile(downloadFolder,'flower_photos');
if ~exist(imageFolder,'dir')
    disp('Downloading Flowers data set (218 MB)...')
    websave(filename,url);
    untar(filename,downloadFolder)
end

꽃 사진을 포함하는 영상 데이터저장소를 만듭니다.

datasetFolder = fullfile(imageFolder);

imds = imageDatastore(datasetFolder, ...
    'IncludeSubfolders',true);

무작위 가로 뒤집기를 포함하도록 데이터를 증대하고, 영상의 크기가 64×64가 되도록 크기를 조정합니다.

augmenter = imageDataAugmenter('RandXReflection',true);
augimds = augmentedImageDatastore([64 64],imds,'DataAugmentation',augmenter);    

생성기 신경망 정의하기

난수 값으로 구성된 1×1×100 배열에서 영상을 생성하는 다음과 같은 신경망 아키텍처를 정의합니다.

이 신경망은 다음을 수행합니다.

  • 사영 및 형태 변경 계층을 사용하여, 잡음으로 구성된 1×1×100 배열을 7×7×128 배열로 변환합니다.

  • 일련의 전치된 컨벌루션 계층, 배치 정규화 계층, ReLU 계층을 사용하여, 결과로 생성된 배열을 64×64×3 배열로 업스케일링합니다.

이 신경망 아키텍처를 계층 그래프로 정의하고 다음과 같은 신경망 속성을 지정합니다.

  • 전치된 컨벌루션 계층에 대해, 각 계층에 대한 내림차순 개수의 필터로 구성된 5×5 필터를 지정하고, 스트라이드를 2로 지정하고, 각 가장자리에서 출력값의 자르기를 지정합니다.

  • 전치된 마지막 컨벌루션 계층에 대해, 생성된 영상의 RGB 채널 3개에 대응되는 3개의 5×5 필터를 지정하고, 출력값 크기를 직전 계층의 크기로 지정합니다.

  • 신경망 끝부분에 tanh 계층을 삽입합니다.

잡음 입력값을 사영 및 형태 변경하려면 사용자 지정 계층 projectAndReshapeLayer를 사용하십시오. 이 계층은 이 예제의 마지막 부분에 지원 파일로 첨부되어 있습니다. projectAndReshapeLayer 계층은 완전 연결 연산을 사용하여 입력값을 업스케일링하고 출력값을 지정된 크기로 형태 변경합니다.

filterSize = 5;
numFilters = 64;
numLatentInputs = 100;

projectionSize = [4 4 512];

layersGenerator = [
    imageInputLayer([1 1 numLatentInputs],'Normalization','none','Name','in')
    projectAndReshapeLayer(projectionSize,numLatentInputs,'proj');
    transposedConv2dLayer(filterSize,4*numFilters,'Name','tconv1')
    batchNormalizationLayer('Name','bnorm1')
    reluLayer('Name','relu1')
    transposedConv2dLayer(filterSize,2*numFilters,'Stride',2,'Cropping','same','Name','tconv2')
    batchNormalizationLayer('Name','bnorm2')
    reluLayer('Name','relu2')
    transposedConv2dLayer(filterSize,numFilters,'Stride',2,'Cropping','same','Name','tconv3')
    batchNormalizationLayer('Name','bnorm3')
    reluLayer('Name','relu3')
    transposedConv2dLayer(filterSize,3,'Stride',2,'Cropping','same','Name','tconv4')
    tanhLayer('Name','tanh')];

lgraphGenerator = layerGraph(layersGenerator);

사용자 지정 훈련 루프를 사용하여 신경망을 훈련시키고 자동 미분을 활성화하려면 계층 그래프를 dlnetwork 객체로 변환하십시오.

dlnetGenerator = dlnetwork(lgraphGenerator);

판별기 신경망 정의하기

실제 및 생성된 64×64 영상을 분류하는 다음과 같은 신경망을 정의합니다.

64×64×3 영상을 받아서 일련의 컨벌루션 계층, 배치 정규화 계층, Leaky ReLU 계층을 사용하여 스칼라 예측 점수를 반환하는 신경망을 만듭니다. 드롭아웃을 사용하여 입력 영상에 잡음을 추가합니다.

  • 드롭아웃 계층에 대해, 드롭아웃 확률을 0.5로 지정합니다.

  • 컨벌루션 계층에 대해, 각 계층에 대한 오름차순 개수의 필터로 구성된 5×5 필터를 지정합니다. 스트라이드를 2로 지정하고 출력값의 채우기를 지정합니다.

  • Leaky ReLU 계층에 대해, 스케일을 0.2로 지정합니다.

  • 마지막 계층에 대해, 하나의 4×4 필터를 갖는 컨벌루션 계층을 지정합니다.

[0,1] 범위의 확률로 출력하기 위해 모델 기울기 함수에 있는 sigmoid 함수를 사용합니다.

dropoutProb = 0.5;
numFilters = 64;
scale = 0.2;

inputSize = [64 64 3];
filterSize = 5;

layersDiscriminator = [
    imageInputLayer(inputSize,'Normalization','none','Name','in')
    dropoutLayer(0.5,'Name','dropout')
    convolution2dLayer(filterSize,numFilters,'Stride',2,'Padding','same','Name','conv1')
    leakyReluLayer(scale,'Name','lrelu1')
    convolution2dLayer(filterSize,2*numFilters,'Stride',2,'Padding','same','Name','conv2')
    batchNormalizationLayer('Name','bn2')
    leakyReluLayer(scale,'Name','lrelu2')
    convolution2dLayer(filterSize,4*numFilters,'Stride',2,'Padding','same','Name','conv3')
    batchNormalizationLayer('Name','bn3')
    leakyReluLayer(scale,'Name','lrelu3')
    convolution2dLayer(filterSize,8*numFilters,'Stride',2,'Padding','same','Name','conv4')
    batchNormalizationLayer('Name','bn4')
    leakyReluLayer(scale,'Name','lrelu4')
    convolution2dLayer(4,1,'Name','conv5')];

lgraphDiscriminator = layerGraph(layersDiscriminator);

사용자 지정 훈련 루프를 사용하여 신경망을 훈련시키고 자동 미분을 활성화하려면 계층 그래프를 dlnetwork 객체로 변환하십시오.

dlnetDiscriminator = dlnetwork(lgraphDiscriminator);

모델 기울기, 손실 함수, 점수 정의하기

이 예제의 모델 기울기 함수 섹션에 나와 있는 함수 modelGradients를 만듭니다. 이 함수는 생성기 신경망과 판별기 신경망, 입력 데이터로 구성된 미니 배치, 난수 값으로 구성된 배열과 뒤집기 인자를 입력값으로 받습니다. 그런 다음 신경망의 학습 가능한 파라미터에 대한 손실의 기울기와 두 신경망의 점수를 반환합니다.

훈련 옵션 지정하기

Epoch 500회에 대해 크기가 128인 미니 배치를 사용하여 훈련시킵니다. 크기가 큰 데이터셋의 경우에는 이렇게 많은 Epoch 횟수만큼 훈련하지 않아도 될 수 있습니다.

numEpochs = 500;
miniBatchSize = 128;

Adam 최적화에 대한 옵션을 지정합니다. 두 신경망에 대해 다음을 지정합니다.

  • 학습률 0.0002

  • 기울기 감쇠 인자 0.5

  • 제곱 기울기 감쇠 인자 0.999

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

판별기가 실제 영상과 생성된 영상을 구분하는 방법을 지나치게 빨리 학습하는 경우 생성기 훈련이 실패할 수 있습니다. 판별기와 생성기의 학습 균형을 맞추려면 레이블을 무작위로 뒤집어서 실제 데이터에 잡음을 추가하십시오.

실제 레이블의 30%를 뒤집도록 지정합니다. 즉, 훈련 중에 총 레이블 개수의 15%가 뒤집힙니다. 그러나 모든 생성된 영상에는 여전히 올바른 레이블이 적용되어 있으므로 이로 인해 생성기의 성능이 저하되지는 않습니다.

flipFactor = 0.3;

100회의 반복마다, 생성된 검증 영상을 표시합니다.

validationFrequency = 100;

모델 훈련시키기

minibatchqueue를 사용하여 영상 미니 배치를 처리하고 관리합니다. 각 미니 배치에 대해 다음을 수행합니다.

  • (이 예제의 마지막 부분에서 정의되는) 사용자 지정 미니 배치 전처리 함수 preprocessMiniBatch를 사용하여 영상을 [-1,1] 범위로 다시 스케일링합니다.

  • 관측값이 128개 미만인 부분 미니 배치를 모두 무시합니다.

  • 각각 공간(spatial), 공간(spatial), 채널(channel), 배치(batch)를 뜻하는 차원 레이블 'SSCB'를 사용하여 영상 데이터의 형식을 지정합니다. 기본적으로 minibatchqueue 객체는 기본 유형 single을 사용하여 데이터를 dlarray 객체로 변환합니다.

  • 사용 가능한 GPU가 있으면 GPU에서 훈련시킵니다. minibatchqueue'OutputEnvironment' 옵션이 "auto"이면 minibatchqueue는 GPU를 사용할 수 있는 경우 각 출력값을 gpuArray로 변환합니다. GPU를 사용하려면 Parallel Computing Toolbox™와 Compute Capability 3.0 이상의 CUDA® 지원 NVIDIA® GPU가 필요합니다.

augimds.MiniBatchSize = miniBatchSize;

executionEnvironment = "auto";

mbq = minibatchqueue(augimds,...
    'MiniBatchSize',miniBatchSize,...
    'PartialMiniBatch','discard',...
    'MiniBatchFcn', @preprocessMiniBatch,...
    'MiniBatchFormat','SSCB',...
    'OutputEnvironment',executionEnvironment);

사용자 지정 훈련 루프를 사용하여 모델을 훈련시킵니다. 루프를 사용해 훈련 데이터를 순회하고 각 반복에서 신경망 파라미터를 업데이트합니다. 훈련 진행 상황을 모니터링하려면, 생성기에 입력할, 난수 값으로 구성된 홀드아웃 배열을 사용하여 생성된 영상 배치를 표시하고, 점수 플롯도 표시하십시오.

Adam에 대한 파라미터를 초기화합니다.

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

훈련 진행 상황을 모니터링하려면, 생성기에 입력된, 난수 값으로 구성된 고정 배열의 홀드아웃 배치를 사용하여 생성된 영상 배치를 표시하고, 신경망 점수도 플로팅하십시오.

홀드아웃 난수 값으로 구성된 배열을 만듭니다.

numValidationImages = 25;
ZValidation = randn(1,1,numLatentInputs,numValidationImages,'single');

데이터를 dlarray 객체로 변환하고 각각 공간(spatial), 공간(spatial), 채널(channel), 배치(batch)를 뜻하는차원 레이블 'SSCB'를 지정합니다.

dlZValidation = dlarray(ZValidation,'SSCB');

GPU 훈련을 위해 데이터를 gpuArray 객체로 변환합니다.

if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
    dlZValidation = gpuArray(dlZValidation);
end

훈련 진행 상황 플롯을 초기화합니다. Figure를 만들고 너비가 두 배가 되도록 크기를 조정합니다.

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

생성된 영상과 신경망 점수를 표시할 서브플롯을 만듭니다.

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

점수 플롯에 대해 애니메이션 선을 초기화합니다.

lineScoreGenerator = animatedline(scoreAxes,'Color',[0 0.447 0.741]);
lineScoreDiscriminator = animatedline(scoreAxes, 'Color', [0.85 0.325 0.098]);
legend('Generator','Discriminator');
ylim([0 1])
xlabel("Iteration")
ylabel("Score")
grid on

GAN을 훈련시킵니다. 각 Epoch에 대해, 데이터저장소를 섞고 루프를 사용해 데이터의 미니 배치를 순회합니다.

각 미니 배치에 대해 다음을 수행합니다.

  • dlfevalmodelGradients 함수를 사용하여 모델 기울기를 평가합니다.

  • adamupdate 함수를 사용하여 신경망 파라미터를 업데이트합니다.

  • 두 신경망의 점수를 플로팅합니다.

  • validationFrequency회의 반복마다, 고정된 홀드아웃 생성기 입력값에 대해 생성된 영상 배치를 표시합니다.

훈련을 실행하는 데 다소 시간이 걸릴 수 있습니다.

iteration = 0;
start = tic;

% Loop over epochs.
for epoch = 1:numEpochs
    
    % Reset and shuffle datastore.
    shuffle(mbq);
    
    % Loop over mini-batches.
    while hasdata(mbq)
        iteration = iteration + 1;
        
        % Read mini-batch of data.
        dlX = next(mbq);
        
        % Generate latent inputs for the generator network. Convert to
        % dlarray and specify the dimension labels 'SSCB' (spatial,
        % spatial, channel, batch). If training on a GPU, then convert
        % latent inputs to gpuArray.
        Z = randn(1,1,numLatentInputs,size(dlX,4),'single');
        dlZ = dlarray(Z,'SSCB');        
        
        if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
            dlZ = gpuArray(dlZ);
        end
        
        % Evaluate the model gradients and the generator state using
        % dlfeval and the modelGradients function listed at the end of the
        % example.
        [gradientsGenerator, gradientsDiscriminator, stateGenerator, scoreGenerator, scoreDiscriminator] = ...
            dlfeval(@modelGradients, dlnetGenerator, dlnetDiscriminator, dlX, dlZ, flipFactor);
        dlnetGenerator.State = stateGenerator;
        
        % Update the discriminator network parameters.
        [dlnetDiscriminator,trailingAvgDiscriminator,trailingAvgSqDiscriminator] = ...
            adamupdate(dlnetDiscriminator, gradientsDiscriminator, ...
            trailingAvgDiscriminator, trailingAvgSqDiscriminator, iteration, ...
            learnRate, gradientDecayFactor, squaredGradientDecayFactor);
        
        % Update the generator network parameters.
        [dlnetGenerator,trailingAvgGenerator,trailingAvgSqGenerator] = ...
            adamupdate(dlnetGenerator, gradientsGenerator, ...
            trailingAvgGenerator, trailingAvgSqGenerator, iteration, ...
            learnRate, gradientDecayFactor, squaredGradientDecayFactor);
        
        % Every validationFrequency iterations, display batch of generated images using the
        % held-out generator input
        if mod(iteration,validationFrequency) == 0 || iteration == 1
            % Generate images using the held-out generator input.
            dlXGeneratedValidation = predict(dlnetGenerator,dlZValidation);
            
            % Tile and rescale the images in the range [0 1].
            I = imtile(extractdata(dlXGeneratedValidation));
            I = rescale(I);
            
            % Display the images.
            subplot(1,2,1);
            image(imageAxes,I)
            xticklabels([]);
            yticklabels([]);
            title("Generated Images");
        end
        
        % Update the scores plot
        subplot(1,2,2)
        addpoints(lineScoreGenerator,iteration,...
            double(gather(extractdata(scoreGenerator))));
        
        addpoints(lineScoreDiscriminator,iteration,...
            double(gather(extractdata(scoreDiscriminator))));
        
        % Update the title with training progress information.
        D = duration(0,0,toc(start),'Format','hh:mm:ss');
        title(...
            "Epoch: " + epoch + ", " + ...
            "Iteration: " + iteration + ", " + ...
            "Elapsed: " + string(D))
        
        drawnow
    end
end

여기서, 판별기는 생성된 영상 중에서 실제 영상을 식별하는 강한 특징 표현을 학습했습니다. 생성기는 실제처럼 보이는 데이터를 생성할 수 있는, 마찬가지로 강한 특징 표현을 학습했습니다.

훈련 플롯에 생성기 신경망과 판별기 신경망의 점수가 나와 있습니다. 신경망 점수를 해석하는 방법에 대한 자세한 내용은 Monitor GAN Training Progress and Identify Common Failure Modes 항목을 참조하십시오.

새 영상 생성하기

새 영상을 생성하려면, predict 함수를 난수 값으로 구성된 1×1×100 배열의 배치를 포함하는 dlarray 객체와 함께 생성기에 사용하십시오. 영상을 함께 표시하려면 imtile 함수를 사용하고, rescale 함수를 사용하여 영상을 다시 스케일링하십시오.

생성기 신경망에 입력할, 난수 값으로 구성된 1×1×100 배열 25개의 배치를 포함하는 dlarray 객체를 만듭니다.

ZNew = randn(1,1,numLatentInputs,25,'single');
dlZNew = dlarray(ZNew,'SSCB');

GPU를 사용하여 영상을 생성하려면 데이터를 gpuArray 객체로도 변환하십시오.

if (executionEnvironment == "auto" && canUseGPU) || executionEnvironment == "gpu"
    dlZNew = gpuArray(dlZNew);
end

생성기 및 입력 데이터와 함께 predict 함수를 사용하여 새 영상을 생성합니다.

dlXGeneratedNew = predict(dlnetGenerator,dlZNew);

영상을 표시합니다.

I = imtile(extractdata(dlXGeneratedNew));
I = rescale(I);
figure
image(I)
axis off
title("Generated Images")

모델 기울기 함수

함수 modelGradients는 생성기 및 판별기 dlnetwork 객체 dlnetGeneratordlnetDiscriminator, 입력 데이터로 구성된 미니 배치 dlX, 난수 값으로 구성된 배열 dlZ , 뒤집을 실제 레이블의 백분율 flipFactor, 를 입력값으로 받습니다. 그런 다음 신경망의 학습 가능한 파라미터에 대한 손실의 기울기, 생성기 상태, 두 신경망의 점수를 반환합니다. 판별기 출력값이 [0,1] 범위에 있지 않으므로 modelGradients 는 sigmoid 함수를 적용하여 출력값을 확률로 변환합니다.

function [gradientsGenerator, gradientsDiscriminator, stateGenerator, scoreGenerator, scoreDiscriminator] = ...
    modelGradients(dlnetGenerator, dlnetDiscriminator, dlX, dlZ, flipFactor)

% Calculate the predictions for real data with the discriminator network.
dlYPred = forward(dlnetDiscriminator, dlX);

% Calculate the predictions for generated data with the discriminator network.
[dlXGenerated,stateGenerator] = forward(dlnetGenerator,dlZ);
dlYPredGenerated = forward(dlnetDiscriminator, dlXGenerated);

% Convert the discriminator outputs to probabilities.
probGenerated = sigmoid(dlYPredGenerated);
probReal = sigmoid(dlYPred);

% Calculate the score of the discriminator.
scoreDiscriminator = ((mean(probReal)+mean(1-probGenerated))/2);

% Calculate the score of the generator.
scoreGenerator = mean(probGenerated);

% Randomly flip a fraction of the labels of the real images.
numObservations = size(probReal,4);
idx = randperm(numObservations,floor(flipFactor * numObservations));

% Flip the labels
probReal(:,:,:,idx) = 1-probReal(:,:,:,idx);

% Calculate the GAN loss.
[lossGenerator, lossDiscriminator] = ganLoss(probReal,probGenerated);

% For each network, calculate the gradients with respect to the loss.
gradientsGenerator = dlgradient(lossGenerator, dlnetGenerator.Learnables,'RetainData',true);
gradientsDiscriminator = dlgradient(lossDiscriminator, dlnetDiscriminator.Learnables);

end

GAN 손실 함수와 점수

생성기의 목적은 판별기가 "real"로 분류하는 데이터를 생성하는 것입니다. 생성기에서 나온 영상이 판별기에 의해 실제 영상으로 분류될 확률을 극대화하려면 음의 로그 가능도 함수를 최소화하십시오.

판별기의 출력값 Y가 주어진 경우:

  • Yˆ=σ(Y)는 입력 영상이 클래스 "real"에 속할 확률입니다.

  • 1-Yˆ는 입력 영상이 클래스 "generated"에 속할 확률입니다.

시그모이드 연산 σmodelGradients 함수에서 수행됩니다. 생성기에 대한 손실 함수는 다음과 같이 지정됩니다.

lossGenerator=-mean(log(YˆGenerated)),

여기서 YˆGenerated는 생성된 영상에 대한 판별기 출력 확률을 포함합니다.

판별기의 목적은 생성기에 "속지" 않는 것입니다. 판별기가 실제 영상과 생성된 영상을 성공적으로 판별해 낼 확률을 극대화하려면 해당하는 음의 로그 가능도 함수 합을 최소화하십시오.

판별기에 대한 손실 함수는 다음과 같이 지정됩니다.

lossDiscriminator=-mean(log(YˆReal))-mean(log(1-YˆGenerated)),

여기서 YˆReal은 실제 영상에 대한 판별기 출력 확률을 포함합니다.

생성기와 판별기가 각각의 목표를 얼마나 잘 달성하는지를 0부터 1까지의 척도로 측정하기 위해 점수 개념을 사용할 수 있습니다.

생성기 점수는 생성된 영상에 대한 판별기 출력값에 대응되는 확률의 평균입니다.

scoreGenerator=mean(YˆGenerated).

판별기 점수는 실제 영상과 생성된 영상에 대한 판별기 출력값에 대응되는 확률의 평균입니다.

scoreDiscriminator=12mean(YˆReal)+12mean(1-YˆGenerated).

점수는 손실에 반비례하지만 실질적으로 동일한 정보를 포함합니다.

function [lossGenerator, lossDiscriminator] = ganLoss(probReal,probGenerated)

% Calculate the loss for the discriminator network.
lossDiscriminator =  -mean(log(probReal)) -mean(log(1-probGenerated));

% Calculate the loss for the generator network.
lossGenerator = -mean(log(probGenerated));

end

미니 배치 전처리 함수

preprocessMiniBatch 함수는 다음 단계를 사용하여 데이터를 전처리합니다.

  1. 입력되는 셀형 배열에서 영상 데이터를 추출하여 숫자형 배열로 결합합니다.

  2. 영상이 [-1,1] 범위 내에 있도록 다시 스케일링합니다.

function X = preprocessMiniBatch(data)
    % Concatenate mini-batch
    X = cat(4,data{:});
    
    % Rescale the images in the range [-1 1].
    X = rescale(X,-1,1,'InputMin',0,'InputMax',255);
end

참고 문헌

  1. The TensorFlow Team. Flowers http://download.tensorflow.org/example_images/flower_photos.tgz

  2. Radford, Alec, Luke Metz, and Soumith Chintala. "Unsupervised representation learning with deep convolutional generative adversarial networks." arXiv preprint arXiv:1511.06434 (2015).

참고 항목

| | | | | | |

관련 항목