


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 classpackage 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