Hopfield Pattern Recognition Application
Hopfield networks can be much larger than four neurons. For the third example, we will examine a 64-neuron Hopfield network. This network is connected to an 8x8 grid, which an application allows you to draw upon. As you draw patterns, you can either train the network with them or present them for recognition.
The user interface for the application can be seen in Figure 3.3.
Figure 3.3: A pattern recognition Hopfield application.

The source code for this example is provided in Listing 3.4.
Listing 3.4: Hopfield Pattern Recognition (HopfieldPattern.cs)
// Introduction to Neural Networks for C#, 2nd Edition // Copyright 2008 by Heaton Research, Inc. // http://www.heatonresearch.com/online/introduction-neural-networks-cs-edi... // // ISBN13: 978-1-60439-009-4 // ISBN: 1-60439-009-3 // // This class is released under the: // GNU Lesser General Public License (LGPL) // http://www.gnu.org/copyleft/lesser.html using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace Chapter03Pattern { static class HopfieldPattern { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new HopfieldRecForm()); } } }
To make use of the application, draw some sort of pattern on the grid and click “Train.” Now draw another pattern and also click “Train.” Finally, draw a pattern similar to one of the two previous patterns in the same location, and click “Go.” The network will attempt to recognize what you drew. You can also click “Clear” to clear the grid. Clicking “Clear Matrix” will clear the training matrix.
The following sections explain how the main methods of this program were constructed.
Drawing the Grid
The grid is drawn using the application’s Paint event. The signature for this method is shown here:
private void HopfieldRecForm_Paint(object sender, PaintEventArgs e)
First, obtain a Graphics object to paint to the form.
Graphics g = e.Graphics;
The grid size is defined by several constants. Unless you change these, the grid itself will be 8x8 and the cells will be 20 pixels square. This means that the buttons will take up more space than the grid; therefore, it looks better if the grid is centered. A margin is calculated to center the grid.
The margin is the actual width minus the grid's width, divided by two.
this.margin = (this.Width - (HopfieldRecForm.CELL_WIDTH * HopfieldRecForm.GRID_X)) / 2;
Next, the index variable is created. This variable holds the current position in the grid bool array. Even though the grid appears visually as an 8x8 matrix, it must be presented to the neural network as a flat 64-part Boolean pattern.
int index = 0;
Create a black SolidBrush and a black Pen object. These will be used to draw a grid.
SolidBrush brush = new SolidBrush(Color.Black); Pen pen = new Pen(Color.Black);
Two loops are then established to loop through the x and y coordinates of the grid.
for (int y = 0; y < HopfieldRecForm.GRID_Y; y++)
{
for (int x = 0; x < HopfieldRecForm.GRID_X; x++)
{ If the grid element for this cell is true, then draw a rectangle and fill it in.
if (this.grid[index++])
{
g.FillRectangle(brush, this.margin + (x *
HopfieldRecForm.CELL_WIDTH), y
* HopfieldRecForm.CELL_HEIGHT,
HopfieldRecForm.CELL_WIDTH,
HopfieldRecForm.CELL_HEIGHT);
} If the grid element for this cell is false, then draw an empty rectangle.
{
g.DrawRectangle(pen, this.margin + (x *
HopfieldRecForm.CELL_WIDTH), y
* HopfieldRecForm.CELL_HEIGHT,
HopfieldRecForm.CELL_WIDTH,
HopfieldRecForm.CELL_HEIGHT);
}The Paint method is called by C# whenever the grid needs to be redrawn. Additionally, other methods will force the Paint method to be called using the Invalidate method.
Toggling Grid Positions
The MouseDown method is called by C# whenever the mouse has been pressed. The signature for the MouseDown event is shown here:
private void HopfieldRecForm_MouseDown(object sender, MouseEventArgs e)
First, the x and y coordinates are calculated in terms of the grid position, and not the pixel coordinates that are passed to the MouseDown event.
int x = ((e.X - this.margin) / HopfieldRecForm.CELL_WIDTH); int y = e.Y / HopfieldRecForm.CELL_HEIGHT;
These coordinates must fall on the grid. If the click was outside of the grid, then the click will be ignored.
if (((x >= 0) && (x < HopfieldRecForm.GRID_X)) && ((y >= 0)
&& (y < HopfieldRecForm.GRID_Y)))
{ The index into the one-dimensional grid array is calculated, then it is toggled using the Boolean ! operator.
int index = (y * HopfieldRecForm.GRID_X) + x; this.grid[index] = !this.grid[index]; }
Finally, the application repaints the grid.
this.Invalidate();
Thus, the grid can be drawn by tracking when the mouse is released.
Training and Presenting Patterns
The “Train” and “Go” buttons allow you to train and recognize patterns respectively. The btnTrain_Click method is called whenever the “Train” button is clicked. The btnTrain_Click method is shown here:
private void btnTrain_Click(object sender, EventArgs e) {
this.hopfield.Train(this.grid);
} As you can see this method simply hands off to the Train method provided by the HopfieldNetwork class.
When the “Go” button is clicked, the Click event is called. This method is shown here.
private void btnGo_Click(object sender, EventArgs e)
{
this.grid = this.hopfield.Present(this.grid);
this.Invalidate();
}As you can see this method simply hands off to the Present method provided by the HopfieldNetwork class. The window is then redrawn to show the output from the neural network.




