//Hopfield neural net taken from: // // HNet hoppy; Buttons [] button; PFont font; PImage [] buffer; boolean [][] mouseBuffer; int state = 0; int paintRatio = 24; int rows,cols; void setup(){ size(300,200); buffer = new PImage[5]; for (int i = 0; i < buffer.length-1; i++) buffer[i] = loadImage(i+".gif"); rows = buffer[0].height; cols = buffer[0].width; buffer[buffer.length-1] = new PImage(cols,rows); mouseBuffer = new boolean[cols][rows]; button = new Buttons[5]; button[0] = new Buttons(200, 0, 100, 20, #EEEE00, "Single step", buffer[buffer.length-1]); button[1] = new Buttons(200, 20, 100, 20, #EEEE00, "Pattern 0", buffer[0]); button[2] = new Buttons(200, 40, 100, 20, #EEEE00, "Pattern 1", buffer[1]); button[3] = new Buttons(200, 60, 100, 20, #EEEE00, "Pattern 2", buffer[2]); button[4] = new Buttons(200, 80, 100, 20, #EEEE00, "Pattern 3", buffer[3]); font = loadFont("Kartika-48.vlw"); textFont(font,26); hoppy = new HNet(buffer); ellipseMode(CORNER); smooth(); } void draw(){ background(220); switch(state){ case 0: image(hoppy.buffer[hoppy.buffer.length-1],0,0,paintRatio*cols,paintRatio*rows); break; default: image(hoppy.buffer[state-1],0,0,paintRatio*cols,paintRatio*rows); break; } for(int i = 0; i < button.length; i++) button[i].draw(); if (mousePressed && overRect(0,0,paintRatio*cols,paintRatio*rows)) paint(); } void paint(){ int cr = -1; int cc = -1; for(int i = 0; i < hoppy.rows; i++) for(int j = 0; j < hoppy.cols; j++) if (overRect(i*paintRatio,j*paintRatio,paintRatio,paintRatio)){ cr = i; cc = j; } if (state == 0 && !mouseBuffer[cr][cc]){ hoppy.testPattern[cr][cc] = - hoppy.testPattern[cr][cc]; if (hoppy.buffer[buffer.length-1].get(cr,cc) == #FFFFFF) hoppy.buffer[buffer.length-1].set(cr,cc, #000000); else hoppy.buffer[buffer.length-1].set(cr,cc, #FFFFFF); hoppy.buffer[buffer.length-1].updatePixels(); } else if (!mouseBuffer[cr][cc]){ hoppy.trainPatterns[state-1][cr][cc] = - hoppy.trainPatterns[state-1][cr][cc]; if (hoppy.buffer[state-1].get(cr,cc) == #FFFFFF) hoppy.buffer[state-1].set(cr,cc, #000000); else hoppy.buffer[state-1].set(cr,cc, #FFFFFF); hoppy.buffer[state-1].updatePixels(); hoppy.retrain(); } mouseBuffer[cr][cc] = true; } void mouseReleased(){ //clear mouse buffer mouseBuffer = new boolean[cols][rows]; } void mousePressed(){ int choice = -1; for(int i = 0; i < button.length; i++) if(button[i].over()) choice = i; switch(choice){ case 0: if (state == 0) hoppy.runSingleStep(); else{ state = 0; button[0].label = "Single Step"; } break; case 1: case 2: case 3: case 4: button[0].label = "Test pattern"; state = choice; break; } } class HNet{ int maxpatterns,rows,cols,last; int [][][][] t; int [][][] trainPatterns; int [][] testPattern; PImage [] buffer; HNet(PImage [] buffer){ this.buffer = buffer; maxpatterns = buffer.length-1; rows = buffer[0].height; cols = buffer[0].width; trainPatterns = new int [maxpatterns][cols][rows]; testPattern = new int [cols][rows]; t = new int [cols][rows][cols][rows]; //connection weights setupTrainingPatterns(); // Initialise test pattern to blank for (int i = 0; i < cols; i++) for (int j = 0; j < rows; j++){ testPattern[i][j] = -1; buffer[buffer.length-1].set(i,j,#000000); } buffer[buffer.length-1].updatePixels(); } void runSingleStep(){ int new_mu[][] = new int[cols][rows]; // Holds new values of mu before copying back int i,j,k,l; // FOR loop counters for (k = 0; k < cols; k++) for (l = 0; l < rows; l++){ int sum = 0; for (i = 0; i < cols; i++) for (j = 0; j < rows; j++) sum += t[i][j][k][l] * testPattern[i][j]; if (sum > 0) // Pass through hard-limiting non-linearity new_mu[k][l] = 1; else new_mu[k][l] = -1; } // Now copy the values present in new_mu back into the test pattern ready to be displayed for (i = 0; i < cols; i++) for (j = 0; j < rows; j++){ testPattern[i][j] = new_mu[i][j]; if (new_mu[i][j] == 1) buffer[buffer.length-1].set(i,j,#FFFFFF); else buffer[buffer.length-1].set(i,j,#000000); } buffer[buffer.length-1].updatePixels(); } void retrain (){ for (int i = 0; i < cols; i++) for (int j = 0; j < rows; j++) for (int k = 0; k < cols; k++) for (int l = 0; l < rows; l++) if (i == k && j == l) t[i][j][k][l] = 0; else { int sum = 0; for (int pattern = 0; pattern < maxpatterns; pattern++) sum += trainPatterns[pattern][i][j] * trainPatterns[pattern][k][l]; t[i][j][k][l] = sum; } } void setupTrainingPatterns (){ for(int i = 0; i < trainPatterns.length; i++) for(int j = 0; j < cols; j++) for(int k = 0; k < rows; k++) if(buffer[i].pixels[j + k * cols] == #FFFFFF) trainPatterns[i][j][k] = +1; else trainPatterns[i][j][k] = -1; retrain(); } }