【问题标题】:ValueError: Can't handle mix of multilabel-indicator and binary Issue with GridSearchCV and KerasClassifierValueError:无法使用 GridSearchCV 和 KerasClassifier 处理多标签指示符和二进制问题的混合
【发布时间】:2017-10-28 11:04:42
【问题描述】:

我有这个用于 MNIST 数据的 CNN 代码,它将数据集分为训练集和测试集,仅用于 2 和 7。在运行它的代码时,它在测试集上给出了大约 98% 的准确率。

所以,为了提高准确性,我尝试使用来自 keras.wrappers.scikit_learn 的 KerasClassifier。使用带有 GridSearchCV 的分类器我想找到最佳参数,但在运行代码时,第一次迭代一切正常,但在下一次迭代中抛出错误。

代码如下:

# This is the normal CNN model without GridSearch
from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
import numpy as np
batch_size = 128
num_classes = 2
epochs = 12
# input image dimensions
img_rows, img_cols = 28, 28

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

#Only look at 3s and 8s
train_picks = np.logical_or(y_train==2,y_train==7)
test_picks = np.logical_or(y_test==2,y_test==7)

x_train = x_train[train_picks]
x_test = x_test[test_picks]
y_train = np.array(y_train[train_picks]==7,dtype=int)
y_test = np.array(y_test[test_picks]==7,dtype=int)


if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Conv2D(4, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
model.add(Conv2D(8, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(16, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

# Improving the accuracy using GridSearch
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV
from keras.models import Sequential
from keras.layers import Dense
def build_model(optimizer):
    print(optimizer,batch_size,epochs)
    model = Sequential()
    model.add(Conv2D(4, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
    model.add(Conv2D(8, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(16, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(2, activation='softmax'))

    model.compile(loss=keras.losses.categorical_crossentropy,
                  optimizer=optimizer,
                  metrics=['accuracy'])
    return model
model = KerasClassifier(build_fn = build_model)
parameters = {'batch_size': [128, 256],
              'epochs': [10, 20],
              'optimizer': ['rmsprop']}
grid_search = GridSearchCV(estimator = model,
                           param_grid = parameters,
                           scoring = 'accuracy',
                           cv = 10)
grid_search = grid_search.fit(x_train, y_train)
best_parameters = grid_search.best_params_
best_accuracy = grid_search.best_score_

这是代码的输出:

rmsprop 128 12
Epoch 1/10
11000/11000 [==============================] - 3s - loss: 0.1654 - acc: 0.9476      
Epoch 2/10
11000/11000 [==============================] - 3s - loss: 0.0699 - acc: 0.9786     
Epoch 3/10
11000/11000 [==============================] - 2s - loss: 0.0557 - acc: 0.9839     
Epoch 4/10
11000/11000 [==============================] - 2s - loss: 0.0510 - acc: 0.9839     
Epoch 5/10
11000/11000 [==============================] - 2s - loss: 0.0471 - acc: 0.9853     
Epoch 6/10
11000/11000 [==============================] - 2s - loss: 0.0417 - acc: 0.9875     
Epoch 7/10
11000/11000 [==============================] - 2s - loss: 0.0399 - acc: 0.9870     
Epoch 8/10
11000/11000 [==============================] - 2s - loss: 0.0365 - acc: 0.9885     
Epoch 9/10
11000/11000 [==============================] - 2s - loss: 0.0342 - acc: 0.9899     
Epoch 10/10
11000/11000 [==============================] - 2s - loss: 0.0321 - acc: 0.9903     
 768/1223 [=================>............] - ETA: 0sTraceback (most recent call last):

  File "<ipython-input-4-975b20661114>", line 30, in <module>
    grid_search = grid_search.fit(x_train, y_train)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_search.py", line 945, in fit
    return self._fit(X, y, groups, ParameterGrid(self.param_grid))

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_search.py", line 564, in _fit
    for parameters in parameter_iterable

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 758, in __call__
    while self.dispatch_one_batch(iterator):

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 608, in dispatch_one_batch
    self._dispatch(tasks)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 571, in _dispatch
    job = self._backend.apply_async(batch, callback=cb)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/_parallel_backends.py", line 109, in apply_async
    result = ImmediateResult(func)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/_parallel_backends.py", line 326, in __init__
    self.results = batch()

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 131, in __call__
    return [func(*args, **kwargs) for func, args, kwargs in self.items]

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/externals/joblib/parallel.py", line 131, in <listcomp>
    return [func(*args, **kwargs) for func, args, kwargs in self.items]

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_validation.py", line 260, in _fit_and_score
    test_score = _score(estimator, X_test, y_test, scorer)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/model_selection/_validation.py", line 288, in _score
    score = scorer(estimator, X_test, y_test)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/metrics/scorer.py", line 98, in __call__
    **self._kwargs)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py", line 172, in accuracy_score
    y_type, y_true, y_pred = _check_targets(y_true, y_pred)

  File "/home/thakkar_/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py", line 82, in _check_targets
    "".format(type_true, type_pred))

ValueError: Can't handle mix of multilabel-indicator and binary

请帮忙!

【问题讨论】:

    标签: python-3.x deep-learning keras conv-neural-network mnist


    【解决方案1】:

    错误似乎在于您解析字典参数的方式..

    来自here的例子:

    import numpy
    from sklearn.model_selection import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    from keras.optimizers import SGD
    # Function to create model, required for KerasClassifier
    def create_model(learn_rate=0.01, momentum=0):
        # create model
        model = Sequential()
        model.add(Dense(12, input_dim=8, activation='relu'))
        model.add(Dense(1, activation='sigmoid'))
        # Compile model
        optimizer = SGD(lr=learn_rate, momentum=momentum)
        model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
        return model
    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]
    # create model
    model = KerasClassifier(build_fn=create_model, epochs=100, batch_size=10, verbose=0)
    # define the grid search parameters
    learn_rate = [0.001, 0.01, 0.1, 0.2, 0.3]
    momentum = [0.0, 0.2, 0.4, 0.6, 0.8, 0.9]
    param_grid = dict(learn_rate=learn_rate, momentum=momentum)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    means = grid_result.cv_results_['mean_test_score']
    stds = grid_result.cv_results_['std_test_score']
    params = grid_result.cv_results_['params']
    for mean, stdev, param in zip(means, stds, params):
        print("%f (%f) with: %r" % (mean, stdev, param))
    

    GridseachCV 基本上从字典中获取与其输入参数匹配的元素,并对其进行训练。您正在解析完整的字典,但 batch_size 和 epochs 不是函数内的参数...

    # Improving the accuracy using GridSearch
    from keras.wrappers.scikit_learn import KerasClassifier
    from sklearn.model_selection import GridSearchCV
    from keras.models import Sequential
    from keras.layers import Dense
    def build_model(optimizer = 'adam'):
        model = Sequential()
        model.add(Conv2D(4, kernel_size=(3, 3),activation='relu',input_shape=input_shape))
        model.add(Conv2D(8, (3, 3), activation='relu'))
        model.add(MaxPooling2D(pool_size=(2, 2)))
        model.add(Dropout(0.25))
        model.add(Flatten())
        model.add(Dense(16, activation='relu'))
        model.add(Dropout(0.5))
        model.add(Dense(2, activation='softmax'))
    
        model.compile(loss=keras.losses.categorical_crossentropy,
                      optimizer=optimizer,
                      metrics=['accuracy'])
        return model
    model = KerasClassifier(build_fn = build_model)
    parameters = {'batch_size': [128, 256],
                  'epochs': [10, 20],
                  'optimizer': ['rmsprop']}
    grid_search = GridSearchCV(estimator = model,
                               param_grid = parameters,
                               scoring = 'accuracy',
                               cv = 10)
    grid_search = grid_search.fit(x_train, y_train)
    best_parameters = grid_search.best_params_
    best_accuracy = grid_search.best_score_
    

    也许这样的事情会起作用..没有测试过。

    【讨论】:

    • No @J.Down 可以打印 batch_size 和 epoch。它们的存在仅在 param_grid 中很重要。问题出在 y_test 和 y_train 的某个地方。
    • @DhavalThakkar 是的。这是正确的。请检查您在 GridSearchCV 中传递的y_train 的格式和KerasClassifier.predict(X_train) 的输出?
    猜你喜欢
    • 2017-08-14
    • 2014-07-26
    • 2019-06-29
    • 2017-09-25
    • 2014-07-30
    • 2019-10-23
    • 2022-01-25
    • 1970-01-01
    • 2016-10-27
    相关资源
    最近更新 更多