Skip to content

Commit ab1c4d4

Browse files
vincentpham1991raghavrv
authored andcommitted
[MRG+1] Catch cases for different class size in MLPClassifier with warm start (scikit-learn#7976) (scikit-learn#8035)
* added test that fails * generate standard value error for different class size * moved num_classes one class down * fixed over-indented lines * standard error occurs a layer up. * created a different label comparison for warm_start * spaces around multiplication sign. * reworded error and added another edge case. * fixed pep8 violation * make test shorter * updated ignore warning
1 parent d97d13e commit ab1c4d4

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

sklearn/neural_network/multilayer_perceptron.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,13 @@ def _validate_input(self, X, y, incremental):
908908
self._label_binarizer = LabelBinarizer()
909909
self._label_binarizer.fit(y)
910910
self.classes_ = self._label_binarizer.classes_
911+
elif self.warm_start:
912+
classes = unique_labels(y)
913+
if set(classes) != set(self.classes_):
914+
raise ValueError("warm_start can only be used where `y` has "
915+
"the same classes as in the previous "
916+
"call to fit. Previously got %s, `y` has %s" %
917+
(self.classes_, classes))
911918
else:
912919
classes = unique_labels(y)
913920
if np.setdiff1d(classes, self.classes_, assume_unique=True):
@@ -939,6 +946,25 @@ def predict(self, X):
939946

940947
return self._label_binarizer.inverse_transform(y_pred)
941948

949+
def fit(self, X, y):
950+
"""Fit the model to data matrix X and target(s) y.
951+
952+
Parameters
953+
----------
954+
X : array-like or sparse matrix, shape (n_samples, n_features)
955+
The input data.
956+
957+
y : array-like, shape (n_samples,) or (n_samples, n_outputs)
958+
The target values (class labels in classification, real numbers in
959+
regression).
960+
961+
Returns
962+
-------
963+
self : returns a trained MLP model.
964+
"""
965+
return self._fit(X, y, incremental=(self.warm_start and
966+
hasattr(self, "classes_")))
967+
942968
@property
943969
def partial_fit(self):
944970
"""Fit the model to data matrix X and target y.

sklearn/neural_network/tests/test_mlp.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from numpy.testing import assert_almost_equal, assert_array_equal
1414

15-
from sklearn.datasets import load_digits, load_boston
15+
from sklearn.datasets import load_digits, load_boston, load_iris
1616
from sklearn.datasets import make_regression, make_multilabel_classification
1717
from sklearn.exceptions import ConvergenceWarning
1818
from sklearn.externals.six.moves import cStringIO as StringIO
@@ -24,6 +24,7 @@
2424
from scipy.sparse import csr_matrix
2525
from sklearn.utils.testing import (assert_raises, assert_greater, assert_equal,
2626
assert_false, ignore_warnings)
27+
from sklearn.utils.testing import assert_raise_message
2728

2829

2930
np.seterr(all='warn')
@@ -49,6 +50,11 @@
4950
Xboston = StandardScaler().fit_transform(boston.data)[: 200]
5051
yboston = boston.target[:200]
5152

53+
iris = load_iris()
54+
55+
X_iris = iris.data
56+
y_iris = iris.target
57+
5258

5359
def test_alpha():
5460
# Test that larger alpha yields weights closer to zero
@@ -556,3 +562,29 @@ def test_adaptive_learning_rate():
556562
clf.fit(X, y)
557563
assert_greater(clf.max_iter, clf.n_iter_)
558564
assert_greater(1e-6, clf._optimizer.learning_rate)
565+
566+
567+
@ignore_warnings(RuntimeError)
568+
def test_warm_start():
569+
X = X_iris
570+
y = y_iris
571+
572+
y_2classes = np.array([0] * 75 + [1] * 75)
573+
y_3classes = np.array([0] * 40 + [1] * 40 + [2] * 70)
574+
y_3classes_alt = np.array([0] * 50 + [1] * 50 + [3] * 50)
575+
y_4classes = np.array([0] * 37 + [1] * 37 + [2] * 38 + [3] * 38)
576+
y_5classes = np.array([0] * 30 + [1] * 30 + [2] * 30 + [3] * 30 + [4] * 30)
577+
578+
# No error raised
579+
clf = MLPClassifier(hidden_layer_sizes=2, solver='lbfgs',
580+
warm_start=True).fit(X, y)
581+
clf.fit(X, y)
582+
clf.fit(X, y_3classes)
583+
584+
for y_i in (y_2classes, y_3classes_alt, y_4classes, y_5classes):
585+
clf = MLPClassifier(hidden_layer_sizes=2, solver='lbfgs',
586+
warm_start=True).fit(X, y)
587+
message = ('warm_start can only be used where `y` has the same '
588+
'classes as in the previous call to fit.'
589+
' Previously got [0 1 2], `y` has %s' % np.unique(y_i))
590+
assert_raise_message(ValueError, message, clf.fit, X, y_i)

0 commit comments

Comments
 (0)