Search code examples
kerasgrid-searchhyperparametersmulticlass-classification

GridSearch for MultiClass KerasClassifier


I am trying to do a grid search for a multiclass classification with Keras. Here is a section of the code:

Some properties of the data are below:

y_
array(['fast', 'immobile', 'immobile', ..., 'slow',
       'immobile', 'slow'],
      dtype='<U17')

y_onehot = pd.get_dummies(y_).values

y_onehot
array([[1, 0, 0],
       [0, 0, 1],
       [0, 0, 1],
    ...
       [0, 1, 0],
       [0, 0, 1],
       [0, 1, 0]], dtype=uint8)

#Do train-test split

y_train.shape
(1904,)

y_train_onehot.shape
(1904, 3)

And the model...

# Function to create model, required for KerasClassifier
def create_model(optimizer='rmsprop', init='glorot_uniform'):
    # create model
    model = Sequential()
    model.add(Dense(2048, input_dim=X_train.shape[1], kernel_initializer=init, activation='relu'))
    model.add(Dense(512, kernel_initializer=init, activation='relu'))
    model.add(Dense(y_train_onehot.shape[1], kernel_initializer=init, activation='softmax'))
    # Compile model
    model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
    return model

# create model
model = KerasClassifier(build_fn=create_model, verbose=0)

# grid search epochs, batch size and optimizer
optimizers = ['rmsprop', 'adam']
init = ['glorot_uniform', 'normal', 'uniform']
epochs = [50, 100, 150]
batches = [5, 10, 20]

param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches, init=init)
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring='accuracy')
grid_result = grid.fit(X_train, y_train_onehot)

And here is the error:

--> grid_result = grid.fit(X_train, y_train_onehot)
ValueError: Classification metrics can't handle a mix of multilabel-indicator and multiclass targets

The code was for a binary model but I am hoping to modify it for a multiclass data set. Kindly assist. Thanks!


Solution

  • The error is in the softmax layer.

    I think you mean y_train_onehot.shape[1] instead of y_train_onehot[1]

    Update 1: This is strange but your second problem seems to be y_train_onehot, would you mind to try 2 things:

    1. try the same model without the onehot encoding on y_train.
    2. if that alone doesn't work, change the loss to sparse_categorical_crossentropy

    Also make sure to change y_train_onehot.shape[1] to the number of classes in the softmax layer