Miyazawa’s Pukiwiki
MATLAB Note/Neural Network Toolbox/SOM(自己組織化マップ)
はすでに存在します。
開始行:
#access
#analog
-目次
#contents
**自己組織化マップ(Self-Organizing Maps, SOM) [#c502a786]
-リファレンス
--[[競合学習ネットワーク:http://www.mathworks.com/access/...
--[[自己組織化マップ:http://www.mathworks.com/access/help...
--[[デモンストレーション:http://www.mathworks.com/access/...
--[[サブプロパティ net.layers のリファレンス:http://dl.cy...
--[[トポロジー関数、距離関数のカスタマイズ:http://dl.cybe...
~
***学習に使用するデータ [#jeb2f023]
-入力として使うのは、おなじみのあれ((Teuvo Kohonen (1995)...
あれ →
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/ani...
--横軸の特徴量の数は、入力層の要素(ノード)数に対応しま...
--縦軸の1行が、逐次型(適応)学習の1回のステップで与えら...
--また、この13×16の入力ベクトルセットが、バッチ型(訓練)...
***基本SOM(単層) [#uef1e63e]
-まずは、Neural Network Toolbox での基本SOMの実装について...
--ここで作成するSOMは、5×4の二次元マップとします。
-まずは入力値と、入力値のラベル(それぞれのデータ名)を宣...
#geshi(matlab){{
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';
}}
--MATLABの仕様では、ネットワークへの入力ベクトルは、行成...
-関数 NETWORK の引数にするために、作成した入力ベクトルの...
#geshi(matlab){{
% 入力ベクトルの行数(Y 軸のサイズ、特徴量の数)、列数(...
[ipSizeY,ipSizeX] = size(P)
% 入力層の要素の範囲を生成
iprange = [min(P') ; max(P')]'; %[最小値 最大値]を特徴...
}}
-続いて、新規のネットワークオブジェクトを生成して、SOMの...
#geshi(matlab){{
opSizeX = 5; %SOM の X 軸(横軸、列成分)のセ...
opSizeY = 4; %SOM の Y 軸(縦軸、行成分)のセ...
% ネットワークアーキテクチャ
net = network(1,1,[0],[1],[0],[1],[0]); %新...
% 引数 : 入力数 = 1、層の数 = 1、層 1 はバイアスをもたな...
% 層 1 は他層との重みをもたない、層 1 は出力をも...
% 入力層の要素の範囲
net.inputs{1}.range = iprange; %入...
% 層 1 の物理的な次元
net.layers{1}.dimensions = [opSizeX opSizeY]; %SOM...
% 層の次元から層 1 のニューロンの位置を求めるトポロジー...
net.layers{1}.topologyFcn = 'gridtop'; %GRI...
% ニューロンの位置から層 1 のニューロン間の距離を求める...
net.layers{1}.distanceFcn = 'boxdist'; %BOX...
% 入力層から層 1 への重み関数
net.inputWeights{1,1}.weightFcn = 'negdist'; %NEG...
% 層 1 の伝達関数
net.layers{1}.transferFcn = 'compet'; %COM...
% 入力層から層 1 への重み行列の更新関数(学習関数)
net.inputWeights{1,1}.learnFcn = 'learnsom'; %LEA...
% 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'; %TRA...
% 訓練関数
net.trainFcn = 'trainr'; %TRA...
% 初期化(Initialization)
net.initFcn = 'initlay'; %INI...
% 層 1 を初期化するために用いる関数
net.layers{1}.initFcn = 'initwb'; %INI...
% 入力層から層 1 への重み行列初期化関数
net.inputWeights{1,1}.initFcn = 'midpoint'; %MID...
net = init(net); %初...
}}
--「''トポロジー関数(topologyFcn )''」とは、SOMの層上の...
--「''距離関数(distanceFcn )''」とは、SOMの層上のノード...
--伝達関数(各ノードの出力)には、[[COMPET:http://dl.cybe...
--学習関数(各ノードの重み付け変更)には、[[LEARNSOM:http...
--初期化関数には、[[MIDPOINT:http://dl.cybernet.co.jp/mat...
---入力ベクトルに依存しない初期化関数として、[[INITZERO:h...
---サンプル:[[これ:http://shower.human.waseda.ac.jp/~m-k...
~
~
--ここまでと同様の処理(ネットワークオブジェクトを宣言 ~...
#geshi(matlab){{
net = newsom(iprange,[5 4],'gridtop','boxdist', 0.9, 100...
}}
とすることでも実現できます。
-これでネットワークの初期設定が終わりました。
--構造体netの中身は、
net
とすることで確認できます。
--初期状態の(初期化された)SOMの各ノードの重み値は、
#geshi(matlab){{
wts = net.IW{1,1}
}}
とすることで確認できます。関数 MIDPOINT によって入力範囲...
--初期状態のSOMの、入力ベクトル空間内における各ノードの位...
#geshi(matlab){{
plotsom(net.iw{1,1},net.layers{1}.distances)
}}
とすることで確認できます。赤い点が初期ニューロンのベクト...
---実行結果は以下のようになります。~
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/SOM...
---「Warning - PLOTSOM only shows first three dimensions....
---2次元の入力ベクトルによるSOMの学習例については、[[これ...
-続いて、学習(重みとバイアスの更新)を行います。
--逐次型の適応学習(ADAPT)か、バッチ型の訓練学習(TRAIN...
-~
#geshi(matlab){{
%ネットワークを逐次型で学習させる(適応)
net.adaptParam.passes = 100; %TRAINSのパラメータ(連...
%入力ベクトルをセル配列に格納
Psize = size(P); %入力ベクトルのデータ数...
Pcell = cell(1,Psize(2)); %入力ベクトルのデータ数...
for count = 1:1:Psize(2)
Pcell{count} = P(:,count); %各セルに各入力データを...
end
% 適応を開始
net = adapt(net,Pcell);
}}
--関数[[ADAPT:http://dl.cybernet.co.jp/matlab/support/man...
---SOMの適応関数として「[[TRAINS:http://dl.cybernet.co.jp...
---ADAPT 学習の入力ベクトルは、[[セル配列:http://dl.cyber...
---適応関数 trains の各ステップの処理のところでプロット命...
-~
#geshi(matlab){{
%ネットワークをバッチ型で学習させる(訓練)
% 訓練関数TRAINRのパラメータを指定
net.trainParam.epochs = 100; %最大エポック数(データセ...
net.trainParam.goal = 0; %パフォーマンスゴール
net.trainParam.show = 25; %表示する間のエポック数(...
net.trainParam.time = inf; %訓練のための最大時間(秒)
% 訓練を開始
net = train(net,P);
}}
--関数[[TRAIN:http://dl.cybernet.co.jp/matlab/support/man...
---SOMの訓練関数として「[[TRAINR:http://dl.cybernet.co.jp...
---訓練学習の経過を詳しく見たい場合は、訓練関数に '''[[tr...
-学習済みネットワークに入力ベクトルを与え、出力結果をシミ...
#geshi(matlab){{
%ネットワークのシミュレーション
a = sim(net,P); %入力ベクトルを与えて、出力ベク...
a = vec2ind(a) % 0 もしくは 1 のスパースなベク...
}}
-出力される値は、「各入力ベクトルに対する競合学習の結果、...
#geshi(matlab){{
%出力層の構造を確認
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,:), '」 のカテゴ...
' → 座標に換算すると (X,Y) = (', int2str(Xco),...
somcell{Yco,Xco} = strcat(somcell{Yco,Xco}, ' ', Pla...
end
somcell
}}
--実行結果は以下のようになります(結果は実行のたびに変わ...
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/SOM...
---「a」は学習を終えたSOMに、入力ベクトルを順番に示したと...
---「outputFields」が今回作成したSOMの構造です。四角形のB...
---最後に、入力ベクトルのラベルに従って入力ベクトルの出力...
--似た特徴量をもった入力値(動物)は、SOM上でお互いに近い...
-
-他の方法で、学習済みのSOMを評価してみます。
--学習を終えたSOMの各ノードの重み値は、
#geshi(matlab){{
wts = net.IW{1,1}
}}
とすることで確認できます。
--初期状態のSOMの、入力ベクトル空間内における各ノードの位...
#geshi(matlab){{
plotsom(net.iw{1,1},net.layers{1}.distances)
}}
とすることで確認できます。
---入力ベクトルが4次元以上の特徴量をもつ場合、[[PLOTSOM:h...
-&color(red){新しい入力値を提示するには};
--例えば、以下のような新しい入力値が、学習済み SOM ではど...
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/ani...
#geshi(matlab){{
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,:), '」 のカテゴ...
' → 座標に換算すると (X,Y) = (', int2str(Xco),...
somcell{Yco,Xco} = strcat(somcell{Yco,Xco}, ' ', Pla...
end
somcell
}}
-&color(red){SOMマップベースのクラスタリング結果表示法};
-&color(red){各ノードがどの入力値にもっとも強く対応付けら...
--各ノードの重み値 net.IW{1,1} を確認します。
***基本SOMの予備的考察 [#p3d40add]
-入力ベクトルに相関がない(重複する値がない)場合の学習結果
--SOM vs K-means法([[testSOMandKMEANS.m:http://shower.hu...
--6つの入力ベクトルを6クラスに分類([[testSomInputVector....
-カテゴリ数の評価
--[[寺島幹彦, 白谷文行, 山本公明,"自己組織化特徴マップ上...
---[[demo_somOnkyoColor.m:http://shower.human.waseda.ac.j...
---'''[[入力の数のみによる判定( L = V ):http://shower.h...
---'''[[入力の数+重みによる判定( L = V / dM ):http://s...
---両端のノードの、(すなわち存在しない)隣接ノードの重み...
-[[参考 前処理と後処理:http://dl.cybernet.co.jp/matlab/s...
***多層SOM - SOM-SOM型 [#pddca1e0]
-&color(red){以下は編集途中のコンテンツです。};
-[[参考 2006.05.30 抑制を加えた単層SOMと多層SOMの考察:htt...
~
-ここで作成するSOMは、1層目、2層目ともに5×4の二次元マップ...
--第 1 層 : 中間層、 第 2 層 : 出力層 です。
-入力ベクトルの宣言までは、単層と同じです。
#geshi(matlab){{
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 軸のサイズ、特徴量の数)、列数(...
[ipSizeY,ipSizeX] = size(P)
% 入力層の要素の範囲を生成
iprange = [min(P') ; max(P')]'; %[最小値 最...
-続いて、新規のネットワークオブジェクトを生成して、SOMの...
opSizeX = 5;
opSizeY = 4;
s = [opSizeX*opSizeY opSizeX*opSizeY]; %[第1層のニ...
Nl = length(s); %ニューロン...
% ネットワークアーキテクチャ
net = network(1, Nl);
% 引数 : 入力層の数 = 1、層の数 = Nl(2) (その他の設定...
for countLayer = 1:1:Nl
net.biasConnect(countLayer) = 0; %バイアスの...
end
net.inputConnect(1,1) = 1; %層 1 のみ入...
for countLayer = 2:1:Nl
% 各層の結合の有無( countLayer 番目の層から countLayer-...
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); % cou...
net.layers{countLayer}.transferFcn = 'compet'; % co...
end
% 各層の重み行列学習関数
% 1番目の入力層から 1 番目の層(中間層)への重み行列学...
net.inputWeights{1,1}.learnFcn = 'learnsom'; % LEA...
% 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'...
net.layerWeights{countLayer,1}.learnParam.order_lr =...
net.layerWeights{countLayer,1}.learnParam.order_step...
net.layerWeights{countLayer,1}.learnParam.tune_lr = ...
net.layerWeights{countLayer,1}.learnParam.tune_nd = ...
end
% 訓練関数
net.trainFcn = 'trainr'
% 初期化関数
net.initFcn = 'initlay'; %INITLAY(層...
% 層から層への重み行列初期化関数
for countLayer = 2:1:Nl
net.layerWeights{countLayer,countLayer-1}.initFcn = ...
end
% 入力層から層 1 への重み行列初期化関数
net.inputWeights{1,1}.initFcn = 'midpoint'; %MIDPOINT(...
% 初期化を実行
net = init(net);
}}
-これでネットワークの初期設定が終わりました。
--初期状態の(初期化された)SOMの各ノードの重み値は、
#geshi(matlab){{
wtsL1 = net.IW{1,1} % 1 番目の入力層から 1 番目の...
wtsL2 = net.LW{2,1} % 1 番目の層から 2 番目の層へ...
}}
とすることで確認できます。関数 MIDPOINT によって入力範囲...
-続いて、学習(重みとバイアスの更新)を行います。
#geshi(matlab){{
%ネットワークをバッチ型で学習させる(訓練)
net.trainParam.epochs = 100; %入力ベクトルを100エポック...
net.trainParam.goal = 0; %パフォーマンスゴール
net.trainParam.show = 25; %表示する間のエポック数(...
net.trainParam.time = inf; %訓練のための最大時間(秒)
net = train(net,P); %学習開始(入力ベクトルに...
}}
-学習済みネットワークに入力ベクトルを与え、出力結果をシミ...
#geshi(matlab){{
% ネットワークのシミュレーション
P %入力ベクトル
% 出力層の構造を確認
outputFields = [];
for count = 1:1:(opSizeX * opSizeY)
outputFields = [outputFields count];
end
% 各入力ベクトルをSOMのマップ型に並べ替えて出力
outputFields = reshape( outputFields, opSizeX, opSizeY )
% ネットワークのシミュレーション 1層目
% 入力層 ⇔ 1 層目 と同じ構造、重みの単層ネットワークを...
% もっとうまいやり方があるかも?
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 番目の入力層から ...
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,:), '」 のカテゴ...
' → 座標に換算すると (X,Y) = (', int2str(Xco),...
Pcell{Yco,Xco} = strcat(Pcell{Yco,Xco}, ' ', Plabel(...
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,:), '」 のカ...
' → 座標に換算すると (X,Y) = (', int2str(X...
Pcell{Yco,Xco} = strcat(Pcell{Yco,Xco}, ' ', Pla...
end
Pcell
end
}}
-デモプログラム
--[[test2LaySOM3.m:http://shower.human.waseda.ac.jp/~m-ko...
***多層SOM - SOM-教師あり型 [#v0844101]
***Tips [#u39cd1ca]
-アーキテクチャ
--[[関数 learnsom:http://www.mathworks.com/access/helpdes...
--[[Neural Network Toolbox および SOM のアーキテクチャに...
→ 逐次型学習とバッチ型学習(エポックとステップ) の違い
→ 競合学習関数 COMPET のアルゴリズム(自作したSimnetとの...
→ 自己組織化マップの重み付け変更関数 LEARNSOM のアルゴリ...
→ 離散入力値/連続入力値、入力値の相関と学習結果に関して
終了行:
#access
#analog
-目次
#contents
**自己組織化マップ(Self-Organizing Maps, SOM) [#c502a786]
-リファレンス
--[[競合学習ネットワーク:http://www.mathworks.com/access/...
--[[自己組織化マップ:http://www.mathworks.com/access/help...
--[[デモンストレーション:http://www.mathworks.com/access/...
--[[サブプロパティ net.layers のリファレンス:http://dl.cy...
--[[トポロジー関数、距離関数のカスタマイズ:http://dl.cybe...
~
***学習に使用するデータ [#jeb2f023]
-入力として使うのは、おなじみのあれ((Teuvo Kohonen (1995)...
あれ →
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/ani...
--横軸の特徴量の数は、入力層の要素(ノード)数に対応しま...
--縦軸の1行が、逐次型(適応)学習の1回のステップで与えら...
--また、この13×16の入力ベクトルセットが、バッチ型(訓練)...
***基本SOM(単層) [#uef1e63e]
-まずは、Neural Network Toolbox での基本SOMの実装について...
--ここで作成するSOMは、5×4の二次元マップとします。
-まずは入力値と、入力値のラベル(それぞれのデータ名)を宣...
#geshi(matlab){{
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';
}}
--MATLABの仕様では、ネットワークへの入力ベクトルは、行成...
-関数 NETWORK の引数にするために、作成した入力ベクトルの...
#geshi(matlab){{
% 入力ベクトルの行数(Y 軸のサイズ、特徴量の数)、列数(...
[ipSizeY,ipSizeX] = size(P)
% 入力層の要素の範囲を生成
iprange = [min(P') ; max(P')]'; %[最小値 最大値]を特徴...
}}
-続いて、新規のネットワークオブジェクトを生成して、SOMの...
#geshi(matlab){{
opSizeX = 5; %SOM の X 軸(横軸、列成分)のセ...
opSizeY = 4; %SOM の Y 軸(縦軸、行成分)のセ...
% ネットワークアーキテクチャ
net = network(1,1,[0],[1],[0],[1],[0]); %新...
% 引数 : 入力数 = 1、層の数 = 1、層 1 はバイアスをもたな...
% 層 1 は他層との重みをもたない、層 1 は出力をも...
% 入力層の要素の範囲
net.inputs{1}.range = iprange; %入...
% 層 1 の物理的な次元
net.layers{1}.dimensions = [opSizeX opSizeY]; %SOM...
% 層の次元から層 1 のニューロンの位置を求めるトポロジー...
net.layers{1}.topologyFcn = 'gridtop'; %GRI...
% ニューロンの位置から層 1 のニューロン間の距離を求める...
net.layers{1}.distanceFcn = 'boxdist'; %BOX...
% 入力層から層 1 への重み関数
net.inputWeights{1,1}.weightFcn = 'negdist'; %NEG...
% 層 1 の伝達関数
net.layers{1}.transferFcn = 'compet'; %COM...
% 入力層から層 1 への重み行列の更新関数(学習関数)
net.inputWeights{1,1}.learnFcn = 'learnsom'; %LEA...
% 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'; %TRA...
% 訓練関数
net.trainFcn = 'trainr'; %TRA...
% 初期化(Initialization)
net.initFcn = 'initlay'; %INI...
% 層 1 を初期化するために用いる関数
net.layers{1}.initFcn = 'initwb'; %INI...
% 入力層から層 1 への重み行列初期化関数
net.inputWeights{1,1}.initFcn = 'midpoint'; %MID...
net = init(net); %初...
}}
--「''トポロジー関数(topologyFcn )''」とは、SOMの層上の...
--「''距離関数(distanceFcn )''」とは、SOMの層上のノード...
--伝達関数(各ノードの出力)には、[[COMPET:http://dl.cybe...
--学習関数(各ノードの重み付け変更)には、[[LEARNSOM:http...
--初期化関数には、[[MIDPOINT:http://dl.cybernet.co.jp/mat...
---入力ベクトルに依存しない初期化関数として、[[INITZERO:h...
---サンプル:[[これ:http://shower.human.waseda.ac.jp/~m-k...
~
~
--ここまでと同様の処理(ネットワークオブジェクトを宣言 ~...
#geshi(matlab){{
net = newsom(iprange,[5 4],'gridtop','boxdist', 0.9, 100...
}}
とすることでも実現できます。
-これでネットワークの初期設定が終わりました。
--構造体netの中身は、
net
とすることで確認できます。
--初期状態の(初期化された)SOMの各ノードの重み値は、
#geshi(matlab){{
wts = net.IW{1,1}
}}
とすることで確認できます。関数 MIDPOINT によって入力範囲...
--初期状態のSOMの、入力ベクトル空間内における各ノードの位...
#geshi(matlab){{
plotsom(net.iw{1,1},net.layers{1}.distances)
}}
とすることで確認できます。赤い点が初期ニューロンのベクト...
---実行結果は以下のようになります。~
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/SOM...
---「Warning - PLOTSOM only shows first three dimensions....
---2次元の入力ベクトルによるSOMの学習例については、[[これ...
-続いて、学習(重みとバイアスの更新)を行います。
--逐次型の適応学習(ADAPT)か、バッチ型の訓練学習(TRAIN...
-~
#geshi(matlab){{
%ネットワークを逐次型で学習させる(適応)
net.adaptParam.passes = 100; %TRAINSのパラメータ(連...
%入力ベクトルをセル配列に格納
Psize = size(P); %入力ベクトルのデータ数...
Pcell = cell(1,Psize(2)); %入力ベクトルのデータ数...
for count = 1:1:Psize(2)
Pcell{count} = P(:,count); %各セルに各入力データを...
end
% 適応を開始
net = adapt(net,Pcell);
}}
--関数[[ADAPT:http://dl.cybernet.co.jp/matlab/support/man...
---SOMの適応関数として「[[TRAINS:http://dl.cybernet.co.jp...
---ADAPT 学習の入力ベクトルは、[[セル配列:http://dl.cyber...
---適応関数 trains の各ステップの処理のところでプロット命...
-~
#geshi(matlab){{
%ネットワークをバッチ型で学習させる(訓練)
% 訓練関数TRAINRのパラメータを指定
net.trainParam.epochs = 100; %最大エポック数(データセ...
net.trainParam.goal = 0; %パフォーマンスゴール
net.trainParam.show = 25; %表示する間のエポック数(...
net.trainParam.time = inf; %訓練のための最大時間(秒)
% 訓練を開始
net = train(net,P);
}}
--関数[[TRAIN:http://dl.cybernet.co.jp/matlab/support/man...
---SOMの訓練関数として「[[TRAINR:http://dl.cybernet.co.jp...
---訓練学習の経過を詳しく見たい場合は、訓練関数に '''[[tr...
-学習済みネットワークに入力ベクトルを与え、出力結果をシミ...
#geshi(matlab){{
%ネットワークのシミュレーション
a = sim(net,P); %入力ベクトルを与えて、出力ベク...
a = vec2ind(a) % 0 もしくは 1 のスパースなベク...
}}
-出力される値は、「各入力ベクトルに対する競合学習の結果、...
#geshi(matlab){{
%出力層の構造を確認
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,:), '」 のカテゴ...
' → 座標に換算すると (X,Y) = (', int2str(Xco),...
somcell{Yco,Xco} = strcat(somcell{Yco,Xco}, ' ', Pla...
end
somcell
}}
--実行結果は以下のようになります(結果は実行のたびに変わ...
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/SOM...
---「a」は学習を終えたSOMに、入力ベクトルを順番に示したと...
---「outputFields」が今回作成したSOMの構造です。四角形のB...
---最後に、入力ベクトルのラベルに従って入力ベクトルの出力...
--似た特徴量をもった入力値(動物)は、SOM上でお互いに近い...
-
-他の方法で、学習済みのSOMを評価してみます。
--学習を終えたSOMの各ノードの重み値は、
#geshi(matlab){{
wts = net.IW{1,1}
}}
とすることで確認できます。
--初期状態のSOMの、入力ベクトル空間内における各ノードの位...
#geshi(matlab){{
plotsom(net.iw{1,1},net.layers{1}.distances)
}}
とすることで確認できます。
---入力ベクトルが4次元以上の特徴量をもつ場合、[[PLOTSOM:h...
-&color(red){新しい入力値を提示するには};
--例えば、以下のような新しい入力値が、学習済み SOM ではど...
&ref(http://shower.human.waseda.ac.jp/~m-kouki/matlab/ani...
#geshi(matlab){{
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,:), '」 のカテゴ...
' → 座標に換算すると (X,Y) = (', int2str(Xco),...
somcell{Yco,Xco} = strcat(somcell{Yco,Xco}, ' ', Pla...
end
somcell
}}
-&color(red){SOMマップベースのクラスタリング結果表示法};
-&color(red){各ノードがどの入力値にもっとも強く対応付けら...
--各ノードの重み値 net.IW{1,1} を確認します。
***基本SOMの予備的考察 [#p3d40add]
-入力ベクトルに相関がない(重複する値がない)場合の学習結果
--SOM vs K-means法([[testSOMandKMEANS.m:http://shower.hu...
--6つの入力ベクトルを6クラスに分類([[testSomInputVector....
-カテゴリ数の評価
--[[寺島幹彦, 白谷文行, 山本公明,"自己組織化特徴マップ上...
---[[demo_somOnkyoColor.m:http://shower.human.waseda.ac.j...
---'''[[入力の数のみによる判定( L = V ):http://shower.h...
---'''[[入力の数+重みによる判定( L = V / dM ):http://s...
---両端のノードの、(すなわち存在しない)隣接ノードの重み...
-[[参考 前処理と後処理:http://dl.cybernet.co.jp/matlab/s...
***多層SOM - SOM-SOM型 [#pddca1e0]
-&color(red){以下は編集途中のコンテンツです。};
-[[参考 2006.05.30 抑制を加えた単層SOMと多層SOMの考察:htt...
~
-ここで作成するSOMは、1層目、2層目ともに5×4の二次元マップ...
--第 1 層 : 中間層、 第 2 層 : 出力層 です。
-入力ベクトルの宣言までは、単層と同じです。
#geshi(matlab){{
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 軸のサイズ、特徴量の数)、列数(...
[ipSizeY,ipSizeX] = size(P)
% 入力層の要素の範囲を生成
iprange = [min(P') ; max(P')]'; %[最小値 最...
-続いて、新規のネットワークオブジェクトを生成して、SOMの...
opSizeX = 5;
opSizeY = 4;
s = [opSizeX*opSizeY opSizeX*opSizeY]; %[第1層のニ...
Nl = length(s); %ニューロン...
% ネットワークアーキテクチャ
net = network(1, Nl);
% 引数 : 入力層の数 = 1、層の数 = Nl(2) (その他の設定...
for countLayer = 1:1:Nl
net.biasConnect(countLayer) = 0; %バイアスの...
end
net.inputConnect(1,1) = 1; %層 1 のみ入...
for countLayer = 2:1:Nl
% 各層の結合の有無( countLayer 番目の層から countLayer-...
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); % cou...
net.layers{countLayer}.transferFcn = 'compet'; % co...
end
% 各層の重み行列学習関数
% 1番目の入力層から 1 番目の層(中間層)への重み行列学...
net.inputWeights{1,1}.learnFcn = 'learnsom'; % LEA...
% 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'...
net.layerWeights{countLayer,1}.learnParam.order_lr =...
net.layerWeights{countLayer,1}.learnParam.order_step...
net.layerWeights{countLayer,1}.learnParam.tune_lr = ...
net.layerWeights{countLayer,1}.learnParam.tune_nd = ...
end
% 訓練関数
net.trainFcn = 'trainr'
% 初期化関数
net.initFcn = 'initlay'; %INITLAY(層...
% 層から層への重み行列初期化関数
for countLayer = 2:1:Nl
net.layerWeights{countLayer,countLayer-1}.initFcn = ...
end
% 入力層から層 1 への重み行列初期化関数
net.inputWeights{1,1}.initFcn = 'midpoint'; %MIDPOINT(...
% 初期化を実行
net = init(net);
}}
-これでネットワークの初期設定が終わりました。
--初期状態の(初期化された)SOMの各ノードの重み値は、
#geshi(matlab){{
wtsL1 = net.IW{1,1} % 1 番目の入力層から 1 番目の...
wtsL2 = net.LW{2,1} % 1 番目の層から 2 番目の層へ...
}}
とすることで確認できます。関数 MIDPOINT によって入力範囲...
-続いて、学習(重みとバイアスの更新)を行います。
#geshi(matlab){{
%ネットワークをバッチ型で学習させる(訓練)
net.trainParam.epochs = 100; %入力ベクトルを100エポック...
net.trainParam.goal = 0; %パフォーマンスゴール
net.trainParam.show = 25; %表示する間のエポック数(...
net.trainParam.time = inf; %訓練のための最大時間(秒)
net = train(net,P); %学習開始(入力ベクトルに...
}}
-学習済みネットワークに入力ベクトルを与え、出力結果をシミ...
#geshi(matlab){{
% ネットワークのシミュレーション
P %入力ベクトル
% 出力層の構造を確認
outputFields = [];
for count = 1:1:(opSizeX * opSizeY)
outputFields = [outputFields count];
end
% 各入力ベクトルをSOMのマップ型に並べ替えて出力
outputFields = reshape( outputFields, opSizeX, opSizeY )
% ネットワークのシミュレーション 1層目
% 入力層 ⇔ 1 層目 と同じ構造、重みの単層ネットワークを...
% もっとうまいやり方があるかも?
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 番目の入力層から ...
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,:), '」 のカテゴ...
' → 座標に換算すると (X,Y) = (', int2str(Xco),...
Pcell{Yco,Xco} = strcat(Pcell{Yco,Xco}, ' ', Plabel(...
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,:), '」 のカ...
' → 座標に換算すると (X,Y) = (', int2str(X...
Pcell{Yco,Xco} = strcat(Pcell{Yco,Xco}, ' ', Pla...
end
Pcell
end
}}
-デモプログラム
--[[test2LaySOM3.m:http://shower.human.waseda.ac.jp/~m-ko...
***多層SOM - SOM-教師あり型 [#v0844101]
***Tips [#u39cd1ca]
-アーキテクチャ
--[[関数 learnsom:http://www.mathworks.com/access/helpdes...
--[[Neural Network Toolbox および SOM のアーキテクチャに...
→ 逐次型学習とバッチ型学習(エポックとステップ) の違い
→ 競合学習関数 COMPET のアルゴリズム(自作したSimnetとの...
→ 自己組織化マップの重み付け変更関数 LEARNSOM のアルゴリ...
→ 離散入力値/連続入力値、入力値の相関と学習結果に関して
ページ名:
既存のページ名で編集する