Main Content

浅層ニューラル ネットワークのプロパティの編集

ヒント

深層学習ネットワークに独自の層を定義する方法については、カスタム深層学習層の定義を参照してください。

Deep Learning Toolbox™ ソフトウェアは柔軟なネットワーク オブジェクト タイプを提供しており、さまざまな種類のネットワークを作成して、そのネットワークを initsimtrain などの関数と合わせて使用できます。

ツールボックスのすべてのネットワーク作成関数を確認するには、以下を入力します。

help nnnetwork

このような柔軟性が得られるのは、ネットワークがオブジェクト指向の表現を持つためです。この表現によって、さまざまなアーキテクチャを定義したり、それらのアーキテクチャにさまざまなアルゴリズムを割り当てたりすることができます。

カスタム ネットワークを作成するには、空のネットワーク (関数 network で取得) から開始して、目的に合わせてそのプロパティを設定します。

net = network

ネットワーク オブジェクトは、ネットワークの構造と動作を指定するために設定できる多くのプロパティで構成されています。

以降の節では、これらのプロパティを使用したカスタム ネットワークの作成方法について説明します。

カスタム ネットワーク

ネットワークを構築する前に、ネットワークがどのようになっているかを知る必要があります。劇的な効果をねらって (そして、ツールボックスを大いに活用するために)、この節では以下に示す非常に複雑なネットワークを作成する手順を説明します。

最初のネットワーク入力の 2 つの要素はそれぞれ 0 ~ 10 の範囲の値を受け取ります。2 番目のネットワーク入力の 5 つの要素はそれぞれ -2 ~ 2 の範囲の値を受け取ります。

このネットワークの設計を終了する前に、初期化と学習に使用するアルゴリズムを指定しなければなりません。

各層の重みとバイアスは、Nguyen・Widrow 層初期化手法 (initnw) を使用して初期化されます。ネットワークは、レーベンバーグ・マルカート法逆伝播 (trainlm) を使用して学習が行われるため、入力ベクトルの例を提示すると、3 番目の層の出力は最小平均二乗誤差 (mse) を使用して、関連付けられたターゲット ベクトルと一致するように学習されます。

ネットワークの定義

最初のステップは、新しいネットワークの作成です。以下のコードを入力して、ネットワークを作成し、その多くのプロパティを表示します。

net = network

アーキテクチャのプロパティ

表示されるプロパティの最初のグループは、architecture プロパティとラベル付けされています。これらのプロパティを使用して、入力と層の数や、それらの結合を選択できます。

入力と層の数.  dimensions グループに表示される最初の 2 つのプロパティは、numInputsnumLayers です。これらのプロパティを使用して、ネットワークにもたせる入力と層の数を選択できます。

net =

    dimensions:
         numInputs: 0
         numLayers: 0
         ...

この時点ではネットワークに入力も層もないことに注意してください。

それを、これらのプロパティをカスタム ネットワーク図の入力の数と層の数に設定することで変更します。

net.numInputs = 2;
net.numLayers = 3;

net.numInputs は入力ソースの数であり、入力ベクトルの要素数 (net.inputs{i}.size) ではありません。

バイアスの結合.  net と入力して Enter キーを押し、プロパティをもう一度表示します。ここでは、ネットワークには 2 つの入力と 3 つの層があります。

net =
    Neural Network:
    dimensions:
         numInputs: 2
         numLayers: 3

connections グループにある次の 4 つのプロパティを確認します。

       biasConnect: [0; 0; 0]
      inputConnect: [0 0; 0 0; 0 0]
      layerConnect: [0 0 0; 0 0 0; 0 0 0]
     outputConnect: [0 0 0]

1 と 0 から成るこれらの行列は、バイアス、入力の重み、層の重み、出力の結合の有無を表します。これらは、現在はすべてが 0 になっており、ネットワークにそのような結合がないことを示しています。

バイアス結合行列は、3 行 1 列のベクトルです。i 番目の層へのバイアス結合を作成するには、net.biasConnect(i)1 に設定します。次のコードを入力して、図に示しているように、最初の層と 3 番目の層がバイアス結合を持つように指定します。

net.biasConnect(1) = 1;
net.biasConnect(3) = 1;

これらの結合を 1 行のコードで定義することもできます。

net.biasConnect = [1; 0; 1];

入力と層の重みの結合.  入力結合行列は 3 行 2 列で、2 つのソース (2 つの入力) から 3 つの結合先 (3 つの層) への結合があることを表しています。したがって、net.inputConnect(i,j) は、j 番目の入力から i 番目の層への入力重み結合があることを表します。

(カスタム ネットワーク図に示しているとおり) 最初の入力を最初の層と 2 番目の層に結合し、2 番目の入力を 2 番目の層に結合するには、以下を入力します。

net.inputConnect(1,1) = 1;
net.inputConnect(2,1) = 1;
net.inputConnect(2,2) = 1;

または 1 行のコードを入力します。

net.inputConnect = [1 0; 1 1; 0 0];

同様に、net.layerConnect(i.j) は、j 番目の層から i 番目の層への層の重み結合があることを表します。次のようにして層 1、2、3 を層 3 に結合します。

net.layerConnect = [0 0 0; 0 0 0; 1 1 1];

出力の結合.  出力結合行列は 1 行 3 列で、3 つのソース (3 つの層) から 1 つの結合先 (外界) への結合があることを表します。

層 2 および 3 をネットワーク出力に結合するには、以下を入力します。

net.outputConnect = [0 1 1];

出力の数

net と入力して Enter キーを押し、最新のプロパティを表示します。最後の 3 つのアーキテクチャ プロパティは読み取り専用の値で、他のプロパティに対する選択によって決定されることを意味します。dimension グループの最初の読み取り専用プロパティは、出力の数です。

numOutputs: 2

層 2 および 3 からの出力結合を定義することによって、ネットワークが 2 つの出力を持つように指定されました。

サブオブジェクトのプロパティ

出力表示にあるプロパティの次のグループは、サブオブジェクトです。

subobjects:
            inputs: {2x1 cell array of 2 inputs}
            layers: {3x1 cell array of 3 layers}
           outputs: {1x3 cell array of 2 outputs}
            biases: {3x1 cell array of 2 biases}
      inputWeights: {3x2 cell array of 3 weights}
      layerWeights: {3x3 cell array of 3 weights}

入力

入力の数 (net.numInputs) を 2 に設定すると、inputs プロパティは 2 つの入力構造体から成る cell 配列になります。それぞれの i 番目の入力構造体 (net.inputs{i}) には、i 番目の入力に関連付けられた追加プロパティが含まれています。

入力構造体の配置を確認するには、以下を入力します。

net.inputs
ans = 
    [1x1 nnetInput]
    [1x1 nnetInput]

最初の入力に関連付けられたプロパティを表示するには、以下を入力します。

net.inputs{1}

プロパティは、次のように表示されます。

ans = 
              name: 'Input'
    feedbackOutput: []
       processFcns: {}
     processParams: {1x0 cell array of 0 params}
   processSettings: {0x0 cell array of 0 settings}
    processedRange: []
     processedSize: 0
             range: []
              size: 0
          userdata: (your custom info)

exampleInput プロパティを設定すると、rangesizeprocessedSizeprocessedRange の各プロパティは、exampleInput の値のプロパティと一致するように自動的に更新されます。

exampleInput プロパティを以下のように設定します。

net.inputs{1}.exampleInput = [0 10 5; 0 3 10];

最初の入力の構造体を再度調べると、今度は新しい値が入っていることがわかります。

processFcns プロパティは 1 つ以上の処理関数に設定できます。これらの関数の一覧を表示するには、help nnprocess と入力します。

次のように、2 番目の入力ベクトルが 5 個の要素に対して −2 から 2 の範囲になるように設定します。

net.inputs{1}.processFcns = {'removeconstantrows','mapminmax'};

新しい入力プロパティを表示します。processParamsprocessSettingsprocessedRangeprocessedSize はすべて更新されており、ネットワークのシミュレーションまたは学習時に入力がネットワークに提示される前に removeconstantrowsmapminmax を使用して処理されることを反映していることがわかります。processParams プロパティには各処理関数の既定のパラメーターが含まれています。これらの値は必要に応じて変更できます。これらのパラメーターの詳細は、各処理関数のリファレンス ページを参照してください。

処理関数を 1 つも使用していない場合は、入力のサイズを直接設定できます。

net.inputs{2}.size = 5;

層.  層の数 (net.numLayers) を 3 に設定すると、layers プロパティは 3 つの層構造体から成る cell 配列になります。最初の層に関連付けられたプロパティを表示するには、以下のコード行を入力します。

net.layers{1}
ans = 
    Neural Network Layer
 
              name: 'Layer'
        dimensions: 0
       distanceFcn: (none)
     distanceParam: (none)
         distances: []
           initFcn: 'initwb'
       netInputFcn: 'netsum'
     netInputParam: (none)
         positions: []
             range: []
              size: 0
       topologyFcn: (none)
       transferFcn: 'purelin'
     transferParam: (none)
          userdata: (your custom info)

次の 3 行のコードを入力して、カスタム ネットワーク図の要件のとおりに、最初の層のサイズを 4 個のニューロンに、その伝達関数を tansig に、初期化関数を Nguyen・Widrow 関数に変更します。

net.layers{1}.size = 4;
net.layers{1}.transferFcn = 'tansig';
net.layers{1}.initFcn = 'initnw';

2 番目の層は 3 個のニューロンと伝達関数 logsig を設定し、initnw を使用して初期化します。次のように 2 番目の層のプロパティを目的の値に設定します。

net.layers{2}.size = 3;
net.layers{2}.transferFcn = 'logsig';
net.layers{2}.initFcn = 'initnw';

既定の値がネットワーク図の値と一致するため、3 番目の層のサイズと伝達関数のプロパティを変更する必要はありません。ただし、初期化関数だけは、次のように設定する必要があります。

net.layers{3}.initFcn = 'initnw';

出力.  outputs プロパティの配置を確認するには、次のコード行を使用します。

net.outputs
ans = 
    []    [1x1 nnetOutput]    [1x1 nnetOutput]

outputs には、層 2 と層 3 に対応する 2 つの出力構造体が含まれていることに注意してください。この配置は net.outputConnect[0 1 1] に設定されている場合に自動的に行われます。

次の式を使用して 2 番目の層の出力構造体を表示します。

net.outputs{2}
ans = 
    Neural Network Output

              name: 'Output'
     feedbackInput: []
     feedbackDelay: 0
      feedbackMode: 'none'
       processFcns: {}
     processParams: {1x0 cell array of 0 params}
   processSettings: {0x0 cell array of 0 settings}
    processedRange: [3x2 double]
     processedSize: 3
             range: [3x2 double]
              size: 3
          userdata: (your custom info)

2 番目の層のサイズ (net.layers{2}.size) が 3 に設定されたときに、size は自動的にこの値に設定されています。3 番目の層の出力構造体の size も正しいことを確認する場合は、この構造体を確認します。

出力には、ターゲット値がネットワークの学習中に使用される前に、その値に自動的に適用される処理プロパティがあります。ネットワークのシミュレーションまたは学習時に、ネットワークの出力値として層の出力値が返される前に、同じ処理設定が層の出力値に逆方向に適用されます。

入力処理プロパティと同様に、exampleOutput プロパティを設定すると、sizerangeprocessedSizeprocessedRange が自動的に更新されます。processFcns を処理関数名の cell 配列リストに設定すると、processParamsprocessSettingsprocessedRange が更新されます。その後で、必要に応じて processParam の値を変更できます。

バイアス、入力の重み、層の重み.  次のコマンドを入力して、バイアスと重みの構造体の配置を確認します。

net.biases
net.inputWeights
net.layerWeights

次に net.biases と入力したときの結果を示します。

ans = 
    [1x1 nnetBias]
    []
    [1x1 nnetBias]

それぞれに、対応する結合 (net.biasConnectnet.inputConnect、および net.layerConnect) に 1 を含む構造体が 1 つずつ含まれています。

以下のコード行を使用してこれらの構造体を確認します。

net.biases{1}
net.biases{3}
net.inputWeights{1,1}
net.inputWeights{2,1}
net.inputWeights{2,2}
net.layerWeights{3,1}
net.layerWeights{3,2}
net.layerWeights{3,3}

たとえば、net.biases{1} と入力すると、以下が出力されます。

    initFcn: (none)
      learn: true
   learnFcn: (none)
 learnParam: (none)
       size: 4
   userdata: (your custom info)

ネットワーク図に従って重みのタップ付き遅延線を指定するために、各重みの delays プロパティを設定します。

net.inputWeights{2,1}.delays = [0 1];
net.inputWeights{2,2}.delays = 1;
net.layerWeights{3,3}.delays = 1;

ネットワーク関数

net と入力して Return キーを再度押し、次の一連のプロパティを確認します。

functions:
      adaptFcn: (none)
    adaptParam: (none)
      derivFcn: 'defaultderiv'
     divideFcn: (none)
   divideParam: (none)
    divideMode: 'sample'
       initFcn: 'initlay'
    performFcn: 'mse'
  performParam: .regularization, .normalization
      plotFcns: {}
    plotParams: {1x0 cell array of 0 params}
      trainFcn: (none)
    trainParam: (none)

これらのプロパティはそれぞれ、基本的なネットワーク演算の関数を定義します。

初期化関数を initlay に設定すると、既に Nguyen・Widrow 初期化関数 initnw に設定された層初期化関数に従って、ネットワークが初期化されます。

net.initFcn = 'initlay';

これは、ネットワークの初期化要件を満たしています。

カスタム ネットワークの最終的な要件を満たすために、性能関数を mse (平均二乗誤差) に設定し、学習関数を trainlm (レーベンバーグ・マルカート法逆伝播) に設定します。

net.performFcn = 'mse';
net.trainFcn = 'trainlm';

分割関数を dividerand (学習データをランダムに分割) に設定します。

net.divideFcn = 'dividerand';

教師あり学習時に、入力データとターゲット データが学習セット、テスト セット、および検証セットにランダムに分割されます。ネットワークの学習は学習データに対して行われ、検証データで性能が低下し始めるまで、つまり汎化がピークに達するまで続きます。テスト データを使用することで、ネットワークの汎化を完全に独立にテストできます。

プロット関数を plotperform (学習、検証、テストの性能をプロット) と plottrainstate (エポックに関する学習アルゴリズムの状態をプロット) に設定します。

net.plotFcns = {'plotperform','plottrainstate'};

重みとバイアスの値

ネットワークの初期化と学習を行う前に、net と入力して Return を押し、ネットワーク プロパティの重みとバイアスのグループを確認します。

weight and bias values:
           IW: {3x2 cell} containing 3 input weight matrices
           LW: {3x3 cell} containing 3 layer weight matrices
            b: {3x1 cell} containing 2 bias vectors

これらの cell 配列には、重み行列とバイアス ベクトルが含まれ、これらは結合プロパティ (net.inputConnectnet.layerConnectnet.biasConnect) に 1 が含まれる位置とサブオブジェクトのプロパティ (net.inputWeightsnet.layerWeightsnet.biases) に構造体が含まれる位置と同じ位置にあります。

次のコードの各行を実行すると、すべてのバイアス ベクトルと重み行列が 0 に設定されていることがわかります。

net.IW{1,1}, net.IW{2,1}, net.IW{2,2}
net.LW{3,1}, net.LW{3,2}, net.LW{3,3}
net.b{1}, net.b{3}

入力の重み net.IW{i,j}、層の重み net.LW{i,j}、バイアス ベクトル net.b{i} にはそれぞれ、i 番目の層 (net.layers{i}.size) のサイズと等しい数の行があります。

入力の重み net.IW{i,j} にはそれぞれ、j 番目の入力のサイズ (net.inputs{j}.size) にその遅延の値の数 (length(net.inputWeights{i,j}.delays)) を乗算した値に等しい数の列があります。

同様に、層の重みにはそれぞれ、j 番目の層のサイズ (net.layers{j}.size) にその遅延の値の数 (length(net.layerWeights{i,j}.delays)) を乗算した値に等しい数の列があります。

ネットワークの動作

初期化

次のコード行を使用してネットワークを初期化します。

net = init(net);

ネットワークのバイアスと重みをもう一度チェックして、それらがどのように変更されたかを確認します。

net.IW{1,1}, net.IW{2,1}, net.IW{2,2}
net.LW{3,1}, net.LW{3,2}, net.LW{3,3}
net.b{1}, net.b{3}

次に例を示します。

net.IW{1,1}
ans =
   -0.3040    0.4703
   -0.5423   -0.1395
    0.5567    0.0604
    0.2667    0.4924

学習

2 つのタイム ステップ (2 列) に対して、2 つの入力ベクトル (1 つは 2 要素、もう 1 つは 5 要素) から成る cell 配列を定義します。

X = {[0; 0] [2; 0.5]; [2; -2; 1; 0; 1] [-1; -1; 1; 0; 1]};

3 個のニューロンがある 2 番目の層と、1 個のニューロンがある 3 番目の層に対する次のターゲット シーケンスに応答するネットワークが必要です。

T = {[1; 1; 1] [0; 0; 0]; 1 -1};

学習の前に、ネットワークのシミュレーションを行って、ネットワークの初期の応答 Y がターゲット T に近いかどうかを確認できます。

Y = sim(net,X)
Y = 
     [3x1 double]    [3x1 double]
     [      1.7148]    [      2.2726]

cell 配列 Y は、ネットワークの出力シーケンスであり、2 番目と 3 番目の層の出力シーケンスでもあります。初期の重みとバイアスが異なるため、2 番目の行について得られる値はここに示している値と異なる場合があります。しかし、これらはターゲット T とはほぼ確実に等しくありません。これは、ここに示している値についても同様です。

次のタスクはオプションです。場合によっては、学習の前に学習パラメーターを変更することがあります。以下のコード行によって、既定のレーベンバーグ・マルカート法学習パラメーター (net.trainFcntrainlm に設定したときに定義されたもの) が表示されます。

net.trainParam

次のプロパティが表示されます。

ans = 
    Show Training Window Feedback   showWindow: true
    Show Command Line Feedback showCommandLine: false
    Command Line Frequency                show: 25
    Maximum Epochs                      epochs: 1000
    Maximum Training Time                 time: Inf
    Performance Goal                      goal: 0
    Minimum Gradient                  min_grad: 1e-07
    Maximum Validation Checks         max_fail: 6
    Mu                                      mu: 0.001
    Mu Decrease Ratio                   mu_dec: 0.1
    Mu Increase Ratio                   mu_inc: 10
    Maximum mu                          mu_max: 10000000000

これらの値の変更が必要になることはそう多くはありません。これらそれぞれの意味については、学習関数のドキュメンテーションを参照してください。これらは既定値で初期化されています。既定値は幅広い問題で良好に機能するため、ここで変更する必要はありません。

次に、次の呼び出しを使用してネットワークの学習を行います。

net = train(net,X,T);

学習時には、ニューラル ネットワーク学習ウィンドウが起動します。性能と学習の状態のプロットを開くには、プロット ボタンをクリックします。

学習の後で、ネットワークのシミュレーションを行って、正しく応答するように学習されたかどうかを確認できます。

Y = sim(net,X)

     [3x1 double]    [3x1 double]
     [      1.0000]    [     -1.0000]

2 番目のネットワーク出力 (cell 配列 Y の 2 番目の行) は、3 番目の層の出力でもあり、ターゲット シーケンス T と一致します。