MATLAB Note/Neural Network Toolbox
Last-modified: 2012-06-09 (土) 01:47:20
Top / MATLAB Note / Neural Network Toolbox
- 目次
構造体net †
- ニューラルネットワークの構造と学習ルールを決定するための全てのパラメータは、構造体(データ集合配列)「net」に格納されます。
- 具体的なパラメータの一覧は、以下の通りです。
Architecture(アーキテクチャ) - ネットワークサブオブジェクトの数と結合方法※引数を指定するプロパティは、引数なしでまとめて呼び出すこともできます(リンク先参照)。名前 内容 形式 net.numInputs ネットワークが入力として受け取るベクトル集合の数 0または正の整数 net.numLayers ネットワークがもつ層の数 0または正の整数 net.biasConnect(i) i 番目の層のバイアスの有無 1 (有り)または 0 (無し) net.inputConnect(i,j) j 番目の入力層から i 番目の層への重みの有無 1 (または0) net.layerConnect(i,j) j 番目の層から i 番目の層への重みの有無 1 (または0) net.outputConnect(i) i 番目の層からのネットワーク出力の有無 1 (または0) net.targetConnect(i) i 番目の層に関連するターゲット(教師情報)の有無 1 (または0) net.numOutputs ネットワークのもつ出力数 ( = sum(net.outputConnect) ) 参照のみ net.numTargets ネットワークのもつターゲット数 ( = sum(net.targetConnect) ) 参照のみ net.numInputDelays シミュレートにおいて与える必要がある過去の入力の時間ステップ数 参照のみ net.numLayerDelays シミュレートに対して与える必要がある過去の層の出力の時間ステップ数 参照のみ
Subobject Structure(サブオブジェクト構造体) - ネットワークの入力、層、出力、ターゲット、バイアス、重み名前 内容 形式 net.inputs{i} i 番目の入力層のプロパティ構造体 以下(参照) net.inputs{i}.range i 番目の入力層の要素の範囲 入力要素数×2の行列(列1<列2) net.inputs{i}.size i 番目の入力層の要素数 0または正の整数 net.inputs{i}.userdata i 番目の入力層に関するカスタマイズ情報 任意
名前 内容 形式 net.layers{i} i 番目の層のプロパティ構造体 以下(参照) net.layers{i}.dimensions i 番目の層のノードの次元(SOM用) 0または正の整数の行ベクトル net.layers{i}.distanceFcn i 番目の層のニューロン間の距離計算用関数(SOM用) boxdistなど(参考) net.layers{i}.distances i 番目の層のニューロン間の距離(SOM用) 参照のみ net.layers{i}.initFcn i 番目の層の初期化関数(ネットワーク初期化関数(net.initFcn)にinitlayを指定した場合) 任意、デフォルトではinitwbなど net.layers{i}.netInputFcn i 番目の層のネット入力の計算用関数 任意、デフォルトではnetprod(積)、netsum(和) net.layers{i}.positions i 番目の層内のニューロンの位置(SOM用) 参照のみ net.layers{i}.size i 番目の層のニューロン数 0または正の整数 net.topologyFcn 層のニューロンの位置計算用関数(SOM用) 任意、デフォルトではgridtopなど(参考) net.layers{i}.transferFcn i 番目の層の出力計算用の伝達関数 任意、デフォルトではいろいろ net.layers{i}.userdata i 番目の層に関するカスタマイズ情報 任意
名前 内容 形式 net.outputs{i} i 番目の層の出力のプロパティ構造体 以下(参照) net.outputs{i}.size i 番目の層の出力の要素数( = i 番目の層のサイズ) 参照のみ net.outputs{i}.userdata i 番目の層の出力に関するカスタマイズ情報 任意
名前 内容 形式 net.targets{i} i 番目の層のターゲットのプロパティ構造体 以下(参照) net.targets{i}.size i 番目の層のターゲット内の要素数( = i 番目の層のサイズ) 参照のみ net.targets{i}.userdata i 番目の層のターゲットに関するカスタマイズ情報 任意
名前 内容 形式 net.biases{i} i 番目の層のバイアスのプロパティ構造体 以下(参照) net.biases{i}.initFcn i 番目の層のバイアスの初期化関数(ネットワーク初期化関数にinitlay、i 番目の層の初期化関数にinitwbを指定した場合) 任意、デフォルトではinitconほか net.biases{i}.learn 訓練および適応中に i 番目のバイアスが変更されるかどうか 0または1 net.biases{i}.learnFcn i 番目の層のバイアス更新用関数(訓練関数がtrainb、trainc、trainr、もしくは適応関数がtrainsの場合) 任意、デフォルトではlearnconなど net.biases{i}.learnParam i 番目の層のバイアス更新関数のパラメータと値 指定した関数による net.biases{i}.size i 番目の層のバイアスのサイズ( = i 番目の層のサイズ) 参照のみ net.biases{i}.userdata i 番目の層のバイアスに関するカスタマイズ情報 任意
名前 内容 形式 net.inputWeights{i,j} j 番目の入力層から i 番目の層への重みのプロパティ構造体 以下(参照) net.inputWeights{i,j}.delays j 番目の入力層と i 番目の層への重みの間のタップ付き遅延線 昇順の0または正の整数値からなる行ベクトル net.inputWeights{i,j}.initFcn j 番目の入力層から i 番目の層への重み行列の初期化関数(ネットワーク初期化関数がinitlay、i番目の層の初期化関数がinitwbの場合) 任意、デフォルトではmidpointなど net.inputWeights{i,j}.learn j 番目の入力層から i 番目の層への重み行列が訓練および適応中に変更されるかどうか 0または1 net.inputWeights{i,j}.learnFcn j 番目の入力層から i 番目の層への重み行列学習関数(訓練関数がtrainb、trainc、trainrであるか、適応関数がtrainsの場合) 任意、デフォルトではlearnsomなど、いろいろ net.inputWeights{i,j}.learnParam j 番目の入力層から i 番目の層の重みへの学習関数のパラメータと値 指定した関数による net.inputWeights{i,j}.size j 番目の入力層から i 番目の層の重み行列への次元 参照のみ net.inputWeights{i,j}.userdata (i,j) 番目の入力重みに関するカスタマイズ情報 任意 net.inputWeights{i,j}.weightFcn j 番目の入力層から i 番目の層への重み適用関数 任意、デフォルトでは dist など
名前 内容 形式 net.layerWeights{i,j} j 番目の層から i 番目の層への重みのプロパティ構造体 以下(参照) net.layerWeights{i,j}.delays 省略、net.inputWeightsと同じ net.layerWeights{i,j}.initFcn 省略、net.inputWeightsと同じ net.layerWeights{i,j}.learn 省略、net.inputWeightsと同じ net.layerWeights{i,j}.learnFcn 省略、net.inputWeightsと同じ net.layerWeights{i,j}.learnParam 省略、net.inputWeightsと同じ net.layerWeights{i,j}.size 省略、net.inputWeightsと同じ net.layerWeights{i,j}.userdata 省略、net.inputWeightsと同じ net.layerWeights{i,j}.weightFcn 省略、net.inputWeightsと同じ
Functions(関数) - ネットワークの適応、初期化、性能の測定、訓練名前 内容 形式 net.adaptFcn ネットワークの逐次型学習(適応)に用いる関数 任意の関数名、デフォルトでは trains など、いろいろ(参照) net.initFcn ネットワークの初期化に用いる関数 任意の関数名、デフォルトでは init など net.performFcn ネットワークのパフォーマンス測定に用いる関数 任意の関数名、デフォルトでは mae、mse、msereg、sse net.trainFcn ネットワークのバッチ型学習(訓練)に用いる関数 任意の関数名、デフォルトでは trainr など、いろいろ(参照)
Parameters(パラメータ)名前 内容 形式 net.adaptParam net.adaptFcnで指定した適応関数のパラメータ 指定した関数による net.initParam net.initFcnで指定した初期化関数のパラメータ 指定した関数による net.performParam net.performFcnで指定したパフォーマンス関数のパラメータ 指定した関数による net.trainParam net.trainFcnで指定した訓練関数のパラメータ 指定した関数による
Weight and Bias Values(重みとバイアスの値) - 調整可能なネットワークのパラメータ、重み関数とバイアスベクトル名前 内容 形式 net.IW{i,j} j 番目の入力層から i 番目の層への重み 対応する層のサイズと同じ数の行列(または空行列[]) net.LW{i,j} j 番目の層から i 番目の層への重み 対応する層のサイズと同じ数の行列(または空行列[]) net.b{i} i 番目の層に対するバイアス 対応する層のサイズと同じ数の行列(または空行列[])
Other(その他) - ユーザデータプロパティ名前 内容 形式 net.userdata ネットワークオブジェクトにカスタマイズの情報を追加する 任意
パーセプトロン †
簡単な例 †
- 上図の入力値は以下のようにして作成しました。
%入力ベクトル(学習データ)を設定 p = [ 2 2 1 0 0 1 -1 -2 -2 -1 2 -1 2 -2 1 2 1 0 ] %1列が1データセット %以下のように表記してもいいです。 p = [[2;-1] [2;2] [1;-1] [0;2] [0;-2] [1;1] [-1;2] [-2;1] [-2;0]]; %ターゲットベクトル(教師データ、カテゴリラベル)を設定 t = [ 0 1 0 1 0 1 1 0 0 ] %各列が入力ベクトルの各データセットに対応 %入力ベクトルをプロット pt0 = p( : , find(t==0) ) %ターゲット(カテゴリ)が0の入力ベクトルを取り出す pt1 = p( : , find(t==1) ) %ターゲット(カテゴリ)が1の入力ベクトルを取り出す plot(pt0(1,:),pt0(2,:),'ob', pt1(1,:),pt1(2,:),'or'); axis([-3 3 -3 3]); %関数 PLOTPV を使えば、自動的にターゲット別の入力ベクトルをプロットしてくれます。 plotpv(p,t);
- パーセプトロンの訓練は、以下のようにします(上のコードに続けて実行します)。
%ネットワークの生成 %2要素(X軸サイズ-2~2、Y軸サイズ-2~2)からなる入力ベクトルをもつ1つのニューロン net = newp([-2 2;-2 +2],1); %ネットワークの訓練 net.trainParam.epochs = 1; %訓練回数(epochsを1にすると、入力ベクトルのセットを1回訓練) net = train(net,p,t); %ネットワークの訓練を開始する(重みとバイアスを調整する) %訓練結果を確認 a = sim(net,p) %訓練後のネットワークの各入力ベクトルに対する出力を調べる error = [a - t] %出力がターゲットベクトルと一致しているかどうかを調べる %訓練結果(識別境界)をプロット figure(1); %figure1ウインドウに描画する plotpv(p,t); hold on %上のプロット(入力ベクトル)を保持したまま下をプロット linehandle=plotpc(net.IW{1},net.b{1}); %分類境界をプロット hold off
- 結果は以下のようになります。
- ターゲット(カテゴリ)0の入力値(2,-1)が、ターゲット1に分類されてしまいました。
- これはerrorの値が「 1 0 0 0 0 0 0 0 0 」と出力されている(入力ベクトルの1列目が分類失敗)ことからも分かります。
- そのため、epochs = 1 では(入力ベクトルを1回ずつ与えただけでは)学習は完了しないことが分かります。
- したがって、続けて学習を行います(上のコードに続けて実行します)。
net.trainParam.epochs = 10; %epochs(訓練回数)を10に設定 net = train(net,p,t); %ネットワークの追加訓練を開始する %訓練結果を確認 a = sim(net,p) error = [a - t] %訓練結果(識別境界)をプロット figure(2); plotpv(p,t); hold on linehandle=plotpc(net.IW{1},net.b{1}); hold off
- 結果は以下のようになります。
- 完全に識別できていることが分かります。
- 訓練の経過メッセージとして、以下が出力されたはずです。
TRAINC, Epoch 0/10
TRAINC, Epoch 4/10
TRAINC, Performance goal met. - これはepochsを10に指定したけれど、4epochsで収束したため、自動的に訓練が終了したことを示しています。epochsは大きい値を指定しておけば、(入力ベクトルが線形分離可能であれば)最適なタイミングで訓練を終了してくれます。
- 入力ベクトルが線形分離可能でなければ、パーセプトロンの性質上、収束することがないので、全てのepochsが終わるまで訓練が続きます( >>demop6 を参照)。
- 訓練の経過メッセージとして、以下が出力されたはずです。
- 訓練を終えたネットワークに対して新規のベクトルを提示して、そのベクトルのカテゴリを判別するには以下のようにします(上のコードに続けて実行します)。
a = sim(net, [[-2;-2] [1;2]]) %新規の入力ベクトル(-2,-2)(1,2)を提示して出力を調べる
- 結果は以下のようになります。
- ベクトル(-2,-2)がカテゴリ0(○)、ベクトル(1,2)がカテゴリ1(+)に、正しく分類されています。
- おまけ 複数ニューロンのパーセプトロン
- 2つ以上のニューロンを持つパーセプトロンに、異なるターゲットベクトルで訓練させることもできます。
- 以下のコードを実行してください(新規に実行します)。
%入力ベクトル(学習データ)を設定 p = [[2;-1] [2;2] [1;-1] [0;2] [0;-2] [1;1] [-1;2] [-2;1] [-2;0]]; %ターゲットベクトル(教師データ、カテゴリラベル)を設定 t = [ 0 1 0 1 0 1 1 0 0 0 0 0 1 0 0 1 1 1 ] %各列が入力ベクトルの各データセットに対応 %ネットワークの生成 %2要素(X軸サイズ-2~2、Y軸サイズ-2~2)からなる入力ベクトルをもつ2つのニューロン net = newp([-2 2;-2 +2],2); %ネットワークの訓練 net.trainParam.epochs = 10; %訓練回数 net = train(net,p,t); %ネットワークの訓練を開始する %訓練結果を確認 a = sim(net,p) error = [a - t] %訓練結果(識別境界)をプロット figure(1); plotpv(p,t); hold on linehandle=plotpc(net.IW{1},net.b{1}); hold off
一層のパーセプトロン †
- 入力層ノード2個、出力層ノード1個の単層パーセプトロンに、AND構造を学習させたいとします。
- すなわち、次のような関係です。
- 入力値とターゲット(期待する出力、教師情報)を定義します。
%入力ベクトルを設定 p = [ 0 1 0 1 0 0 1 1 ] %1列が1データセット %ターゲットベクトルを設定 t = [ 0 0 0 1 ] %各列が入力ベクトルの各データセットに対応 %ターゲット別の入力ベクトルをプロット plotpv(p,t);
- まずは、新規にネットワークオブジェクトを宣言します。
net = network(1,1,[1],[1],[0],[1],[1]);
- 新規ネットワークは、関数NETWORKで定義されます(構造体netはnetworkを呼び出さないと定義できない?)。
- 引数の詳細は、以下の通りです。パーセプトロンのデフォルト設定にしています。
引数 対応するプロパティ(詳細な記述) 説明 1 net.numInputs = 1 入力数(入力層の数) = 1 1 net.numLayers = 1 層の数 = 1 [1] net.biasConnect( biasConnect(1) ) = [1] 出力層(第1層)はバイアスをもつ [1] net.inputConnect( inputConnect(1,1) ) = [1] 出力層は入力層に対して重みをもつ [0] net.layerConnect( layerConnect(1,:) ) = [0] 出力層は全ての他層に対して重みをもたない [1] net.outputConnect( outputConnect(1) ) = [1] ネットワークは出力層からの出力をもつ [1] net.targetConnect( targetConnect(1) ) = [1] ネットワークは出力層からのターゲットをもつ - これ以外のパラメータには値が代入されません。そのため、以下でネットワークの特性を設定する必要があります。
- 続いて、パーセプトロン固有のプロパティを設定します。
% 1番目の入力層の要素の範囲 net.inputs{1}.range = [0 1;0 1]; %入力層のノードは2つ(1列目0~1、2列目0~1 の2要素) % 1番目の層(出力層)のニューロン数 net.layers{1}.size = 1; %出力層のノードは1つ % 出力計算用の伝達関数 net.layers{1}.transferFcn = 'hardlim'; %ハードリミット伝達関数(0か1かで出力) % ネットワークのパフォーマンス測定関数 net.performFcn = 'mae'; %MAE(平均絶対誤差) % 1番目の入力層から出力層への重み行列学習関数 net.inputWeights{1,1}.learnFcn = 'learnp'; %LEARNP(パーセプトロン重み学習関数) % 出力層のバイアス更新用関数 net.biases{1}.learnFcn = 'learnp'; %LEARNP(パーセプトロンバイアス学習関数) % 適応関数(逐次型学習で使用) net.adaptFcn = 'trains'; %TRAINS(継続的な順番で増加訓練) % 訓練関数(バッチ型学習と逐次型学習で使用) net.trainFcn = 'trainc'; %TRAINC(周期的な順番で増加訓練) % 初期化関数 net.initFcn = 'initlay'; %ネットワーク初期化関数 net.layers{1}.initFcn = 'initwb'; %出力層の初期化関数 net.biases{1}.initFcn = 'initzero'; %出力層のバイアスの初期化関数 net.inputWeights{1,1}.initFcn = 'initzero'; %出力層の重みの初期化関数 %初期化を実行 net = init(net);
- 「伝達関数(transferFcn)」とは、ネットワークの各ノード(ニューロン)が、入力された値に対してどのような値を出力するかを決定する関数です。 → (例) (伝達関数の一覧)
- 「学習関数(leranFcn)」とは、ネットワークの各ノードの出力をもとに、各ノードの重み値(シナプス結合値)を更新する関数です。 → (学習関数の一覧)
- 「適応関数(adaptFcn)」とは、逐次型学習を行なう関数です(詳細は後述)。
- 「訓練関数(trainFcn)」とは、バッチ型学習を行なう関数です(詳細は後述)。
- これでネットワークの初期設定が終わりました。構造体netの中身は、
net
とすることで確認できます。- ここまでと同様の処理(ネットワークオブジェクトを宣言 ~ パーセプトロンのプロパティ設定)は、関数NEWPを使って、
newp([0 1;0 1], 1); %パーセプトロンネットワークを作成(引数:入力要素範囲、出力層ノード数)
とすることでも実現できます。 - 入力ベクトルのサイズ(特徴量の数、最大値・最小値)が不明の場合、以下のようにします。
% 入力ベクトルのサイズ(size(p)の1番目の要素が行数、すなわち特徴量の数) vectorsize = size(p); % ネットワークに入力する入力層の要素の範囲を格納する配列を宣言 vectorlength = []; for count = 1 : 1 : vectorsize(1) vectorlength = [vectorlength ; min(p(count,:)) max(p(count,:))]; end net = newp(vectorlength, 1);
- ここまでと同様の処理(ネットワークオブジェクトを宣言 ~ パーセプトロンのプロパティ設定)は、関数NEWPを使って、
- 続いて、学習(重みとバイアスの更新)を行います。
%ネットワークを逐次型で学習させる(適応) net.adaptParam.passes = 40; %適応関数TRAINSのパラメータ(列全体を通る40個のパス) net = adapt(net,p,t); %入力ベクトルに対して重みとバイアスを調整
- 関数ADAPTは、逐次型学習(入力ベクトルの各行(ステップ)に対して、毎回重みを更新)を行います。
- パーセプトロンのプロパティ設定の際に、適応関数(net.adaptFcn)として「TRAINS」を指定しているため、適応関数パラメータ(net.adaptParam)として、net.adaptParam.passes を指定します。
- 「連続列全体を通るパス」とは、入力ベクトルセット全てを1回とした適応回数です。
- 適応関数 trains の各ステップの処理のところでプロット命令を追記すると、リアルタイムに適応学習の経過を観察できます。例えば trains_passsteps.m(限定公開)。
%ネットワークをバッチ型で学習させる(訓練) net.trainParam.epochs = 10; %訓練関数TRAINCのパラメータ %(入力ベクトルを10エポック繰り返し入力) net = train(net,p,t); %学習を開始する %(入力ベクトルに対して重みとバイアスを調整)
- 関数TRAINは、バッチ型学習(入力ベクトル全体に対して、最後にまとめて重みを更新)を行います。
- パーセプトロンのプロパティ設定の際に、訓練関数(net.trainFcn)として「TRAINC」を指定しているため、訓練関数パラメータ(net.trainParam)として、net.trainParam.epochs を指定します(他のパラメータはデフォルトのまま)。
- エポックとは、入力ベクトルセット全てを1回とした訓練回数です。
- パフォーマンスの評価と学習の収束について
- 最後に、学習済みネットワークに入力ベクトルを与え、出力結果をシミュレートします。またターゲットベクトルに対するエラー率を求め、識別境界をプロットします。
%訓練結果を確認 a = sim(net,p) %訓練後のネットワークの各入力ベクトルに対する出力を調べる error = [a - t] %出力がターゲットベクトルと一致しているかどうかを調べる length(find(error == 0)) / length(t) %正解率を求める %訓練結果(識別境界)をプロット figure(1); %figure1ウインドウに描画する plotpv(p,t); hold on %上のプロット(入力ベクトル)を保持したまま下をプロット linehandle=plotpc(net.IW{1},net.b{1}); %分類境界をプロット hold off
- 訓練関数について
- 上記のネットワークは、毎回結果が同じ?
- TRAINRを使うと結果がランダムに変わる
補記 †
- 入力ベクトルの特徴量数、サイズが未知の場合
%入力ベクトルを指定 p = [ 1 0 0 1 0 0 0 0 0 1 0 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 0 0 1 ]' %ターゲット(教師データ)を指定 t = [ 1 1 0 0 1 ]' % 入力ベクトルのサイズを調べる(size(p)の1番目の要素が行数、すなわち特徴量の数) vectorsize = size(p); % ネットワークに入力する入力層の要素の範囲を格納する配列を宣言 vectorlength = []; for count = 1 : 1 : vectorsize(1) vectorlength = [vectorlength ; min(p(count,:)) max(p(count,:))]; end vectorlength %ネットワークの生成 %2要素(X軸サイズ-2~2、Y軸サイズ-2~2)からなる入力ベクトルをもつ1つのニューロン net = newp(vectorlength, 1);
- 正解率を求めるには
length(find(error == 0)) / length(t)
- 20071228 追記 : 正解率は 1.00 までいくと過学習のようです。0.50~0.70 くらいにしておかないと、他のデータに適応できません。最適な値は学習回数(エポック数)、入力ベクトルの数、中間層ノードの数などを調整するしかありません。
二層のパーセプトロン †
- 多層ネットワークは、線形分離可能な問題しか解けない単層パーセプトロンの欠点を解決するために考案されました。
- 単層パーセプトロンでは、XOR構造を学習させることはできませんでした(線形分離不可能)。
- そのため、以下のような入力層ノード2個、中間層ノード2個、出力層ノード1個の多層パーセプトロンを作成し、バックプロパゲーションによってネットワークの訓練を行うことを考えます。
- 入力値とターゲット(期待する出力、教師情報)を定義します。
p = [ 0 1 0 1 0 0 1 1 ] t = [ 1 0 0 1 ]
- 新規にネットワークオブジェクトを宣言して、パーセプトロン固有のプロパティを設定します。
s = [2 1] %[1番目の層のニューロンの数 2番目の層のニューロンの数] Nl = length(s); %ニューロンの数ベクトル s の列数(層の数)を指定、ここでは 2 % ネットワークアーキテクチャ net = network(1,Nl); %入力層の数1、層の数2 で新規ネットワーク生成 net.biasConnect = ones(Nl,1); %各層のバイアスの有無(全て有り) net.inputConnect(1,1) = 1; %第1入力層から1層目(中間層)への重みの有無(有り) net.layerConnect = [ 0 0 1 0 ]; %1層目(中間層)から2層目(出力層)への結合 net.outputConnect(Nl) = 1; %Nl番目の層(出力層)のネットワーク出力の有無(有り) net.targetConnect(Nl) = 1; %Nl番目の層(出力層)のターゲットの有無(有り) % 1番目の入力層の要素の範囲 net.inputs{1}.range = [0 1;0 1]; %入力層のノードは2つ(1列目0~1、2列目0~1) % 1番目の層(出力層)のニューロン数、出力計算用の伝達関数 tf = {'tansig' 'purelin'} %1層目(中間層)=TANSIG、2層目(出力層)=PURELIN for count = 1 : Nl net.layers{count}.size = s(count); %count番目の層のニューロン数 net.layers{count}.transferFcn = tf{count}; %count番目の層の伝達関数 end % ネットワークのパフォーマンス測定関数 net.performFcn = 'mae' %MAE(平均絶対誤差) % 1番目の入力層から 1 番目の層(中間層)への重み行列学習関数 net.inputWeights{1,1}.learnFcn = 'learnp'; %LEARNP(パーセプトロン重み学習関数) % 層どうしの重み行列学習関数、バイアス更新用関数 for count = 1 : 2 net.layerWeights{count,:}.learnFcn = 'learnp'; %count番目の層の重み行列学習関数 net.biases{count}.learnFcn = 'learnp'; %count番目の層のバイアス学習関数 end % 訓練関数(バッチ型学習と逐次型学習で使用) net.trainfcn = 'trainlm' %TRAINLM (Levenberg-Marquardtバックプロパゲーション) % 初期化関数 net.initFcn = 'initlay'; for count = 1 : Nl net.layers{count}.initFcn = 'initnw'; end net = init(net); %初期化を実行
- 逐次型学習関数(net.adaptFcn)は指定していないため、バッチ型学習のみ対応しています。
- 訓練関数として、TRAINLMを指定しています(詳細)。他にもいろいろなバックプロパゲーション関数があります。
- バックプロパゲーションの伝達関数は、非線形微分可能な出力を出すものである必要があります(参考)。
- 単層パーセプトロンで使用していたハードリミット伝達関数は、微分不可能(0 か 1 かの離散値を出力するため)なので、バックプロパゲーションで使用することはできません。
- ここでは、中間層に正接シグモイド伝達関数、出力層に線形伝達関数を使用しています(参考)。
- 続いて、学習(重みとバイアスの更新)を行います。
%ネットワークをバッチ型で学習させる(訓練) net.trainParam.epochs = 30; %入力ベクトルを30エポック繰り返し入力 net = train(net,p,t); %学習開始(入力ベクトルに対して重みとバイアスを調整)
- 最後に、学習済みネットワークに入力ベクトルを与え、出力結果をシミュレートします。
%結果をプロット p %入力ベクトル t %ターゲットベクトル a = sim(net,p) %ネットワークの出力
- XOR構造を学習できていることが分かります。
- 学習を終えたネットワークの各ノードの重みは、以下のようになっています。