Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

New training option #63

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

New training option #63

wants to merge 1 commit into from

Conversation

antoniodeluca
Copy link

Added a new training option that enable users to specify if the weights of the neural network have to be (re)initialized or not. This is very useful when an user wants to call more time the neural network training method or for any other reason for which one doesn't want that weights change.

…ts of the neural network have to be (re)initialized or not.
@ClimbsRocks
Copy link

@antoniodeluca , if this does what I think it does, you're my hero!

Say I've been training a net for 2 days, and it's 84 iterations in by this point (turns out understanding human attraction is rather complex, even for a computer). I'd love to be able to train that same net even more at some point in the future, to take advantage of the two days worth of work that has already gone into training it.

If your PR does that, I'd be super happy! I'd been debating how complex this would be to implement myself; I'm glad I bothered checking out the PRs here to find you've already figured it out, and see that the tests for this are longer than the source code!

@antoniodeluca
Copy link
Author

@ClimbsRocks , yes it does exactly what you need. Hope it will help you.

@ClimbsRocks
Copy link

It already is! I created GridSearch for this library, and then at the end, I wanted to train the best classifier for significantly longer. Allowing the classifier to warm start at the point it had previously trained to has been awesome!

It's part of a larger project, but I hope to spin gridSearch out into it's own repo pretty soon to make harthur's awesome brainjs even more accessible to developers. I love her philosophy of abstracting away complexity, which pretty directly contrasts with scikit-learn's approach. I'm actually trying to build out my project to take that philosophy of avoiding unnecessary complexity to an even higher level.

Thanks again for this critical component of it!

ClimbsRocks added a commit to ClimbsRocks/warmBrain that referenced this pull request Oct 10, 2015
again, borrowed from:

harthur#63
ClimbsRocks added a commit to ClimbsRocks/warmBrain that referenced this pull request Oct 10, 2015
per https://github.com/harthur/brain/pull/63/files

This allows a brain that has already been trained to continue to train on top of what it has already learned.

Previously, every call to .train() would start fresh with a totally new neural net, even if you had previously trained one for several days.

tests warm start ability

again, borrowed from:

harthur#63

updates package.json for warmBrain

explains difference between warmBrain and harthur/brain

removes capital letter in name

fixes formatting
ClimbsRocks added a commit to ClimbsRocks/warmBrain that referenced this pull request Oct 10, 2015
per https://github.com/harthur/brain/pull/63/files

This allows a brain that has already been trained to continue to train on top of what it has already learned.

Previously, every call to .train() would start fresh with a totally new neural net, even if you had previously trained one for several days.

tests warm start ability

again, borrowed from:

harthur#63

updates package.json for warmBrain

explains difference between warmBrain and harthur/brain

removes capital letter in name

fixes formatting

bumps version number
@Archivist062
Copy link

Thanks a lot, I'll need this too and I prefer this as using streams or anything. gotta be useful in my IA development. You made my day.

@marcj
Copy link

marcj commented Dec 31, 2015

For me this pull-request does not work. Here a simple example:

net.train([{input: [1, 1], output: [0]}]); //trains 1,1 => 0
net.runInput([1, 1]); //results 0.0702838678761908 => correct

net.train([{input: [1, 0], output: [1]}]); //trains 1,0 => 1
net.runInput([1, 1]); //results 0.850795812504698 => incorrect
net.runInput([1, 0]); //results 0.929557447931592 => correct

I've simply commented out this this.initialize() call, so it never gets initialized.

To me its seems a lot of iterations to learn the new 1,0 => 1 overwrite simply the learned 1,1=>0 as the result of the learning, not through resetting the weights.

@antoniodeluca
Copy link
Author

@marcj, your code is not working because you are not passing the "initialization" parameter.
brainjs normally reinitializes the weights each time you call the train function (because the initialization parameter value defaults to "true").
If you want to preserve the weights for the next training sessions you should pass a "false" initialization parameter.
This is not needed on the first training session because it is supposed that the first time you train the neural network the weights have to be initialized.
You could see an example of the code looking into the commit test case.
For brevity here are two little example snippets:

First training session

net.train(data, {
errorThresh: 0.2,
iterations: 100000
});

Second training session

net.train(data, {
errorThresh: 0.2,
iterations: 1,
initialization: false
})

@marcj
Copy link

marcj commented Dec 31, 2015

Well, as I said

I've simply commented out this this.initialize() call, so it never gets initialized.

What I mean with that is that I deleted the line this.initialize(sizes); manually, so the network.js does not reset anything when I call train().
so, there's no need to pass the "initialization" parameter. :) I tested with this your approach of being able to continue the learning process by skipping the reset/initialize method.

@marcj
Copy link

marcj commented Dec 31, 2015

Is there a reason why you only use one iteration for the second training? I guess with such low iterations the network has no chance to learn enough to get the errors low. Also with one iteration there's no need to pass any errorThreshold because the network has no chance to react with one iteration to a high error rate.

@antoniodeluca
Copy link
Author

@marcj, I do not think that the initialize function should be removed.
It is very good to have an initialization function that properly represents a point in which the system prepares the data structures and does eventual needed tasks.

@antoniodeluca
Copy link
Author

@marcj, the second training is done with one iterarion just as an example.
Sorry if the example was very minimalist.
The intention was just to show the use of the initialization parameter.
In your real scenario you have to do as many iterations as you need.

@mindphlux1
Copy link

Hi, I'm trying to use your patch with loading a neural network from a file first, however it fails with the error

rain/lib/neuralnetwork.js:180
this.errors[layer][node] = error;
^
TypeError: Cannot read property '3' of undefined

The way I am doing is to load the file with fromJSON and then running train() with the 'initialization' parameter set to false, but it doesn't seem to work.

Apparently some default values are set in the init method that is disabled.

What can I do?

Thanks

@marcj
Copy link

marcj commented Jan 2, 2016

@antoniodeluca, well I called this.initialize() on my own in my userland code of course, so the network is initialized after is has been created.

Can you confirm this behavior of this code?

net.train([{input: [1, 1], output: [0]}]); //trains 1,1 => 0
net.runInput([1, 1]); //results 0.0702838678761908 => correct

net.train([{input: [1, 0], output: [1]}], {initialization: false}); //trains 1,0 => 1
net.runInput([1, 1]); //results 0.850795812504698 => incorrect
net.runInput([1, 0]); //results 0.929557447931592 => correct

@robertleeplummerjr
Copy link

Would you consider closing this here, and reopening at: https://github.com/harthur-org/brain.js/pulls?

If so, we could add you as a collaborator.

@antoniodeluca
Copy link
Author

Yes, sure. I do it today or tomorrow.

Copy link

@Dok11 Dok11 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why

_.isUndefined(options.initialization) ? true : options.initialization;

Maybe can write as

_.isUndefined(options.initialization) || options.initialization;

@robertleeplummerjr
Copy link

Sometime back I added a keepNetworkIntact argument, I believe it does exactly what you want: https://github.com/harthur-org/brain.js/blob/3843729dd0ae5cb8e6be21b6040c254a9fcf4e0b/src/neural-network.js#L41

@robertleeplummerjr
Copy link

Usage example:

const net = brain.NeuralNetwork();
net.train([]);
//sometime later
net.train([], { keepNetworkIntact: true });

This was referenced Dec 21, 2016
@Dok11
Copy link

Dok11 commented Dec 22, 2016

Sometime back I added a keepNetworkIntact argument

I installed 'npm install brain.js' and these not have argument keepNetworkIntact. What?

@robertleeplummerjr
Copy link

We need to bump the version. In the meantime, can you install via: npm i https://github.com/harthur-org/brain.js.git?

@Dok11
Copy link

Dok11 commented Dec 22, 2016

@robertleeplummerjr thank you, that's work, and arg 'keepNetworkIntact' too ok!

@robertleeplummerjr
Copy link

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

Successfully merging this pull request may close these issues.

None yet

7 participants