Info

This question is closed. Reopen it to edit or answer.

implement 2D Self-Organized-Maps output wrong answer in matlab

1 view (last 30 days)
I have read the SOM algorithm form here http://www.ai-junkie.com/ann/som/som2.html and I tried using the matlab to implement it.
What I have encountered problem is that the cluster output for all nodes is the same.
It should output 9 cluster in the form of 9 distinct 2D point.
=====Input layer=====
And I use generate 9 type data from normal distribution means: form [1,1], [2,2] ~[9,9].
Wach type has 9 samples.
I use cell array which each element store one 2D point.
=====Output layer=====
I use the 3 X 3 map that will output 9 cluster.
I use cell array which each element store one 2D point.
=====Problem encountered=====
I have checked the algorithm for many times and cannot find the error.
Please point out the error, I cannot figure it out by myself and I have spent time for debugging about all two days.
Or you can give me some suggestion or advice to get a better approach, please.
Thank for your help in advance.
=====Code implementation=====
% ==========initialization part==========
% data
% how many cluster(output node)
clusterSize = 9;
% how many data(input number)
dataSize = 81;
% data dimension(input node)
dataDimension = sqrt(dataSize);
% cluster dimension(map width or map length, I use square map)
clusterDimension = sqrt(clusterSize);
% parameter
% neighbor radius
iniRadius = clusterDimension / 2;
curRadius = iniRadius;
% learning rate
iniRate = 0.1;
curRate = iniRate;
% how many iteration time shoud do
curEpoch = 1;
maxEpoch = 2000;
% used to update radius by the formula
timeConstant = 1000 / log(iniRadius);
% stroe the distance between one input vector to all the output node
distanceCluster = zeros(clusterDimension, clusterDimension);
% store the distance between BMU and one outputNode
distanceBMU = zeros(clusterDimension, clusterDimension);
% used to update weight by the formula
influence = 0;
% used to display how many progress finished
progress = 0;
% generate data
% generate data by normal distribution from [1,1] [2,2] .... [9.9]
% data{1, j}, data{2,j} ........... are the same type if the j is the same
data = cell(dataDimension, dataDimension);
for i = 1:dataDimension
for j = 1:dataDimension
data{i, j} = normrnd([j, j], 0.1, 1, 2);
end
end
% random weight
% using random number to initial weight
cluster = cell(clusterDimension, clusterDimension);
for i = 1:clusterDimension
for j = 1:clusterDimension
cluster{i, j} = rand(1,2);
end
end
% ==========training part==========
for t = 1:maxEpoch
% diplay progress
% display the progress the program has finished
if(mod(t, maxEpoch / 10) == 0)
progress = progress + 10;
disp(['progress has finished: ' num2str(progress) '% ......']);
end
for i = 1:dataDimension
for j = 1:dataDimension
% given one input vector
tempData = cell2mat(data(i, j));
% calculate distance between data and cluster
% iterate over all the output node for one input vector
for k = 1:clusterDimension
for l = 1:clusterDimension
% given one output node
tempCluster = cell2mat(cluster(k, l));
% calculate the distacne between one input vector to one output node
distanceCluster(k, l) = sqrt(sum((tempData - tempCluster).^2));
end
end
% BestMatchUnit(BMU)
% get the min distance by sort the distance
[V I] = min(distanceCluster(:));
% get the index of them
[I1,I2] = ind2sub(size(distanceCluster),I);
% store the BMU vector
BMU = cell2mat(cluster(I1, I2));
% update weight
% calculate distance between cluster and BMU
% iterate over all the output node for update weight
for k = 1:clusterDimension
for l = 1:clusterDimension
% given one output node
tempCluster = cell2mat(cluster(k, l));
% following are by the formula
% calculate the distance between BMU and one output node
distanceBMU = sqrt(sum((BMU - tempCluster).^2));
% calculate the influence by the formula
influence = exp((- distanceBMU * distanceBMU) / (2 * curRadius * curRadius));
% update the weight
cluster{k, l} = cluster{k, l} + influence * curRate * (tempData - cluster{k, l});
end
end
end
end
% update the neighbor radius and learning rate
curRadius = iniRadius * exp(-t / timeConstant);
curRate = iniRate * exp(-t / 1000);
end
  2 Comments
Greg Heath
Greg Heath on 9 Jun 2014
Do you think it is disrespectful to ask someone to try, without pay, to understand uncommented code that is that lengthy?

Answers (1)

Image Analyst
Image Analyst on 9 Jun 2014
Follow this link and it will most likely lead you to the solution: http://blogs.mathworks.com/videos/2012/07/03/debugging-in-matlab/
  1 Comment
Greg Heath
Greg Heath on 9 Jun 2014
Edited: Greg Heath on 9 Jun 2014
The program runs without error. What is the resulting answer and why is it wrong?

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!