Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network converted from ANN doesn't retain weights after training? #601

Closed
0xnurl opened this issue Nov 29, 2022 · 3 comments
Closed

Network converted from ANN doesn't retain weights after training? #601

0xnurl opened this issue Nov 29, 2022 · 3 comments

Comments

@0xnurl
Copy link
Contributor

0xnurl commented Nov 29, 2022

First of all thank you so much for this very impressive project!

My current process:

  1. Build a deep ANN using a regular PyTorch module.
  2. Convert the ANN to SNN using bindsnet.conversion.ann_to_snn().
  3. Train the SNN using Network.run()

For training, I am following the training and test methods in examples/eth_mnist.py.
For conversion from ANN to SNN, I am following this conversion example script.

The SNN seems to learn something, and reaches ~50% accuracy on MNIST.

However, the SNN doesn't seem to retain the weights learned while running Network.run(). When I test or retrain the SNN, it resets to the same performance it had before running run().

I am attaching a minimal reproduction script. The critical part is that after running _train_snn() for the second time, the performace resets and progresses in the same way as it did during the first training.

More details:

  • I am running the SNN training on the exact same data in both times.
  • If the ANN is trained before conversion to SNN, the weights of the ANN are retained (but the network still doesn't improve after training as an SNN)

Thank you in advance for any help!

bindnset_issue.py.txt

@Hananel-Hazan
Copy link
Collaborator

Thank you for using BindsNET.
I'm a little confused, are you training the SNN twice?

The conversion process should be:

  1. Build an ANN using a regular PyTorch module and train it using your favorite gradient descent method.
  2. Building an SNN with the same topology as the ANN from the previous step.
  3. Converting the ANN weights to the equivalent range for SNN from the previous step.
  4. Testing SNN on the testing data.

Note

  1. when the training/conversion process finish, use network. train(mode=False) to freeze the weights.
  2. ANN conversion to SNN should be used only once, running the code twice can lead to unexpected results. If the conversion wasn't successful the first time, some parameters need to be changed, and the process need to be started again.

ps. The script that you are using to convert the network is not updated and is not part of the supported code in BindsNET. The code you are using probably contain some code that needs to be update. With that said, I will be happy to help you use it, and hopefully, you can help by contributing your time to fix some of the small kinks that exist in the BindsNET code.

@0xnurl
Copy link
Contributor Author

0xnurl commented Nov 29, 2022

Thanks Hananel for the very quick reply!

We're not training the SNN twice. We're just using the ANN->SNN conversion as a way to build a deep SNN architecture. We couldn't find an example of a multilayer architecture in your example, so we've been using this method. Does this make sense?

So our process is:

  1. Build multilayer ANN in PyTorch.
  2. Convert to SNN using bindsnet.conversion.ann_to_snn()
  3. Train SNN as in your examples (eth_mnist.py)

So basically this should work right? The problem is that after step 3, the SNN doesn't seem to retain the weights.

Re: unsupported code, yes I'm aware of that and even opened a pull request to update the external script.
However, the conversion module is part of the BindsNET package, so should be supported, right?

Any help would be much appreciated.
Thanks again!

@Hananel-Hazan
Copy link
Collaborator

If I'm not mistaken (I didnt use this part of the code for a long time) the method bindsnet.conversion.ann_to_snn() assume that the given ANN is already fully trained. The result of this method is an equivalent SNN that should perform similarly to the ANN.
The only training here should be performed on the ANN, not the SNN. Therefore, step three is not relevant.

About the PR, if the code work on the main BindsNET, I will be glad if you submit it to this repository, with only one request, you will help in the future to update the code if necessary to new upcoming changes in PyTorch/BindsNET.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants