aigamedev / scikit-neuralnetwork

Deep neural networks without the learning cliff! Classifiers and regressors compatible with scikit-learn.
BSD 3-Clause "New" or "Revised" License
1.2k stars 221 forks source link

use set_parameters() to load trained parameters for a classifier #205

Open shangwang99 opened 8 years ago

shangwang99 commented 8 years ago

Instructed by the document, I constructed a classifier and trained it using the following code:

clf = Classifier( layers=[ Layer("Sigmoid", units=1000), Layer("Softmax",units=8)], learning_rate=0.009, n_iter=50) clf.fit(x[train],y[train])

And made prediction using: pred = clf.predict(x[test])

Then I extracted and saved the parameters of the classifier using param = clf.get_parameters() np.save('./param.npy')

When I build a new classifier and try to initialise it with set_parameters using following code: clf2 = Classifier( layers=[ Layer("Sigmoid", units=1000), Layer("Softmax",units=8)], learning_rate=0.009, n_iter=50)

clf2.set_parameters(param) pred2 = clf2.predict(x[test])

I got the following error:

assert self.label_binarizers != [],\ --> 451 "Can't predict without fitting: output classes are unknown." 452 453 yp = self.predict_proba(X, collapse=False)

AssertionError: Can't predict without fitting: output classes are unknown.

I also tried clf2.set_parameters([(param[0].weights,param[0].biases), (param[1].weights,param[1].biases)]) and clf2 = Classifier( layers=[ Layer("Sigmoid", units=1000), Layer("Softmax",units=8)], parameters=[(param[0].weights,param[0].biases), (param[1].weights,param[1].biases)])

I still got the error. And I tested clf2.is_initialized, the result is False.

Could someone give any suggestions to deal with this or an example of using set_parameters() to initialize a classifier?

Thank you very much. :)

alexjc commented 8 years ago

To save a classifier it's best if you just use pickle so everything is saved correctly. There are tests for that.

If you don't use pickle you may need to call _initialize yourself with the right data. See if you can find the function in the code and let me know if it works!

shangwang99 commented 8 years ago

@alexjc Thank you very much for your quick response.

I tried your method using the following code:

clf2 = Classifier( layers=[ Layer("Sigmoid", units=1000), Layer("Softmax",units=8)], learning_rate=0.009, n_iter=50)

clf2._initialize(newx[train])

Then clf2.is_initialized returns True. Great, it is initialized.

And then I set the parameters of this new classifier using clf2.set_parameters(param) and test using clf2.get_parameters(). I got the parameters!!

But when I use this to make prediction clf2.predict(newx[test]), I still got an assertion error


AssertionError Traceback (most recent call last)

in () ----> 1 clf2.predict(newx[test]) /Users/anaconda/lib/python2.7/site-packages/sknn/mlp.pyc in predict(self, X) 449 """ 450 assert self.label_binarizers != [],\ --> 451 "Can't predict without fitting: output classes are unknown." 452 453 yp = self.predict_proba(X, collapse=False) AssertionError: Can't predict without fitting: output classes are unknown. May I know how to deal with this? Thank you very much! :)
alexjc commented 8 years ago

You need to pass y to _initialize otherwise it can't know the classes. I think I'm going to remove this case, you should use pickle for classifiers—there are too many things to restore.

shangwang99 commented 8 years ago

@alexjc When I try to add y in the _initialize, I got the following error. y is a list of multi-class labels, for example [5, 5, 5, 5, 6, 6, 7, 7, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4].

clf2._initialize(newx[train],newy[train])

IndexError Traceback (most recent call last)

in () ----> 1 clf3._initialize(newx[train],newy[train]) /Users/anaconda/lib/python2.7/site-packages/sknn/mlp.pyc in _initialize(self, X, y, w) 36 assert not self.is_initialized,\ 37 "This neural network has already been initialized." ---> 38 self._create_specs(X, y) 39 40 backend.setup() /Users/anaconda/lib/python2.7/site-packages/sknn/mlp.pyc in _create_specs(self, X, y) 62 self.layers[-1].units = y.shape[1] 63 else: ---> 64 assert y is None or self.layers[-1].units == y.shape[1],\ 65 "Mismatch between dataset size and units in output layer." 66 IndexError: tuple index out of range Thenk you very much for your help. :)
alexjc commented 8 years ago

Probably won't work unless it's fixed. Try partial_fit with classes and empty data?