# Self organising map classifying everything to one coordinate

1. Nov 20, 2015

### NotASmurf

Hey all,just coded this SOM based on the explination on the ai-junkie website, it seems to place all the input vectors in one single common coordinate, what am I doing wrong? I suspect its the training loop as that was the one part that the site was unclear about, Any help appreciated.

Code (Text):
static void Main(string[] args)
{
SOM som = new SOM(3, 5, 2, 0.1, new double[][] { new double[] {0,0,0 }, new double[] {0,0,0 } },0.00000001);
List<string> lines = new List<string>();
som.training_data = new double[lines.Count][];

for (int i = 0; i < som.training_data.Length; i++)
{
string[] h = lines[i].Split(',');
som.training_data[i] = new double[h.Length-1];
for (int j = 1; j < h.Length; j++)
{
som.training_data[i][j - 1] = Convert.ToSingle(h[j]);
}
}

som.Train();
for (int i = 0; i < som.training_data.Length; i++)
{
var best = som.Classify(som.training_data[i]);
Console.WriteLine(lines[i].Split(',')[0]+" "+best[0]+" "+best[1]);
}

}
}
public class MathUtil
{
public static double Exp(double map_rad, double t, double lambda)
{
return map_rad * Math.Exp(-1 * (t / lambda));
}
public static double ExpLearn(double t, double lambda)
{
return Math.Exp(-1 * (t / lambda));
}
public static double Gaussian(int iteration, double distance, double neigh)
{
return Math.Exp(-1 * ((distance * distance) / 2 * neigh * neigh));
}
}
public class Node
{
public double[] vec;
public double error;
Random r = new Random();
public Node(int dim)
{
vec = new double[dim];
for (int i = 0; i < dim; i++)
{
vec[i] = r.NextDouble();
}
}
public double Distance(double[] vec)
{
double sum = 0;
for (int i = 0; i < vec.Length; i++)
{
sum += Math.Pow(this.vec[i] - vec[i], 2);
}
return Math.Sqrt(sum);
}
public static double Distance(double[] vec,double[] vec2)
{
double sum = 0;
for (int i = 0; i < vec.Length; i++)
{
sum += Math.Pow(vec[i] - vec2[i], 2);
}
return Math.Sqrt(sum);
}
public double UpdateWeight(double[] inp_vec, double learn, int iteration, double neigh)
{
double sum = 0;
for (int i = 0; i < inp_vec.Length; i++)
{
double delta = learn * MathUtil.Gaussian(iteration, Distance(inp_vec), neigh) * (vec[i] - inp_vec[i]);
vec[i] = vec[i] + delta;
sum += delta;
}
error = sum / vec.Length;
return sum / vec.Length;
}

{
double square_sum = 0;
for (int i = 0; i < pos_me.Length; i++)
{
square_sum += Math.Pow(pos_me[i] - pos_win[i], 2);
}
{
return true;
}
return false;
}
}

public class SOM
{
public Node[,] nodes;
public double width;
public Random r = new Random();
public double[][] training_data;
public double height;
public double Max_Error;
public double learn_t0;

public int[] Classify(double[] vec)
{
int[] best = new int[2];
best = GetBMU(vec);
return best;
}
public double GetError()
{
double error = 0;
for (int i = 0; i < nodes.GetLength(0); i++)
{
for (int j = 0; j < nodes.GetLength(1); j++)
{
error += nodes[i, j].error;
}
}
return error;
}
{
}
public double LearnFac(int iteration)
{
return learn_t0 * MathUtil.ExpLearn(iteration, lambda(iteration));
}
public double lambda(int iteration)
{
}
{
get
{
return Math.Max(width, height) / 2;
}
}

public int[] GetBMU(double[] ran_tr_vec)
{
int[] best = new int[2];
double smallest = double.MaxValue;
for (int i = 0; i < nodes.GetLength(0); i++)
{
for (int j = 0; j < nodes.GetLength(1); j++)
{
if (Node.Distance(nodes[i, j].vec, ran_tr_vec) < smallest)
{
best[0] = i;
best[1] = j;
}
}
}
return best;
}
public void Train()
{
for (int u = 0; u < 10000; u++)//while(GetError()>Max_Error)//
{
for (int ind = 0; ind < training_data.Length; ind++)
{
int iter = u;
var inp_vec = training_data[ind];//r.Next(0, training_data.Length)];
int[] best = GetBMU(inp_vec);
#region Update_Weights
for (int i = 0; i < nodes.GetLength(0); i++)
{
for (int j = 0; j < nodes.GetLength(1); j++)
{
{
}
}
}
#endregion
}
Console.WriteLine(GetError());
}
}
public SOM(int dim, int len, int bredth, double learn, double[][] tr_data, double Max_Error)
{
#region ini
training_data = tr_data;
learn_t0 = learn;
width = bredth;
height = len;
this.Max_Error = Max_Error;
nodes = new Node[len, bredth];
for (int i = 0; i < nodes.GetLength(0); i++)
{
for (int j = 0; j < nodes.GetLength(1); j++)
{
nodes[i, j] = new Node(dim);
}
}
#endregion

}
}
}

2. Nov 20, 2015

### NotASmurf

The exact glitch seems to be that it always classify things as the dimension vector - (1,1) if it has width 5 and length 6 it would classify everything as (4,5). Any ideas?