メインコンテンツ

importNetworkFromPyTorch

PyTorch ネットワークを MATLAB ネットワークとしてインポートする

R2022b 以降

    説明

    net = importNetworkFromPyTorch(modelfile) は、事前学習済みかつトレース済みの PyTorch® モデルを modelfile ファイルからインポートします。この関数は、初期化されていない dlnetwork オブジェクトとしてネットワーク net を返します。

    importNetworkFromPyTorch には、Deep Learning Toolbox™ Converter for PyTorch Models サポート パッケージが必要です。このサポート パッケージがインストールされていない場合、importNetworkFromPyTorch によってダウンロード用リンクが表示されます。

    メモ

    importNetworkFromPyTorch 関数は、PyTorch 層をインポートするときにカスタム層を生成できます。詳細については、アルゴリズムを参照してください。関数は、生成されたカスタム層を +modelfile 名前空間に保存します。

    net = importNetworkFromPyTorch(modelfile,Name=Value) は、1 つ以上の名前と値の引数で指定された追加オプションを使用して、事前学習済みかつトレース済みの PyTorch ネットワークをインポートします。たとえば、Namespace="CustomLayers" は、生成されたカスタム層と関連する関数を現在のフォルダーの +CustomLayers 名前空間に保存します。名前と値の引数 PyTorchInputSizes が指定されている場合、この関数は、初期化された dlnetwork としてネットワーク net を返すことがあります。

    PyTorch モデルをトレースする方法については、https://pytorch.org/docs/stable/generated/torch.jit.trace.htmlを参照してください。

    すべて折りたたむ

    事前学習済みかつトレース済みの PyTorch モデルを、初期化されていない dlnetwork オブジェクトとしてインポートします。次に、インポートしたネットワークに入力層を追加します。

    この例では、MNASNet (Copyright© Soumith Chintala 2016) PyTorch モデルをインポートします。MNASNet は、ImageNet データベースのイメージを使って学習させるイメージ分類モデルです。MathWorks の Web サイトから、mnasnet1_0 ファイルをダウンロードします。ファイルのサイズは約 17 MB です。

    modelfile = matlab.internal.examples.downloadSupportFile("nnet", ...
        "data/PyTorchModels/mnasnet1_0.pt");

    importNetworkFromPyTorch 関数を使用して MNASNet モデルをインポートします。この関数は、入力層がなく初期化されていない dlnetwork オブジェクトとしてモデルをインポートします。ソフトウェアは、入力層の数、追加する入力層のタイプ、および入力層の追加方法に関する情報を含む警告を表示します。

    net = importNetworkFromPyTorch(modelfile)
    Warning: Network was imported as an uninitialized dlnetwork. Before using the network, add input layer(s):
    
    % Create imageInputLayer for the network input at index 1:
    inputLayer1 = imageInputLayer(<inputSize1>, Normalization="none");
    
    % Add input layers to the network and initialize:
    net = addInputLayer(net, inputLayer1, Initialize=true);
    
    
    
    net = 
      dlnetwork with properties:
    
             Layers: [3×1 nnet.cnn.layer.Layer]
        Connections: [2×2 table]
         Learnables: [210×3 table]
              State: [104×3 table]
         InputNames: {'TopLevelModule:layers'}
        OutputNames: {'TopLevelModule:classifier'}
        Initialized: 0
    
      View summary with summary.
    
    

    インポートしたネットワークの入力サイズを指定して、イメージ入力層を作成します。次に、インポートしたネットワークにイメージ入力層を追加し、addInputLayer関数を使用してネットワークを初期化します。

    InputSize = [224 224 3];
    inputLayer = imageInputLayer(InputSize,Normalization="none");
    net = addInputLayer(net,inputLayer,Initialize=true);

    インポートしたネットワークを解析し、入力層を表示します。ネットワークは予測に使用する準備ができています。

    analyzeNetwork(net)

    pytorchexample1.png

    名前と値の引数 PyTorchInputSizes を使用して、事前学習済みかつトレース済みの PyTorch モデルを初期化された dlnetwork オブジェクトとしてインポートします。

    この例では、MNASNet (Copyright© Soumith Chintala 2016) PyTorch モデルをインポートします。MNASNet は、ImageNet データベースのイメージを使って学習させるイメージ分類モデルです。MathWorks の Web サイトから、mnasnet1_0.pt ファイルをダウンロードします。ファイルのサイズは約 17 MB です。

    modelfile = matlab.internal.examples.downloadSupportFile("nnet", ...
        "data/PyTorchModels/mnasnet1_0.pt");

    名前と値の引数 PyTorchInputSizes が指定された importNetworkFromPyTorch 関数を使用して、MNASNet モデルをインポートします。224x224 のカラー イメージがこの PyTorch モデルの有効な入力サイズであることがわかっています。ソフトウェアは、イメージのバッチに対して入力層を自動的に作成して追加します。これにより、1 行のコードでネットワークを初期化されたネットワークとしてインポートすることができます。

    net = importNetworkFromPyTorch(modelfile,PyTorchInputSizes=[NaN,3,224,224])
    net = 
      dlnetwork with properties:
    
             Layers: [4×1 nnet.cnn.layer.Layer]
        Connections: [3×2 table]
         Learnables: [210×3 table]
              State: [104×3 table]
         InputNames: {'InputLayer1'}
        OutputNames: {'TopLevelModule:classifier'}
        Initialized: 1
    
      View summary with summary.
    
    

    ネットワークは予測に使用する準備ができています。

    事前学習済みかつトレース済みの PyTorch モデルを、初期化されていない dlnetwork オブジェクトとしてインポートします。次に、インポートしたネットワークを初期化します。

    この例では、MNASNet (Copyright© Soumith Chintala 2016) PyTorch モデルをインポートします。MNASNet は、ImageNet データベースのイメージを使って学習させるイメージ分類モデルです。MathWorks の Web サイトから、mnasnet1_0 ファイルをダウンロードします。ファイルのサイズは約 17 MB です。

    modelfile = matlab.internal.examples.downloadSupportFile("nnet", ...
        "data/PyTorchModels/mnasnet1_0.pt");

    importNetworkFromPyTorch 関数を使用して MNASNet モデルをインポートします。この関数は、初期化されていない dlnetwork オブジェクトとしてモデルをインポートします。

    net = importNetworkFromPyTorch(modelfile)
    Warning: Network was imported as an uninitialized dlnetwork. Before using the network, add input layer(s):
    
    % Create imageInputLayer for the network input at index 1:
    inputLayer1 = imageInputLayer(<inputSize1>, Normalization="none");
    
    % Add input layers to the network and initialize:
    net = addInputLayer(net, inputLayer1, Initialize=true);
    
    
    
    net = 
      dlnetwork with properties:
    
             Layers: [3×1 nnet.cnn.layer.Layer]
        Connections: [2×2 table]
         Learnables: [210×3 table]
              State: [104×3 table]
         InputNames: {'TopLevelModule:layers'}
        OutputNames: {'TopLevelModule:classifier'}
        Initialized: 0
    
      View summary with summary.
    
    

    net は、ネストされたネットワークを含む単一のnetworkLayer層で構成される dlnetwork オブジェクトです。net の入力サイズを指定し、ネットワークへの入力を表すランダムな dlarray オブジェクトを作成します。dlarray オブジェクトのデータ形式は、2 次元イメージ入力を表す "SSCB" (空間、空間、チャネル、バッチ) の次元をもたなければなりません。詳細については、dlnetwork での予測のためのデータ形式を参照してください。

    InputSize = [224 224 3];
    X = dlarray(rand(InputSize),"SSCB");

    initialize関数を使用して、インポートしたネットワークの学習可能なパラメーターを初期化します。

    net = initialize(net,X);

    これで、インポートしたネットワークを予測に使用する準備が整いました。expandLayers関数を使用して networkLayer を展開し、インポートしたネットワークを解析します。

    netExpanded = expandLayers(net)
    netExpanded = 
      dlnetwork with properties:
    
             Layers: [152×1 nnet.cnn.layer.Layer]
        Connections: [161×2 table]
         Learnables: [210×3 table]
              State: [104×3 table]
         InputNames: {'TopLevelModule:layers:0'}
        OutputNames: {'TopLevelModule:classifier:1:ATEN12'}
        Initialized: 1
    
      View summary with summary.
    
    
    analyzeNetwork(netExpanded)

    pytorchexample3.png

    事前学習済みかつトレース済みの PyTorch モデルを、初期化されていない dlnetwork オブジェクトとしてインポートし、イメージを分類します。

    この例では、MNASNet (Copyright© Soumith Chintala 2016) PyTorch モデルをインポートします。MNASNet は、ImageNet データベースのイメージを使って学習させるイメージ分類モデルです。MathWorks の Web サイトから、mnasnet1_0 ファイルをダウンロードします。ファイルのサイズは約 17 MB です。

    modelfile = matlab.internal.examples.downloadSupportFile("nnet", ...
        "data/PyTorchModels/mnasnet1_0.pt");

    importNetworkFromPyTorch 関数を使用して MNASNet モデルをインポートします。この関数は、初期化されていない dlnetwork オブジェクトとしてモデルをインポートします。

    net = importNetworkFromPyTorch(modelfile)
    Warning: Network was imported as an uninitialized dlnetwork. Before using the network, add input layer(s):
    
    % Create imageInputLayer for the network input at index 1:
    inputLayer1 = imageInputLayer(<inputSize1>, Normalization="none");
    
    % Add input layers to the network and initialize:
    net = addInputLayer(net, inputLayer1, Initialize=true);
    
    
    
    net = 
      dlnetwork with properties:
    
             Layers: [3×1 nnet.cnn.layer.Layer]
        Connections: [2×2 table]
         Learnables: [210×3 table]
              State: [104×3 table]
         InputNames: {'TopLevelModule:layers'}
        OutputNames: {'TopLevelModule:classifier'}
        Initialized: 0
    
      View summary with summary.
    
    

    インポートしたネットワークの入力サイズを指定して、イメージ入力層を作成します。次に、インポートしたネットワークにイメージ入力層を追加し、addInputLayer 関数を使用してネットワークを初期化します。

    InputSize = [224 224 3];
    inputLayer = imageInputLayer(InputSize,Normalization="none");
    net = addInputLayer(net,inputLayer,Initialize=true);

    分類するイメージを読み取ります。

    Im = imread("peppers.png");

    イメージのサイズをネットワークの入力サイズに変更します。イメージを表示します。

    InputSize = [224 224 3];
    Im = imresize(Im,InputSize(1:2));
    imshow(Im)

    MNASNet への入力には、さらなる前処理が必要です。イメージを再スケーリングします。次に、学習イメージの平均を減算し、学習イメージの標準偏差で除算して、イメージを正規化します。詳細については、入力データの前処理を参照してください。

    Im = rescale(Im,0,1);
    
    meanIm = [0.485 0.456 0.406];
    stdIm = [0.229 0.224 0.225];
    Im = (Im - reshape(meanIm,[1 1 3]))./reshape(stdIm,[1 1 3]);

    イメージをdlarrayオブジェクトに変換します。"SSCB" (空間、空間、チャネル、バッチ) の次元でイメージの形式を整えます。

    Im_dlarray = dlarray(single(Im),"SSCB");

    同じく ImageNet のイメージで学習させた squeezenet から、クラス名を取得します。

    [~,ClassNames] = imagePretrainedNetwork("squeezenet");

    イメージを分類し、予測されたラベルを見つけます。

    prob = predict(net,Im_dlarray);
    [~,label_ind] = max(prob);

    分類結果を表示します。

    ClassNames(label_ind)
    ans = 
    "bell pepper"
    

    事前学習済みかつトレース済みの PyTorch モデルを、初期化されていない dlnetwork オブジェクトとしてインポートします。次に、ソフトウェアによって生成されたカスタム層を見つけます。

    この例では、findCustomLayers 補助関数を使用します。

    この例では、MNASNet (Copyright© Soumith Chintala 2016) PyTorch モデルをインポートします。MNASNet は、ImageNet データベースのイメージを使って学習させるイメージ分類モデルです。MathWorks の Web サイトから、mnasnet1_0 ファイルをダウンロードします。ファイルのサイズは約 17 MB です。

    modelfile = matlab.internal.examples.downloadSupportFile("nnet", ...
        "data/PyTorchModels/mnasnet1_0.pt");

    importNetworkFromPyTorch 関数を使用して MNASNet モデルをインポートします。この関数は、初期化されていない dlnetwork オブジェクトとしてモデルをインポートします。

    net = importNetworkFromPyTorch(modelfile)
    Warning: Network was imported as an uninitialized dlnetwork. Before using the network, add input layer(s):
    
    % Create imageInputLayer for the network input at index 1:
    inputLayer1 = imageInputLayer(<inputSize1>, Normalization="none");
    
    % Add input layers to the network and initialize:
    net = addInputLayer(net, inputLayer1, Initialize=true);
    
    
    
    net = 
      dlnetwork with properties:
    
             Layers: [3×1 nnet.cnn.layer.Layer]
        Connections: [2×2 table]
         Learnables: [210×3 table]
              State: [104×3 table]
         InputNames: {'TopLevelModule:layers'}
        OutputNames: {'TopLevelModule:classifier'}
        Initialized: 0
    
      View summary with summary.
    
    

    net は、ネストされたネットワークを含む単一のnetworkLayer層で構成される dlnetwork オブジェクトです。expandLayers関数を使用して、ネストされたネットワーク層を展開します。

    net = expandLayers(net);

    importNetworkFromPyTorch 関数は、MATLAB の組み込みの層または関数に変換できない PyTorch 層のカスタム層を生成します。詳細については、アルゴリズムを参照してください。ソフトウェアは、自動的に生成されたカスタム層を現在のフォルダーの +mnasnet1_0 名前空間に保存し、関連する関数を +ops 内部名前空間に保存します。カスタム層と関連する関数を確認するには、名前空間を調べます。

    pytorchexample2.png

    findCustomLayers 補助関数を使用して、生成されたカスタム層のインデックスを見つけることもできます。カスタム層を表示します。

    ind = findCustomLayers(net.Layers,'+mnasnet1_0')
    ind = 1×2
    
       150   152
    
    
    net.Layers(ind)
    ans = 
      2×1 Layer array with layers:
    
         1   'TopLevelModule:ATEN14'                Custom Layer   mnasnet1_0.TopLevelModule_ATEN14
         2   'TopLevelModule:classifier:1:ATEN12'   Custom Layer   mnasnet1_0.TopLevelModule_classifier_1_ATEN12
    

    補助関数

    findCustomLayers 補助関数は、importNetworkFromPyTorch によって自動的に生成されるカスタム層の indices に対応する logical ベクトルを返します。

    function indices = findCustomLayers(layers,Namespace)
    
    s = what(['.' filesep Namespace]);
    
    indices = zeros(1,length(s.m));
    for i = 1:length(layers)
        for j = 1:length(s.m)
            if strcmpi(class(layers(i)),[Namespace(2:end) '.' s.m{j}(1:end-2)])
                indices(j) = i;
            end
        end
    end
    
    end

    この例では、PyTorch からネットワークをインポートし、新しいイメージを分類するようにネットワークに学習させる方法を説明します。importNetworkFromPytorch 関数を使用し、初期化されていない dlnetwork オブジェクトとしてネットワークをインポートします。カスタム学習ループを使用してネットワークに学習させます。

    この例では、modelLoss 補助関数、modelPredictions 補助関数、および preprocessMiniBatchPredictors 補助関数を使用します。

    この例では、サポート ファイル new_fcLayer も使用します。サポート ファイルにアクセスするには、ライブ エディターで例を開きます。

    データの読み込み

    75 枚のイメージが含まれている MerchData データ セットを解凍します。新しいイメージをイメージ データストアとして読み込みます。関数 imageDatastore は、フォルダー名に基づいてイメージに自動的にラベルを付け、このデータを ImageDatastore オブジェクトとして格納します。データを学習データ セットと検証データ セットに分割します。イメージの 70% を学習に使用し、30% を検証に使用します。

    unzip("MerchData.zip");
    imds = imageDatastore("MerchData", ...
        IncludeSubfolders=true, ...
        LabelSource="foldernames"); 
    [imdsTrain,imdsValidation] = splitEachLabel(imds,0.7);

    この例で使用されるネットワークには、サイズが 224×224×3 の入力イメージが必要です。学習イメージのサイズを自動的に変更するには、拡張イメージ データストアを使用します。イメージを水平軸方向と垂直軸方向に最大 30 ピクセルだけランダムに平行移動します。データ拡張は、ネットワークで過適合が発生したり、学習イメージの正確な詳細が記憶されたりすることを防止するのに役立ちます。

    inputSize = [224 224 3];
    
    pixelRange = [-30 30];
    scaleRange = [0.9 1.1];
    imageAugmenter = imageDataAugmenter(...
        RandXReflection=true, ...
        RandXTranslation=pixelRange, ...
        RandYTranslation=pixelRange, ...
        RandXScale=scaleRange, ...
        RandYScale=scaleRange);
    augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
        DataAugmentation=imageAugmenter);

    他のデータ拡張を実行せずに検証イメージのサイズを自動的に変更するには、追加の前処理演算を指定せずに拡張イメージ データストアを使用します。

    augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

    学習データ内のクラスの数を決定します。

    classes = categories(imdsTrain.Labels);
    numClasses = numel(classes);

    ネットワークのインポート

    MNASNet (Copyright© Soumith Chintala 2016) PyTorch モデルをダウンロードします。MNASNet は、ImageNet データベースのイメージを使って学習させるイメージ分類モデルです。MathWorks の Web サイトから、mnasnet1_0 ファイルをダウンロードします。ファイルのサイズは約 17 MB です。

    modelfile = matlab.internal.examples.downloadSupportFile("nnet", ...
        "data/PyTorchModels/mnasnet1_0.pt");

    importNetworkFromPyTorch 関数を使用して、初期化されていない dlnetwork オブジェクトとして MNASNet モデルをインポートします。

    net = importNetworkFromPyTorch(modelfile)
    Warning: Network was imported as an uninitialized dlnetwork. Before using the network, add input layer(s):
    
    % Create imageInputLayer for the network input at index 1:
    inputLayer1 = imageInputLayer(<inputSize1>, Normalization="none");
    
    % Add input layers to the network and initialize:
    net = addInputLayer(net, inputLayer1, Initialize=true);
    
    
    
    net = 
      dlnetwork with properties:
    
             Layers: [3×1 nnet.cnn.layer.Layer]
        Connections: [2×2 table]
         Learnables: [210×3 table]
              State: [104×3 table]
         InputNames: {'TopLevelModule:layers'}
        OutputNames: {'TopLevelModule:classifier'}
        Initialized: 0
    
      View summary with summary.
    
    

    net は、ネストされたネットワークを含む単一のnetworkLayer層で構成される dlnetwork オブジェクトです。expandLayers関数を使用して networkLayer を展開します。analyzeNetwork関数を使用して、インポートしたネットワークの最後の層を表示します。

    net = expandLayers(net);
    analyzeNetwork(net)

    2024-11-25_17-52-34.png

    TopLevelModule:classifier:1:ATEN12 層は、importNetworkFromPyTorch 関数によって生成されたカスタム層であり、インポートしたネットワークの最後の学習可能な層です。この層には、特徴を組み合わせる方法に関する情報が含まれており、ネットワークはそれを抽出してクラスの確率および損失値を生成します。

    最後の層の置き換え

    インポートしたネットワークに再学習させて新しいイメージを分類させるには、最後の層を新しい全結合層に置き換えます。新しい層 new_fclayer を新しいデータ セットに適応させます。2 つの入力があるため、この層はカスタム層でなければなりません。

    new_fcLayer 層を初期化し、TopLevelModule:classifier:1:ATEN12 層を new_fcLayer に置き換えます。

    newLayer = new_fcLayer("TopLevelModule:classifier:fc1","Custom Layer", ...
        {'in'},{'out'},numClasses);
    net = replaceLayer(net,"TopLevelModule:classifier:1:ATEN12",newLayer);

    ネットワークにソフトマックス層を追加し、そのソフトマックス層を新しい全結合層に接続します。

    net = addLayers(net,softmaxLayer(Name="sm1"));
    net = connectLayers(net,"TopLevelModule:classifier:fc1","sm1");
    net.OutputNames = "sm1";

    入力層の追加

    ネットワークにイメージ入力層を追加し、ネットワークを初期化します。

    inputLayer = imageInputLayer(inputSize,Normalization="none");
    net = addInputLayer(net,inputLayer,Initialize=true);

    ネットワークを解析します。最初の層と最後の層を表示します。

    analyzeNetwork(net)

    2024-11-25_18-03-08.png

    2024-11-25_18-00-52.png

    モデル損失関数の定義

    深層ニューラル ネットワークの学習は最適化タスクです。ニューラル ネットワークを関数 f(X;θ) として扱うことで (ここで、X はネットワーク入力、θ は学習可能なパラメーターのセット)、θ を最適化して学習データに基づく損失値を最小化できます。たとえば、入力 X と対応するターゲット T に対して、予測 Y=f(X;θ)T の間の誤差が最小になるように、学習可能なパラメーター θ を最適化します。

    この例のモデル損失関数のセクションにリストされている modelLoss 関数を作成します。この関数は、dlnetwork オブジェクト、入力データのミニバッチ、および対応するターゲットを入力として受け取ります。この関数は、損失、学習可能なパラメーターに対するその損失の勾配、およびネットワークの状態を返します。

    学習オプションの指定

    ミニバッチ サイズを 20 として 15 エポック学習させます。

    numEpochs = 15;
    miniBatchSize = 20;

    SGDM 最適化のオプションを指定します。初期学習率を 0.001、減衰を 0.005、モーメンタムを 0.9 に指定します。

    initialLearnRate = 0.001;
    decay = 0.005;
    momentum = 0.9;

    ネットワークの学習

    学習中にイメージのミニバッチを処理および管理するminibatchqueueオブジェクトを作成します。各ミニバッチに対して次の手順を実行します。

    1. カスタム ミニバッチ前処理関数 preprocessMiniBatch (この例の最後に定義) を使用して、ラベルを one-hot 符号化変数に変換します。

    2. イメージ データを次元ラベル "SSCB" (spatial、spatial、channel、batch) で形式を整えます。既定では、minibatchqueue オブジェクトは、基となる型が single である dlarray オブジェクトにデータを変換します。クラス ラベルの形式は整えません。

    3. GPU が利用できる場合、GPU で学習を行います。既定では、minibatchqueue オブジェクトは、GPU が利用可能な場合、各出力を gpuArray オブジェクトに変換します。GPU を使用するには、Parallel Computing Toolbox™ ライセンスとサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。

    mbq = minibatchqueue(augimdsTrain,...
        MiniBatchSize=miniBatchSize,...
        MiniBatchFcn=@preprocessMiniBatch,...
        MiniBatchFormat=["SSCB" ""]);

    モーメンタム項付き勾配降下法 (SGDM) ソルバーの速度パラメーターを初期化します。

    velocity = [];

    学習の進行状況モニター用に合計反復回数を計算します。

    numObservationsTrain = numel(imdsTrain.Files);
    numIterationsPerEpoch = ceil(numObservationsTrain/miniBatchSize);
    numIterations = numEpochs*numIterationsPerEpoch;

    trainingProgressMonitorオブジェクトを初期化します。監視オブジェクトを作成するとタイマーが開始されるため、学習ループの直後でオブジェクトを作成します。

    monitor = trainingProgressMonitor(Metrics="Loss",Info=["Epoch","LearnRate"],XLabel="Iteration");

    カスタム学習ループを使用してネットワークに学習させます。各エポックについて、データをシャッフルしてデータのミニバッチをループで回します。各ミニバッチに対して次の手順を実行します。

    1. dlfeval関数と modelLoss 関数を使用してモデルの損失、勾配、および状態を評価し、ネットワークの状態を更新します。

    2. 時間ベースの減衰学習率スケジュールの学習率を決定します。

    3. sgdmupdate関数を使用してネットワーク パラメーターを更新します。

    4. 学習の進行状況モニターで、損失、学習率、およびエポックの値を更新します。

    5. Stop プロパティが true である場合は停止します。[停止] ボタンをクリックしたときに TrainingProgressMonitor オブジェクトの Stop プロパティ値が true に変更します。

    epoch = 0;
    iteration = 0;
    
    % Loop over epochs.
    while epoch < numEpochs && ~monitor.Stop
        
        epoch = epoch + 1;
    
        % Shuffle data.
        shuffle(mbq);
        
        % Loop over mini-batches.
        while hasdata(mbq) && ~monitor.Stop
    
            iteration = iteration + 1;
            
            % Read mini-batch of data.
            [X,T] = next(mbq);
            
            % Evaluate the model gradients, state, and loss using dlfeval and the
            % modelLoss function and update the network state.
            [loss,gradients,state] = dlfeval(@modelLoss,net,X,T);
            net.State = state;
            
            % Determine learning rate for time-based decay learning rate schedule.
            learnRate = initialLearnRate/(1 + decay*iteration);
            
            % Update the network parameters using the SGDM optimizer.
            [net,velocity] = sgdmupdate(net,gradients,velocity,learnRate,momentum);
            
            % Update the training progress monitor.
            recordMetrics(monitor,iteration,Loss=loss);
            updateInfo(monitor,Epoch=epoch,LearnRate=learnRate);
            monitor.Progress = 100*iteration/numIterations;
        end
    end

    検証イメージの分類

    真のラベルをもつ検証セットで予測を比較し、モデルの分類精度をテストします。

    学習後、新しいデータで予測を行う際にラベルは必要ありません。テスト データの予測子のみを含む minibatchqueue オブジェクトを作成します。

    • テスト用のラベルを無視するには、ミニバッチ キューの出力数を 1 に設定します。

    • 学習に使用するのと同じミニバッチ サイズを指定します。

    • 例の最後にリストされている preprocessMiniBatchPredictors 関数を使用し、予測子の前処理を行います。

    • データストアの単一出力の場合は、ミニバッチの形式 "SSCB" (空間、空間、チャネル、バッチ) を指定します。

    numOutputs = 1;
    
    mbqTest = minibatchqueue(augimdsValidation,numOutputs, ...
        MiniBatchSize=miniBatchSize, ...
        MiniBatchFcn=@preprocessMiniBatchPredictors, ...
        MiniBatchFormat="SSCB");

    ミニバッチをループ処理し、例の最後にリストされている modelPredictions 関数を使用してイメージを分類します。

    YTest = modelPredictions(net,mbqTest,classes);

    分類精度を評価します。

    TTest = imdsValidation.Labels;
    accuracy = mean(TTest == YTest)

    混同チャートで予測を可視化します。対角線上の大きな値は、対応するクラスに対する正確な予測を示しています。対角線外の大きな値は、対応するクラス間での強い混同を示しています。

    figure
    confusionchart(TTest,YTest)

    補助関数

    モデル損失関数

    modelLoss 関数は、dlnetwork オブジェクト net、入力データ X のミニバッチ、および対応するターゲット T を入力として受け取ります。この関数は、net 内の損失、学習可能なパラメーターに関する損失の勾配、およびネットワークの状態を返します。勾配を自動的に計算するには、dlgradient関数を使用します。

    function [loss,gradients,state] = modelLoss(net,X,T)
    
    % Forward data through network.
    [Y,state] = forward(net,X);
    
    % Calculate cross-entropy loss.
    loss = crossentropy(Y,T);
    
    % Calculate gradients of loss with respect to learnable parameters.
    gradients = dlgradient(loss,net.Learnables);
    
    end

    モデル予測関数

    modelPredictions 関数は、dlnetwork オブジェクト net、入力データの minibatchqueue である mbq、およびネットワーク クラスを入力として受け取ります。この関数は、minibatchqueue オブジェクト内のすべてのデータを反復処理し、モデルの予測を計算します。この関数は、onehotdecode関数を使用して、スコアが最も高い予測されたクラスを見つけます。

    function Y = modelPredictions(net,mbq,classes)
    
    Y = [];
    
    % Loop over mini-batches.
    while hasdata(mbq)
        X = next(mbq);
    
        % Make prediction.
        scores = predict(net,X);
    
        % Decode labels and append to output.
        labels = onehotdecode(scores,classes,1)';
        Y = [Y; labels];
    end
    
    end

    ミニ バッチ前処理関数

    preprocessMiniBatch 関数は、次の手順を使用して予測子とラベルのミニバッチを前処理します。

    1. 関数 preprocessMiniBatchPredictors を使用してイメージを前処理します。

    2. 入力 cell 配列からラベル データを抽出し、その結果を 2 番目の次元に沿って categorical 配列に連結します。

    3. カテゴリカル ラベルを数値配列に one-hot 符号化します。最初の次元への符号化は、ネットワーク出力の形状と一致する符号化された配列を生成します。

    function [X,T] = preprocessMiniBatch(dataX,dataT)
    
    % Preprocess predictors.
    X = preprocessMiniBatchPredictors(dataX);
    
    % Extract label data from cell and concatenate.
    T = cat(2,dataT{1:end});
    
    % One-hot encode labels.
    T = onehotencode(T,1);
    
    end

    ミニバッチ予測子前処理関数

    preprocessMiniBatchPredictors 関数は、入力 cell 配列からイメージ データを抽出し、その結果を数値配列に連結することで、予測子のミニバッチを前処理します。グレースケール入力の場合、4 番目の次元で連結することにより、3 番目の次元が各イメージに追加されます。この次元は、大きさが 1 のチャネル次元として使用されます。

    function X = preprocessMiniBatchPredictors(dataX)
    
    % Concatenate.
    X = cat(4,dataX{1:end});
    
    end

    入力引数

    すべて折りたたむ

    PyTorch モデル ファイルの名前。文字ベクトルまたは string スカラーとして指定します。modelfile は現在のフォルダー内にあるか、ファイルへの絶対パスまたは相対パスが含まれていなければなりません。PyTorch モデルは、事前学習されていなければならず、なおかつ 1 回の推論反復にわたってトレースされていなければなりません。

    PyTorch モデルをトレースする方法については、https://pytorch.org/docs/stable/generated/torch.jit.trace.htmlおよび学習済みの PyTorch モデルのトレースと保存を参照してください。

    例: "mobilenet_v3.pt"

    名前と値の引数

    すべて折りたたむ

    オプションの引数のペアを Name1=Value1,...,NameN=ValueN として指定します。ここで、Name は引数名で、Value は対応する値です。名前と値の引数は他の引数の後に指定しなければなりませんが、ペアの順序は重要ではありません。

    例: importNetworkFromPyTorch(modelfile,Namespace="CustomLayers") は、modelfile 内のネットワークをインポートし、カスタム層の名前空間 +Namespace を現在のフォルダーに保存します。

    importNetworkFromPyTorch がカスタム層を保存するカスタム層名前空間の名前。文字ベクトルまたは string スカラーとして指定します。importNetworkFromPyTorch は、カスタム層の名前空間 +Namespace を現在のフォルダーに保存します。Namespace を指定しない場合、importNetworkFromPyTorch は、カスタム層を現在のフォルダー内の名前空間 +modelfile に保存します。名前空間の詳細については、名前空間の作成を参照してください。

    カスタムの PyTorch 層をインポートしたとき、またはソフトウェアが PyTorch 層をそれと等価な組み込みの MATLAB® 層に変換できないとき、importNetworkFromPyTorch はカスタム層の生成を試みます。importNetworkFromPyTorch は、生成した各カスタム層を、+Namespace で個別の MATLAB コード ファイルとして保存します。カスタム層を表示または編集するには、関連する MATLAB コード ファイルを開きます。カスタム層の詳細については、カスタム層を参照してください。

    +Namespace 名前空間には、+ops 内部名前空間を含めることもできます。この内部名前空間には、自動生成されたカスタム層が使用する PyTorch 演算子に対応する MATLAB 関数が格納されます。importNetworkFromPyTorch は、各演算子に関連する MATLAB 関数を +ops 内部名前空間の個別の MATLAB コード ファイルに保存します。dlnetwork のオブジェクト関数 (predict 関数など) は、カスタム層とやり取りするときにこれらの演算子を使用します。+ops 内部名前空間にはプレースホルダー関数を含めることもできます。詳細については、プレースホルダー関数を参照してください。

    例: Namespace="mobilenet_v3"

    PyTorch ネットワーク入力の次元サイズ。数値配列、string スカラー、または cell 配列として指定します。次元の入力順序は PyTorch ネットワークと同じです。ネットワークへの入力が単一の非スカラー入力である場合にのみ、PyTorchInputSizes を数値配列として指定できます。ネットワークに複数の入力がある場合、PyTorchInputSizes は入力サイズの cell 配列でなければなりません。入力のサイズまたは形状が不明な場合、PyTorchInputSize"unknown" として指定します。入力が PyTorch の 0 次元スカラーに対応する場合、PyTorchInputSize"scalar" として指定します。

    importNetworkFromPyTorch がサポートする標準入力層は、ImageInputLayer (SSCB)、FeatureInputLayer (CB)、ImageInputLayer3D (SSSCB)、および SequenceInputLayer (CBT) です。ここで、S は空間、C はチャネル、B はバッチ、T は時間です。importNetworkFromPyTorch は、PyTorchInputSizes を使用した非標準の入力もサポートします。たとえば、関数呼び出し net = importNetworkFromPyTorch("nonStandardModel.pt",PyTorchInputSizes=[1 3 224]) を使用し、ネットワークをインポートして入力次元のサイズを指定します。次に、関数呼び出し X = dlarray(rand(1 3 224),"UUU") および net = initialize(net,X) を使用し、U のラベル (U は不明を表す) が付けられた dlarray オブジェクトを使ってネットワークを初期化します。ソフトウェアは、U のラベルが付けられた dlarray を PyTorch の順序に従うデータとして解釈します。

    例: PyTorchInputSizes=[NaN 3 224 224] は、イメージのバッチである 1 つの入力をもつネットワークです。

    例: PyTorchInputSizes={[NaN 3 224 224],"unknown"} は、2 つの入力をもつネットワークです。最初の入力はイメージのバッチであり、2 番目の入力のサイズは不明です。

    データ型: numeric array | string | cell array

    ネットワーク構成の表現。次のいずれかの値として指定します。

    • "networklayer"networkLayer 層オブジェクトを使用して、インポートされたネットワーク内のネットワーク構成を表現します。この値を指定すると、ソフトウェアは、カスタム層の数が増えないという制約の下で可能な限り多くの PyTorch 関数を Deep Learning Toolbox 層に変換します。

    • "customlayer" — 入れ子のカスタム層を使用して、インポートされたネットワーク内のネットワーク構成を表現します。この値を指定すると、importNetworkFromPyTorch は、一連の PyTorch 関数を Deep Learning Toolbox 関数に変換してから、それらをカスタム層に統合します。カスタム層の詳細については、カスタム深層学習層の定義を参照してください。

    例: PreferredNestingType="customlayer"

    データ型: char | string

    出力引数

    すべて折りたたむ

    事前学習済みの PyTorch ネットワーク。初期化されていない dlnetwork オブジェクトとして返されます。

    制限

    • importNetworkFromPyTorch 関数は、Version 2.0 以外の PyTorch のバージョンで作成されたほとんどの (ただしすべてではない) ネットワークをインポートできます。この関数は PyTorch Version 2.0 を完全にサポートします。

    • importNetworkFromPyTorch 関数は、torchvision 演算子を含む PyTorch オブジェクト検出モデルをサポートしていません。

    詳細

    すべて折りたたむ

    ヒント

    • 事前学習済みのネットワークを新しいイメージの予測または転移学習に使用するには、インポートしたモデルの学習に使用したイメージと同じようにイメージを前処理しなければなりません。最も一般的な前処理ステップは、イメージのサイズ変更、イメージの平均値の減算、イメージの BGR 形式から RGB 形式への変換です。

      • イメージのサイズを変更するには、imresize を使用します。たとえば、imresize(image,[227 227 3]) のようにします。

      • RGB 形式から BGR 形式にイメージを変換するには、flip を使用します。たとえば、flip(image,3) のようにします。

      学習および予測用のイメージの前処理の詳細については、イメージの深層学習向け前処理を参照してください。

    • 名前空間 +Namespace の親フォルダーが MATLAB パス上にない場合、この名前空間のメンバーにアクセスすることはできません。詳細については、名前空間と MATLAB パスを参照してください。

    • MATLAB は 1 ベースのインデックスを使用しますが、Python は 0 ベースのインデックスを使用します。つまり、配列の最初の要素のインデックスは、MATLAB と Python でそれぞれ 1 と 0 になります。MATLAB のインデックスの詳細については、配列インデックス付けを参照してください。MATLAB で、Python で作成されたインデックス (ind) の配列を使用するには、配列を ind+1 に変換します。

    • Python ライブラリの競合が発生した場合は、pyenv 関数を使用して、名前と値の引数 ExecutionMode"OutOfProcess" として指定します。

    • その他のヒントについては、TensorFlow、PyTorch、および ONNX からモデルをインポートする際のヒントを参照してください。

    アルゴリズム

    importNetworkFromPyTorch 関数は、次の手順を順番に試し、PyTorch 層を MATLAB にインポートします。

    1. 関数は、PyTorch 層を組み込みの MATLAB 層としてインポートすることを試みます。詳細については、PyTorch 層の変換を参照してください。

    2. 関数は、PyTorch 層を組み込みの MATLAB 関数としてインポートすることを試みます。詳細については、PyTorch 層の変換を参照してください。

    3. 関数は、PyTorch 層をカスタム層としてインポートすることを試みます。importNetworkFromPyTorch は、生成されたカスタム層および関連する関数を +Namespace 名前空間に保存します。例については、PyTorch からのネットワークのインポートおよび生成されたカスタム層の検索を参照してください。

    4. 関数は、プレースホルダー関数を含むカスタム層として PyTorch 層をインポートします。プレースホルダー関数は、ネットワークを使用する前に補完しなければなりません。プレースホルダー関数を参照してください。

    最初の 3 つのケースでは、インポートされたネットワークは初期化後に予測の準備が整います。

    代替機能

    アプリ

    ディープ ネットワーク デザイナーアプリを使用して、外部プラットフォームからネットワークをインポートすることもできます。アプリは importNetworkFromPyTorch 関数を使用してネットワークをインポートし、進行状況ダイアログ ボックスを表示します。インポート プロセス中に、アプリはネットワークに入力層を追加し (可能な場合)、注意が必要な問題の詳細を含むインポート レポートを表示します。ネットワークをインポートした後、ネットワークを対話的に編集、可視化、および解析できます。ネットワークの編集が完了したら、それを Simulink® にエクスポートするか、ネットワークを構築するための MATLAB コードを生成できます。

    ブロック

    PyTorch Model Predict ブロックを使用して PyTorch ネットワークを扱うこともできます。このブロックを使用すると、Python 関数を読み込んでデータを前処理および後処理したり、入力端子と出力端子を対話的に構成したりすることもできます。

    バージョン履歴

    R2022b で導入

    すべて展開する