Repository: keras-team/keras

Issue:
IndexError: index 1 is out of bounds for axis 1 with size 1
- [x] Check that you are up-to-date with the master branch of Keras. You can update with:
pip install git+git://github.com/fchollet/keras.git --upgrade --no-deps

- [x] If running on TensorFlow, check that you are up-to-date with the latest version. The installation instructions can be found [here](https://www.tensorflow.org/get_started/os_setup).

- [x] Provide a link to a GitHub Gist of a Python script that can reproduce your issue (or just copy the script here if it is short).

Dear all,

The problem arises at the [line 220 in the sklearn wrapper](https://github.com/fchollet/keras/blob/master/keras/wrappers/scikit_learn.py#L220).

Here is a minimal example that reproduces the error (I also attached sample data).
The sample data is composed by a matrix (X) of 50 observations and 50 features, and the corresponding target variable (y), composed by 50 observations. The data type of the matrix is floating point, while the target variable is an integer in [0, 2).

Thanks,
Francesco

```
from keras.models import Sequential
from keras.layers import BatchNormalization, Dense
from keras.wrappers.scikit_learn import KerasClassifier
import numpy as np
import pandas as pd
from sklearn.model_selection import GridSearchCV


def _fit(X, y):

  nn = KerasClassifier(build_fn=_arch, verbose=1, epochs=1)
  clf = GridSearchCV(
    nn,
    param_grid={
      'input_shape': [(X.shape[1],)],
      'dense_nodes': [np.linspace(X.shape[1], 2, nlayers, dtype=int)
        for nlayers in range(3, 4)]},
    scoring='f1_macro',
    n_jobs=1)
  clf.fit(X.values, y.values)

def _arch(input_shape, dense_nodes):

  arch = Sequential()
  arch.add(BatchNormalization(input_shape=input_shape))
  for nodes in dense_nodes[:-1]:
    arch.add(Dense(nodes, activation='relu'))
  arch.add(Dense(dense_nodes[-1], activation='sigmoid'))
  arch.compile(
    optimizer='sgd',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy'])

  return arch

X = pd.read_table('X_50_50.txt', sep='\t', index_col=0)
y = pd.read_table('y_50.txt', sep='\t', index_col=0)

_fit(X, y)

```

[X_50_50.txt](https://github.com/fchollet/keras/files/864158/X_50_50.txt)
[y_50.txt](https://github.com/fchollet/keras/files/864160/y_50.txt)




Discussion:
Trying to prefix the target variable with 'cls' string (e.g. 'cls1', 'cls0') gives me another error:

```
ValueError: could not convert string to float: 'cls1'
```
The problem arises at [line 196](https://github.com/fchollet/keras/blob/master/keras/wrappers/scikit_learn.py#L196)

```
y = np.array(y)
if len(y.shape) != 1:
    self.classes_ = np.arange(y.shape[1])
else:
    self.classes_ = np.unique(y)
    y = np.searchsorted(self.classes_, y)
self.n_classes_ = len(self.classes_)
return super(KerasClassifier, self).fit(x, y, **kwargs)
```

Line 196 is

```
if len(y.shape) != 1:
    self.classes_ = np.arange(y.shape[1])
```

However, it doesn't check whether the y array has shape (nsamples, 1), because it assumes that with a one-dimensional array, the y array has shape (nsamples,). Following this, the statement collapses to

```
self.classes_ = np.arange(1)
```

I'm working on an update and if it works on a PR.

Thanks,
Francesco

Resolving patch:
diff --git a/keras/wrappers/scikit_learn.py b/keras/wrappers/scikit_learn.py
--- a/keras/wrappers/scikit_learn.py
+++ b/keras/wrappers/scikit_learn.py
@@ -192,11 +192,13 @@ def fit(self, x, y, **kwargs):
                 details about the training history at each epoch.
         """
         y = np.array(y)
-        if len(y.shape) != 1:
+        if len(y.shape) == 2 and y.shape[1] > 1:
             self.classes_ = np.arange(y.shape[1])
-        else:
+        elif (len(y.shape) == 2 and y.shape[1] == 1) or len(y.shape) == 1:
             self.classes_ = np.unique(y)
             y = np.searchsorted(self.classes_, y)
+        else:
+            raise ValueError('Invalid shape for y')
         self.n_classes_ = len(self.classes_)
         return super(KerasClassifier, self).fit(x, y, **kwargs)
 


Test patch: