I am learning how to use Hopfield Neural network as a context addressable memory. The objective is to obtain a fixed point of the network which indicates an equilibrium state. This state vector remains unchanged for successive iterations and is called a fixed point. When the network reaches the fixed point, we say that a decision or goal has been reached. As can be seen from below illustration, by recursive application of the formula, X2 is the fixed point.

WeightMatrix           = [0.0 0.0 -1 0 1;
                          0.0 0.0 0 -1 0;
                          0.0 -1 0.0 0 -1;
                         -1 1.0 0.0 0.0 0.0;
                          0.0 0.0 0.0 1 0.0];

X1 = (1 0 0 0 0)   %Initial training example
X1*W = [0,0,-1,0,1];

X2 = f(X1*W) = [1,0,0,0,1]
X2*W = [0,0,-1,1,1];  X3 = f(X2*W) = [1,0,0,1,1]
X3*W = [-1,1,-1,1,1]; X4 = f(X3*W) = [1,1,0,1,1]
X4*W = [-1,1,-1,0,1]; X5 = f(X4*W) = [1,1,0,0,1]
X5*W = [0,0,-1,0,1];  X6 = f(X5*W) = [1,0,0,0,1] = X6 = **X2**

Problem : The above example is based on the paper Download link titled "Application study in decision support with fuzzy cognitive map" explains how to train a [Fuzzy Cognitive Map][2] with this example in Section 2.2. When I simulated the example, using the same logistic sigmoid thresholding function

logistic sigmoid function f(X1*W) = 1/(1+exp(-X1*W). 

, I am not getting the same output after passing the result into the thresholding function as mentioned in the paper. As a result, the program/network is iterating millions of time and not converging to a fixed point. By passing the result of X1*W into f, I am getting real valued numbers for X2 and not binary !! Same problem for the rest of the iterations.

Is there something wrong in my understanding of how convergence/memory recall is performed or is my code incorrect? Please help


Training1 = [1,0,0,0,0];

lambda =1;
 t = 1;
X(t,:) = Training1;
 err = 1; 
  Out = X(t,:)*WeightMatrix;
  temp  =  1./(1+exp(-lambda.*Out));  
  err = ((Out - temp)*(Out - temp).')/numel(temp);
t = t+1
 X(t,:) = temp;

First, since your function $f$ is not binary, you shouldn't expect to get binary outputs. The original formulation of Hopfield networks assume a binary threshold activation function. The function you're using results in something more like a mean field approximation to a Boltzmann machine. Hopfield's original paper is quite approachable and a fun read.

Second, the reason you're not getting convergence is you need to update the units asynchronously, i.e, one at at time. Assuming these dynamics it is straight forward to show that the network must converge to a fixed state because the energy function is a monotonically decreasing function of time.

edit: Responding to a comment here due to space constraints.

Say you want to store a set of $m$ binary patterns $x^{(1)}, \ldots, x^{(m)}$ with $x^{(i)} \in \{0,1\}^n$ in a Hopfield network. Then as described in equation [2] in the paper I linked, you can set

$$W_{ij} = \sum_{k=1}^m (2 x_i^{(k)} - 1)(2 x_j^{(k)} - 1)$$

if $i \neq j$ and $0$ otherwise, where $W \in \mathbb{R}^{n \times n}$ is the weight matrix.

The purpose of a Hopfield network is to act as a content addressable memory, so given a noisy version of some stored binary pattern we would like the network to output the original pattern. If you want to see this work simply take one of you original patterns, flip a few of the bits, initialize the network with the state of the noisy pattern, and iterate the dynamics of of the network until convergence $(*)$. After doing this you can compare the state the network converged to with the original pattern before applying noise. Ideally you'll recover the correct pattern, but all kinds of things can screw this up (read the original paper).

$(*)$ Because units update one at a time, simply observing that the state of the network doesn't change between two successive iterations doesn't imply the network has converged. Picking a different unit to update very well might have caused the network to change states. As such, one needs to be sure the state doesn't change even after visiting every unit to guarantee convergence.

  • $\begingroup$ Thanx for the reply & the link. In this example the authors have mentioned sigmoid function that's why I am not getting the output in binary. Is it possible to determine which thresholding they have used by looking at the example? Secondly, how do I update the weights after each input since I don't have a target to compare to in order to get an error. Could you kindly illustrate by correcting where I have gone wrong? $\endgroup$ – SKM Mar 25 '14 at 15:56
  • $\begingroup$ I edited my answer as my response was too long to post here. $\endgroup$ – alto Mar 25 '14 at 16:50
  • $\begingroup$ Jst to clarify if I understood correctly.Suppose I start with X1 = (1 0 0 0 0).W would be the weight equation which you mentioned.I compare the output of f(X1*W)= X2 with X1 i.eThis is the error = X1-X2. Then how do I update the weight from prev to the new so that X3=f(X2*W_new)?I am sorry but it is still not clear. $\endgroup$ – SKM Mar 26 '14 at 2:05

Your weight matrix has to be symmetrical when you initialize it! It's an incredibly important concept when it comes to hopfield nets, as it allows for the Hebbian learning rule to actually apply. Try initalizing it by creating a triangular matrix with zeros at the diagonal and below, then add it's tranpose. From there, it should work.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.