//
// Klasse KohonenNetz
//
// Projekt FingerPrint
//
// Written by Christian Birzer, Peter Söllner Juni 1998
//
// Die KohonenNetz - Klasse ist der Kern allen Lernens - das Gedächtnis.
// Sie definiert die Feature- und Output - Map, sowie alle notwendigen
// Initialisierungs-, Lern- und Suchfunktionen. Eine KohonenNetz - Klasse
// wird für eine bestimmte Eingangs- und Ausgangsdimension von Vektoren
// erstellt und kann dann nur mit solchen Vektoren verwendet werden.
// Zusätzlich besitzt die Klasse zwei Zeichenmethoden, die zur
// Visualisierung der Feature - Map dienen.

import java.awt.*;

public class KohonenNetz
{
private NeuroVektor m_FeatureMap[][]; // Die Feature - Map
private NeuroVektor m_OutputMap[][]; // Die Output - Map
private float m_eps, m_sig; // Aktuelle Varianz und Lernrate
private int m_zi, m_zj; // Zentrum der letzten Suche
private boolean m_autoeps=false; // Lernen mit oder ohne Autolernrate

/*
**
** Konstruktor der KohonenNetz - Klasse, der die Dimension des
** Netzes, der Eingabevektoren und der Ausgabevektoren festlegt
** und die Maps initialisiert.
**
*/
public KohonenNetz(int dim, int in, int out)
{
m_FeatureMap=new NeuroVektor[dim][dim];
m_OutputMap=new NeuroVektor[dim][dim];
// Neuronen (NeuroVektor) erzeugen.
for (int i=0; i for (int j=0; j m_FeatureMap[i][j]=new NeuroVektor(in);
m_OutputMap[i][j]=new NeuroVektor(out);
}
}

public int GetMapDim()
{
// Liefert die Dimension der Feature - Map zurück.
return m_FeatureMap.length;
}

public int GetInputDim()
{
// Liefert die Dimension der Eingabevektoren zurück.
return m_FeatureMap[0][0].GetCount();
}

public int GetOutputDim()
{
// Liefert die Dimension der Ausgabevektoren zurück.
return m_OutputMap[0][0].GetCount();
}

public NeuroVektor GetOutputVektor(int i, int j)
{
// Liefert das Neuron an der Stelle (i,j) zurück.
return m_OutputMap[i][j];
}

public float Lernrate(float eps)
{
// Setzt die Lernrate neu.
float tmp=m_eps;
m_eps=eps;
return tmp;
}

public float Varianz(float varianz)
{
// Setzt die Varianz (Radius) neu.
float tmp=m_sig;
m_sig=varianz;
return tmp;
}

public float Varianz()
{
// Gibt die Varianz zurück.
return m_sig;
}

public void AutoLernrate(boolean a)
{
// Stellt die Lernmethode ein: 'a' = true -> Autolernrate aktiv.
m_autoeps=a;
}

public boolean AutoLernrate()
{
// Liefert die aktuelle Lernmethode zurück.
return m_autoeps;
}


/*
**
** InitFeatureMap - Methoden, zur Vorbelegung der Feature - Map
** mit Anfnagswerten. Es gibt neben der klassischen Methode mit der
** Vorbelegung durch Zufallszahlen noch die Möglichkeit die Map
** definiert, in einer Art Pyramidenlandschaft vorzubelegen.
**
*/
public void InitFeatureMap(byte val)
{
// Initialisiert die Feature - Map mit einem festen Wert 'val'.
for (int i=0; i for (int j=0; j m_FeatureMap[i][j].InitVektor(val);
}

public void InitFeatureMap(byte min, byte max)
{
// Initialisiert die Feature - Map mit Zufallswerten
// zwischen dem Wert 'min' und dem Wert 'max'.
for (int i=0; i for (int j=0; j m_FeatureMap[i][j].InitVektor(min,max);
}

public void InitFeatureMap()
{
// Initialisiert die Feature - Map pyramidenförmig, mit
// bereits vorhandenen Zentren an den Spitzen (Null - Vektor).
byte max=50, ri, rj;
byte n=(byte)(m_FeatureMap.length/5), n2=(byte)(n/2);
double dy=(4*max)/(n*n), dx=0.0, val=0.0;

for (int i=0; i if ((ri=(byte)(i%n))==0) dx=0;
else dx+=((ri<=n2)?dy:-dy);
for (int j=0; j if ((rj=(byte)(j%n))==0) val=max;
else val+=((rj<=n2)?-dx:dx);
if (val>max) val=max;
m_FeatureMap[i][j].InitVektor((byte)val);
}
}
}

/*
**
** InitOutput - Methoden, zum Vorbelegen der Output - Map.
**
*/
public void InitOutputMap(byte val)
{
// Initialisiert die Output - Map mit dem festen Wert 'val'.
for (int i=0; i for (int j=0; j m_OutputMap[i][j].InitVektor(val);
}

public void InitOutputMap(byte min, byte max)
{
// Initialisiert die Output - Map mit Zufallswerten zwischen
// dem Wert 'min' und dem Wert 'max'.
for (int i=0; i for (int j=0; j m_OutputMap[i][j].InitVektor(min,max);
}

/*
**
** Zentrum - Funktion, die das Neuron mit der besten Aktivität
** bzgl. dem Eingabevektor ermittelt. Hiefür kommt die GetLevel-
** Methode der NeuroVektor - Klasse zum Einsatz.
**
**
*/
public int Zentrum(NeuroVektor input)
{
// Berechnet die Koordinaten des Neurons mit der größten
// Aktivierungsenergie für das Eingabemuster 'muster'.
int i, j, level, minlevel=Integer.MAX_VALUE;

for (i=0; i for (j=0; j // Aktivierungslevel für dieses Neuron berechnen.
level=input.GetLevel(m_FeatureMap[i][j]);
if (level // Falls besser wie das bisherige, merken und
// altes verwerfen.
minlevel=level;
m_zi=i;
m_zj=j;
}
}

return minlevel;
// Falls 'minlevel' 0 ist, dann konnte bzw. wurde Muster zu
// 100% gelernt; es existiert ein genaues Zentrum
// für diesen Eingabevektor
}

public int ZentrumI()
{
// Gibt die Zeile des Zentrum der letzten Suche zurück
// (die von der Funktion Zentrum ermittelt wurde).
return m_zi;
}

public int ZentrumJ()
{
// Gibt die Spalte des Zentrums der letzten Suche zurück
// (die von der Funktion Zentrum ermittelt wurde).
return m_zj;
}

/*
**
** LerneMuster - Funktion, die für ein Ausgabemuster ein Eingabe-
** muster anhand der aktuellen Lernrate und Varianz lernt.
**
*/
public int LerneMuster(NeuroVektor input, NeuroVektor output)
{
// Führt einen Lernschritt für das Eingabemuster 'input' und
// das dazugehörige Ausgabemuster 'output' durch.
int level=Zentrum(input), zi=0, zj=0, di, dj, i, j, z;
float sig2=(m_sig*m_sig)*2, t, eps=(float)Math.sqrt(level+1);
// Matrixgrenzen berechnen, anhand des Radius (Varianz).
int iup=m_zi+(int)m_sig, idown=(m_zi<(int)m_sig)?0:(m_zi-(int)m_sig);
int jup=m_zj+(int)m_sig, jdown=(m_zj<(int)m_sig)?0:(m_zj-(int)m_sig);

iup=(iup>m_FeatureMap.length)?m_FeatureMap.length:iup;
jup=(jup>m_FeatureMap[0].length)?m_FeatureMap[0].length:jup;

// Falls Autolernen aktiv ist, ignoriere gesetzte Lernrate in 'm_eps'.
eps=(m_autoeps)?eps/(eps+10):m_eps;

for (i=idown; i di=i-m_zi; di*=di;
for (j=jdown; j dj=j-m_zj; dj*=dj;
t=(float)Math.exp(-((di+dj) / sig2))*eps;
// Berechne die Gewichte in der Feature - Map neu.
for (z=0; z m_FeatureMap[i][j].Add((int)(t*(input.Value(z)-m_FeatureMap[i][j].Value(z))),z);
// Berechne die Gewichte in der Output - Map neu.
for (z=0; z m_OutputMap[i][j].Add((int)(t*(output.Value(z)-m_OutputMap[i][j].Value(z))),z);
}
}
return level;
// Je kleiner 'level', um so besser ist das Zentrum ausgebildet
}

/*
// Diese Methode arbeitet nach einem modifiziertem Verfahren,
// das anhand der Varianz den Radius der Neuronenbeeinflussung
// ermittelt.
public int LerneMuster(NeuroVektor input, NeuroVektor output)
{
int level=Zentrum(input), zi=0, zj=0, di, dj, i, j, z;
float sig2=m_sig*2, t, eps=(float)Math.sqrt(level+1);
// 'r' ist maximaler Radius um das Erregungszentrum
int r=(int) Math.round(Math.sqrt(sig2*m_lim)), iup=m_zi+r, jup=m_zj+r;
int idown=(m_zi
iup=(iup>m_FeatureMap.length)?m_FeatureMap.length:iup;
jup=(jup>m_FeatureMap[0].length)?m_FeatureMap[0].length:jup;

// eps=(m_autoeps)?eps/(eps+6):m_eps; // 97,4% 100%







Home About myself My Friends's Pages

1