自己組織化マップのコードを書いてみた
自己組織化マップを簡単に勉強してみたので,
ついでにMATLABでプログラムを書いてみた.
アルゴリズムはwikipediaとかを参考に書いてみた.
RGBのデータを適当に用意して,そのデータに対してSOMを試してみた.
以下,ソースと実行結果.
ソース
% setting sample data clear; nData = 1000; data_x = 0.6*rand(nData, 3)+ 0.4; % setting node width = 10; height = 10; nNode = height * width; node_x = rand(nNode, 3); % % loop nLoop = 100; for iLoop = 1:nLoop sigma = exp(-0.01*iLoop); alpha = sigma; for iData = 1:nData dist = node_x - repmat(data_x(iData,:), nNode, 1); dist = sum(dist.^2, 2); [~, min_node_i] = min(dist); near_node_is = getNearNode(min_node_i, height, width); min_data_x = data_x(iData,:); for inn = 1:numel(near_node_is) near_node_i = near_node_is(inn); near_node_x = node_x(near_node_i,:); coff = alpha * exp(-dist(near_node_i) / sigma); node_x(near_node_i,:) = near_node_x + coff * (min_data_x - near_node_x); end end figure(1); image(reshape(node_x, height, width, 3)); drawnow; end
% メッシュ上でノードiの近傍のノードを返す function nis = getNearNode(i, h, w) y = mod(i-1, h)+1; x = ceil(i / h); foo = @(x,y) (x-1)*h + y; nis = [i]; % plane if y+1 <= h, nis = [nis, foo(x,y+1)]; end if y-1 >= 1, nis = [nis, foo(x,y-1)]; end if x+1 <= w, nis = [nis, foo(x+1,y)]; end if x-1 >= 1, nis = [nis, foo(x-1,y)]; end % taurus % nis = [nis, foo(x,mod(y,h)+1)]; % nis = [nis, foo(x,mod(y-1,h)+1)]; % nis = [nis, foo(mod(x,w)+1,y)]; % nis = [nis, foo(mod(x-1,w)+1,y)]; end
実行結果
メッシュのノードごとに出力してみた.
データは色なので,フルカラーとRGBごとに出力してみた.
それっぽくクラスタリングできてますねー.
なかなか,面白い結果.
SOMの説明には大体,ニューラルネットワークがふんたらという説明があるけど,あれじゃ全然分からないと思うんだ.
おいら,SOMの感覚は2次元多様体状のメッシュを多次元のデータにフィッティングして,データを近似する感じ.
まぁ正しいかどうかは分かんないけど.