public class BHN
{
//Number 0, 1, 2, and 3 are
represented with the activation values of arrays a0, a1, a2, and a3.
static final int[] a0_first_test =
{
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, +1, -1, -1, -1, -1, -1, -1, +1,
-1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
-1, +1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
};
static final int[] inverted_0 =
{
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
+1, -1, -1, -1, -1, -1, -1, -1, -1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
};
static final int[] a0 =
{
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, +1, +1, +1, +1, +1, +1, +1, +1,
-1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
+1, +1, -1, -1, -1, -1, -1, -1, +1,
+1,
-1, +1, +1, +1, +1, +1, +1, +1, +1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
};
static final int[] unknown =
{
-1, -1, -1, -1, +1, +1, -1, -1, +1,
-1,
-1, +1, +1, +1, +1, +1, +1, +1, +1,
-1,
+1, +1, -1, -1, -1, +1, -1, +1, +1,
-1,
+1, +1, -1, +1, -1, +1, -1, -1, +1,
+1,
-1, +1, -1, +1, -1, -1, -1, -1, -1,
+1,
-1, +1, +1, +1, +1, +1, +1, +1, +1,
-1,
+1, -1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, -1, +1, -1, -1, -1, -1, +1, -1,
+1,
-1, -1, +1, -1, +1, +1, -1, +1, +1,
-1,
-1, +1, +1, -1, -1, -1, +1, +1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, +1, -1, -1, -1, -1, -1,
-1,
};
static final int[] a1_first_test =
{
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, +1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
};
static final int[] a1 =
{
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, +1, +1, +1, -1, -1, -1,
-1,
-1, -1, +1, +1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
};
static final int[] a1_noisy10 =
{
-1, -1, +1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, +1, +1, +1, -1, +1, -1,
-1,
-1, -1, +1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
+1,
-1, -1, +1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, +1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, +1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
+1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, +1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, +1, +1, +1, -1, +1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, -1, -1,
-1,
};
static final int[] a2_first_test =
{
-1, -1, +1, +1, +1, +1, +1, +1, -1, -1,
-1, +1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, +1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, +1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, +1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, -1, -1, -1, -1, -1, -1, +1, -1,
-1,
-1, -1, -1, -1, -1, -1, +1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, -1, -1, -1, -1,
-1,
-1, -1, -1, +1, -1, -1, -1, -1, -1,
-1,
-1, -1, +1, -1, -1, -1, -1, -1, +1,
-1,
-1, +1, +1, +1, +1, +1, +1, +1, +1, -1
};
static final int[] a2 =
{
-1, -1, +1, +1, +1, +1, +1, +1, -1, -1,
-1, +1, +1, +1, +1, +1, +1, +1, +1,
-1,
-1, +1, +1, -1, -1, -1, -1, +1, +1,
-1,
-1, +1, +1, -1, -1, -1, -1, +1, +1,
-1,
-1, +1, +1, -1, -1, -1, -1, +1, +1, -1,
-1, -1, -1, -1, -1, -1, +1, +1, -1,
-1,
-1, -1, -1, -1, -1, +1, +1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, +1, +1, -1, -1, -1, -1,
-1,
-1, -1, +1, +1, -1, -1, -1, -1, -1,
-1,
-1, +1, +1, +1, +1, +1, +1, +1, +1,
-1,
-1, +1, +1, +1, +1, +1, +1, +1, +1, -1
};
static final int[] a2_noisy20 =
{
+1, -1, +1, +1, +1, +1, -1, +1, -1, -1,
-1, +1, -1, +1, -1, +1, +1, +1, +1,
-1,
-1, +1, +1, -1, +1, +1, -1, +1, +1,
-1,
-1, -1, +1, -1, -1, -1, -1, +1, +1,
+1,
-1, -1, +1, -1, -1, +1, -1, +1, +1,
-1,
-1, +1, +1, -1, -1, -1, +1, +1, -1,
-1,
-1, -1, -1, -1, +1, -1, +1, -1, -1,
-1,
-1, -1, +1, -1, +1, +1, +1, -1, -1,
-1,
+1, -1, -1, +1, -1, -1, -1, -1, -1,
-1,
-1, -1, -1, +1, -1, -1, -1, +1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, +1, -1, +1, +1, +1, -1, +1, +1, -1
};
static final int[] a2_noisy30 =
{
+1, -1, +1, -1, +1, +1, +1, +1, +1, -1,
-1, -1, +1, +1, -1, +1, +1, +1, -1,
-1,
+1, +1, +1, -1, -1, -1, +1, +1, -1,
-1,
-1, +1, +1, +1, +1, +1, -1, +1, +1,
-1,
-1, +1, +1, -1, -1, -1, +1, -1, -1,
-1,
-1, +1, -1, -1, -1, -1, +1, -1, -1,
+1,
+1, -1, -1, +1, -1, +1, +1, +1, -1,
-1,
-1, -1, +1, -1, +1, -1, -1, -1, +1,
-1,
-1, -1, -1, -1, +1, -1, +1, -1, -1,
+1,
+1, -1, +1, +1, -1, +1, -1, -1, -1,
+1,
-1, +1, -1, +1, +1, +1, +1, -1, -1,
-1,
-1, -1, +1, +1, -1, +1, +1, +1, +1, +1
};
static final int[] a3_first_test =
{
-1, +1, +1, +1, +1, +1, +1, +1, +1, -1,
-1, -1, -1, -1, -1, -1, -1, +1, -1,
-1,
-1, -1, -1, -1, -1, -1, +1, -1, -1,
-1,
-1, -1, -1, -1, -1, +1, -1, -1, -1,
-1,
-1, -1, -1, -1, +1, -1, -1, -1, -1,
-1,
-1, -1, -1, +1, +1, +1, +1, -1, -1,
-1,
-1, -1, -1, -1, -1, -1, -1, +1, -1,
-1,
-1, -1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, -1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, -1, -1, -1, -1, -1, -1, -1, +1,
-1,
-1, -1, -1, -1, -1, -1, -1, +1, -1,
-1,
-1, +1, +1, +1, +1, +1, +1, -1, -1, -1
};
static final int[] a3 =
{
-1, +1, +1, +1, +1, +1, +1, +1, +1, -1,
-1, +1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, -1, -1, -1, +1, +1, -1, -1,
-1,
-1, -1, -1, -1, +1, +1, -1, -1, -1,
-1,
-1, -1, -1, +1, +1, -1, -1, -1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, -1, -1,
-1,
-1, -1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, -1, -1, -1, -1, -1, -1, +1, +1,
-1,
-1, -1, -1, -1, -1, -1, -1, +1, +1,
-1,
-1, -1, -1, -1, -1, -1, -1, +1, +1,
-1,
-1, +1, +1, +1, +1, +1, +1, +1, -1,
-1,
-1, +1, +1, +1, +1, +1, +1, -1, -1, -1
};
static final int MAX_NEURONS = 120;
static int[][] w; //Connection
strength matrix
static int[] a;
public static void main(String[]
args)
{
w = new int[MAX_NEURONS][MAX_NEURONS];
a = new int[MAX_NEURONS];
//-------------------------------------------------------------------------
//PART1 - training the network
//-------------------------------------------------------------------------
//Set all connection strengths to 0;
for (int i = 0; i < MAX_NEURONS; i++)
for (int j = 0; j < MAX_NEURONS; j++)
w[i][j] = 0;
//Look at
every pair of neurons and the connection strength between them.
//If a pair
neurons have the same activation we increase their connection strength by
+1.
//That means,
if they are both +1, or if they are both -1,
//the
connection strength is increased by +1.
//If the
neurons have opposite activations then the connection strength
//is decreased
by 1 (add -1).
//Set all
connection strengths for digit 0
updateConnections(a0);
//Set all
connection strengths for digit 1
updateConnections(a1);
//Set all
connection strengths for digit 2
updateConnections(a2);
//Set all
connection strengths for digit 3
updateConnections(a3);
//Debug: Print
the connection strengths at the end of the training cycle
//for (int i =
0; i < MAX_NEURONS; i++)
// for (int j = 0; j < MAX_NEURONS; j++)
// System.out.println("t[" +
i + "][" + j + "]= " + w[i][j]);
//-------------------------------------------------------------------------
//PART2 - updating the neurons
//-------------------------------------------------------------------------
System.out.println("Original
activations for digit 0 are:");
displayActivation(a0);
System.out.println("Updated
activations for digit 0 are:");
updateNeurons(a0);
displayActivation(a);
System.out.println("Original
activations for digit 1 are:");
displayActivation(a1);
System.out.println("Updated
activations for digit 1 are:");
updateNeurons(a1);
displayActivation(a);
System.out.println("Original
activations for digit 2 are:");
displayActivation(a2);
System.out.println("Updated
activations for digit 2 are:");
updateNeurons(a2);
displayActivation(a);
System.out.println("Original
activations for digit 3 are:");
displayActivation(a3);
System.out.println("Updated
activations for digit 3 are:");
updateNeurons(a3);
displayActivation(a);
System.out.println("Original
activations for digit 1 with 10 percent noise are:");
displayActivation(a1_noisy10);
System.out.println("Updated
activations for digit 1 with 10 percent noise are:");
updateNeurons(a1_noisy10);
displayActivation(a);
System.out.println("Original
activations for digit 2 with 20 percent noise are:");
displayActivation(a2_noisy20);
System.out.println("Updated
activations for digit 2 with 20 percent noise are:");
updateNeurons(a2_noisy20);
displayActivation(a);
System.out.println("Original
activations for digit 2 with 30 percent noise are:");
displayActivation(a2_noisy30);
System.out.println("Updated
activations for digit 2 with 30 percent noise are:");
updateNeurons(a2_noisy30);
displayActivation(a);
System.out.println("Original
activations for unknown pattern are:");
displayActivation(unknown);
System.out.println("Updated
activations for unknown pattern are:");
updateNeurons(unknown);
displayActivation(a);
System.out.println("Original
activations for inverted digit 0 are:");
displayActivation(inverted_0);
System.out.println("Updated
activations for inverted digit 0 are:");
updateNeurons(inverted_0);
displayActivation(a);
}
public static void updateConnections(int
[]selectedActivation)
{
//Set all
connection strengths for digit 3
for (int i = 0; i < MAX_NEURONS - 1; i++)
{
for (int j = i + 1; j
< MAX_NEURONS; j++)
{
//no unit is
connected to itself
if(i == j)
continue;
if
(selectedActivation[i] * selectedActivation[j] > 0)
{
w[i][j] = w[i][j] + 1;
w[j][i] = w[j][i] + 1;
}
else
{
w[i][j] = w[i][j] - 1;
w[j][i] = w[j][i] - 1;
}
}
}
}
public static void
displayActivation(int pattern[])
{
for (int i = 1; i <= MAX_NEURONS; i++)
{
if( pattern[i-1] == -1)
System.out.print("-");
else
System.out.print("X");
System.out.print("\t");
if(i % 10 == 0)
System.out.print("\n");
}
System.out.print("\n\n");
}
public static void updateNeurons(int[]
selectedActivation)
{
boolean cycle_complete
= false;
int[] old_a_result
= new int[MAX_NEURONS];
for (int i = 0; i < MAX_NEURONS; i++)
a[i] = 0;
while
(!cycle_complete)
{
for (int i = 0; i < MAX_NEURONS; i++)
{
double netInput = 0.0;
for (int j = 0; j < MAX_NEURONS; j++)
{
//Calculate
the net input
netInput += selectedActivation[j]
* w[i][j];
}
if (netInput >
0)
a[i] = +1;
else if (netInput <
0)
a[i] = -1;
else
a[i] =
selectedActivation[i];
cycle_complete = true; //Assume the
cycle is complete
for (int k = 0; k < MAX_NEURONS; k++)
{
if (a[k] !=
old_a_result[k])
{
old_a_result[k]
= a[k];
cycle_complete
= false;
break;
}
old_a_result[k] = a[k];
}
}
}
}
}