/* * Artificial Intelligence for Humans * Volume 3: Deep Learning and Neural Networks * Java Version * http://www.aifh.org * http://www.jeffheaton.com * * Code repository: * https://github.com/jeffheaton/aifh * * Copyright 2014-2015 by Jeff Heaton * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * For more information on Heaton Research copyrights, licenses * and trademarks visit: * http://www.heatonresearch.com/copyright */ package com.heatonresearch.aifh.examples.classic.hopfield; import com.heatonresearch.aifh.energetic.HopfieldNetwork; import com.heatonresearch.aifh.energetic.TrainHopfieldHebbian; /** * Simple class to recognize some patterns with a Hopfield Neural Network. * This version makes use of the storkey training. * * * This is very loosely based on a an example by Karsten Kutza, * written in C on 1996-01-30. (link below is no longer active) * http://www.neural-networks-at-your-fingertips.com/hopfield.html * * I translated it to Java and adapted it to use Encog for neural * network processing. I mainly kept the patterns from the * original example. * */ public class HopfieldAssociateHebbian { public static final int HEIGHT = 10; public static final int WIDTH = 10; /** * The neural network will learn these patterns. */ public static final String[][] PATTERN = { { "O O O O O ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O" }, { "OO OO OO", "OO OO OO", " OO OO ", " OO OO ", "OO OO OO", "OO OO OO", " OO OO ", " OO OO ", "OO OO OO", "OO OO OO" }, { "OOOOO ", "OOOOO ", "OOOOO ", "OOOOO ", "OOOOO ", " OOOOO", " OOOOO", " OOOOO", " OOOOO", " OOOOO" }, { "O O O O", " O O O ", " O O O ", "O O O O", " O O O ", " O O O ", "O O O O", " O O O ", " O O O ", "O O O O" }, { "OOOOOOOOOO", "O O", "O OOOOOO O", "O O O O", "O O OO O O", "O O OO O O", "O O O O", "O OOOOOO O", "O O", "OOOOOOOOOO" } }; /** * The neural network will be tested on these patterns, to see * which of the last set they are the closest to. */ public static final String[][] PATTERN2 = { { " ", " ", " ", " ", " ", " O O O O O", "O O O O O ", " O O O O O", "O O O O O ", " O O O O O" }, { "OOO O O", " O OOO OO", " O O OO O", " OOO O ", "OO O OOO", " O OOO O", "O OO O O", " O OOO ", "OO OOO O ", " O O OOO" }, { "OOOOO ", "O O OOO ", "O O OOO ", "O O OOO ", "OOOOO ", " OOOOO", " OOO O O", " OOO O O", " OOO O O", " OOOOO" }, { "O OOOO O", "OO OOOO ", "OOO OOOO ", "OOOO OOOO", " OOOO OOO", " OOOO OO", "O OOOO O", "OO OOOO ", "OOO OOOO ", "OOOO OOOO" }, { "OOOOOOOOOO", "O O", "O O", "O O", "O OO O", "O OO O", "O O", "O O", "O O", "OOOOOOOOOO" } }; public static double[] convertPattern(String[][] data, int index) { int resultIndex = 0; double[] result = new double[WIDTH*HEIGHT]; for(int row=0;row<HEIGHT;row++) { for(int col=0;col<WIDTH;col++) { char ch = data[index][row].charAt(col); result[resultIndex++] = (ch!=' ')?1:-1; } } return result; } public static void display(double[] pattern1,double[] pattern2) { int index1 = 0; int index2 = 0; for(int row = 0;row<HEIGHT;row++) { StringBuilder line = new StringBuilder(); for(int col = 0;col<WIDTH;col++) { if(pattern1[index1++]>0) line.append('O'); else line.append(' '); } line.append(" -> "); for(int col = 0;col<WIDTH;col++) { if(pattern2[index2++]>0) line.append('O'); else line.append(' '); } System.out.println(line.toString()); } } public static void evaluate(HopfieldNetwork hopfieldLogic, String[][] pattern) { for(int i=0;i<pattern.length;i++) { double[] pattern1 = convertPattern(pattern,i); hopfieldLogic.setCurrentState(pattern1); int cycles = hopfieldLogic.runUntilStable(100); double[] pattern2 = hopfieldLogic.getCurrentState(); System.out.println("Cycles until stable(max 100): " + cycles + ", result="); display( pattern1, pattern2); System.out.println("----------------------"); } } public void run() { HopfieldNetwork hopfieldLogic = new HopfieldNetwork(WIDTH*HEIGHT); TrainHopfieldHebbian train = new TrainHopfieldHebbian(hopfieldLogic); for(int i=0;i<PATTERN.length;i++) { train.addPattern(convertPattern(PATTERN, i)); } train.learn(); evaluate(hopfieldLogic,PATTERN); evaluate(hopfieldLogic,PATTERN2); } public static void main(String[] args) { HopfieldAssociateHebbian program = new HopfieldAssociateHebbian(); program.run(); } }