Main Content

사용자 지정 회귀 출력 계층 정의하기

사용자 지정 출력 계층은 권장되지 않습니다. 대신 trainnet 함수를 사용하고 사용자 지정 손실 함수를 지정하십시오. 손실 함수에 대한 사용자 지정 역방향 함수를 지정하려면 deep.DifferentiableFunction 객체를 사용하십시오. 자세한 내용은 Define Custom Deep Learning Operations 항목을 참조하십시오.

평균절대오차 손실을 사용하여 신경망을 훈련시키려면 trainnet 함수를 사용하고 손실 함수 "mae"를 지정하십시오.

trainNetwork 함수를 사용할 때 회귀 문제를 위해 다른 손실 함수를 사용하려면 이 예제를 가이드로 참고하여 사용자 지정 회귀 출력 계층을 정의할 수 있습니다. 이 예제에서는 평균절대오차(MAE) 손실이 있는 사용자 지정 회귀 출력 계층을 만드는 방법을 보여줍니다.

사용자 지정 회귀 출력 계층을 정의하려면 이 예제에서 제공하는 템플릿을 사용할 수 있습니다. 이 예제에서는 다음과 같은 단계를 수행합니다.

  1. 계층에 이름 지정하기 – MATLAB®에서 사용할 수 있도록 계층에 이름을 지정합니다.

  2. 계층 속성 선언하기 – 계층의 속성을 지정합니다.

  3. 생성자 함수 만들기(선택 사항) – 계층을 생성하고 속성을 초기화하는 방법을 지정합니다. 생성자 함수를 지정하지 않으면 생성 시점에 속성이 ''로 초기화됩니다.

  4. 순방향 손실 함수 만들기 – 예측값과 훈련 목표값 사이의 손실을 지정합니다.

  5. 역방향 손실 함수 만들기(선택 사항) – 예측값에 대한 손실의 도함수를 지정합니다. 역방향 손실 함수를 지정하지 않을 경우 순방향 손실 함수가 dlarray 객체를 지원해야 합니다.

회귀 MAE 계층은 회귀 문제에서 평균절대오차 손실을 계산합니다. MAE 손실은 2개의 연속 확률 변수 사이의 오차 측정값입니다. 예측값 Y와 훈련 목표값 T에 대해, Y와 T 사이의 MAE 손실은 다음과 같이 지정됩니다.

L=1Nn=1N(1Ri=1R|YniTni|),

여기서 N은 관측값의 개수이고 R은 응답 변수의 개수입니다.

회귀 출력 계층 템플릿

회귀 출력 계층 템플릿을 MATLAB에서 새 파일에 복사합니다. 이 템플릿은 회귀 출력 계층의 구조를 제공하며 계층 동작을 정의하는 함수를 포함합니다.

classdef myRegressionLayer < nnet.layer.RegressionLayer % ...
        % & nnet.layer.Acceleratable % (Optional)
        
    properties
        % (Optional) Layer properties.

        % Layer properties go here.
    end
 
    methods
        function layer = myRegressionLayer()           
            % (Optional) Create a myRegressionLayer.

            % Layer constructor function goes here.
        end

        function loss = forwardLoss(layer,Y,T)
            % Return the loss between the predictions Y and the training
            % targets T.
            %
            % Inputs:
            %         layer - Output layer
            %         Y     – Predictions made by network
            %         T     – Training targets
            %
            % Output:
            %         loss  - Loss between Y and T

            % Layer forward loss function goes here.
        end
        
        function dLdY = backwardLoss(layer,Y,T)
            % (Optional) Backward propagate the derivative of the loss 
            % function.
            %
            % Inputs:
            %         layer - Output layer
            %         Y     – Predictions made by network
            %         T     – Training targets
            %
            % Output:
            %         dLdY  - Derivative of the loss with respect to the 
            %                 predictions Y        

            % Layer backward loss function goes here.
        end
    end
end

계층에 이름 지정하고 슈퍼클래스 지정하기

먼저 계층에 이름을 지정합니다. 클래스 파일의 첫 번째 줄에서 기존 이름 myRegressionLayermaeRegressionLayer로 바꿉니다. 계층이 가속을 지원하므로 nnet.layer.Acceleratable 클래스도 포함시키십시오. 사용자 지정 계층 가속에 대한 자세한 내용은 Custom Layer Function Acceleration 항목을 참조하십시오.

classdef maeRegressionLayer < nnet.layer.RegressionLayer ...
        & nnet.layer.Acceleratable
    ...
end

다음으로, myRegressionLayer 생성자 함수(methods 섹션에 있는 첫 번째 함수)가 계층과 동일한 이름을 갖도록 이름을 변경합니다.

    methods
        function layer = maeRegressionLayer()           
            ...
        end

        ...
     end

계층 저장하기

계층 클래스 파일을 새 파일 maeRegressionLayer.m에 저장합니다. 파일 이름은 계층 이름과 일치해야 합니다. 계층을 사용하려면 파일을 현재 폴더 또는 MATLAB 경로의 폴더에 저장해야 합니다.

계층 속성 선언하기

properties 섹션에서 계층 속성을 선언합니다.

기본적으로 사용자 지정 출력 계층은 다음과 같은 속성을 갖습니다.

  • Name계층 이름으로, 문자형 벡터 또는 string형 스칼라로 지정됩니다. Layer 배열 입력값에 대해 trainnetdlnetwork 함수는 이름이 ""인 계층에 자동으로 이름을 할당합니다.

  • Description — 계층에 대한 한 줄 설명으로, 문자형 벡터 또는 string형 스칼라로 지정됩니다. 이 설명은 계층이 Layer 배열에 표시되는 경우에 나타납니다. 계층 설명을 지정하지 않을 경우 "Classification Output" 또는 "Regression Output"이 표시됩니다.

  • Type — 계층 유형으로, 문자형 벡터 또는 string형 스칼라로 지정됩니다. Type의 값은 계층이 Layer 배열에 표시되는 경우에 나타납니다. 계층 유형을 지정하지 않을 경우 계층 클래스 이름이 표시됩니다.

사용자 지정 분류 계층은 다음과 같은 속성도 갖습니다.

  • Classes출력 계층의 클래스로, categorical형 벡터, string형 배열, 문자형 벡터로 구성된 셀형 배열 또는 "auto"로 지정됩니다. Classes"auto"인 경우, 소프트웨어가 훈련 시점에 자동으로 클래스를 설정합니다. string형 배열 또는 문자형 벡터로 구성된 셀형 배열 str을 지정하면, 출력 계층의 클래스가 categorical(str,str)로 설정됩니다.

사용자 지정 회귀 계층은 다음과 같은 속성도 갖습니다.

  • ResponseNames응답 변수의 이름으로, 문자형 벡터로 구성된 셀형 배열 또는 string형 배열로 지정됩니다. 소프트웨어는 훈련 시점에 훈련 데이터에 따라 자동으로 응답 변수의 이름을 설정합니다. 디폴트 값은 {}입니다.

계층에 다른 속성이 없는 경우 properties 섹션을 생략할 수 있습니다.

계층에 추가 속성이 필요하지 않으므로 properties 섹션을 제거해도 됩니다.

생성자 함수 만들기

계층을 생성하고 계층 속성을 초기화하는 함수를 만듭니다. 계층을 만드는 데 필요한 변수를 생성자 함수의 입력값으로 지정합니다.

생성 시점에 Name 속성을 초기화하려면 입력 인수 name을 지정하십시오. 함수 상단에 함수의 구문에 대해 설명하는 주석을 추가합니다.

        function layer = maeRegressionLayer(name)
            % layer = maeRegressionLayer(name) creates a
            % mean-absolute-error regression layer and specifies the layer
            % name.

            ...
        end

계층 속성 초기화하기

주석 % Layer constructor function goes here를 계층 속성을 초기화하는 코드로 바꿉니다.

계층의 Description 속성을 설정하여 계층에 한 줄 설명을 제공합니다. Name 속성을 입력 인수 name으로 설정합니다. 계층의 유형과 크기를 설명하려면 설명을 설정합니다.

        function layer = maeRegressionLayer(name)
            % layer = maeRegressionLayer(name) creates a
            % mean-absolute-error regression layer and specifies the layer
            % name.
			
            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = 'Mean absolute error';
        end

순방향 손실 함수 만들기

신경망이 생성한 예측값과 훈련 목표값 사이의 MAE 손실을 반환하는 forwardLoss라는 함수를 만듭니다. forwardLoss의 구문은 loss = forwardLoss(layer, Y, T)입니다. 여기서 Y는 이전 계층의 출력값이고 T는 훈련 목표값을 포함합니다.

회귀 문제의 경우, T의 차원도 문제의 유형에 따라 달라집니다.

회귀 작업
형태데이터 형식
2차원 영상 회귀1×1×R×N. 여기서 R은 응답 변수의 개수이고 N은 관측값의 개수입니다."SSCB"
2차원 image-to-image 회귀h×w×c×N. 여기서 h, w, c는 각각 출력값의 높이, 너비, 채널 개수이고 N은 관측값의 개수입니다."SSCB"
3차원 영상 회귀1×1×1×R×N. 여기서 R은 응답 변수의 개수이고 N은 관측값의 개수입니다."SSSCB"
3차원 image-to-image 회귀h×w×d×c×N. 여기서 h, w, d, c는 각각 출력값의 높이, 너비, 깊이, 채널 개수이고 N은 관측값의 개수입니다."SSSCB"
sequence-to-one 회귀R×N. 여기서 R은 응답 변수의 개수이고 N은 관측값의 개수입니다."CB"
sequence-to-sequence 회귀R×S×N. 여기서 R은 응답 변수의 개수이고 N은 관측값의 개수이고 S는 시퀀스 길이입니다."CBT"

예를 들어, 신경망이 1개의 응답 변수를 갖는 영상 회귀 신경망을 정의하고 미니 배치의 크기가 50이라면 T는 크기가 1×1×1×50인 4차원 배열입니다.

Y의 크기는 이전 계층의 출력값에 따라 달라집니다. Y의 크기가 T와 같도록 하려면 출력 계층 앞에 올바른 크기를 출력하는 계층을 포함시켜야 합니다. 예를 들어, R개의 응답 변수를 갖는 영상 회귀의 경우, Y가 올바른 크기를 갖는 4차원 배열이 되도록 하려면 크기가 R인 완전 연결 계층을 출력 계층 앞에 포함시킬 수 있습니다.

회귀 MAE 계층은 회귀 문제에서 평균절대오차 손실을 계산합니다. MAE 손실은 2개의 연속 확률 변수 사이의 오차 측정값입니다. 예측값 Y와 훈련 목표값 T에 대해, Y와 T 사이의 MAE 손실은 다음과 같이 지정됩니다.

L=1Nn=1N(1Ri=1R|YniTni|),

여기서 N은 관측값의 개수이고 R은 응답 변수의 개수입니다.

입력값 YT는 각각 방정식의 Y와 T에 대응됩니다. 출력값 loss는 L에 대응됩니다. loss가 반드시 스칼라가 되도록 하려면 미니 배치에 대한 평균 손실을 출력합니다. 함수 상단에 함수의 구문에 대해 설명하는 주석을 추가합니다.

        function loss = forwardLoss(layer, Y, T)
            % loss = forwardLoss(layer, Y, T) returns the MAE loss between
            % the predictions Y and the training targets T.

            % Calculate MAE.
            R = size(Y,3);
            meanAbsoluteError = sum(abs(Y-T),3)/R;
    
            % Take mean over mini-batch.
            N = size(Y,4);
            loss = sum(meanAbsoluteError)/N;
        end

forwardLoss 함수는 dlarray 객체를 지원하는 함수만 사용하므로 backwardLoss 함수를 정의하는 것은 선택 사항입니다. dlarray 객체를 지원하는 함수 목록은 List of Functions with dlarray Support 항목을 참조하십시오.

완성된 계층

완성된 회귀 출력 계층 클래스 파일을 확인합니다.

classdef maeRegressionLayer < nnet.layer.RegressionLayer ...
        & nnet.layer.Acceleratable
    % Example custom regression layer with mean-absolute-error loss.
    
    methods
        function layer = maeRegressionLayer(name)
            % layer = maeRegressionLayer(name) creates a
            % mean-absolute-error regression layer and specifies the layer
            % name.
			
            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = 'Mean absolute error';
        end
        
        function loss = forwardLoss(layer, Y, T)
            % loss = forwardLoss(layer, Y, T) returns the MAE loss between
            % the predictions Y and the training targets T.

            % Calculate MAE.
            R = size(Y,3);
            meanAbsoluteError = sum(abs(Y-T),3)/R;
    
            % Take mean over mini-batch.
            N = size(Y,4);
            loss = sum(meanAbsoluteError)/N;
        end
    end
end

GPU 호환성

계층 순방향 함수가 dlarray 객체를 완전히 지원하는 경우 이 계층은 GPU와 호환됩니다. 그렇지 않은 경우, 계층이 GPU와 호환되려면 계층 함수가 gpuArray (Parallel Computing Toolbox) 형식의 입력값을 지원하고 출력값을 이 형식으로 반환해야 합니다.

여러 MATLAB 내장 함수는 gpuArray (Parallel Computing Toolbox) 입력 인수와 dlarray 입력 인수를 지원합니다. dlarray 객체를 지원하는 함수 목록은 List of Functions with dlarray Support 항목을 참조하십시오. GPU에서 실행되는 함수 목록은 GPU에서 MATLAB 함수 실행하기 (Parallel Computing Toolbox) 항목을 참조하십시오. 딥러닝을 위해 GPU를 사용하려면 지원되는 GPU 장치도 필요합니다. 지원되는 장치에 대한 자세한 내용은 GPU 연산 요구 사항 (Parallel Computing Toolbox) 항목을 참조하십시오. MATLAB에서 GPU를 사용하는 것에 관한 자세한 내용은 MATLAB에서의 GPU 연산 (Parallel Computing Toolbox) 항목을 참조하십시오.

maeRegressionLayer에서 forwardLoss에 사용된 MATLAB 함수는 dlarray 객체를 지원하므로 이 계층은 GPU와 호환됩니다.

출력 계층 유효성 검사하기

사용자 지정 분류 출력 계층 maeRegressionLayer의 계층 유효성을 검사합니다.

이 예제에 지원 파일로 첨부되어 있는 계층 maeRegressionLayer의 인스턴스를 만듭니다.

layer = maeRegressionLayer('mae');

checkLayer를 사용하여 계층이 유효한지 검사합니다. 계층에 대한 일반적인 입력값의 단일 관측값을 유효한 입력 크기로 지정합니다. 계층에는 1×1×R×N 배열 입력값이 필요합니다. 여기서 R은 응답 변수의 개수이고 N은 미니 배치에 있는 관측값의 개수입니다.

validInputSize = [1 1 10];
checkLayer(layer,validInputSize,'ObservationDimension',4);
Skipping GPU tests. No compatible GPU device found.
 
Skipping code generation compatibility tests. To check validity of the layer for code generation, specify the CheckCodegenCompatibility and ObservationDimension options.
 
Running nnet.checklayer.TestOutputLayerWithoutBackward
........
Done nnet.checklayer.TestOutputLayerWithoutBackward
__________

Test Summary:
	 8 Passed, 0 Failed, 0 Incomplete, 2 Skipped.
	 Time elapsed: 0.17995 seconds.

테스트 요약은 합격한 테스트, 실패한 테스트, 미완료 테스트, 건너뛴 테스트의 개수를 보고합니다.

신경망에 사용자 지정 회귀 출력 계층 포함시키기

Deep Learning Toolbox의 출력 계층을 다루듯이 동일한 방식으로 사용자 지정 출력 계층을 사용할 수 있습니다. 이 섹션에서는 앞에서 만든 사용자 지정 출력 계층을 사용하여 회귀용 신경망을 만들고 훈련시키는 방법을 보여줍니다.

이 예제에서는 컨벌루션 신경망 아키텍처를 구성하고 신경망을 훈련시킨 다음 훈련된 신경망을 사용하여 손으로 쓴 숫자의 회전 각도를 예측합니다. 이러한 예측은 광학 문자 인식 분야에 유용합니다.

예제 훈련 데이터를 불러옵니다.

[XTrain,~,TTrain] = digitTrain4DArrayData;

회귀 출력 계층 maeRegressionLayer를 포함하여 계층 배열을 만듭니다.

layers = [
    imageInputLayer([28 28 1])
    convolution2dLayer(5,20)
    batchNormalizationLayer
    reluLayer
    fullyConnectedLayer(1)
    maeRegressionLayer('mae')]
layers = 
  6x1 Layer array with layers:

     1   ''      Image Input           28x28x1 images with 'zerocenter' normalization
     2   ''      2-D Convolution       20 5x5 convolutions with stride [1  1] and padding [0  0  0  0]
     3   ''      Batch Normalization   Batch normalization
     4   ''      ReLU                  ReLU
     5   ''      Fully Connected       1 fully connected layer
     6   'mae'   Regression Output     Mean absolute error

훈련 옵션을 설정하고 신경망을 훈련시킵니다.

options = trainingOptions('sgdm');
net = trainNetwork(XTrain,TTrain,layers,options);
Training on single CPU.
Initializing input data normalization.
|========================================================================================|
|  Epoch  |  Iteration  |  Time Elapsed  |  Mini-batch  |  Mini-batch  |  Base Learning  |
|         |             |   (hh:mm:ss)   |     RMSE     |     Loss     |      Rate       |
|========================================================================================|
|       1 |           1 |       00:00:00 |        28.28 |         25.1 |          0.0100 |
|       2 |          50 |       00:00:04 |        14.27 |         11.3 |          0.0100 |
|       3 |         100 |       00:00:07 |        14.90 |         11.9 |          0.0100 |
|       4 |         150 |       00:00:11 |        10.21 |          8.0 |          0.0100 |
|       6 |         200 |       00:00:15 |        10.15 |          7.9 |          0.0100 |
|       7 |         250 |       00:00:19 |        11.57 |          9.0 |          0.0100 |
|       8 |         300 |       00:00:23 |        10.86 |          8.4 |          0.0100 |
|       9 |         350 |       00:00:27 |         9.94 |          7.7 |          0.0100 |
|      11 |         400 |       00:00:31 |         9.97 |          7.2 |          0.0100 |
|      12 |         450 |       00:00:36 |         8.88 |          6.7 |          0.0100 |
|      13 |         500 |       00:00:40 |         9.39 |          5.9 |          0.0100 |
|      15 |         550 |       00:00:44 |         8.73 |          6.2 |          0.0100 |
|      16 |         600 |       00:00:48 |         8.95 |          6.6 |          0.0100 |
|      17 |         650 |       00:00:52 |         8.01 |          5.7 |          0.0100 |
|      18 |         700 |       00:00:56 |         8.35 |          6.2 |          0.0100 |
|      20 |         750 |       00:01:00 |         7.13 |          5.6 |          0.0100 |
|      21 |         800 |       00:01:05 |         7.50 |          5.5 |          0.0100 |
|      22 |         850 |       00:01:09 |         7.11 |          5.6 |          0.0100 |
|      24 |         900 |       00:01:12 |         7.43 |          5.4 |          0.0100 |
|      25 |         950 |       00:01:17 |         6.66 |          4.9 |          0.0100 |
|      26 |        1000 |       00:01:21 |         6.82 |          4.8 |          0.0100 |
|      27 |        1050 |       00:01:25 |         6.65 |          5.1 |          0.0100 |
|      29 |        1100 |       00:01:29 |         7.39 |          5.9 |          0.0100 |
|      30 |        1150 |       00:01:33 |         7.10 |          5.4 |          0.0100 |
|      30 |        1170 |       00:01:35 |         6.64 |          5.0 |          0.0100 |
|========================================================================================|
Training finished: Max epochs completed.

예측된 회전 각도와 실제 회전 각도 사이의 예측 오차를 계산하여 신경망 성능을 평가합니다.

[XTest,~,TTest] = digitTest4DArrayData;
YPred = predict(net,XTest);
predictionError = TTest - YPred;

실제 각도로부터 허용 가능한 오차 범위 내에 있는 예측값의 개수를 계산합니다. 임계값을 10도로 설정하고 예측값이 이 임계값 내에 있는 비율을 계산합니다.

thr = 10;
numCorrect = sum(abs(predictionError) < thr);
numTestImages = size(XTest,4);
accuracy = numCorrect/numTestImages
accuracy = 0.7622

참고 항목

| | | | | |

관련 항목