Main Content

심층 신경망 디자이너를 사용하는 전이 학습을 위해 신경망 준비하기

이 예제에서는 심층 신경망 디자이너 앱을 사용하는 전이 학습을 위해 신경망을 대화형 방식으로 준비하는 방법을 보여줍니다.

전이 학습은 사전 훈련된 딥러닝 신경망이 새로운 작업을 학습하도록 미세 조정하는 과정입니다. 전이 학습을 사용하는 것은 신경망을 처음부터 훈련시키는 것보다 일반적으로 더 빠르고 쉽습니다. 학습된 특징을 보다 적은 양의 데이터를 사용하여 새로운 작업으로 빠르게 전이할 수 있습니다.

데이터 추출하기

MathWorks Merch 데이터셋을 추출합니다. MathWorks Merch 데이터셋은 5개의 클래스(cap, cube, playing cards, screwdriver, torch)에 속하는 MathWorks 기념품 75개의 영상을 포함하는 소규모 데이터셋입니다. 데이터는 영상들이 이 5개 클래스에 해당하는 하위 폴더에 속하도록 정렬되어 있습니다.

folderName = "MerchData";
unzip("MerchData.zip",folderName);

영상 데이터저장소를 만듭니다. 영상 데이터저장소를 사용하면 메모리에 담을 수 없는 데이터를 포함하여 다량의 영상 데이터 모음을 저장할 수 있고 신경망 훈련 중에 영상 배치를 효율적으로 읽어 들일 수 있습니다. 추출된 영상이 있는 폴더를 지정하고 하위 폴더 이름이 영상 레이블에 대응됨을 표시합니다.

imds = imageDatastore(folderName, ...
    IncludeSubfolders=true, ...
    LabelSource="foldernames");

샘플 영상 몇 개를 표시합니다.

numImages = numel(imds.Labels);
idx = randperm(numImages,16);
I = imtile(imds,Frames=idx);
figure
imshow(I)

클래스 이름과 클래스 개수를 추출합니다.

classNames = categories(imds.Labels);
numClasses = numel(classNames)
numClasses = 5

데이터를 훈련 데이터셋, 검증 데이터셋, 테스트 데이터셋으로 분할합니다. 영상의 70%는 훈련용, 15%는 검증용, 15%는 테스트용으로 사용합니다. splitEachLabel 함수는 영상 데이터저장소를 2개의 새로운 데이터저장소로 분할합니다.

[imdsTrain,imdsValidation,imdsTest] = splitEachLabel(imds,0.7,0.15,0.15,"randomized");

사전 훈련된 신경망 선택하기

심층 신경망 디자이너를 열려면 탭의 머신러닝 및 딥러닝에서 앱 아이콘을 클릭합니다. 또는 명령줄에서 앱을 열 수도 있습니다.

deepNetworkDesigner

심층 신경망 디자이너는 다양한 영상에 알맞은 풍부한 특징 표현을 학습한 여러 사전 훈련된 영상 분류 신경망을 제공합니다. 전이 학습은 영상이 신경망을 훈련시키는 데 사용된 원래 영상과 비슷한 경우에 가장 효과적입니다. 훈련 영상이 ImageNet 데이터베이스의 영상과 같은 자연 영상이라면 어떠한 사전 훈련된 신경망이라도 모두 적합합니다. 사용 가능한 신경망 목록과 이들을 비교하는 방법은 사전 훈련된 심층 신경망 항목을 참조하십시오.

데이터가 ImageNet 데이터와 매우 다르다면, 예를 들어 아주 작은 영상, 스펙트로그램 또는 영상이 아닌 데이터가 있다면 새로운 신경망을 훈련시키는 것이 나을 수 있습니다. 신경망을 처음부터 훈련시키는 방법을 보여주는 예제는 Get Started with Time Series Forecasting 항목을 참조하십시오.

SqueezeNet에는 추가 지원 패키지가 필요하지 않습니다. 다른 사전 훈련된 신경망의 경우, 필수 지원 패키지가 설치되어 있지 않으면 앱에서 설치 옵션이 제공됩니다.

사전 훈련된 신경망 목록에서 SqueezeNet을 선택하고 열기를 클릭합니다.

신경망 탐색하기

심층 신경망 디자이너의 디자이너 창에 전체 신경망의 축소된 형태가 표시됩니다.

신경망 플롯을 살펴봅니다. 마우스를 사용하여 확대하려면 Ctrl+스크롤 휠을 사용하십시오. 패닝하려면 화살표 키를 사용하거나 스크롤 휠을 누르고 마우스를 끄십시오. 속성을 볼 계층을 하나 선택합니다. 속성 창에서 신경망 요약을 보려면 모든 계층을 선택 취소하십시오.

영상 입력 계층 'input'을 선택합니다. 이 신경망의 입력 크기가 227×227×3픽셀임을 확인할 수 있습니다.

입력 크기를 변수 inputSize에 저장합니다.

inputSize = [227 227 3];

훈련을 위해 신경망 준비하기

사전 훈련된 신경망을 전이 학습을 위해 사용하려면 클래스 개수가 새로운 데이터 세트와 일치하도록 변경해야 합니다. 먼저 신경망에서 마지막 학습 가능한 계층을 찾습니다. SqueezeNet의 마지막 학습 가능한 계층은 마지막 컨벌루션 계층인 'conv10'입니다. 'conv10' 계층을 선택합니다. 속성 창 하단에서 계층 잠금 해제를 클릭합니다. 나타나는 경고 대화 상자에서 무시하고 잠금 해제를 클릭합니다. 이렇게 하면 계층 속성의 잠금이 해제되어 새 작업에 맞게 계층 속성을 조정할 수 있습니다.

R2023b 이전: 신경망을 새 데이터에 맞게 조정하려면 계층을 잠금 해제하는 대신에 계층을 바꿔야 합니다. 새 컨벌루션 2차원 계층에서 FilterSize를 [1 1]로 설정합니다.

NumFilters 속성은 분류 문제에 대한 클래스 개수를 정의합니다. NumFilters를 새 데이터의 클래스 개수(이 예제에서는 5)로 변경합니다.

전이된 계층보다 새 계층에서 학습이 더 빨리 이루어지도록 WeightLearnRateFactorBiasLearnRateFactor10으로 설정하여 학습률을 변경합니다.

신경망 확인하기

신경망이 훈련 준비가 되었는지 확인하려면 분석을 클릭하십시오. 딥러닝 신경망 분석기에 보고되는 오류나 경고가 없으므로 신경망이 훈련할 준비가 된 것입니다. 신경망을 내보내기 위해 내보내기를 클릭합니다. 앱은 신경망을 변수 net_1에 저장합니다.

훈련을 위해 데이터 준비하기

데이터저장소의 영상은 크기가 다를 수 있습니다. 훈련 영상의 크기를 자동으로 조정하려면 증대 영상 데이터저장소를 사용하십시오. 데이터 증대는 신경망이 과적합되는 것을 방지하고 훈련 영상의 정확한 세부 정보가 기억되지 않도록 하는 데에도 도움이 됩니다. 훈련 영상에 대해 추가로 수행할 증대 연산을 지정합니다. 즉, 세로 축을 따라 훈련 영상을 무작위로 뒤집고, 최대 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);
augimdsTest = augmentedImageDatastore(inputSize(1:2),imdsTest);

훈련 옵션 지정하기

훈련 옵션을 지정합니다. 옵션 중에서 선택하려면 경험적 분석이 필요합니다. 실험을 실행하여 다양한 훈련 옵션 구성을 살펴보려면 Experiment Manager 앱을 사용합니다.

  • Adam 최적화 함수를 사용하여 훈련시킵니다.

  • 전이된 계층의 학습을 늦추려면 초기 학습률을 작은 값으로 설정하십시오.

  • Epoch를 적은 횟수로 지정합니다. Epoch 1회는 전체 훈련 데이터 세트에 대한 하나의 완전한 훈련 주기를 의미합니다. 전이 학습에서는 그렇게 많은 Epoch 횟수만큼 훈련하지 않아도 됩니다.

  • 검증 데이터에 대한 정확도가 Epoch 1회마다 한 번씩 계산되도록 검증 데이터와 검증 빈도를 지정합니다.

  • 미니 배치의 크기, 즉 각 반복당 사용할 영상의 개수를 지정합니다. 매 Epoch마다 데이터 세트 전체가 사용되도록 하려면 미니 배치 크기가 훈련 샘플 개수를 균등하게 나누도록 설정하십시오.

  • 훈련 진행 상황을 플롯으로 표시하고 정확도 메트릭을 모니터링합니다.

  • 상세 출력값을 비활성화합니다.

options = trainingOptions("adam", ...
    InitialLearnRate=0.0001, ...
    MaxEpochs=8, ...
    ValidationData=imdsValidation, ...
    ValidationFrequency=5, ...
    MiniBatchSize=11, ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=false);

신경망 훈련시키기

trainnet 함수를 사용하여 신경망을 훈련시킵니다. 분류 작업에는 교차 엔트로피 손실을 사용합니다. 기본적으로 trainnet 함수는 GPU를 사용할 수 있으면 GPU를 사용합니다. GPU를 사용하려면 Parallel Computing Toolbox™ 라이선스와 지원되는 GPU 장치가 필요합니다. 지원되는 장치에 대한 자세한 내용은 GPU 연산 요구 사항 (Parallel Computing Toolbox) 항목을 참조하십시오. GPU를 사용할 수 없는 경우, trainnet 함수는 CPU를 사용합니다. 실행 환경을 지정하려면 ExecutionEnvironment 훈련 옵션을 사용하십시오.

net = trainnet(imdsTrain,net_1,"crossentropy",options);

신경망 테스트하기

테스트 영상을 분류합니다. 여러 개의 관측값을 사용하여 예측을 수행하려면 minibatchpredict 함수를 사용합니다. 예측 점수를 레이블로 변환하려면 scores2label 함수를 사용합니다. minibatchpredict 함수는 GPU를 사용할 수 있으면 자동으로 GPU를 사용합니다.

YTest = minibatchpredict(net,augimdsTest);
YTest = scores2label(YTest,classNames);

분류 정확도를 혼동 차트로 시각화합니다.

TTest = imdsTest.Labels;
figure
confusionchart(TTest,YTest);

새 데이터를 사용하여 예측하기

영상을 분류합니다. JPEG 파일에서 영상을 읽어 들이고 크기를 조정한 다음 single 데이터형으로 변환합니다.

im = imread("MerchDataTest.jpg");
im = imresize(im,inputSize(1:2));
X = single(im);

영상을 분류합니다. 하나의 관측값을 사용하여 예측을 수행하려면 predict 함수를 사용하십시오. GPU를 사용하려면 먼저 데이터를 gpuArray로 변환합니다.

if canUseGPU
    X = gpuArray(X);
end
scores = predict(net,X);
[label,score] = scores2label(scores,classNames);

영상을 예측 레이블 및 그에 대응되는 점수와 함께 표시합니다.

figure
imshow(im)
title(string(label) + " (Score: " + gather(score) + ")")

참고 항목

관련 항목