Main Content

書式化された入力をもつカスタム深層学習層の定義

目的のタスクに必要な層が Deep Learning Toolbox™ に用意されていない場合、この例を指針として使用して独自のカスタム層を定義できます。組み込み層の一覧については、深層学習層の一覧を参照してください。

カスタム深層学習層を定義するために、この例で提供するテンプレートを使用できます。この例では、次のステップで説明を進めます。

  1. 層の命名 — MATLAB® で使用できるように層に名前を付けます。

  2. 層のプロパティの宣言 — 層のプロパティ (学習可能なパラメーターや状態パラメーターなど) を指定します。

  3. コンストラクター関数の作成 (オプション) — 層の構築とそのプロパティ初期化の方法を指定します。コンストラクター関数を指定しない場合、作成時に NameDescription、および Type の各プロパティは [] で初期化され、層の入力および出力の数は 1 に設定されます。

  4. 初期化関数の作成 (オプション) — ネットワークの初期化時に学習可能なパラメーターと状態パラメーターを初期化する方法を指定します。初期化関数を指定しない場合、ネットワークの初期化時にパラメーターは初期化されません。

  5. 順方向関数の作成 — 予測時および学習時に層経由でデータを順方向にパス (順伝播) する方法を指定します。

  6. リセット ステート関数の作成 (オプション) — 状態パラメーターをリセットする方法を指定します。

  7. 逆方向関数の作成 (オプション) — 入力データおよび学習可能なパラメーターにおける損失の微分を指定します (逆伝播)。逆方向関数を指定しない場合、順方向関数は dlarray オブジェクトをサポートしなければなりません。

層の関数を定義するときに、dlarray オブジェクトを使用できます。dlarray オブジェクトを使用すると、次元にラベルを付けることができるため、高次元のデータをより簡単に扱うことができます。たとえば、"S""T""C""B" のラベルを使用して、各次元が空間、時間、チャネル、バッチのどの次元に対応するかを示すことができます。特に指定がないその他の次元については、ラベル "U" を使用します。特定の次元に対して演算を行うオブジェクト関数 dlarray の場合、dlarray オブジェクトを直接書式化するか、DataFormat オプションを使用することで、次元ラベルを指定できます。

書式化された dlarray オブジェクトをカスタム層で使用することで、次元の並べ替え、追加、削除を行う層など、入力と出力の書式が異なる層を定義することもできます。たとえば、書式が "SSCB" (spatial、spatial、channel、batch) であるイメージのミニバッチを入力として受け取り、書式が "CBT" (channel、batch、time) であるシーケンスのミニバッチを出力する層を定義できます。書式化された dlarray オブジェクトを使用すると、入力形式が異なるデータの処理が可能な層を定義することもできます。たとえば、書式 "SSCB" (spatial、spatial、channel、batch) と "CBT" (channel、batch、time) の入力をサポートする層を定義できます。

dlarray オブジェクトは、自動微分のサポートを有効にすることもできます。この場合、順方向関数が dlarray オブジェクトを完全にサポートしている場合、逆方向関数の定義はオプションです。

この例では、一般に敵対的生成ネットワーク (GAN) で使用される "投影および形状変更" 層を作成する方法を示します。この層は、ノイズから成り形式が "CB" (channel、batch) である配列を取り、全結合演算、形状変更演算、ラベル変更演算を使用して、イメージから成り形式が "SSCB" (spatial、spatial、channel、batch) であるミニバッチに投影して形状を変更します。

中間層テンプレート

中間層のテンプレートを 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 [Z,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:
            %         Z     - 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 Z with 
            %    Z1,...,ZM, 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 [Z,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:
            %         Z      - 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 Z with 
            %    Z1,...,ZM, 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,Z,dLdZ,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 
            %         Z       - Layer output data 
            %         dLdZ    - 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 Z and dlZ with
            %    Z1,...,ZM and dLdZ,...,dLdZM, 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

層の命名とスーパークラスの指定

まず、層に名前を付けます。クラス ファイルの最初の行で、既存の名前 myLayerprojectAndReshapeLayer に置き換えます。

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

逆方向関数を指定しない場合、既定では、層関数は "書式化されていない" dlarray オブジェクトを入力として受け取ります。層が、"書式化された" dlarray オブジェクトを入力として受け取り、さらに書式化された dlarray オブジェクトを出力するように指定するには、カスタム層の定義時に nnet.layer.Formattable クラスから継承します。

投影および形状変更層が入力データとは異なる次元でデータを出力するため (つまり、空間次元が追加されたデータを出力するため)、この層は nnet.layer.Formattable からも継承しなければなりません。これにより、この層が書式化された dlarray オブジェクトを受け取って出力できるようになります。

次に、スーパークラス nnet.layer.Layer および nnet.layer.Formattable の両方から継承するように指定します。この層の関数は高速化もサポートするため、nnet.layer.Acceleratable からも継承します。カスタム層の関数の高速化に関する詳細については、Custom Layer Function Accelerationを参照してください。

classdef projectAndReshapeLayer < nnet.layer.Layer ...
        & nnet.layer.Formattable ...
        & nnet.layer.Acceleratable
    ...
end

次に、コンストラクター関数 myLayer (methods セクションの最初の関数) の名前を層と同じ名前に変更します。

    methods
        function layer = projectAndReshapeLayer()           
            ...
        end

        ...
     end

層の保存

層のクラス ファイルを projectAndReshapeLayer.m という名前の新しいファイルに保存します。このファイル名は層の名前に一致しなければなりません。この層を使用するには、このファイルを現在のフォルダーまたは MATLAB パス上のフォルダーに保存しなければなりません。

プロパティおよび学習可能なパラメーターの宣言

層のプロパティを properties セクションで宣言し、学習可能なパラメーターを properties (Learnable) セクションにリストすることによって宣言します。

既定では、カスタム中間層に次のプロパティがあります。これらのプロパティを properties セクションで宣言しないでください。

Property説明
Name層の名前。文字ベクトルまたは string スカラーとして指定します。Layer 配列入力の場合、関数 trainnettrainNetworkassembleNetworklayerGraph、および dlnetwork は、名前が "" の層に自動的に名前を割り当てます。
Description

層についての 1 行の説明。string スカラーまたは文字ベクトルとして指定します。この説明は、層が Layer 配列に表示されるときに表示されます。

層の説明を指定しない場合、層のクラス名が表示されます。

Type

層のタイプ。文字ベクトルまたは string スカラーとして指定します。Type の値は、層が Layer 配列に表示されるときに表示されます。

層のタイプを指定しない場合、層のクラス名が表示されます。

NumInputs層の入力の数。正の整数として指定します。この値を指定しない場合、NumInputsInputNames の名前の数に自動的に設定されます。既定値は 1 です。
InputNames層の入力の名前。文字ベクトルの cell 配列として指定します。この値を指定せず、NumInputs が 1 より大きい場合、InputNames{'in1',...,'inN'} に自動的に設定されます。ここで、N = NumInputs です。既定値は {'in'} です。
NumOutputs層の出力の数。正の整数として指定します。この値を指定しない場合、NumOutputsOutputNames の名前の数に自動的に設定されます。既定値は 1 です。
OutputNames層の出力の名前。文字ベクトルの cell 配列として指定します。この値を指定せず、NumOutputs が 1 より大きい場合、OutputNames{'out1',...,'outM'} に自動的に設定されます。ここで、M = NumOutputs です。既定値は {'out'} です。

層にその他のプロパティがない場合は、properties セクションを省略できます。

ヒント

複数の入力がある層を作成する場合、層のコンストラクターで NumInputsInputNames のいずれかのプロパティを設定しなければなりません。複数の出力がある層を作成している場合、層のコンストラクターで NumOutputsOutputNames のいずれかのプロパティを設定しなければなりません。例については、複数の入力があるカスタム深層学習層の定義を参照してください。

投影および形状変更層には、層の出力サイズを保持する追加のプロパティが必要です。properties セクションで、OutputSize という名前のプロパティを 1 つ指定します。

    properties
        % Output size
        OutputSize
    end

投影および形状変更層は、2 つの学習可能なパラメーター (全結合演算の重みとバイアス) をもちます。これらの学習可能なパラメーターを properties (Learnable) セクションで宣言し、パラメーター Weights および Bias をそれぞれ呼び出します。

    properties (Learnable)
    % Layer learnable parameters
        Weights 
        Bias 
    end

コンストラクター関数の作成

層を構築する関数を作成し、層のプロパティを初期化します。層を作成するために必要な変数をコンストラクター関数への入力として指定します。

投影および形状変更層のコンストラクター関数には、層の出力サイズを指定する 1 つの入力引数と、層の名前を指定する 1 つのオプションの入力引数が必要です。

コンストラクター関数 projectAndReshapeLayer で、outputSize という名前の必須の入力引数を指定し、オプションの引数を NameValueArgs という名前をもつ名前と値の引数として指定します。関数の構文を説明するコメントを関数の上部に追加します。

        function layer = projectAndReshapeLayer(outputSize,NameValueArgs)
            % layer = projectAndReshapeLayer(outputSize) creates a
            % projectAndReshapeLayer object that projects and reshapes the
            % input to the specified output size.
            %
            % layer = projectAndReshapeLayer(outputSize,Name=name) also
            % specifies the layer name.
            
            ...
        end

入力引数の解析

arguments ブロックを使用して入力引数を解析します。関数構文と同じ順序で引数をリストし、既定値を指定します。その後、入力 NameValueArgs から値を抽出します。

            % Parse input arguments.
            arguments
                outputSize
                NameValueArgs.Name = ''
            end
            
            name = NameValueArgs.Name;

層のプロパティの初期化

コンストラクター関数で、層のプロパティを初期化します。コメント % Layer constructor function goes here を、層のプロパティを初期化するコードに置き換えます。学習可能なパラメーターまたは状態パラメーターは、コンストラクター関数で初期化せず、関数 initialize で初期化します。

Name プロパティを入力引数 name に設定します。

            % Set layer name.
            layer.Name = name;

層の Description プロパティを設定して、層に 1 行の説明を指定します。層のタイプとサイズの説明を設定します。

            % Set layer description.
            layer.Description = "Project and reshape layer with output size " + join(string(outputSize));

Type プロパティを設定して層のタイプを指定します。Type の値は、層が Layer 配列に表示されるときに表示されます。

            % Set layer type.
            layer.Type = "Project and Reshape";

層のプロパティ OutputSize を指定した入力値に設定します。

            % Set output size.
            layer.OutputSize = outputSize;

完成したコンストラクター関数を表示します。

        function layer = projectAndReshapeLayer(outputSize,NameValueArgs)
            % layer = projectAndReshapeLayer(outputSize)
            % creates a projectAndReshapeLayer object that projects and
            % reshapes the input to the specified output size.
            %
            % layer = projectAndReshapeLayer(outputSize,Name=name)
            % also specifies the layer name.
                                  
            % Parse input arguments.
            arguments
                outputSize
                NameValueArgs.Name = '';
            end
            
            name = NameValueArgs.Name;
            
            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "Project and reshape layer with output size " + join(string(outputSize));
            
            % Set layer type.
            layer.Type = "Project and Reshape";
            
            % Set output size.
            layer.OutputSize = outputSize;
        end

このコンストラクター関数を使用すると、コマンド projectAndReshapeLayer([4 4 512],Name="proj"); によって "proj" という名前の投影および形状変更層が作成されます。この層は、サイズが 4×4 である 512 個のイメージから成るバッチに入力配列を投影します。

初期化関数の作成

ネットワークの初期化時に層の学習可能なパラメーターと状態パラメーターを初期化する関数を作成します。この関数では、プロパティが空の場合、学習可能なパラメーターと状態パラメーターのみを初期化するようにしてください。それ以外の場合に初期化すると、MAT ファイルからネットワークを読み込んだときに、ソフトウェアによって上書きされる可能性があります。

学習可能なパラメーター Weights を初期化するには、Glorot の初期化を使用してランダム配列を生成します。学習可能なパラメーター Bias を初期化するには、入力データのチャネル数と同じ数のチャネルをもち、0 から成るベクトルを作成します。重みとバイアスが空である場合にのみ、それらを初期化してください。

ネットワークが使用できるようになるまで入力データのサイズは不明であるため、networkDataLayout オブジェクトを使用して学習可能なパラメーターと状態パラメーターを初期化する初期化関数を作成しなければなりません (このオブジェクトは関数に渡されます)。ネットワークのデータ レイアウト オブジェクトには、想定される入力データのサイズと形式に関する情報が格納されます。サイズと形式の情報を使用して学習可能なパラメーターと状態パラメーターを正しいサイズで初期化する初期化関数を作成します。

投影および形状変更層は、全結合演算を適用して入力をイメージのバッチに投影します。Glorot の初期化を使用して重みを初期化し、0 から成る配列を使用してバイアスを初期化します。関数 initializeGlorot および initializeZeros は、敵対的生成ネットワーク (GAN) の学習の例にサポート ファイルとして添付されています。これらの関数にアクセスするには、この例をライブ スクリプトとして開きます。深層学習演算用の学習可能なパラメーターの初期化に関する詳細については、モデル関数の学習可能パラメーターの初期化を参照してください。

        function layer = initialize(layer,layout)
            % layer = initialize(layer,layout) initializes the layer
            % learnable parameters using the specified input layout.   
    
            % Layer output size.
            outputSize = layer.OutputSize;

            % Initialize fully connect weights.
            if isempty(layer.Weights)
    
                % Find number of channels.
                idx = finddim(layout,"C");
                numChannels = layout.Size(idx);
    
                % Initialize using Glorot.
                sz = [prod(outputSize) numChannels];
                numOut = prod(outputSize);
                numIn = numChannels;
                layer.Weights = initializeGlorot(sz,numOut,numIn);
            end
    
            % Initialize fully connect bias.
            if isempty(layer.Bias)
    
                % Initialize with zeros.
                layer.Bias = initializeZeros([prod(outputSize) 1]);
            end
        end

順方向関数の作成

予測時と学習時に使用する層の順方向関数を作成します。

"予測時" に層経由でデータを順伝播させて結果を出力する、predict という名前の関数を作成します。

関数 predict の構文は、層のタイプによって異なります。

  • Z = predict(layer,X) は、層を介して入力データ X を転送し、結果 Z を出力します。この場合、layer は、1 つの入力と 1 つの出力をもちます。

  • [Z,state] = predict(layer,X) は、更新された状態パラメーター state も出力します。この場合、layer は 1 つの状態パラメーターをもちます。

複数の入力、複数の出力、または複数の状態パラメーターを使用して、層の構文を調整できます。

  • 複数の入力をもつ層の場合、XX1,...,XN に置き換えます。ここで、N は入力の数です。NumInputs プロパティは N と一致しなければなりません。

  • 複数の出力をもつ層の場合、ZZ1,...,ZM に置き換えます。ここで、M は出力の数です。NumOutputs プロパティは M と一致しなければなりません。

  • 複数の状態パラメーターをもつ層の場合、statestate1,...,stateK に置き換えます。ここで、K は状態パラメーターの数です。

ヒント

層への入力の数が変化する可能性がある場合、X1,…,XN ではなく varargin を使用します。この場合、varargin は入力の cell 配列です。ここで、varargin{i}Xi に対応します。

出力の数が変化する可能性がある場合、Z1,…,ZN ではなく varargout を使用します。この場合、varargout は出力の cell 配列です。ここで、varargout{j}Zj に対応します。

ヒント

学習可能なパラメーターの dlnetwork オブジェクトがカスタム層にある場合、カスタム層の関数 predict 内で、dlnetwork の関数 predict を使用します。これを行うと、dlnetwork オブジェクトの関数 predict は適切な層処理を使用して予測を行います。dlnetwork に状態パラメーターがある場合、ネットワークの状態も返します。

投影および形状変更層の入力および出力はそれぞれ 1 つのみであるため、投影および形状変更層の predict の構文は Z = 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"

シーケンスを出力する層の場合、その層は、任意の長さのシーケンス、または時間次元をもたないデータを出力できます。関数 trainNetwork を使用して、シーケンスを出力するネットワークに学習させる場合は、入力シーケンスと出力シーケンスの長さが一致していなければならない点に注意してください。

このカスタム層は nnet.layer.Formattable クラスから継承しているため、この層は、前の層の出力に対応するラベルをもつ書式化された dlarray オブジェクトを受け取ります。

関数 forward"学習時" に層経由でデータを順伝播させ、メモリ値も出力します。

関数 forward の構文は、層のタイプによって異なります。

  • Z = forward(layer,X) は、層を介して入力データ X を転送し、結果 Z を出力します。この場合、layer は、1 つの入力と 1 つの出力をもちます。

  • [Z,state] = forward(layer,X) は、更新された状態パラメーター state も出力します。この場合、layer は 1 つの状態パラメーターをもちます。

  • [__,memory] = forward(layer,X) は、前述の構文のいずれかを使用して、カスタム関数 backward のメモリ値も返します。カスタム関数 forward とカスタム関数 backward の両方が層に存在する場合、順方向関数によってメモリ値が返されなければなりません。

複数の入力、複数の出力、または複数の状態パラメーターを使用して、層の構文を調整できます。

  • 複数の入力をもつ層の場合、XX1,...,XN に置き換えます。ここで、N は入力の数です。NumInputs プロパティは N と一致しなければなりません。

  • 複数の出力をもつ層の場合、ZZ1,...,ZM に置き換えます。ここで、M は出力の数です。NumOutputs プロパティは M と一致しなければなりません。

  • 複数の状態パラメーターをもつ層の場合、statestate1,...,stateK に置き換えます。ここで、K は状態パラメーターの数です。

ヒント

層への入力の数が変化する可能性がある場合、X1,…,XN ではなく varargin を使用します。この場合、varargin は入力の cell 配列です。ここで、varargin{i}Xi に対応します。

出力の数が変化する可能性がある場合、Z1,…,ZN ではなく varargout を使用します。この場合、varargout は出力の cell 配列です。ここで、varargout{j}Zj に対応します。

ヒント

学習可能なパラメーターの dlnetwork オブジェクトがカスタム層にある場合、カスタム層の関数 forward 内で、dlnetwork オブジェクトの関数 forward を使用します。これを行うと、dlnetwork オブジェクトの関数 forward は適切な層処理を使用して学習を行います。

投影および形状変更演算は、3 つの演算で構成されます。

  • 学習可能な重みとバイアスに全結合演算を適用する。

  • 指定された出力サイズに出力を形状変更する。

  • 出力の形式が 'SSCB' (spatial、spatial、channel、batch) となるように、次元のラベルを変更する

この演算を関数 predict に実装します。投影および形状変更層では、学習にメモリまたは別の順方向関数が必要ないため、クラス ファイルから関数 forward を削除できます。関数の構文を説明するコメントを関数の上部に追加します。

        function Z = predict(layer, X)
            % Forward input data through the layer at prediction time and
            % output the result.
            % 
            % Inputs:
            %         layer - Layer to forward propagate through
            %         X     - Input data, specified as a formatted dlarray
            %                 with a 'C' and optionally a 'B' dimension.
            % Outputs:
            %         Z     - Output of layer forward function returned as 
            %                 a formatted dlarray with format 'SSCB'.

            % Fully connect.
            weights = layer.Weights;
            bias = layer.Bias;
            X = fullyconnect(X,weights,bias);
            
            % Reshape.
            outputSize = layer.OutputSize;
            Z = reshape(X, outputSize(1), outputSize(2), outputSize(3), []);
            
            % Relabel.
            Z = dlarray(Z,'SSCB');
        end

ヒント

zeros のような関数を使用して配列を事前に割り当てる場合、これらの配列のデータ型が層関数の入力と一致していることを確認しなければなりません。別の配列と同じデータ型のゼロの配列を作成するには、zeros"like" オプションを使用します。たとえば、配列 X と同じデータ型でサイズが sz のゼロの配列を初期化するには、Z = zeros(sz,"like",X) を使用します。

関数 predictdlarray オブジェクトをサポートする関数のみを使用するため、関数 backward の定義はオプションです。dlarray オブジェクトをサポートしている関数の一覧については、dlarray をサポートする関数の一覧を参照してください。

完成した層

完成した層のクラス ファイルを表示します。

classdef projectAndReshapeLayer < nnet.layer.Layer ... 
        & nnet.layer.Formattable ...
        & nnet.layer.Acceleratable
    % Example project and reshape layer.

    properties
        % Output size
        OutputSize
    end

    properties (Learnable)
    % Layer learnable parameters
        Weights 
        Bias 
    end
    
    methods
        function layer = projectAndReshapeLayer(outputSize,NameValueArgs)
            % layer = projectAndReshapeLayer(outputSize)
            % creates a projectAndReshapeLayer object that projects and
            % reshapes the input to the specified output size.
            %
            % layer = projectAndReshapeLayer(outputSize,Name=name)
            % also specifies the layer name.
                                  
            % Parse input arguments.
            arguments
                outputSize
                NameValueArgs.Name = '';
            end
            
            name = NameValueArgs.Name;
            
            % Set layer name.
            layer.Name = name;

            % Set layer description.
            layer.Description = "Project and reshape layer with output size " + join(string(outputSize));
            
            % Set layer type.
            layer.Type = "Project and Reshape";
            
            % Set output size.
            layer.OutputSize = outputSize;
        end

        function layer = initialize(layer,layout)
            % layer = initialize(layer,layout) initializes the layer
            % learnable parameters using the specified input layout.   
    
            % Layer output size.
            outputSize = layer.OutputSize;

            % Initialize fully connect weights.
            if isempty(layer.Weights)
    
                % Find number of channels.
                idx = finddim(layout,"C");
                numChannels = layout.Size(idx);
    
                % Initialize using Glorot.
                sz = [prod(outputSize) numChannels];
                numOut = prod(outputSize);
                numIn = numChannels;
                layer.Weights = initializeGlorot(sz,numOut,numIn);
            end
    
            % Initialize fully connect bias.
            if isempty(layer.Bias)
    
                % Initialize with zeros.
                layer.Bias = initializeZeros([prod(outputSize) 1]);
            end
        end

        function Z = predict(layer, X)
            % Forward input data through the layer at prediction time and
            % output the result.
            % 
            % Inputs:
            %         layer - Layer to forward propagate through
            %         X     - Input data, specified as a formatted dlarray
            %                 with a 'C' and optionally a 'B' dimension.
            % Outputs:
            %         Z     - Output of layer forward function returned as 
            %                 a formatted dlarray with format 'SSCB'.

            % Fully connect.
            weights = layer.Weights;
            bias = layer.Bias;
            X = fullyconnect(X,weights,bias);
            
            % Reshape.
            outputSize = layer.OutputSize;
            Z = reshape(X, outputSize(1), outputSize(2), outputSize(3), []);
            
            % Relabel.
            Z = dlarray(Z,'SSCB');
        end
    end
end

GPU 互換性

層の順方向関数が dlarray オブジェクトを完全にサポートしている場合、層は GPU 互換です。そうでない場合、GPU 互換にするには、層関数が入力をサポートし、gpuArray (Parallel Computing Toolbox) 型の出力を返さなければなりません。

多くの MATLAB 組み込み関数が入力引数 gpuArray (Parallel Computing Toolbox) および dlarray をサポートしています。dlarray オブジェクトをサポートしている関数の一覧については、dlarray をサポートする関数の一覧を参照してください。GPU で実行される関数の一覧については、GPU での MATLAB 関数の実行 (Parallel Computing Toolbox)を参照してください。深層学習に GPU を使用するには、サポートされている GPU デバイスもなければなりません。サポートされているデバイスについては、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。MATLAB での GPU の使用の詳細は、MATLAB での GPU 計算 (Parallel Computing Toolbox)を参照してください。

この例では、predict で使用される MATLAB 関数はすべて、dlarray オブジェクトをサポートしているため、層は GPU 互換です。

ネットワークにカスタム層を含める

1×1×100 の乱数値の配列からイメージを生成する、GAN 用のジェネレーター ネットワーク アーキテクチャを以下のように定義します。

このネットワークは、次を行います。

  • "project and reshape" 層を使用して、サイズ 100 のランダム ベクトルを 7×7×128 の配列に変換。

  • 一連の転置畳み込み層と ReLU 層を使用して、結果の配列を 64×64×3 の配列にアップスケーリング。

このネットワーク アーキテクチャを層グラフとして定義し、次のネットワーク プロパティを指定します。

  • 転置畳み込み層では、各層のフィルター数を減らして 5 x 5 のフィルターを指定し、ストライドを 2 に指定し、各エッジでの出力のトリミングを指定します。

  • 最後の転置畳み込み層では、生成されたイメージの 3 つの RGB チャネルに対応する 3 つの 5 x 5 のフィルターと、前の層の出力サイズを設定。

  • ネットワークの最後に、tanh 層を追加。

ノイズ入力を投影して形状変更するには、カスタム層 projectAndReshapeLayer. を使用します。

filterSize = 5;
numFilters = 64;
numLatentInputs = 100;

projectionSize = [4 4 512];

layersG = [
    featureInputLayer(numLatentInputs,Normalization="none")
    projectAndReshapeLayer(projectionSize);
    transposedConv2dLayer(filterSize,4*numFilters)
    reluLayer
    transposedConv2dLayer(filterSize,2*numFilters,Stride=2,Cropping="same")
    reluLayer
    transposedConv2dLayer(filterSize,numFilters,Stride=2,Cropping="same")
    reluLayer
    transposedConv2dLayer(filterSize,3,Stride=2,Cropping="same")
    tanhLayer];

関数 analyzeNetwork を使用して、層の活性化のサイズと形式を確認します。カスタム学習ループ ワークフローのネットワークを解析するには、TargetUsage オプションを "dlnetwork" に設定します。

analyzeNetwork(layersG,TargetUsage="dlnetwork")

予想どおり、投影および形状変更層は、形式が "CB" (channel、batch) である入力データを取り、形式が "SSCB" (spatial、spatial、channel、batch) であるデータを出力します。

カスタム学習ループを使用してネットワークに学習させ、自動微分を有効にするには、層配列を dlnetwork オブジェクトに変換します。

netG = dlnetwork(layersG);

参考

| | | | | | | | | | |

関連するトピック