bayerj / arac

C++ library for neural networks.
Other
39 stars 57 forks source link

bug in basic Feedforward net when _setParameters is used. #11

Closed BAM-BAM-BAM closed 13 years ago

BAM-BAM-BAM commented 13 years ago

I've found that using _setParameters on a fast (arac) network will somehow screw it up. Here's a simple script that ilustrates this. I create a three node network (one input, one hidden node, and one output node; the hidden layer is a sigmoidal layer and the other two are linear). When passing 0.0 to the input, the sigmoidal layer should output 0.5, which, when multiplied by the connection weight from the hidden to the output layer should yield the output. However, after _setParameters is called on the network, the output typically ends up being a very small number (on the order of 1e-310).

from pybrain.tools.shortcuts import buildNetwork

netSLOW = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=False) netFAST = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=True ) netSLOW.forget = True netFAST.forget = True

netSLOW_output = netSLOW.activate([0.0]) netFAST_output = netFAST.activate([0.0]) assert( netSLOW_output == [0.5_netSLOW.params[1]] ) # SUCCESS assert( netFAST_output == [0.5_netFAST.params[1]] ) # SUCCESS

netFAST._setParameters(netSLOW.params)

netFAST_output = netFAST.activate([0.0]) assert( netFAST_output == [0.5*netFAST.params[1]] ) # FAILURE!

I have no idea how to fix this! Should some method other than _setParameters be used to change parameters?

Thanks, John

bayerj commented 13 years ago

Have you tried using the .params property instead? You should be able to assign new values to the parameters by using

net.params[:] = ...

On 31 August 2011 03:15, BAM-BAM-BAM reply@reply.github.com wrote:

I've found that using _setParameters on a fast (arac) network will somehow screw it up.  Here's a simple script that ilustrates this.  I create a three node network (one input, one hidden node, and one output node; the hidden layer is a sigmoidal layer and the other two are linear).  When passing 0.0 to the input, the sigmoidal layer should output 0.5, which, when multiplied by the connection weight from the hidden to the output layer should yield the output.  However, after _setParameters is called on the network, the output typically ends up being a very small number (on the order of 1e-310).

from pybrain.tools.shortcuts import buildNetwork

netSLOW = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=False) netFAST = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=True ) netSLOW.forget = True netFAST.forget = True

netSLOW_output = netSLOW.activate([0.0]) netFAST_output = netFAST.activate([0.0]) assert( netSLOW_output == [0.5_netSLOW.params[1]] ) # SUCCESS assert( netFAST_output == [0.5_netFAST.params[1]] ) # SUCCESS

netFAST._setParameters(netSLOW.params)

netFAST_output = netFAST.activate([0.0]) assert( netFAST_output == [0.5*netFAST.params[1]] ) # FAILURE!

I have no idea how to fix this!  Should some method other than _setParameters be used to change parameters?

Thanks, John

Reply to this email directly or view it on GitHub: https://github.com/bayerj/arac/issues/11

Dipl. Inf. Justin Bayer Lehrstuhl für Robotik und Echtzeitsysteme, Technische Universität München http://www6.in.tum.de/Main/Bayerj

BAM-BAM-BAM commented 13 years ago

Well THAT makes a big difference! :)

Now I often get identical values output from both the slow and fast network. But I do get differences anywhere from 2% to 10% of the time. Good enough for me right now! Here's the code I used to test (note that I had to fix shortcuts.py to deal with recurrent networks correctly:

from numpy.random import randn
from pybrain.tools.shortcuts import buildNetwork

netSLOW = buildNetwork(1, 1, 1, bias=True , recurrent=True , fast=False)
netFAST = buildNetwork(1, 1, 1, bias=True , recurrent=True , fast=True )

netSLOW.forget = True
netFAST.forget = True

#import pdb; pdb.set_trace()

netFAST.params[:] = netSLOW.params

diffs = 0
for i in xrange(10000):
  input = [randn() for _ in xrange(netSLOW.indim)]
  netSLOW_output = netSLOW.activate(input)
  netFAST_output = netFAST.activate(input)
  #print "%5d %21.18f %21.18f %21.18f %21.18f" % (i, input[0], netSLOW_output[0],     netFAST_output[0], netFAST_output[0] - netSLOW_output[0])
  if list(netSLOW_output) != list(netFAST_output):
    diffs += 1

print "Differences:", diffs

Thanks for your help! John

BAM-BAM-BAM commented 13 years ago

Hi Justin,

Thanks for your help.

I have another question: How do you clear the inputbuffer and outputbuffer of a fast network? I would like to have the same functionality that _resetBuffers() has for slow networks; i.e. clear all the stored activations. I tried reset(), but that just sets the values to zero but maintains the previous buffer lengths. The buffer lengths grow without bound.

The only way I've been able to do this is to reset() and then call _resetBuffers(). In that order, otherwise I get segmentation faults. Is there a better way to do this?

Thanks! John

On Wed, Aug 31, 2011 at 3:50 AM, bayerj < reply@reply.github.com>wrote:

Have you tried using the .params property instead? You should be able to assign new values to the parameters by using

net.params[:] = ...

On 31 August 2011 03:15, BAM-BAM-BAM reply@reply.github.com wrote:

I've found that using _setParameters on a fast (arac) network will somehow screw it up. Here's a simple script that ilustrates this. I create a three node network (one input, one hidden node, and one output node; the hidden layer is a sigmoidal layer and the other two are linear). When passing 0.0 to the input, the sigmoidal layer should output 0.5, which, when multiplied by the connection weight from the hidden to the output layer should yield the output. However, after _setParameters is called on the network, the output typically ends up being a very small number (on the order of 1e-310).

from pybrain.tools.shortcuts import buildNetwork

netSLOW = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=False) netFAST = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=True ) netSLOW.forget = True netFAST.forget = True

netSLOW_output = netSLOW.activate([0.0]) netFAST_output = netFAST.activate([0.0]) assert( netSLOW_output == [0.5_netSLOW.params[1]] ) # SUCCESS assert( netFAST_output == [0.5_netFAST.params[1]] ) # SUCCESS

netFAST._setParameters(netSLOW.params)

netFAST_output = netFAST.activate([0.0]) assert( netFAST_output == [0.5*netFAST.params[1]] ) # FAILURE!

I have no idea how to fix this! Should some method other than _setParameters be used to change parameters?

Thanks, John

Reply to this email directly or view it on GitHub: https://github.com/bayerj/arac/issues/11

Dipl. Inf. Justin Bayer Lehrstuhl fr Robotik und Echtzeitsysteme, Technische Universitt Mnchen http://www6.in.tum.de/Main/Bayerj

Reply to this email directly or view it on GitHub: https://github.com/bayerj/arac/issues/11#issuecomment-1955345

bayerj commented 13 years ago

I don't know of a method from the top of my head.

The reason is, that Python itself never frees memory it allocated once. Thus, even reducing the size of the buffers will not result in a lower memory footprint.

Do you run into memory problems? If so, you will have to go another route. BPTT needs to have the whole sequence in memory to work. Maybe it is easier to chunk your data into sequences of lesser length.

On 31 August 2011 20:02, BAM-BAM-BAM reply@reply.github.com wrote:

Hi Justin,

Thanks for your help.

I have another question:  How do you clear the inputbuffer and outputbuffer of a fast network? I would like to have the same functionality that _resetBuffers() has for slow networks; i.e. clear all the stored activations.  I tried reset(), but that just sets the values to zero but maintains the previous buffer lengths.  The buffer lengths grow without bound.

The only way I've been able to do this is to reset() and then call _resetBuffers().  In that order, otherwise I get segmentation faults.  Is there a better way to do this?

Thanks! John

On Wed, Aug 31, 2011 at 3:50 AM, bayerj < reply@reply.github.com>wrote:

Have you tried using the .params property instead? You should be able to assign new values to the parameters by using

 net.params[:] = ...

On 31 August 2011 03:15, BAM-BAM-BAM reply@reply.github.com wrote:

I've found that using _setParameters on a fast (arac) network will somehow screw it up.  Here's a simple script that ilustrates this.  I create a three node network (one input, one hidden node, and one output node; the hidden layer is a sigmoidal layer and the other two are linear).  When passing 0.0 to the input, the sigmoidal layer should output 0.5, which, when multiplied by the connection weight from the hidden to the output layer should yield the output.  However, after _setParameters is called on the network, the output typically ends up being a very small number (on the order of 1e-310).

from pybrain.tools.shortcuts import buildNetwork

netSLOW = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=False) netFAST = buildNetwork(1, 1, 1, bias=False, recurrent=False, fast=True ) netSLOW.forget = True netFAST.forget = True

netSLOW_output = netSLOW.activate([0.0]) netFAST_output = netFAST.activate([0.0]) assert( netSLOW_output == [0.5_netSLOW.params[1]] ) # SUCCESS assert( netFAST_output == [0.5_netFAST.params[1]] ) # SUCCESS

netFAST._setParameters(netSLOW.params)

netFAST_output = netFAST.activate([0.0]) assert( netFAST_output == [0.5*netFAST.params[1]] ) # FAILURE!

I have no idea how to fix this!  Should some method other than _setParameters be used to change parameters?

Thanks, John

Reply to this email directly or view it on GitHub: https://github.com/bayerj/arac/issues/11

Dipl. Inf. Justin Bayer Lehrstuhl fr Robotik und Echtzeitsysteme, Technische Universitt Mnchen http://www6.in.tum.de/Main/Bayerj

Reply to this email directly or view it on GitHub: https://github.com/bayerj/arac/issues/11#issuecomment-1955345

Reply to this email directly or view it on GitHub: https://github.com/bayerj/arac/issues/11#issuecomment-1960079

Dipl. Inf. Justin Bayer Lehrstuhl für Robotik und Echtzeitsysteme, Technische Universität München http://www6.in.tum.de/Main/Bayerj