HopField Neural Network in Simple Java
In 1982 Dr. John Hopfield illustrated the the concept of Hopfield artificial neural network. The hopfield artificial neural network can be use to understand some functionalities of a human brain. Basically the hopfield artificial neural network can be use to memorize single or more patterns and reconstruct the pattern based on the partial input of the pattern.
This post is about java code of a simple hopfield neural network. Bellow java code illustrate how hopfield neural network stores a 4 bit binary pattern and recall the pattern based on the input partial pattern. Please copy past this code segment to a notepad, compile and run it.
HopField class
package HopField;
public class Hopfield {
int NETWORK_SIZE = 4;// size of the network
int matrix[][] = new int[NETWORK_SIZE][NETWORK_SIZE];// 2D array to stor
// weight matrix
int input[] = new int[NETWORK_SIZE];// array to stor the inputs
int output[] = new int[NETWORK_SIZE];// array to stor the outputs
// initialize the pattern that network is going to learn
public void initpattern() {// input pattern.the network is going to learn
// this pattern
input[0] = 0;
input[1] = 1;
input[2] = 0;
input[3] = 1;
}
// initialize the weight matrix
// |0 0 0 0|
// |0 0 0 0|
// |0 0 0 0|
// |0 0 0 0|
public void initweight() {
for (int row = 0; row < NETWORK_SIZE; row++) {
for (int col = 0; col < NETWORK_SIZE; col++) {
matrix[row][col] = 0;
}
}
}
// train the network
public void train() {
int work[][] = new int[NETWORK_SIZE][NETWORK_SIZE];// 2d array to store
// the results of
// multiplication of
// the
// input sequence by
// its transposition
int bipolar[] = new int[NETWORK_SIZE];// array to stor the bipolar
// values of
// the input pattern
// first convert to bipolar(0=-1, 1=1)
for (int x = 0; x < NETWORK_SIZE; x++) {
if (input[x] == 0)
bipolar[x] = -1;
else
bipolar[x] = 1;
}
// multiply bipoler with its transpose
for (int row = 0; row < NETWORK_SIZE; row++)
for (int col = 0; col < NETWORK_SIZE; col++) {
work[row][col] = bipolar[row] * bipolar[col];// assign those
// values to
// work[][]
}
for (int x = 0; x < NETWORK_SIZE; x++)
work[x][x] -= 1;// assign 0 to weight of each of
// the four neurons back to itself
// work matrix must be added to the existing weight matrix
for (int row = 0; row < NETWORK_SIZE; row++)
for (int col = 0; col < NETWORK_SIZE; col++) {
matrix[row][col] = (matrix[row][col] + work[row][col]);
}
}
public void clear() {
for (int row = 0; row < NETWORK_SIZE; row++)
for (int col = 0; col < NETWORK_SIZE; col++)
matrix[row][col] = 0;
}
public void run() {
boolean pattern[] = new boolean[NETWORK_SIZE];
int wt[][] = new int[NETWORK_SIZE][NETWORK_SIZE];
for (int row = 0; row < NETWORK_SIZE; row++)
for (int col = 0; col < NETWORK_SIZE; col++)
wt[row][col] = matrix[row][col];
for (int row = 0; row < NETWORK_SIZE; row++) {// create a boolean array
// using input pattern
int i = input[row];
if (i == 0)
pattern[row] = false;
else
pattern[row] = true;
}
// call the layer class
Layer net = new Layer(wt);
net.activation(pattern);
// we receive a boolean array
for (int row = 0; row < NETWORK_SIZE; row++) {
if (net.output[row])
output[row] = 1;
else
output[row] = 0;
if (net.output[row] == pattern[row])
System.out.println("Position" + (row + 1) + " Correct");
else
System.out.println("Position" + (row + 1) + " Wrong");
}
}
// function to insert a pattern to network to check the similarity
public void makeChange() {
this.input[0] = 0;
this.input[1] = 1;
this.input[2] = 1;
this.input[3] = 1;
}
public static void main(String[] args) {
Hopfield hop = new Hopfield();
hop.initweight();
System.out.println("Initial Weights");
for (int row = 0; row < hop.NETWORK_SIZE; row++) {
for (int col = 0; col < hop.NETWORK_SIZE; col++) {
System.out.print(" " + hop.matrix[row][col]);
}
System.out.println();
}
System.out.println("-----------------------------------------");
hop.initpattern();
hop.train();
System.out.println("Trained Weights");
for (int row = 0; row < hop.NETWORK_SIZE; row++) {
for (int col = 0; col < hop.NETWORK_SIZE; col++) {
System.out.print(" " + hop.matrix[row][col]);
}
System.out.println();
}
System.out.println("-----------------------------------------");
System.out.println("The Network is trained for...");
for (int i = 0; i < hop.NETWORK_SIZE; i++) {
System.out.print(" " + hop.input[i]);
}
System.out.println();
hop.makeChange();
System.out.println("Input pattern to network...");
for (int i = 0; i < hop.NETWORK_SIZE; i++) {
System.out.print(" " + hop.input[i]);
}
System.out.println();
hop.run();
System.out.println("Network output");
for (int i = 0; i < hop.NETWORK_SIZE; i++) {
System.out.print(" " + hop.output[i]);
}
}
}
Layer class
package HopField;
public class Layer {
protected Neuron neuron[] = new Neuron[4];// An array of neurons
protected boolean output[] = new boolean[4];// The output of the neurons
protected int neurons;// The number of neurons in this layer. And because
// this is a single layer
// neural network, this is also the number of neurons in the network.
public static final double lambda = 1.0;// A constant to multiply against
// the threshold function. This is
// not used, and is set to 1
Layer(int weights[][]) {// Constructor
neurons = weights[0].length;// 4
neuron = new Neuron[neurons];// initiate the neuron array
output = new boolean[neurons];// initiate the output array
for (int i = 0; i < neurons; i++)
neuron[i] = new Neuron(weights[i]);
}
public boolean threshold(int k) {// The threshold method is used to
// determine if the neural network will
// fire
// for a given pattern. This threshold uses the hyperbolic tangent
// (tanh)
double kk = k * lambda;
double a = Math.exp(kk);
double b = Math.exp(-kk);
double tanh = (a - b) / (a + b);
return (tanh >= 0);
}
void activation(boolean pattern[]) {
for (int i = 0; i < 4; i++) {
neuron[i].activation = neuron[i].act(pattern);
output[i] = threshold(neuron[i].activation);
}
}
}
Neuron Class
package HopField;
public class Neuron {
public int weightv[];// The weights between this neuron and the other
// neurons on the layer
public int activation;// Activation results for this neuron
// The constructor. The weights between this neuron and every other
// neuron(including itself) is passed in as an array. Usually the weight
// between this neuron and itself is zero.
public Neuron(int in[]) {
weightv = in;
}
public int act(boolean x[]) {// This method is called to determine if the
// neuron would activate, or fireF
int temp = 0;
for (int i = 0; i < x.length; i++)
if (x[i])// if true
temp = temp + weightv[i];
return temp;
}
}
Try it....more on next
Very intersting.
ReplyDeleteRare Code
ReplyDelete