beyond_inifinity
beyond_inifinity

Reputation: 453

ValueError: Classification metrics can't handle a mix of multilabel-indicator on pretrained CNN

in tensorflow, I intend to tune hyperparams in pre-trained CNN for the image classification tasks. To do so, I used a pre-trained model like vgg16 to extract features and used extracted embedded features as inputs for convolutional neural net (CNN). Basically, I place CNN on the top of the pre-trained model for training. I am trying to optimize hyperparameter like batch_size, epochs, drop-rate, using GridSeatchCV, but I got the following type error:

TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got array([200, 201, 202, 203,...

I also tried like this:

grid_search = grid_search.fit(np.array(df_train_tf), np.array(labels_tr_tf[1:1001]))

but now I am having the following error:

ValueError: Classification metrics can't handle a mix of multilabel-indicator and multiclass targets

I looked into this error on SObut it couldn't get rid of error above. How to fix this?

in my CNN, I was passing flatten dim tensor as input to CNN, and extracted embedded features from pre-trained model was 1 dim feature vector which I converted to tensor. When I tried to run grid-search for hyperparam optimization, I got above type error. I am trying to understand why I have such an error. Can anyone point me out what's going on? Thanks

my attempt:

from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV

model = KerasClassifier(build_fn=myCNN)
parameters = {'dim': [256,512, 784,1024, 2048],
              'epochs': [25,50,75,100,125,150,200],
              'batch_size':[32,64,128,192, 256],
              'drop_rate': [0.1,0.2,0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
              'opt': ['rmsprop', 'adam', 'sgd'],
              'actv_func': ['relu', 'tanh']}

grid_search = GridSearchCV(estimator=model,
                           param_grid=parameters,
                           scoring='accuracy',
                           cv=5)

grid_search = grid_search.fit(df_train_tf, labels_tr_tf[1:1001])

where df_train_tf is tensor of pre-trained embedding features and labels_tr_tf is tensor of one-hot encoded labels. Here is how df_train_tf, labels_tr_tf looks like.

df_train_tf.shape:
TensorShape([1000, 2048])

labels_tr_tf[1:1001].shape:
TensorShape([1000, 100])

type(labels_tr_tf[1:1001]):
tensorflow.python.framework.ops.EagerTensor

type(df_train_tf):
tensorflow.python.framework.ops.EagerTensor

df_train_tf:

<tf.Tensor: shape=(1000, 2048), dtype=float32, numpy=
array([[ 2.3664525 ,  6.4614077 , 22.128284  , ...,  2.8993628 ,
         7.6006427 ,  4.022856  ],
       [ 2.8110769 ,  0.        , 21.861437  , ...,  2.8580594 ,
         3.8210764 ,  3.4176886 ],...]

labels_tr_tf[1:1001]:
<tf.Tensor: shape=(1000, 100), dtype=float32, numpy=
array([[0., 0., 0., ..., 0., 0., 0.],
       [1., 0., 0., ..., 0., 0., 0.],
       [0., 0., 0., ..., 0., 0., 0.],..]

I didn't find any clue why I am getting this error. Can anyone point me out how to make this right? any solution to fix the above type error? Any idea? thanks

Upvotes: 1

Views: 378

Answers (1)

mujjiga
mujjiga

Reputation: 16896

For multiclass labels to work with sklearn GridSearchCV, the labels should be not be one-hot-encoded. They should be 1d or column vector containing more than two discrete values. Check the docs for representations.

So we have to convert one-hot-encoded targets to 1D and which in turn will need us to change the loss function to sparse_categorical_crossentropy

Sample code:

X = np.random.randn(1000, 2048)
y = np.array([i for i in range(100)]*10) # <- 1D array with target labels

def myModel():
  model = keras.models.Sequential()
  model.add(keras.layers.Dense(100, input_dim=2048, activation='softmax'))
  model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
  return model
  

model = KerasClassifier(build_fn=myModel)
parameters = { 'epochs': [10, 20, 30],
               'batch_size':[1, 2, 3, 4, 5, 6, 7,8] }              

grid_search = GridSearchCV(estimator=model,
                           param_grid=parameters,
                           scoring='accuracy',
                           cv=2)

grid_search = grid_search.fit(X, y)
print (grid_search.best_params_)

Output:

Epoch 1/10
500/500 [==============================] - 2s 3ms/step - loss: 5.6664 - accuracy: 0.0100
Epoch 2/10
500/500 [==============================] - 1s 3ms/step - loss: 0.0066 - accuracy: 1.0000
Epoch 3/10
500/500 [==============================] - 1s 3ms/step - loss: 9.9609e-04 - accuracy: 1.0000
------ output truncated ------
{'batch_size': 3, 'epochs': 20}

Upvotes: 2

Related Questions