トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索   ヘルプ   最終更新のRSS

MATLAB Note/Neural Network Toolbox/SOM(自己組織化マップ)

Last-modified: 2013-03-08 (金) 02:59:42
Top / MATLAB Note / Neural Network Toolbox / SOM(自己組織化マップ)

自己組織化マップ(Self-Organizing Maps, SOM)

学習に使用するデータ

  • 入力として使うのは、おなじみのあれ*1です。
    あれ → animal.JPG
    • 横軸の特徴量の数は、入力層の要素(ノード)数に対応します。
    • 縦軸の1行が、逐次型(適応)学習の1回のステップで与えられる入力ベクトルに対応します。
    • また、この13×16の入力ベクトルセットが、バッチ型(訓練)学習の1回のエポックで与えられる入力ベクトルに対応します。

基本SOM(単層)

  • まずは、Neural Network Toolbox での基本SOMの実装についてまとめておきます。
    • ここで作成するSOMは、5×4の二次元マップとします。
  • まずは入力値と、入力値のラベル(それぞれのデータ名)を宣言します。
     P = [
         1 0 0 1 0 0 0 0 1 0 0 1 0
         1 0 0 1 0 0 0 0 1 0 0 0 0
         1 0 0 1 0 0 0 0 1 0 0 1 1
         1 0 0 1 0 0 0 0 1 0 0 1 1
         1 0 0 1 0 0 0 0 1 1 0 1 0
         1 0 0 1 0 0 0 0 1 1 0 1 0
         0 1 0 1 0 0 0 0 1 1 0 0 0
         0 1 0 0 1 1 0 0 0 0 1 0 0
         0 1 0 0 1 1 0 0 0 0 1 0 0
         0 1 0 0 1 1 0 1 0 1 1 0 0
         1 0 0 0 1 1 0 0 0 1 0 0 0
         0 0 1 0 1 1 0 0 0 1 1 0 0
         0 0 1 0 1 1 0 1 0 1 1 0 0
         0 0 1 0 1 1 1 1 0 0 1 0 0
         0 0 1 0 1 1 1 1 0 0 1 0 0
         0 0 1 0 1 1 1 0 0 0 0 0 0
     ]
     Plabel = strvcat('ハト','メンドリ','アヒル','ガチョウ','フクロウ','タカ','ワシ','キツネ',...
        'イヌ','オオカミ','ネコ','トラ','ライオン','ウマ','シマウマ','ウシ') %STRVCAT 文字列を垂直に結合
    
     %行と列を転置
     P = P';
  • MATLABの仕様では、ネットワークへの入力ベクトルは、行成分を特徴量、列成分を1つの入力データにする必要があります(上図の逆です)。そのため、最後に行と列を転置しています。
  • 関数 NETWORK の引数にするために、作成した入力ベクトルのサイズを調べておきます。
     % 入力ベクトルの行数(Y 軸のサイズ、特徴量の数)、列数(X 軸のサイズ、データセットの数)を調べる
     [ipSizeY,ipSizeX] = size(P)
     % 入力層の要素の範囲を生成
     iprange = [min(P') ; max(P')]';   %[最小値 最大値]を特徴量の数だけ行方向に連結
  • 続いて、新規のネットワークオブジェクトを生成して、SOMの固有プロパティを宣言します。
     opSizeX = 5;            %SOM の X 軸(横軸、列成分)のセル数
     opSizeY = 4;            %SOM の Y 軸(縦軸、行成分)のセル数
    
     % ネットワークアーキテクチャ
     net = network(1,1,[0],[1],[0],[1],[0]);             %新規のネットワークを作成
     % 引数 : 入力数 = 1、層の数 = 1、層 1 はバイアスをもたない、層 1 は入力からの重みをもつ、
     %        層 1 は他層との重みをもたない、層 1 は出力をもつ、層 1 はターゲットをもたない
    
     % 入力層の要素の範囲
     net.inputs{1}.range = iprange;                      %入力ベクトルのサイズ(13×2)
     % 層 1 の物理的な次元
     net.layers{1}.dimensions = [opSizeX opSizeY];       %SOM の X, Y,..軸それぞれのセル数
     % 層の次元から層 1 のニューロンの位置を求めるトポロジー関数
     net.layers{1}.topologyFcn = 'gridtop';              %GRIDTOP(格子状層トポロジー関数) 
     % ニューロンの位置から層 1 のニューロン間の距離を求める距離関数
     net.layers{1}.distanceFcn = 'boxdist';              %BOXDIST(2つの位置ベクトル間の距離)
     % 入力層から層 1 への重み関数
     net.inputWeights{1,1}.weightFcn = 'negdist';        %NEGDIST(正規化列重み初期化関数)
     % 層 1 の伝達関数
     net.layers{1}.transferFcn = 'compet';               %COMPET(競合伝達関数)
    
     % 入力層から層 1 への重み行列の更新関数(学習関数)
     net.inputWeights{1,1}.learnFcn = 'learnsom';        %LEARNSOM(SOM重み学習関数)
     % LEARNSOMのパラメータを指定
     net.inputWeights{1,1}.learnParam.order_lr = 0.9;     %順序付けフェイズの学習比(デフォルト)
     net.inputWeights{1,1}.learnParam.order_steps = 1000; %順序付けフェイズのステップ数(デフォルト)
     net.inputWeights{1,1}.learnParam.tune_lr = 0.02;     %調整フェイズの学習比(デフォルト)
     net.inputWeights{1,1}.learnParam.tune_nd = 1;        %調整フェイズの近傍距離(デフォルト)
    
     % 適応関数
     net.adaptFcn = 'trains';                            %TRAINS(重みとバイアスによる)
     % 訓練関数
     net.trainFcn = 'trainr';                            %TRAINR(ランダムな順番での逐次型訓練)
    
     % 初期化(Initialization)
     net.initFcn = 'initlay';                            %INITLAY(層ごと)
     % 層 1 を初期化するために用いる関数
     net.layers{1}.initFcn = 'initwb';                   %INITWB(重みとバイアスによる)
     % 入力層から層 1 への重み行列初期化関数
     net.inputWeights{1,1}.initFcn = 'midpoint';         %MIDPOINT(中間点重み初期化)
     net = init(net);                                    %初期化を実行する
  • トポロジー関数(topologyFcn )」とは、SOMの層上のノードの配置形式のことで、ここではGRIDTOP(四角形に配置)を指定しています(詳細)。
  • 距離関数(distanceFcn )」とは、SOMの層上のノード同士の距離の計算方法のことで、ここではBOXDIST(四角形の座標で計算)を指定しています(詳細)。
  • 伝達関数(各ノードの出力)には、COMPET(勝利ノードのみ 1 を出力)を指定しています(参考)。その他の伝達関数として、デフォルトではSOFTMAX(最大の入力をもつノードは1に最も近い値を出力、それ以外は0に近い値を出力)が用意されています。
  • 学習関数(各ノードの重み付け変更)には、LEARNSOMを指定しています(詳細)。
  • 初期化関数には、MIDPOINT(全ノードを入力ベクトル範囲の中央値で初期化)を指定しています(参考)。
    • 入力ベクトルに依存しない初期化関数として、INITZERO(ゼロベクトル初期化)、RANDS(ランダム値初期化)があります。
    • サンプル:これを実行してみてください。

  • ここまでと同様の処理(ネットワークオブジェクトを宣言 ~ SOMのプロパティ設定)は、関数NEWSOMを使って、
     net = newsom(iprange,[5 4],'gridtop','boxdist', 0.9, 1000, 0.02, 1);
    とすることでも実現できます。
  • これでネットワークの初期設定が終わりました。
    • 構造体netの中身は、
      net
      とすることで確認できます。
    • 初期状態の(初期化された)SOMの各ノードの重み値は、
       wts = net.IW{1,1}
      とすることで確認できます。関数 MIDPOINT によって入力範囲の中央に初期化されているため、全て同じ値(0.5×13)です。
    • 初期状態のSOMの、入力ベクトル空間内における各ノードの位置は、
       plotsom(net.iw{1,1},net.layers{1}.distances)
      とすることで確認できます。赤い点が初期ニューロンのベクトル(全て同じ値)です。
      • 実行結果は以下のようになります。
        SOM_1.JPG
  • 「Warning - PLOTSOM only shows first three dimensions.」というエラーが出ています。入力ベクトルは実際には13次元の特徴量を持っているけれど、ここでは3次元までしか表示できません、ということです。
  • 2次元の入力ベクトルによるSOMの学習例については、これを入力ベクトルにして試してみてください。
  • 続いて、学習(重みとバイアスの更新)を行います。
    • 逐次型の適応学習(ADAPT)か、バッチ型の訓練学習(TRAIN)か、どちらかを選択して実行します。
     %ネットワークを逐次型で学習させる(適応)
     net.adaptParam.passes = 100;    %TRAINSのパラメータ(連続列全体を通る100個のパス)
     %入力ベクトルをセル配列に格納
     Psize = size(P);                %入力ベクトルのデータ数(=総ステップ数)
     Pcell = cell(1,Psize(2));       %入力ベクトルのデータ数個のセルを持ったセル配列
     for count = 1:1:Psize(2)
         Pcell{count} = P(:,count);  %各セルに各入力データを代入
     end
     % 適応を開始
     net = adapt(net,Pcell);
  • 関数ADAPTは、逐次型学習(入力ベクトルの各行(ステップ)に対して、毎回重みを更新)を行います。
    • SOMの適応関数として「TRAINS」を指定しているため、関数のパラメータを指定する必要があります(指定しなければ、デフォルトのままで実行)。
    • ADAPT 学習の入力ベクトルは、セル配列である必要があります。
    • 適応関数 trains の各ステップの処理のところでプロット命令を追記すると、リアルタイムに適応学習の経過を観察できます。例えば trains_passsteps.m(限定公開)
  •  %ネットワークをバッチ型で学習させる(訓練)
     % 訓練関数TRAINRのパラメータを指定
     net.trainParam.epochs = 100;  %最大エポック数(データセットを100エポック繰り返し訓練)
     net.trainParam.goal = 0;      %パフォーマンスゴール
     net.trainParam.show = 25;     %表示する間のエポック数(表示なしの場合NaN)
     net.trainParam.time = inf;    %訓練のための最大時間(秒)
     % 訓練を開始
     net = train(net,P);
  • 関数TRAINは、バッチ型学習(入力ベクトル全体に対して、最後にまとめて重みを更新)を行います。
    • SOMの訓練関数として「TRAINR」を指定しているため、関数のパラメータを指定する必要があります(指定しなければ、デフォルトのままで実行)。
    • 訓練学習の経過を詳しく見たい場合は、訓練関数に trainr_epochsteps.m を使用してください(限定公開)。
  • 学習済みネットワークに入力ベクトルを与え、出力結果をシミュレートします。
     %ネットワークのシミュレーション
     a = sim(net,P);         %入力ベクトルを与えて、出力ベクトルをクラスのインデックスに変換する
     a = vec2ind(a)          % 0 もしくは 1 のスパースなベクトルを、連続値のベクトルに変換
  • 出力される値は、「各入力ベクトルに対する競合学習の結果、SOMの何番のノードが勝利したか」です。そのため、ここでもう一度SOMの構造を確認して、何番のノードがどの位置にあるのかを確認します。
     %出力層の構造を確認
     outputFields = [];
     for count = 1:1:(opSizeX * opSizeY)
         outputFields = [outputFields count];
     end
     %各入力ベクトルをSOMのマップ型に並べ替えて出力
     outputFields = reshape( outputFields, opSizeX, opSizeY )
     %SOMのマップ型のセル配列を作成する
     somcell = cell(opSizeX, opSizeY);
     %入力ベクトルのラベルと出力ベクトルを合わせて表示する
     for count = 1 : 1 : length(Plabel)
         [Yco,Xco] = find(outputFields == a(count));
         disp(strcat('入力 「', Plabel(count,:), '」 のカテゴリは ', int2str(a(count)),...
             ' → 座標に換算すると (X,Y) = (', int2str(Xco), ', ', int2str(Yco), ')'));
         somcell{Yco,Xco} = strcat(somcell{Yco,Xco}, ' ', Plabel(count,:));
     end
     somcell
  • 実行結果は以下のようになります(結果は実行のたびに変わります)。
    SOM_2.png
    • 「a」は学習を終えたSOMに、入力ベクトルを順番に示したとき、それぞれ何番のノードと対応付けられたか(入力ベクトルに対する競合学習の結果、どのノードが「勝利」したか)を示します。
    • 「outputFields」が今回作成したSOMの構造です。四角形のBOXDIST構造で、数字は各ノードの番号を示します。
    • 最後に、入力ベクトルのラベルに従って入力ベクトルの出力ノードとその座標を計算して、学習結果を求めています。
  • 似た特徴量をもった入力値(動物)は、SOM上でお互いに近い位置に配置されていることが分かります。
  • 他の方法で、学習済みのSOMを評価してみます。
    • 学習を終えたSOMの各ノードの重み値は、
       wts = net.IW{1,1}
      とすることで確認できます。
  • 初期状態のSOMの、入力ベクトル空間内における各ノードの位置は、
     plotsom(net.iw{1,1},net.layers{1}.distances)
    とすることで確認できます。
  • 入力ベクトルが4次元以上の特徴量をもつ場合、PLOTSOMによる表示はあまり効果的ではないですが、3次元以下の場合、入力ベクトル空間内の密度の高いところ(多くの入力値が存在するところ)に多くのノードが近づく様子が確認できます。
  • 新しい入力値を提示するには
    • 例えば、以下のような新しい入力値が、学習済み SOM ではどのクラスに分類されるかを確認します。
      animal_tuika.png
       P2 = [
           0 1 0 1 0 0 0 0 0 1 0 0 0
           1 0 0 1 0 1 0 0 1 0 0 0 1
       ]
       P2label = strvcat('ヒト','ペンギン')
      
       %連結
       P = [P P2']
       Plabel = [Plabel ; P2label]
      
       %評価
       a = sim(net,P);
       a = vec2ind(a);
       outputFields = [];
       for count = 1:1:(opSizeX * opSizeY)
           outputFields = [outputFields count];
       end
       outputFields = reshape( outputFields, opSizeX, opSizeY )
       somcell = cell(opSizeX, opSizeY);
       for count = 1 : 1 : length(Plabel)
           [Yco,Xco] = find(outputFields == a(count));
           disp(strcat('入力 「', Plabel(count,:), '」 のカテゴリは ', int2str(a(count)),...
               ' → 座標に換算すると (X,Y) = (', int2str(Xco), ', ', int2str(Yco), ')'));
           somcell{Yco,Xco} = strcat(somcell{Yco,Xco}, ' ', Plabel(count,:));
       end
       somcell
  • SOMマップベースのクラスタリング結果表示法
  • 各ノードがどの入力値にもっとも強く対応付けられているかを知るには
    • 各ノードの重み値 net.IW{1,1} を確認します。

基本SOMの予備的考察

多層SOM - SOM-SOM型

  • 入力ベクトルの宣言までは、単層と同じです。
     P = [
         1 0 0 1 0 0 0 0 1 0 0 1 0
         1 0 0 1 0 0 0 0 1 0 0 0 0
         1 0 0 1 0 0 0 0 1 0 0 1 1
         1 0 0 1 0 0 0 0 1 0 0 1 1
         1 0 0 1 0 0 0 0 1 1 0 1 0
         1 0 0 1 0 0 0 0 1 1 0 1 0
         0 1 0 1 0 0 0 0 1 1 0 0 0
         0 1 0 0 1 1 0 0 0 0 1 0 0
         0 1 0 0 1 1 0 0 0 0 1 0 0
         0 1 0 0 1 1 0 1 0 1 1 0 0
         1 0 0 0 1 1 0 0 0 1 0 0 0
         0 0 1 0 1 1 0 0 0 1 1 0 0
         0 0 1 0 1 1 0 1 0 1 1 0 0
         0 0 1 0 1 1 1 1 0 0 1 0 0
         0 0 1 0 1 1 1 1 0 0 1 0 0
         0 0 1 0 1 1 1 0 0 0 0 0 0
     ]
     Plabel = strvcat('ハト','メンドリ','アヒル','ガチョウ','フクロウ','タカ','ワシ','キツネ',...
        'イヌ','オオカミ','ネコ','トラ','ライオン','ウマ','シマウマ','ウシ')
     P = P';                                     %行と列を転置
    
     % 入力ベクトルの行数(Y 軸のサイズ、特徴量の数)、列数(X 軸のサイズ、データセットの数)を調べる
     [ipSizeY,ipSizeX] = size(P)
     % 入力層の要素の範囲を生成
     iprange = [min(P') ; max(P')]';             %[最小値 最大値]を特徴量の数だけ行方向に連結
    
    -続いて、新規のネットワークオブジェクトを生成して、SOMの固有プロパティを宣言します。 
     opSizeX = 5;
     opSizeY = 4;
     s = [opSizeX*opSizeY opSizeX*opSizeY];      %[第1層のニューロン数 第2層のニューロン数]
     Nl = length(s);                             %ニューロンの数 s の列数(層の数)
    
     % ネットワークアーキテクチャ
     net = network(1, Nl);
     % 引数 : 入力層の数 = 1、層の数 = Nl(2) (その他の設定は以下で個別に指定)
     for countLayer = 1:1:Nl
         net.biasConnect(countLayer) = 0;        %バイアスの有無(層 1 も層 2 もバイアスをもたない)
     end
     net.inputConnect(1,1) = 1;                  %層 1 のみ入力層からの重みをもつ
     for countLayer = 2:1:Nl
     % 各層の結合の有無( countLayer 番目の層から countLayer-1 番目の層へ結合する)
         net.layerConnect(countLayer,countLayer-1) = 1;
     end
     net.outputConnect(Nl) = 1;                  % Nl 番目の層(出力層)はネットワーク出力をもつ
    
     net.inputs{1}.range = iprange;              % 1 番目の入力層の要素の範囲を指定
    
     for countLayer = 1:1:Nl
        % countLayer 番目の層の物理的な次元(この説明では、各層は全て同じサイズ)
        net.layers{countLayer}.dimensions = [opSizeX opSizeY];
        %層の次元から countLayer 番目の層のニューロンの位置を求めるトポロジー関数
        net.layers{countLayer}.topologyFcn = 'gridtop';
        %※ ニューロンの位置から 1 番目の層(中間層)のニューロン間の距離を求める距離関数
        net.layers{countLayer}.distanceFcn = 'boxdist';
     end
    
     % 入力層から 1 番目の層(中間層)への重み関数
     net.inputWeights{1,1}.weightFcn = 'negdist';
    
     % 各層(出力層)のニューロン数、出力計算用の伝達関数
     for countLayer = 1:1:Nl
       net.layers{countLayer}.size = s(countLayer);     % countLayer 番目の層のニューロン数
        net.layers{countLayer}.transferFcn = 'compet';   % countLayer 番目の層の伝達関数
     end
    
     % 各層の重み行列学習関数
     %  1番目の入力層から 1 番目の層(中間層)への重み行列学習関数
     net.inputWeights{1,1}.learnFcn = 'learnsom';       % LEARNSOM(SOM重み学習関数) 
     % LEARNSOMのパラメータを指定
     net.inputWeights{1,1}.learnParam.order_lr = 0.9;     %順序付けフェイズの学習比
     net.inputWeights{1,1}.learnParam.order_steps = 1000; %順序付けフェイズのステップ数
     net.inputWeights{1,1}.learnParam.tune_lr = 0.02;     %調整フェイズの学習比
     net.inputWeights{1,1}.learnParam.tune_nd = 1;        %調整フェイズの近傍距離
     %  層どうしの重み行列学習関数、バイアス更新用関数
     for countLayer = 2:1:Nl
         net.layerWeights{countLayer,1}.learnFcn = 'learnsom';      % LEARNSOM 
         net.layerWeights{countLayer,1}.learnParam.order_lr = 0.9;     %順序付けフェイズの学習比
         net.layerWeights{countLayer,1}.learnParam.order_steps = 1000; %順序付けフェイズのステップ数
         net.layerWeights{countLayer,1}.learnParam.tune_lr = 0.02;     %調整フェイズの学習比
         net.layerWeights{countLayer,1}.learnParam.tune_nd = 1;        %調整フェイズの近傍距離
     end
    
     % 訓練関数
     net.trainFcn = 'trainr'
    
     % 初期化関数
     net.initFcn = 'initlay';                    %INITLAY(層ごと)
     %  層から層への重み行列初期化関数
     for countLayer = 2:1:Nl
         net.layerWeights{countLayer,countLayer-1}.initFcn = 'midpoint';
     end
     %  入力層から層 1 への重み行列初期化関数
     net.inputWeights{1,1}.initFcn = 'midpoint'; %MIDPOINT(中間点重み初期化)
     % 初期化を実行
     net = init(net);
  • これでネットワークの初期設定が終わりました。
    • 初期状態の(初期化された)SOMの各ノードの重み値は、
       wtsL1 = net.IW{1,1}       % 1 番目の入力層から 1 番目の層への重み
       wtsL2 = net.LW{2,1}       % 1 番目の層から 2 番目の層への重み
      とすることで確認できます。関数 MIDPOINT によって入力範囲の中央に初期化されているため、全て同じ値(0.5×13)です。
  • 続いて、学習(重みとバイアスの更新)を行います。
     %ネットワークをバッチ型で学習させる(訓練)
     net.trainParam.epochs = 100;  %入力ベクトルを100エポック繰り返し入力
     net.trainParam.goal = 0;      %パフォーマンスゴール
     net.trainParam.show = 25;     %表示する間のエポック数(表示なしの場合NaN)
     net.trainParam.time = inf;    %訓練のための最大時間(秒)
     net = train(net,P);           %学習開始(入力ベクトルに対して重みとバイアスを調整)
  • 学習済みネットワークに入力ベクトルを与え、出力結果をシミュレートします。
     % ネットワークのシミュレーション
     P                       %入力ベクトル
     % 出力層の構造を確認
     outputFields = [];
     for count = 1:1:(opSizeX * opSizeY)
         outputFields = [outputFields count];
     end
     % 各入力ベクトルをSOMのマップ型に並べ替えて出力
     outputFields = reshape( outputFields, opSizeX, opSizeY )
    
     % ネットワークのシミュレーション 1層目
     %  入力層 ⇔ 1 層目 と同じ構造、重みの単層ネットワークを作成して、それに対してsimを実行します。
     %     もっとうまいやり方があるかも?
     simnet1 = network(1, 1);
     simnet1.biasConnect(1) = 0;
     simnet1.inputConnect(1,1) = 1;
     simnet1.outputConnect(1) = 1;
     simnet1.inputs{1}.range = iprange;
     simnet1.layers{1}.dimensions = [opSizeX opSizeY];
     simnet1.layers{1}.topologyFcn = 'gridtop';
     simnet1.layers{1}.distanceFcn = 'boxdist';
     simnet1.inputWeights{1,1}.weightFcn = 'negdist';
     simnet1.layers{1}.transferFcn = 'compet';
     simnet1.inputWeights{1,1}.learnFcn = 'learnsom';
     simnet1.inputWeights{1,1}.learnParam.order_lr = 0.9;
     simnet1.inputWeights{1,1}.learnParam.order_steps = 1000;
     simnet1.inputWeights{1,1}.learnParam.tune_lr = 0.02;
     simnet1.inputWeights{1,1}.learnParam.tune_nd = 1;
     simnet1.initFcn = 'initlay';
     simnet1.inputWeights{1,1}.initFcn = 'midpoint';
     simnet1 = init(simnet1);           %初期化を実行
     % 学習済みネットワークの 入力層 ⇔ 1 層目 の重みをコピー
     simnet1.IW{1,1} = net.IW{1,1};
     wtsL1 = simnet1.IW{1,1}            % 1 番目の入力層から 1 番目の層への重み
     aL1 = sim(simnet1,P);              %ネットワークの出力
     aL1 = vec2ind(aL1)                 % 0 もしくは 1 のスパースなベクトルを、連続値のベクトルに変換
     Pcell = cell(opSizeX, opSizeY);
     for count = 1 : 1 : length(Plabel)
         [Yco,Xco] = find(outputFields == aL1(count));
         disp(strcat('入力 「', Plabel(count,:), '」 のカテゴリは ', int2str(aL1(count)),...
             ' → 座標に換算すると (X,Y) = (', int2str(Xco), ', ', int2str(Yco), ')'));
         Pcell{Yco,Xco} = strcat(Pcell{Yco,Xco}, ' ', Plabel(count,:));
     end
     Pcell
    
     % ネットワークのシミュレーション 出力層
     %  こちらは、普通に学習済みネットワークをシミュレーションします。
     if Nl > 1
        wtsL2 = net.LW{2,1}             % 1 番目の層から 2 番目の層への重み
         aL2 = sim(net,P);               %ネットワークの出力
         aL2 = vec2ind(aL2);             % 0 もしくは 1 のスパースなベクトルを、連続値のベクトルに変換
         %入力ベクトルのラベルと出力ベクトルを合わせて表示する
         Pcell = cell(opSizeX, opSizeY);
         for count = 1 : 1 : length(Plabel)
             [Yco,Xco] = find(outputFields == aL2(count));
             disp(strcat('入力 「', Plabel(count,:), '」 のカテゴリは ', int2str(aL2(count)),...
                 ' → 座標に換算すると (X,Y) = (', int2str(Xco), ', ', int2str(Yco), ')'));
             Pcell{Yco,Xco} = strcat(Pcell{Yco,Xco}, ' ', Plabel(count,:));
         end
         Pcell
     end

多層SOM - SOM-教師あり型

Tips


*1 Teuvo Kohonen (1995).『Self-Organizing Maps』, Springer. (徳高平蔵・堀尾恵一・堀尾正昭・大薮又茂・藤村喜久郎訳(2003). 自己組織化マップ.『シュプリンガー・フェアラーク東京』.).