0
$\begingroup$

Trying to implement the Storkey rule...

I can use the below algorithm to train an initial pattern -- because it goes into the if statement and simply uses the hebbian learning/outer-product method. But if I then try to train a new pattern on top of those old weights, something odd happens: the network, when presented with the new pattern, still converges on the old one...

I think the error is with how I am computing the variable post_synaptic...?

def storkey_rule(pattern, old_weights=None):
    """
    pattern: 2-dimensional array
    old_weights: square array of length pattern.shape[0]*pattern.shape[1]
    """

    mem = pattern.flatten()
    n = len(mem)

    if type(old_weights) == type(None):
        new_weights = np.outer(mem,mem) - np.identity(n)
        return new_weights

    hebbian_term  = np.outer(mem,mem) - np.identity(n)

    net_inputs    = old_weights.dot(mem) #equivalent to (but faster than?) np.matmul(old_weights, mem)

    # I think pre_synpatic can stay put...
    pre_synaptic  = np.outer(mem,net_inputs)

    # but post-synaptic has to be changed somehow....?
    post_synaptic = pre_synaptic.T #equivalent to np.outer(net_inputs,mem)

    new_weights = old_weights + (1./n)*(hebbian_term - pre_synaptic - post_synaptic)

    return new_weights

Here's a link to the jupyter notebook where I'm developing this. You can see that when I try to train and then expose the network on/to the Neil deGrasse Tyson image, it still settles on the 'Deal with it' image it was initially trained on.

$\endgroup$
2
  • $\begingroup$ Thank you, you saved our lives and most importantly our weekend!! we love you <3 $\endgroup$
    – user372708
    Commented Nov 11, 2022 at 11:08
  • $\begingroup$ @user372708 uhhh you're welcome? lol, how did I save your lives/weekend? $\endgroup$ Commented Jan 20, 2023 at 16:10

1 Answer 1

0
$\begingroup$

Gosh, I was looking in entirely the wrong place for the problem! The matrix math was all fine (at least, with the fix I apply below, the network learns multiple patterns...). The problem was that the code in my question trained the first pattern simply on the hebbian learning rule, but subsequent patterns only got (1/n) worth of hebbian learning! In other words, the very first pattern made a huge impact on the weights, and subsequent patterns very little. That's why the code in the question caused the network to always converge on the first pattern, regardless of the input.

So to fix that, I re-wrote the if-statement.

def storkey_rule(pattern, old_weights=None)
    """
    pattern: 2-dimensional array
    old_weights: square array of length pattern.shape[0]*pattern.shape[1]
    """

    mem = pattern.flatten()
    n = len(mem)

    if type(old_weights) == type(None):
        old_weights = np.zeros(n)

    hebbian_term  = np.outer(mem,mem) - np.identity(n)

    net_inputs    = old_weights.dot(mem) #equivalent to (but faster than?) np.matmul(old_weights, mem)

    pre_synaptic  = np.outer(mem,net_inputs)
    post_synaptic = pre_synaptic.T #equivalent to np.outer(net_inputs,mem)

    new_weights = old_weights + (1./n)*(hebbian_term - pre_synaptic - post_synaptic)

    return new_weights
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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