Main Content

영상 데이터와 특징 데이터로 신경망 훈련시키기

이 예제에서는 영상과 특징 입력 데이터를 모두 사용하여 손으로 쓴 숫자를 분류하는 신경망을 훈련시키는 방법을 보여줍니다.

훈련 데이터 불러오기

숫자 영상, 레이블, 시계 방향 회전 각도를 불러옵니다.

load DigitsDataTrain

trainnet 함수를 사용하여 여러 개의 입력을 갖는 신경망을 훈련시키려면 훈련 예측 변수와 응답 변수를 포함하는 단일 데이터저장소를 만듭니다. 숫자형 배열을 데이터저장소로 변환하려면 arrayDatastore를 사용하십시오. 그런 다음 combine 함수를 사용하여 단일 데이터저장소로 결합합니다.

dsX1Train = arrayDatastore(XTrain,IterationDimension=4);
dsX2Train = arrayDatastore(anglesTrain);
dsTTrain = arrayDatastore(labelsTrain);
dsTrain = combine(dsX1Train,dsX2Train,dsTTrain);

임의의 훈련 영상 20개를 표시합니다.

numObservationsTrain = numel(labelsTrain);
idx = randperm(numObservationsTrain,20);

figure
tiledlayout("flow");
for i = 1:numel(idx)
    nexttile
    imshow(XTrain(:,:,:,idx(i)))
    title("Angle: " + anglesTrain(idx(i)))
end

신경망 아키텍처 정의하기

다음과 같은 신경망을 정의합니다.

image1.png

  • 영상 입력에 대해, 입력 데이터와 일치하는 크기를 갖는 영상 입력 계층을 지정합니다.

  • 특징 입력에 대해, 크기가 입력 특징의 개수와 일치하는 특징 입력 계층을 지정합니다.

  • 영상 입력 분기에 대해, 컨벌루션, 배치 정규화, ReLU 계층 블록을 지정합니다. 여기서 컨벌루션 계층은 16개의 5×5 필터를 가집니다.

  • 배치 정규화 계층의 출력을 특징 벡터로 변환하기 위해, 크기가 50인 완전 연결 계층을 포함시킵니다.

  • 첫 번째 완전 연결 계층의 출력을 특징 입력과 결합하기 위해, 완전 연결 계층의 "SSCB"(공간, 공간, 채널, 배치) 출력에 평탄화 계층을 사용해서 평탄화하여 형식이 "CB"가 되도록 합니다.

  • 평탄화 계층의 출력을 첫 번째 차원(채널 차원)을 따라 특징 입력과 결합합니다.

  • 분류 출력에 대해, 출력 크기가 클래스 개수와 일치하는 완전 연결 계층을 포함시키고 그 뒤에 소프트맥스 계층을 포함시킵니다.

빈 신경망을 만듭니다.

net = dlnetwork;

신경망의 기본 분기를 포함하는 계층 배열을 만든 다음 신경망에 추가합니다.

[h,w,numChannels,numObservations] = size(XTrain);
numFeatures = 1;
classNames = categories(labelsTrain);
numClasses = numel(classNames);

imageInputSize = [h w numChannels];
filterSize = 5;
numFilters = 16;

layers = [
    imageInputLayer(imageInputSize,Normalization="none")
    convolution2dLayer(filterSize,numFilters)
    batchNormalizationLayer
    reluLayer
    fullyConnectedLayer(50)
    flattenLayer
    concatenationLayer(1,2,Name="cat")
    fullyConnectedLayer(numClasses)
    softmaxLayer];

net = addLayers(net,layers);

신경망에 특징 입력 계층을 추가하고 이를 결합 계층의 두 번째 입력에 연결합니다.

featInput = featureInputLayer(numFeatures,Name="features");
net = addLayers(net,featInput);
net = connectLayers(net,"features","cat/in2");

신경망을 플롯에 시각화합니다.

figure
plot(net)

훈련 옵션 지정하기

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

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

  • 훈련을 Epoch 15회 수행합니다.

  • 학습률 0.01로 훈련시킵니다.

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

  • 세부 정보가 출력되지 않도록 합니다.

options = trainingOptions("sgdm", ...
    MaxEpochs=15, ...
    InitialLearnRate=0.01, ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=0);

신경망 훈련시키기

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

net = trainnet(dsTrain,net,"crossentropy",options);

신경망 테스트하기

테스트 세트에 대한 예측값을 실제 레이블과 비교하여 신경망의 분류 정확도를 테스트합니다.

테스트 데이터를 불러옵니다.

load DigitsDataTest

minibatchpredict 함수를 사용하여 예측을 수행하고 scores2label 함수를 사용하여 점수를 레이블로 변환합니다. 기본적으로 minibatchpredict 함수는 GPU를 사용할 수 있으면 GPU를 사용합니다.

scores = minibatchpredict(net,XTest,anglesTest);
YTest = scores2label(scores,classNames);

예측값을 혼동행렬 차트로 시각화합니다.

figure
confusionchart(labelsTest,YTest)

분류 정확도를 평가합니다.

accuracy = mean(YTest == labelsTest)
accuracy = 0.9852

영상 일부를 예측값과 함께 표시합니다.

idx = randperm(size(XTest,4),9);
figure
tiledlayout(3,3)
for i = 1:9
    nexttile
    I = XTest(:,:,:,idx(i));
    imshow(I)

    label = string(YTest(idx(i)));
    title("Predicted Label: " + label)
end

참고 항목

| | | | | | | |

관련 예제

세부 정보