【问题标题】:Multilabel classification with imbalanced dataset具有不平衡数据集的多标签分类
【发布时间】:2020-10-23 03:18:31
【问题描述】:

我正在尝试做一个多标签分类问题,它有一个不平衡的数据集。 样本总数为1130个,在1130个样本中,第一类出现在其中913个。二等215次,三等423次。

在模型架构中,我有 3 个输出节点,并应用了 sigmoid 激活。

input_tensor = Input(shape=(256, 256, 3))
base_model = VGG16(input_tensor=input_tensor,weights='imagenet',pooling=None, include_top=False)

#base_model.summary()

x = base_model.output

x = GlobalAveragePooling2D()(x)

x = tf.math.reduce_max(x,axis=0,keepdims=True)

x = Dense(512,activation='relu')(x)

output_1 = Dense(3, activation='sigmoid')(x)

sagittal_model_abn = Model(inputs=base_model.input, outputs=output_1)

for layer in base_model.layers:
    layer.trainable = True

我正在使用二元交叉熵损失,我使用这个函数计算它。 我正在使用加权损失来处理不平衡。

        if y_true[0]==1:
            loss_abn = -1*K.log(y_pred[0][0])*cwb[0][1]
        elif y_true[0]==0:
            loss_abn = -1*K.log(1-y_pred[0][0])*cwb[0][0]
        if y_true[1]==1:
            loss_acl = -1*K.log(y_pred[0][1])*cwb[1][1]
        elif y_true[1]==0:
            loss_acl = -1*K.log(1-y_pred[0][1])*cwb[1][0]
        if y_true[2]==1:
            loss_men = -1*K.log(y_pred[0][2])*cwb[2][1]
        elif y_true[2]==0:
            loss_men = -1*K.log(1-y_pred[0][2])*cwb[2][0]

        loss_value_ds = loss_abn + loss_acl + loss_men

cwb 包含类权重。

y_true 是长度为 3 的真实标签。

y_pred 是一个形状为 (1,3) 的 numpy 数组

我根据类的出现和不出现分别对类进行加权。

例如,如果标签为 1,我将其视为出现,如果为 0,则将其视为未出现。

所以,第一类的标签 1 在 1130 次中出现了 913 次

所以第一类标签 1 的类权重为 1130/913,约为 1.23,第一类标签 0 的权重为 1130/(1130-913)

当我训练模型时,准确率会波动(或几乎保持不变),并且损失会减少。

我对每个样本都得到这样的预测

[[0.51018655 0.5010625 0.50482965]]

所有类的每次迭代预测值都在 0.49 - 0.51 范围内

尝试更改 FC 层中的节点数,但行为仍然相同。

谁能帮忙?

使用tf.math,reduce_max 会导致问题吗?用@tf.function做我用tf.math.reduce_max做的操作应该有用吗?

注意

我分别为每个类别加权标签 1 和 0。

cwb = {0: {0: 5.207373271889401, 1: 1.2376779846659365}, 
       1: {0: 1.2255965292841648, 1: 5.4326923076923075}, 
       2: {0: 1.5416098226466575, 1: 2.8463476070528966}}

编辑

我使用model.fit()训练时的结果。

Epoch 1/20
1130/1130 [==============================] - 1383s 1s/step - loss: 4.1638 - binary_accuracy: 0.4558 - val_loss: 5.0439 - val_binary_accuracy: 0.3944
Epoch 2/20
1130/1130 [==============================] - 1397s 1s/step - loss: 4.1608 - binary_accuracy: 0.4165 - val_loss: 5.0526 - val_binary_accuracy: 0.5194
Epoch 3/20
1130/1130 [==============================] - 1402s 1s/step - loss: 4.1608 - binary_accuracy: 0.4814 - val_loss: 5.1469 - val_binary_accuracy: 0.6361
Epoch 4/20
1130/1130 [==============================] - 1407s 1s/step - loss: 4.1722 - binary_accuracy: 0.4472 - val_loss: 5.0501 - val_binary_accuracy: 0.5583
Epoch 5/20
1130/1130 [==============================] - 1397s 1s/step - loss: 4.1591 - binary_accuracy: 0.4991 - val_loss: 5.0521 - val_binary_accuracy: 0.6028
Epoch 6/20
1130/1130 [==============================] - 1375s 1s/step - loss: 4.1596 - binary_accuracy: 0.5431 - val_loss: 5.0515 - val_binary_accuracy: 0.5917
Epoch 7/20
1130/1130 [==============================] - 1370s 1s/step - loss: 4.1595 - binary_accuracy: 0.4962 - val_loss: 5.0526 - val_binary_accuracy: 0.6000
Epoch 8/20
1130/1130 [==============================] - 1387s 1s/step - loss: 4.1591 - binary_accuracy: 0.5316 - val_loss: 5.0523 - val_binary_accuracy: 0.6028
Epoch 9/20
1130/1130 [==============================] - 1391s 1s/step - loss: 4.1590 - binary_accuracy: 0.4909 - val_loss: 5.0521 - val_binary_accuracy: 0.6028
Epoch 10/20
1130/1130 [==============================] - 1400s 1s/step - loss: 4.1590 - binary_accuracy: 0.5369 - val_loss: 5.0519 - val_binary_accuracy: 0.6028
Epoch 11/20
1130/1130 [==============================] - 1397s 1s/step - loss: 4.1590 - binary_accuracy: 0.4808 - val_loss: 5.0519 - val_binary_accuracy: 0.6028
Epoch 12/20
1130/1130 [==============================] - 1394s 1s/step - loss: 4.1590 - binary_accuracy: 0.5469 - val_loss: 5.0522 - val_binary_accuracy: 0.6028

【问题讨论】:

  • 我认为你不应该对它们之间的不同类进行加权。您应该为每个类别加权标签 0 和 1。例如:对于您的第一堂课,您的 0 标签应该是 1130/913,而 1 的标签应该是 1130/217 (217=1130-917)。对于第二类:标签1的权重为1130/215等...
  • @federicober 我就是这么做的。我用 1130/217 为第一类加权标签 0,用 1130/913 加权标签 1,因为标签 1 出现 913 次,0 出现 217 次。
  • 您是否尝试过使用 3 个单独的分类器?
  • @federicober 我会在几个小时内告诉你。
  • @federicober 输出还是这样[[0.49103534]] [[0.48069718]] [[0.50579894]]。输出接近 0.5,这意味着 sigmoid 的输入几乎为零。我检查了,权重不为零。

标签: python tensorflow keras neural-network multilabel-classification


【解决方案1】:

我会尝试 label powerset 方法。

尝试根据标签和数据集将其设置为可能的组合总数,而不是 3 个输出节点。例如,对于具有 3 个不同类别的多标签分类,有 7 个可能的输出。

比如说,标签是 A、B 和 C。将输出 0 映射到 A、1 映射到 B、2 映射到 C、3 映射到 AB、4 映射到 AC 等等。

在训练和测试之前使用一个简单的转换函数,这个问题可以转化为一个多类、单标签的问题。

【讨论】:

  • 数据集是一个不平衡的多标签数据集。对一个类进行过采样也可能对与之关联的其他类进行过采样。您提供的链接是针对多类分类问题
猜你喜欢
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 2020-02-01
  • 2021-02-26
  • 2017-11-03
  • 2021-04-19
  • 2017-05-26
  • 2016-04-02
相关资源
最近更新 更多