Main Content

학습 가능한 파라미터를 갖는 사용자 지정 딥러닝 계층 정의하기

Deep Learning Toolbox™가 작업에 필요한 계층을 제공하지 않을 경우, 이 예제를 가이드로 참고하여 자신만의 고유한 사용자 지정 계층을 정의할 수 있습니다. 내장 계층 목록은 딥러닝 계층 목록 항목을 참조하십시오.

사용자 지정 딥러닝 계층을 정의하려면 이 예제에서 제공하는 템플릿을 사용할 수 있습니다. 이 예제에서는 다음 단계를 수행합니다.

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

  2. 계층 속성 선언하기 — 학습 가능한 파라미터와 상태 파라미터를 비롯한 계층의 속성을 지정합니다.

  3. 생성자 함수 만들기(선택 사항) — 계층을 생성하고 속성을 초기화하는 방법을 지정합니다. 생성자 함수를 지정하지 않으면 생성 시점에 Name, Description, Type 속성이 []로 초기화되고 계층 입력값 개수와 출력값 개수가 1로 설정됩니다.

  4. 초기화 함수 만들기(선택 사항) — 신경망이 초기화될 때 학습 가능 파라미터와 상태 파라미터를 초기화하는 방법을 지정합니다 초기화 함수를 지정하지 않은 경우에는 소프트웨어가 신경망을 초기화할 때 파라미터를 초기화하지 않습니다.

  5. 순방향 함수 만들기 — 예측 시점과 훈련 시점에 데이터가 계층을 어떻게 순방향으로 통과하는지(순방향 전파) 지정합니다.

  6. 상태 재설정 함수 만들기(선택 사항) — 상태 파라미터를 재설정하는 방법을 지정합니다.

  7. 역방향 함수 만들기(선택 사항) — 입력 데이터와 학습 가능한 파라미터에 대한 손실의 도함수를 지정합니다(역방향 전파). 역방향 함수를 지정하지 않을 경우 순방향 함수가 dlarray 객체를 지원해야 합니다.

계층 함수를 정의할 때는 dlarray 객체를 사용하면 됩니다. dlarray 객체를 사용하면 차원에 레이블을 지정할 수 있기 때문에 차원이 높은 데이터로 작업하기가 더 쉽습니다. 예를 들어 "S", "T", "C", "B" 레이블을 사용하여 어떤 차원이 각각 공간 차원, 시간 차원, 채널 차원, 배치 차원에 해당하는지 레이블을 지정할 수 있습니다. 지정되지 않은 차원과 기타 자원에는 "U" 레이블을 사용하십시오. 특정 차원에 대해 연산을 수행하는 dlarray 객체 함수에는 직접 dlarray 객체 형식을 지정하거나 DataFormat 옵션을 사용하여 차원 레이블을 지정할 수 있습니다.

사용자 지정 계층에서 형식이 지정된 dlarray 객체를 사용하면 입력값과 출력값의 형식이 서로 다른 계층(예: 차원을 치환, 추가 또는 제거하는 계층)을 정의할 수 있습니다. 예를 들어 공간(spatial), 공간(spatial), 채널(channel), 배치(batch)를 뜻하는 형식 "SSCB"의 영상으로 구성된 미니 배치를 입력값으로 취하고, 채널(channel), 배치(batch), 시간(time)을 뜻하는 형식 "CBT"의 시퀀스로 구성된 미니 배치를 출력값으로 취하는 계층을 정의할 수 있습니다. 형식이 지정된 dlarray 객체를 사용하면 서로 다른 입력 형식을 가진 데이터에 대해 연산을 수행할 수 있는 계층도 정의할 수 있습니다. 예를 들면 형식이 "SSCB"(공간, 공간, 채널, 배치)인 입력값과 "CBT"(채널, 배치, 시간)인 입력값을 지원하는 계층을 정의할 수 있습니다.

dlarray 객체를 사용하면 자동 미분도 지원할 수 있습니다. 결과적으로 순방향 함수가 dlarray 객체를 완전히 지원한다면 역방향 함수를 정의하는 것을 선택할 수 있습니다.

사용자 지정 계층 순방향 함수에서 형식이 지정된 dlarray 객체를 사용하기 위한 지원을 활성화하려면 사용자 지정 계층을 정의할 때 nnet.layer.Formattable 클래스에서도 상속하십시오. 예제는 Define Custom Deep Learning Layer with Formatted Inputs 항목을 참조하십시오.

이 예제에서는 4개의 학습 가능한 파라미터가 있는 계층인 SReLU 계층을 만들고 이를 신경망에서 사용하는 방법을 보여줍니다. SReLU 계층은 임계값 적용 연산을 수행하며 이때 계층은 각 채널에 대해 구간을 벗어난 값을 스케일링합니다. 구간 임계값과 스케일링 인자는 학습 가능한 파라미터입니다.[1]

SReLU 연산은 다음과 같이 지정됩니다.

f(xi)={til+ail(xitil)if xitilxiif til<xi<tirtir+air(xitir)if tirxi

여기서 xi는 채널 i의 입력이고, tli 및 tri는 각각 채널 i의 왼쪽 및 오른쪽 임계값이며, ali 및 ari는 각각 채널 i의 왼쪽 및 오른쪽 스케일링 인자입니다. 이 임계값과 스케일링 인자는 학습 가능한 파라미터이며, 계층은 훈련하는 동안 이들 파라미터를 학습합니다.

사용자 지정 계층 템플릿

다음의 사용자 지정 계층 템플릿을 MATLAB에 새 파일로 복사합니다. 이 템플릿은 계층 클래스 정의의 구조를 제공합니다. 다음과 같은 내용을 포함합니다.

  • 계층 속성, 학습 가능한 파라미터, 상태 파라미터에 대한 properties 블록(선택 사항)

  • 계층 생성자 함수.

  • initialize 함수(선택 사항).

  • predict 함수 및 forward 함수(선택 사항).

  • 상태 속성을 갖는 계층을 위한 resetState 함수(선택 사항).

  • backward 함수(선택 사항).

classdef myLayer < nnet.layer.Layer % ...
        % & nnet.layer.Formattable ... % (Optional) 
        % & nnet.layer.Acceleratable % (Optional)

    properties
        % (Optional) Layer properties.

        % Declare layer properties here.
    end

    properties (Learnable)
        % (Optional) Layer learnable parameters.

        % Declare learnable parameters here.
    end

    properties (State)
        % (Optional) Layer state parameters.

        % Declare state parameters here.
    end

    properties (Learnable, State)
        % (Optional) Nested dlnetwork objects with both learnable
        % parameters and state parameters.

        % Declare nested networks with learnable and state parameters here.
    end

    methods
        function layer = myLayer()
            % (Optional) Create a myLayer.
            % This function must have the same name as the class.

            % Define layer constructor function here.
        end

        function layer = initialize(layer,layout)
            % (Optional) Initialize layer learnable and state parameters.
            %
            % Inputs:
            %         layer  - Layer to initialize
            %         layout - Data layout, specified as a networkDataLayout
            %                  object
            %
            % Outputs:
            %         layer - Initialized layer
            %
            %  - For layers with multiple inputs, replace layout with 
            %    layout1,...,layoutN, where N is the number of inputs.
            
            % Define layer initialization function here.
        end
        

        function [Y,state] = predict(layer,X)
            % Forward input data through the layer at prediction time and
            % output the result and updated state.
            %
            % Inputs:
            %         layer - Layer to forward propagate through 
            %         X     - Input data
            % Outputs:
            %         Y     - Output of layer forward function
            %         state - (Optional) Updated layer state
            %
            %  - For layers with multiple inputs, replace X with X1,...,XN, 
            %    where N is the number of inputs.
            %  - For layers with multiple outputs, replace Y with 
            %    Y1,...,YM, where M is the number of outputs.
            %  - For layers with multiple state parameters, replace state 
            %    with state1,...,stateK, where K is the number of state 
            %    parameters.

            % Define layer predict function here.
        end

        function [Y,state,memory] = forward(layer,X)
            % (Optional) Forward input data through the layer at training
            % time and output the result, the updated state, and a memory
            % value.
            %
            % Inputs:
            %         layer - Layer to forward propagate through 
            %         X     - Layer input data
            % Outputs:
            %         Y      - Output of layer forward function 
            %         state  - (Optional) Updated layer state 
            %         memory - (Optional) Memory value for custom backward
            %                  function
            %
            %  - For layers with multiple inputs, replace X with X1,...,XN, 
            %    where N is the number of inputs.
            %  - For layers with multiple outputs, replace Y with 
            %    Y1,...,YM, where M is the number of outputs.
            %  - For layers with multiple state parameters, replace state 
            %    with state1,...,stateK, where K is the number of state 
            %    parameters.

            % Define layer forward function here.
        end

        function layer = resetState(layer)
            % (Optional) Reset layer state.

            % Define reset state function here.
        end

        function [dLdX,dLdW,dLdSin] = backward(layer,X,Y,dLdY,dLdSout,memory)
            % (Optional) Backward propagate the derivative of the loss
            % function through the layer.
            %
            % Inputs:
            %         layer   - Layer to backward propagate through 
            %         X       - Layer input data 
            %         Y       - Layer output data 
            %         dLdY    - Derivative of loss with respect to layer 
            %                   output
            %         dLdSout - (Optional) Derivative of loss with respect 
            %                   to state output
            %         memory  - Memory value from forward function
            % Outputs:
            %         dLdX   - Derivative of loss with respect to layer input
            %         dLdW   - (Optional) Derivative of loss with respect to
            %                  learnable parameter 
            %         dLdSin - (Optional) Derivative of loss with respect to 
            %                  state input
            %
            %  - For layers with state parameters, the backward syntax must
            %    include both dLdSout and dLdSin, or neither.
            %  - For layers with multiple inputs, replace X and dLdX with
            %    X1,...,XN and dLdX1,...,dLdXN, respectively, where N is
            %    the number of inputs.
            %  - For layers with multiple outputs, replace Y and dLdY with
            %    Y1,...,YM and dLdY,...,dLdYM, respectively, where M is the
            %    number of outputs.
            %  - For layers with multiple learnable parameters, replace 
            %    dLdW with dLdW1,...,dLdWP, where P is the number of 
            %    learnable parameters.
            %  - For layers with multiple state parameters, replace dLdSin
            %    and dLdSout with dLdSin1,...,dLdSinK and 
            %    dLdSout1,...,dldSoutK, respectively, where K is the number
            %    of state parameters.

            % Define layer backward function here.
        end
    end
end

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

먼저 계층에 이름을 지정합니다. 클래스 파일의 첫 번째 줄에서 기존 이름 myLayersreluLayer로 바꿉니다.

classdef sreluLayer < nnet.layer.Layer % ...
        % & nnet.layer.Formattable ... % (Optional) 
        % & nnet.layer.Acceleratable % (Optional)
    ...
end

역방향 함수를 지정하지 않았다면 계층 함수는 기본적으로 형식이 지정되지 않은 dlarray 객체를 입력값으로 받습니다. 계층이 형식이 지정된 dlarray 객체를 입력값으로 받고 형식이 지정된 dlarray 객체를 출력하도록 지정하려면 사용자 지정 계층을 정의할 때 nnet.layer.Formattable 클래스도 상속하십시오.

계층 함수는 가속을 지원하므로 nnet.layer.Acceleratable도 상속하십시오. 사용자 지정 계층 함수의 가속에 대한 자세한 내용은 Custom Layer Function Acceleration 항목을 참조하십시오. 이 계층은 Formattable 입력값이 필요하지 않으므로 nnet.layer.Formattable 슈퍼클래스(선택 항목)를 제거하십시오.

classdef sreluLayer < nnet.layer.Layer ...
        & nnet.layer.Acceleratable
    ...
end

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

    methods
        function layer = sreluLayer()           
            ...
        end

        ...
     end

계층 저장하기

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

속성과 학습 가능한 파라미터 선언하기

properties 섹션에서 계층 속성을 선언하고 properties (Learnable) 섹션에서 학습 가능한 파라미터를 나열하여 선언합니다.

기본적으로 사용자 지정 계층은 다음과 같은 속성을 갖습니다. 다음 속성은 properties 섹션에서 선언하지 마십시오.

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

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

계층 설명을 지정하지 않으면 계층 클래스 이름이 표시됩니다.

Type

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

계층 유형을 지정하지 않을 경우 계층 클래스 이름이 표시됩니다.

NumInputs계층에 대한 입력값의 개수로, 양의 정수로 지정됩니다. 이 값을 지정하지 않으면 NumInputsInputNames의 이름 개수로 자동으로 설정됩니다. 디폴트 값은 1입니다.
InputNames계층의 입력값 이름으로, 문자형 벡터로 구성된 셀형 배열로 지정됩니다. 이 값을 지정하지 않았고 NumInputs가 1보다 크면, InputNames{'in1',...,'inN'}으로 자동으로 설정됩니다. 여기서 NNumInputs와 동일합니다. 디폴트 값은 {'in'}입니다.
NumOutputs계층에 대한 출력값의 개수로, 양의 정수로 지정됩니다. 이 값을 지정하지 않으면 NumOutputsOutputNames의 이름 개수로 자동으로 설정됩니다. 디폴트 값은 1입니다.
OutputNames계층의 출력값 이름으로, 문자형 벡터로 구성된 셀형 배열로 지정됩니다. 이 값을 지정하지 않았고 NumOutputs가 1보다 크면, OutputNames{'out1',...,'outM'}으로 자동으로 설정됩니다. 여기서 MNumOutputs와 동일합니다. 디폴트 값은 {'out'}입니다.

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

입력값이 여러 개인 계층을 만들 때는 계층 생성자에서 NumInputs 또는 InputNames 속성을 설정해야 합니다. 출력값이 여러 개인 계층을 만들 때는 계층 생성자에서 NumOutputs 또는 OutputNames 속성을 설정해야 합니다. 예제는 Define Custom Deep Learning Layer with Multiple Inputs 항목을 참조하십시오.

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

SReLU 계층은 4개의 학습 가능한 파라미터(왼쪽과 오른쪽의 임계값, 왼쪽과 오른쪽의 스케일링 인자)를 가집니다. 이 학습 가능한 파라미터를 properties (Learnable) 섹션에서 선언하고 파라미터 Alpha를 호출합니다.

    properties (Learnable)
    % Layer learnable parameters
    
        LeftSlope
        RightSlope
        LeftThreshold
        RightThreshold
    end

생성자 함수 만들기

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

SReLU 계층 생성자 함수에는 하나의 선택적 인수(계층 이름)가 필요합니다. sreluLayer 함수의 args에 선택적 이름-값 인수에 해당하는 하나의 입력 인수를 지정합니다. 함수 상단에 함수의 구문에 대해 설명하는 주석을 추가합니다.

        function layer = sreluLayer(args)
            % layer = sreluLayercreates a SReLU layer.
            %
            % layer = sreluLayer(Name=name) also specifies the
            % layer name

            ...
        end

계층 속성 초기화하기

생성자 함수에서 계층 속성을 초기화합니다. 주석 % Layer constructor function goes here를 계층 속성을 초기화하는 코드로 바꿉니다. 학습 가능 파라미터 또는 상태 파라미터는 생성자 함수에서 초기화하지 말고 initialize 함수에서 초기화하십시오.

arguments 블록을 사용하여 입력 인수를 구문 분석하고 Name 속성을 설정합니다.

            arguments
                args.Name = "";
            end

            % Set layer name.
            layer.Name = args.Name;

계층의 Description 속성을 설정하여 계층에 한 줄 설명을 제공합니다. 계층의 유형을 설명하려면 설명을 설정합니다.

            % Set layer description.
            layer.Description = "SReLU";

완성된 생성자 함수를 확인합니다.

        function layer = sreluLayer(args) 
            % layer = sreluLayer creates a SReLU layer.
            %
            % layer = sreluLayer(Name=name) also specifies the
            % layer name.
    
            arguments
                args.Name = "";
            end
    
            % Set layer name.
            layer.Name = args.Name;

            % Set layer description.
            layer.Description = "SReLU";
        end

명령 sreluLayer(Name="srelu")는 이 생성자 함수를 사용하여 이름이 "srelu"인 SReLU 계층을 만듭니다.

초기화 함수 만들기

신경망이 초기화될 때 계층의 학습 가능 파라미터와 상태 파라미터를 초기화하는 함수를 만듭니다. 속성이 비어 있는 경우 함수가 학습 가능 파라미터와 상태 파라미터만 초기화하는지 확인하십시오. 그렇지 않으면 MAT 파일에서 신경망을 불러올 때 덮어쓰기가 발생할 수 있습니다.

학습 가능 파라미터를 초기화하려면 입력 데이터와 같은 채널 개수를 갖는 확률 벡터를 생성합니다.

신경망을 사용할 준비가 될 때까지 입력 데이터의 크기를 알 수 없으므로 소프트웨어가 함수에 제공하는 networkDataLayout 객체를 사용하여 학습 가능 파라미터와 상태 파라미터를 초기화하는 초기화 함수를 만들어야 합니다. 신경망 데이터 계층 객체는 예상 입력 데이터의 크기와 형식에 대한 정보를 포함합니다. 이러한 크기 및 형식 정보를 사용하여 학습 가능 파라미터와 상태 파라미터를 초기화하는 초기화 함수를 만들어서 이들 파라미터가 올바른 크기를 갖도록 합니다.

학습 가능 파라미터는 입력 관측값과 같은 개수의 차원을 가집니다. 여기서 채널 차원은 입력 데이터의 채널 차원과 크기가 동일하고 나머지 차원은 한원소입니다. 입력 networkDataLayout 객체에서 크기 및 형식 정보를 추출하고 같은 개수의 채널을 갖는 학습 가능 파라미터를 초기화하는 initialize 함수를 만듭니다.

        function layer = initialize(layer,layout)
            % layer = initialize(layer,layout) initializes the layer
            % learnable parameters using the specified input layout.

            % Find number of channels.
            idx = finddim(layout,"C");
            numChannels = layout.Size(idx);

            % Initialize empty learnable parameters.
            sz = ones(1,numel(layout.Size);
            sz(idx) = numChannels;
            
            if isempty(layer.LeftSlope)
                layer.LeftSlope = rand(sz);
            end
            
            if isempty(layer.RightSlope)
                layer.RightSlope = rand(sz);
            end
            
            if isempty(layer.LeftThreshold)
                layer.LeftThreshold = rand(sz);
            end
            
            if isempty(layer.RightThreshold)
                layer.RightThreshold = rand(sz);
            end
        end

순방향 함수 만들기

예측 시점과 훈련 시점에 사용할 계층 순방향 함수를 만듭니다.

예측 시점에 데이터를 계층에 순방향으로 전파하고 결과를 출력하는 함수 predict를 만듭니다.

predict 함수 구문은 계층 유형에 따라 달라집니다.

  • Y = predict(layer,X)는 입력 데이터 X를 순방향으로 계층에 통과시키고 결과 Y를 출력합니다. 여기서 layer는 하나의 입력값과 하나의 출력값을 갖습니다.

  • [Y,state] = predict(layer,X)는 업데이트된 상태 파라미터 state도 출력합니다. 여기서 layer는 하나의 상태 파라미터를 갖습니다.

계층이 여러 개의 입력값, 여러 개의 출력값 또는 여러 개의 상태 파라미터를 사용하도록 구문을 조정할 수 있습니다.

  • 입력값이 여러 개인 계층의 경우 XX1,...,XN으로 대체합니다. 여기서 N은 입력값의 개수입니다. NumInputs 속성은 N과 일치해야 합니다.

  • 출력값이 여러 개인 계층의 경우 YY1,...,YM으로 대체합니다. 여기서 M은 출력값의 개수입니다. NumOutputs 속성은 M과 일치해야 합니다.

  • 상태 파라미터가 여러 개인 계층의 경우 statestate1,...,stateK로 대체합니다. 여기서 K는 상태 파라미터의 개수입니다.

계층에 대한 입력값의 개수가 가변인 경우에는 X1,…,XN 대신 varargin을 사용하십시오. 이 경우 varargin은 입력값으로 구성된 셀형 배열입니다. 여기서 varargin{i}Xi에 대응됩니다.

출력값의 개수가 가변인 경우에는 Y1,…,YM 대신 varargout을 사용하십시오. 이 경우 varargout은 출력값으로 구성된 셀형 배열입니다. 여기서 varargout{j}Yj에 대응됩니다.

사용자 지정 계층에 학습 가능한 파라미터에 대한 dlnetwork 객체가 있는 경우, 사용자 지정 계층의 predict 함수에서 dlnetwork에 대해 predict 함수를 사용하십시오. 그렇게 하면 dlnetwork 객체 predict 함수가 예측에 적합한 계층 연산을 사용합니다. dlnetwork가 상태 파라미터를 갖는 경우 신경망 상태도 반환하십시오.

SReLU 계층에는 입력값 1개와 출력값 1개밖에 없으므로 SReLU 계층에 대한 predict의 구문은 Y = predict(layer,X)입니다.

기본적으로 계층은 predict를 훈련 시점에 순방향 함수로 사용합니다. 훈련 시점에 다른 순방향 함수를 사용하거나 사용자 지정 역방향 함수에 필요한 값을 유지하려면 forward라는 이름의 함수도 만들어야 합니다.

입력값의 차원은 데이터의 유형 및 연결된 계층의 출력값에 따라 달라집니다.

계층 입력값
형태데이터 형식
2차원 영상

h×w×c×N 숫자형 배열로, 여기서 h, w, c, N은 각각 영상의 높이, 너비, 채널 개수, 관측값의 개수입니다.

"SSCB"
3차원 영상h×w×d×c×N 숫자형 배열로, 여기서 h, w, d, c, N은 각각 영상의 높이, 너비, 깊이, 채널 개수, 영상 관측값의 개수입니다."SSSCB"
벡터 시퀀스

c×N×s 행렬로, 여기서 c는 시퀀스의 특징 개수이고 N은 시퀀스 관측값의 개수, s는 시퀀스 길이입니다.

"CBT"
2차원 영상 시퀀스

h×w×c×N×s 배열로, 여기서 h, w, c는 각각 영상의 높이, 너비, 채널 개수이고 N은 영상 시퀀스 관측값의 개수, s는 시퀀스 길이입니다.

"SSCBT"
3차원 영상 시퀀스

h×w×d×c×N×s 배열로, 여기서 h, w, d, c는 각각 영상의 높이, 너비, 깊이, 채널 개수이고, N은 영상 시퀀스 관측값의 개수, s는 시퀀스 길이입니다.

"SSSCBT"
특징c×N 배열로, 여기서 c는 특징의 개수이고 N은 관측값의 개수입니다."CB"

시퀀스를 출력하는 계층은 임의 길이의 시퀀스를 출력하거나 시간 차원이 없는 데이터를 출력할 수 있습니다.

forward 함수는 훈련 시점에 데이터를 계층에 순방향으로 전파하고 메모리 값도 출력합니다.

forward 함수 구문은 계층 유형에 따라 달라집니다.

  • Y = forward(layer,X)는 입력 데이터 X를 순방향으로 계층에 통과시키고 결과 Y를 출력합니다. 여기서 layer는 하나의 입력값과 하나의 출력값을 갖습니다.

  • [Y,state] = forward(layer,X)는 업데이트된 상태 파라미터 state도 출력합니다. 여기서 layer는 하나의 상태 파라미터를 갖습니다.

  • [__,memory] = forward(layer,X)는 위의 구문 중 하나를 사용하여 사용자 지정 backward 함수에 대한 메모리 값도 반환합니다. 계층이 사용자 지정 forward 함수와 사용자 지정 backward 함수를 모두 갖고 있다면 순방향 함수는 메모리 값을 반환해야 합니다.

계층이 여러 개의 입력값, 여러 개의 출력값 또는 여러 개의 상태 파라미터를 사용하도록 구문을 조정할 수 있습니다.

  • 입력값이 여러 개인 계층의 경우 XX1,...,XN으로 대체합니다. 여기서 N은 입력값의 개수입니다. NumInputs 속성은 N과 일치해야 합니다.

  • 출력값이 여러 개인 계층의 경우 YY1,...,YM으로 대체합니다. 여기서 M은 출력값의 개수입니다. NumOutputs 속성은 M과 일치해야 합니다.

  • 상태 파라미터가 여러 개인 계층의 경우 statestate1,...,stateK로 대체합니다. 여기서 K는 상태 파라미터의 개수입니다.

계층에 대한 입력값의 개수가 가변인 경우에는 X1,…,XN 대신 varargin을 사용하십시오. 이 경우 varargin은 입력값으로 구성된 셀형 배열입니다. 여기서 varargin{i}Xi에 대응됩니다.

출력값의 개수가 가변인 경우에는 Y1,…,YM 대신 varargout을 사용하십시오. 이 경우 varargout은 출력값으로 구성된 셀형 배열입니다. 여기서 varargout{j}Yj에 대응됩니다.

사용자 지정 계층에 학습 가능한 파라미터에 대한 dlnetwork 객체가 있는 경우, 사용자 지정 계층의 forward 함수에서 dlnetwork 객체의 forward 함수를 사용하십시오. 그렇게 하면 dlnetwork 객체 forward 함수가 훈련에 적합한 계층 연산을 사용합니다.

SReLU 연산은 다음과 같이 지정됩니다.

f(xi)={til+ail(xitil)if xitilxiif til<xi<tirtir+air(xitir)if tirxi

여기서 xi는 채널 i의 입력이고, tli 및 tri는 각각 채널 i의 왼쪽 및 오른쪽 임계값이며, ali 및 ari는 각각 채널 i의 왼쪽 및 오른쪽 스케일링 인자입니다. 이 임계값과 스케일링 인자는 학습 가능한 파라미터이며, 계층은 훈련하는 동안 이들 파라미터를 학습합니다.

이 연산을 predict에 구현합니다. SReLU 계층에서는 훈련을 위해 메모리나 다른 순방향 함수가 필요하지 않으므로 클래스 파일에서 forward 함수를 제거해도 됩니다. 함수 상단에 함수의 구문에 대해 설명하는 주석을 추가합니다.

zeros와 같은 함수를 사용하여 배열을 사전할당할 경우, 이들 배열의 데이터형이 계층 함수 입력값에 부합하는지 확인해야 합니다. 다른 배열과 동일한 데이터형을 가진 0으로 구성된 배열을 만들려면 zeros"like" 옵션을 사용하십시오. 예를 들어, 크기가 sz이고 배열 X와 동일한 데이터형을 갖는 0으로 구성된 배열을 만들려면 Y = zeros(sz,"like",X)를 사용하십시오.

        function Y = predict(layer, X)
            % Y = predict(layer, X) forwards the input data X through the
            % layer and outputs the result Y.
            
            tl = layer.LeftThreshold;
            al = layer.LeftSlope;
            tr = layer.RightThreshold;
            ar = layer.RightSlope;
            
            Y = (X <= tl) .* (tl + al.*(X-tl)) ...
                + ((tl < X) & (X < tr)) .* X ...
                + (tr <= X) .* (tr + ar.*(X-tr));
        end

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

완성된 계층

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

classdef sreluLayer < nnet.layer.Layer ...
        & nnet.layer.Acceleratable
    % Example custom SReLU layer.

    properties (Learnable)
    % Layer learnable parameters
    
        LeftSlope
        RightSlope
        LeftThreshold
        RightThreshold
    end

    methods
        function layer = sreluLayer(args) 
            % layer = sreluLayer creates a SReLU layer.
            %
            % layer = sreluLayer(Name=name) also specifies the
            % layer name.
    
            arguments
                args.Name = "";
            end
    
            % Set layer name.
            layer.Name = args.Name;

            % Set layer description.
            layer.Description = "SReLU";
        end

        function layer = initialize(layer,layout)
            % layer = initialize(layer,layout) initializes the layer
            % learnable parameters using the specified input layout.

            % Find number of channels.
            idx = finddim(layout,"C");
            numChannels = layout.Size(idx);

            % Initialize empty learnable parameters.
            sz = ones(1,numel(layout.Size);
            sz(idx) = numChannels;
            
            if isempty(layer.LeftSlope)
                layer.LeftSlope = rand(sz);
            end
            
            if isempty(layer.RightSlope)
                layer.RightSlope = rand(sz);
            end
            
            if isempty(layer.LeftThreshold)
                layer.LeftThreshold = rand(sz);
            end
            
            if isempty(layer.RightThreshold)
                layer.RightThreshold = rand(sz);
            end
        end

        function Y = predict(layer, X)
            % Y = predict(layer, X) forwards the input data X through the
            % layer and outputs the result Y.
            
            tl = layer.LeftThreshold;
            al = layer.LeftSlope;
            tr = layer.RightThreshold;
            ar = layer.RightSlope;
            
            Y = (X <= tl) .* (tl + al.*(X-tl)) ...
                + ((tl < X) & (X < tr)) .* X ...
                + (tr <= X) .* (tr + ar.*(X-tr));
        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) 항목을 참조하십시오.

이 예제에서, predict에 사용된 MATLAB 함수는 모두 dlarray 객체를 지원하므로 이 계층은 GPU와 호환됩니다.

checkLayer를 사용하여 사용자 지정 계층의 유효성 검사하기

사용자 지정 계층 sreluLayer의 계층 유효성을 검사합니다.

사용자 지정 계층 sreluLayer는 지원 파일로 이 예제에 첨부되어 있으며 입력 데이터에 SReLU 연산을 적용합니다. 이 계층에 액세스하려면 이 예제를 라이브 스크립트로 여십시오.

계층의 인스턴스를 만듭니다.

layer = sreluLayer;

계층에 대한 일반적인 입력값의 예상 입력 크기와 형식을 지정하는 networkDataFormat 객체를 생성합니다. 유효한 입력 크기 [24 24 20 128]을 지정합니다. 여기서 차원은 이전 계층 출력값의 높이, 너비, 채널 개수, 관측값 개수에 해당합니다. 형식을 "SSCB"(공간, 공간, 채널, 배치)로 지정합니다.

validInputSize = [24 24 20 128];
layout = networkDataLayout(validInputSize,"SSCB");

checkLayer를 사용하여 계층 유효성을 검사합니다.

checkLayer(layer,layout)
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.TestLayerWithoutBackward
.......... ..........
Done nnet.checklayer.TestLayerWithoutBackward
__________

Test Summary:
	 20 Passed, 0 Failed, 0 Incomplete, 14 Skipped.
	 Time elapsed: 0.28208 seconds.

함수는 계층에서 문제를 검출하지 않습니다.

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

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

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

load DigitsDataTrain

이 예제에 지원 파일로 첨부되어 있는 사용자 지정 계층 sreluLayer를 포함하는 계층 배열을 만듭니다. 이 계층에 액세스하려면 이 예제를 라이브 스크립트로 여십시오.

layers = [ 
    imageInputLayer([28 28 1])
    convolution2dLayer(5,20)
    batchNormalizationLayer
    sreluLayer
    fullyConnectedLayer(10)
    softmaxLayer];

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

options = trainingOptions("adam",MaxEpochs=10,Metrics="accuracy");
net = trainnet(XTrain,labelsTrain,layers,"crossentropy",options);
    Iteration    Epoch    TimeElapsed    LearnRate    TrainingLoss    TrainingAccuracy
    _________    _____    ___________    _________    ____________    ________________
            1        1       00:00:01        0.001          2.6767              10.156
           50        2       00:00:09        0.001         0.68524              74.219
          100        3       00:00:18        0.001         0.46823              86.719
          150        4       00:00:27        0.001         0.23939               93.75
          200        6       00:00:33        0.001        0.096779              99.219
          250        7       00:00:38        0.001        0.045862                 100
          300        8       00:00:42        0.001        0.050238                 100
          350        9       00:00:45        0.001        0.033407                 100
          390       10       00:00:49        0.001        0.032987                 100
Training stopped: Max epochs completed

테스트 영상을 분류하고 정확도를 계산하여 신경망 성능을 평가합니다. 여러 개의 관측값을 사용하여 예측을 수행하려면 minibatchpredict 함수를 사용합니다. 예측 점수를 레이블로 변환하려면 scores2label 함수를 사용합니다. minibatchpredict 함수는 GPU를 사용할 수 있으면 자동으로 GPU를 사용합니다.

load DigitsDataTest
scores = minibatchpredict(net,XTest);
classNames = categories(labelsTest);
YTest = scores2label(scores,classNames);
accuracy = mean(YTest==labelsTest)
accuracy = 0.9588

참고 문헌

[1] Hu, Xiaobin, Peifeng Niu, Jianmei Wang, and Xinxin Zhang. “A Dynamic Rectified Linear Activation Units.” IEEE Access 7 (2019): 180409–16. https://doi.org/10.1109/ACCESS.2019.2959036.

참고 항목

| | | | | | | | | | | |

관련 항목