【问题标题】:ValueError: Classification metrics can't handle a mix of multilabel-indicator on pretrained CNNValueError:分类指标无法处理预训练 CNN 上的多标签指标混合
【发布时间】:2020-10-19 18:39:44
【问题描述】:

在 tensorflow 中,我打算在预训练的 CNN 中调整超参数以用于图像分类任务。为此,我使用了像 vgg16 这样的预训练模型来提取特征,并使用提取的嵌入特征作为卷积神经网络 (CNN) 的输入。基本上,我将 CNN 放在预训练模型的顶部进行训练。我正在尝试使用GridSeatchCV 优化batch_size, epochs, drop-rate 之类的超参数,但出现以下类型错误:

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

我也试过这样:

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

但现在我遇到以下错误:

ValueError:分类指标无法处理混合 多标签指标和多类目标

我在SO上查看了这个错误,但它无法摆脱上面的错误。如何解决这个问题?

在我的 CNN 中,我将 flatten dim 张量作为输入传递给 CNN,从预训练模型中提取的嵌入特征是 1 个 dim 特征向量,我将其转换为张量。当我尝试运行网格搜索以进行超参数优化时,出现上述类型错误。我试图理解为什么我有这样的错误。谁能指出我发生了什么事?谢谢

我的尝试

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])

其中df_train_tf 是预训练嵌入特征的张量,labels_tr_tf 是 one-hot 编码标签的张量。这是df_train_tf, labels_tr_tf 的样子。

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.],..]

我没有找到任何线索为什么我会收到此错误。谁能指出我如何做到这一点?任何解决上述类型错误的解决方案?任何想法?谢谢

【问题讨论】:

    标签: python tensorflow error-handling conv-neural-network


    【解决方案1】:

    对于与 sklearn GridSearchCV 一起使用的多类标签,标签不应是 one-hot-encoded。它们应该是一维或包含两个以上离散值的列向量。检查docs 的陈述。

    因此我们必须将 one-hot-encoded 目标转换为 1D,而这又需要我们将损失函数更改为 sparse_categorical_crossentropy

    示例代码:

    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_)
    

    输出:

    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}
    

    【讨论】:

    • 谢谢。在我的示例中,如何将 eagerTensor 类型 labels_tr_tf 转换为 1 D?有什么提示吗?
    • 因为你的 labels_tr_tf 是 one-hot-encoded 只需做 np.argmax(labels_tr_tf, axis=1)
    • 谢谢,它成功了。您介意指出在预训练的 CNN 中调整超参数的最佳方法是什么吗?还有什么想法吗?
    • @beyond_inifinity 你可以试试这个框架ax.dev
    • 如何调整 Dense 层的超参数,例如 Dense(128)Dense(256)?有什么想法吗?
    猜你喜欢
    • 2019-10-23
    • 2019-06-29
    • 2021-03-18
    • 2021-12-20
    • 2017-09-25
    • 2021-04-14
    • 2020-05-10
    • 2020-12-30
    • 2019-09-07
    相关资源
    最近更新 更多