Main Content

이 페이지의 내용은 이전 릴리스에 관한 것입니다. 해당 영문 페이지는 최신 릴리스에서 제거되었습니다.

사전 훈련된 신경망을 사용한 전이 학습

이 예제에서는 사전 훈련된 GoogLeNet 컨벌루션 신경망이 새로운 영상 모음에 대해 분류를 수행하도록 미세 조정하는 방법을 보여줍니다.

1백만 개가 넘는 영상에 대해 훈련된 GoogLeNet은 영상을 키보드, 커피 머그잔, 연필, 각종 동물 등 1,000가지 사물 범주로 분류할 수 있습니다. 이 신경망은 다양한 영상을 대표하는 다양한 특징을 학습했습니다. 이 신경망은 영상을 입력값으로 받아서 영상에 있는 사물에 대한 레이블과 각 사물 범주의 확률을 출력합니다.

전이 학습은 딥러닝 응용 분야에서 널리 사용됩니다. 사전 훈련된 신경망을 새로운 작업을 학습하기 위한 출발점으로 사용할 수 있습니다. 전이 학습으로 신경망을 미세 조정하는 것은 무작위로 초기화된 가중치를 사용하여 신경망을 처음부터 훈련시키는 것보다 일반적으로 훨씬 더 빠르고 쉽습니다. 학습된 특징을 보다 적은 개수의 훈련 영상을 사용하여 새로운 작업으로 빠르게 전이할 수 있습니다.

데이터 불러오기

새 영상의 압축을 풀고 영상 데이터저장소로 불러옵니다. imageDatastore는 폴더 이름을 기준으로 영상에 자동으로 레이블을 지정하고 데이터를 ImageDatastore 객체로 저장합니다. 영상 데이터저장소를 사용하면 메모리에 담을 수 없는 데이터를 포함하여 다량의 영상 데이터를 저장할 수 있고 컨벌루션 신경망 훈련 중에 영상 배치를 효율적으로 읽어 들일 수 있습니다.

unzip('MerchData.zip');
imds = imageDatastore('MerchData', ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

데이터를 훈련 데이터 세트와 검증 데이터 세트로 나눕니다. 영상의 70%는 훈련용으로 사용하고 30%는 검증용으로 사용합니다. splitEachLabel은 영상 데이터저장소를 2개의 새로운 데이터저장소로 분할합니다.

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');

이 매우 작은 데이터 세트에는 이제 55개의 훈련 영상과 20개의 검증 영상이 포함됩니다. 샘플 영상 몇 개를 표시합니다.

numTrainImages = numel(imdsTrain.Labels);
idx = randperm(numTrainImages,16);
figure
for i = 1:16
    subplot(4,4,i)
    I = readimage(imdsTrain,idx(i));
    imshow(I)
end

사전 훈련된 신경망 불러오기

사전 훈련된 GoogLeNet 신경망을 불러옵니다. Deep Learning Toolbox™ Model for GoogLeNet Network가 설치되어 있지 않으면 이를 다운로드할 수 있는 링크가 제공됩니다.

net = googlenet;

deepNetworkDesigner를 사용하여 신경망 아키텍처에 대한 대화형 방식 시각화와 신경망 계층에 대한 상세한 정보를 표시합니다.

deepNetworkDesigner(net)

영상 입력 계층인 첫 번째 계층은 크기가 224×224×3인 입력 영상이 필요합니다. 여기서 3은 색 채널의 개수입니다.

inputSize = net.Layers(1).InputSize
inputSize = 1×3

   224   224     3

마지막 계층 바꾸기

사전 훈련된 신경망 net의 완전 연결 계층과 분류 계층은 1,000개의 클래스에 대해 구성되어 있습니다. GoogLeNet의 두 계층 loss3-classifieroutput은 신경망이 추출하는 특징을 클래스 확률, 손실 값 및 예측된 레이블로 조합하는 방법에 대한 정보를 포함합니다. 사전 훈련된 신경망을 새로운 영상을 분류하도록 다시 훈련시키려면 이 두 계층을 새 데이터 세트에 맞게 조정된 새로운 계층으로 바꾸십시오.

훈련된 신경망에서 계층 그래프를 추출합니다.

lgraph = layerGraph(net); 

이 완전 연결 계층을 출력값의 개수가 클래스 개수와 같은 새로운 완전 연결 계층으로 교체합니다. 전이된 계층보다 새로운 계층에서 학습이 더 빠르게 이루어지도록 하려면 완전 연결 계층의 WeightLearnRateFactor 값과 BiasLearnRateFactor 값을 높이십시오.

numClasses = numel(categories(imdsTrain.Labels))
numClasses = 5
newLearnableLayer = fullyConnectedLayer(numClasses, ...
    'Name','new_fc', ...
    'WeightLearnRateFactor',10, ...
    'BiasLearnRateFactor',10);
    
lgraph = replaceLayer(lgraph,'loss3-classifier',newLearnableLayer);

분류 계층은 신경망의 출력 클래스를 지정합니다. 분류 계층을 클래스 레이블이 없는 새로운 계층으로 바꿉니다. trainNetwork는 훈련을 진행할 때 계층의 출력 클래스를 자동으로 설정합니다.

newClassLayer = classificationLayer('Name','new_classoutput');
lgraph = replaceLayer(lgraph,'output',newClassLayer);

신경망 훈련시키기

이 신경망의 입력 영상은 크기가 224×224×3이어야 하는데 영상 데이터저장소의 영상은 이와 크기가 다릅니다. 증대 영상 데이터저장소를 사용하여 훈련 영상의 크기를 자동으로 조정합니다. 훈련 영상에 대해 추가로 수행할 증대 연산을 지정합니다. 즉, 세로 축을 따라 훈련 영상을 무작위로 뒤집고, 최대 30개의 픽셀을 가로와 세로 방향으로 무작위로 평행 이동합니다. 데이터 증대는 신경망이 과적합되는 것을 방지하고 훈련 영상의 정확한 세부 정보가 기억되지 않도록 하는 데 도움이 됩니다.

pixelRange = [-30 30];
imageAugmenter = imageDataAugmenter( ...
    'RandXReflection',true, ...
    'RandXTranslation',pixelRange, ...
    'RandYTranslation',pixelRange);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
    'DataAugmentation',imageAugmenter);

추가적인 데이터 증대를 수행하지 않고 검증 영상의 크기를 자동으로 조정하려면 증대 영상 데이터저장소를 추가적인 전처리 연산 지정 없이 사용하십시오.

augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

훈련 옵션을 지정합니다. 전이 학습을 위해, 사전 훈련된 신경망의 앞쪽 계층의 특징(전이된 계층 가중치)을 유지합니다. 전이된 계층의 학습을 늦추려면 초기 학습률을 작은 값으로 설정하십시오. 이전 단계에서는 새로운 마지막 계층의 학습 속도를 높이기 위해 완전 연결 계층의 학습률 인자를 증가시켰습니다. 이러한 조합으로 학습률을 설정하면 새로운 계층에서는 학습이 빨라지고 나머지 계층에서는 학습이 느려집니다. 전이 학습을 수행할 때는 많은 횟수의 Epoch에 대해 훈련을 진행하지 않아도 됩니다. Epoch 1회는 전체 훈련 데이터 세트에 대한 하나의 완전한 훈련 주기를 의미합니다. 미니 배치 크기와 검증 데이터를 지정합니다. 훈련 중에 ValidationFrequency번의 반복마다 신경망이 검증됩니다.

options = trainingOptions('sgdm', ...
    'MiniBatchSize',10, ...
    'MaxEpochs',6, ...
    'InitialLearnRate',1e-4, ...
    'Shuffle','every-epoch', ...
    'ValidationData',augimdsValidation, ...
    'ValidationFrequency',3, ...
    'Verbose',false, ...
    'Plots','training-progress');

전이된 계층과 새로운 계층으로 구성된 신경망을 훈련시킵니다. 기본적으로 trainNetwork는 GPU를 사용할 수 있으면 GPU를 사용합니다. GPU를 사용하려면 Parallel Computing Toolbox™와 지원되는 GPU 장치가 필요합니다. 지원되는 장치에 대한 자세한 내용은 GPU 연산 요구 사항 (Parallel Computing Toolbox) 항목을 참조하십시오. GPU를 사용할 수 없으면 CPU를 사용합니다. trainingOptions'ExecutionEnvironment' 이름-값 쌍 인수를 사용하여 실행 환경을 지정할 수도 있습니다.

netTransfer = trainNetwork(augimdsTrain,lgraph,options);

검증 영상 분류하기

미세 조정한 신경망을 사용하여 검증 영상을 분류합니다.

[YPred,scores] = classify(netTransfer,augimdsValidation);

4개의 샘플 검증 영상을 예측된 레이블과 함께 표시합니다.

idx = randperm(numel(imdsValidation.Files),4);
figure
for i = 1:4
    subplot(2,2,i)
    I = readimage(imdsValidation,idx(i));
    imshow(I)
    label = YPred(idx(i));
    title(string(label));
end

검증 세트에 대한 분류 정확도를 계산합니다. 정확도는 신경망이 올바르게 예측하는 레이블의 비율입니다.

YValidation = imdsValidation.Labels;
accuracy = mean(YPred == YValidation)
accuracy = 1

분류 정확도를 높이기 위한 팁을 보려면 딥러닝 팁과 요령 항목을 참조하십시오.

참고 문헌

[1] Krizhevsky, Alex, Ilya Sutskever, and Geoffrey E. Hinton. "ImageNet Classification with Deep Convolutional Neural Networks." Advances in neural information processing systems 25 (2012).

[2] Szegedy, Christian, Wei Liu, Yangqing Jia, Pierre Sermanet, Scott Reed, Dragomir Anguelov, Dumitru Erhan, Vincent Vanhoucke, and Andrew Rabinovich. "Going deeper with convolutions." Proceedings of the IEEE conference on computer vision and pattern recognition (2015): 1–9.

참고 항목

| | | | |

관련 항목