在 Keras 中使用不平衡样本训练多标签分类器

数据挖掘 Python 神经网络 分类 喀拉斯 多标签分类
2022-02-14 02:54:09

我正在尝试训练一个接收样本的 keras 模型,比如说xi样品i,并预测多个独立标签,y^ij, 这样y^ij=1如果模型预测样本xi有标签j, 和0除此以外。

我反复遇到的问题是每个标签的样本数量在标签之间不平衡。特别是,这里是每个标签有多少样本的计数(当然有重复计数,因为我们正在处理多标签分类)。我的模型有 23 个标签。

total: 6790
Counter({22: 4702, 0: 1749, 12: 130, 8: 43, 16: 39,
         15: 30, 17: 24, 20: 17, 4: 13, 5: 13, 19: 9,
         6: 7, 7: 6, 2: 4, 10: 4})

但是,我不确定如何按尺寸衡量它们的重量。我看到了这个问题,但它使用标签的单热编码,即假设每个样本只有一个真正的标签。它本质上是一个稀疏的分类问题。我也遇到了这个问题,但我相信这个问题与类的每个样本权重有关,不知何故。接受的答案没有说明如何计算训练样本的权重。

到目前为止我尝试了什么:我计算了每个标签相对于其出现次数与总样本的任意权重。 class_weight = dict((c,round((1/v)*total,1)) for c,v in class_occ.items())class_occ上面显示的计数器在哪里。这是我得到的:

class_weights: {0: 3.9, 2: 1697.5, 4: 522.3, 5: 522.3, 6: 970.0, 7: 1131.7, 8: 157.9, 10: 1697.5, 12: 52.2, 15: 226.3, 16: 174.1, 17: 282.9, 19: 754.4, 20: 399.4, 22: 1.4}

然后,在训练模型时,我将它作为一个 kwarg 提供:

model.fit(x=...., class_weight=class_weight)

然而,该模型此后并没有真正学习,准确率保持在 0.1 左右的低水平。为了提供一些上下文,这是我编译模型的方式:

out = Dense(numclasses+1, activation='sigmoid', name='out')(dense_top)

model = Model(inputs=[input], outputs=[out])
model.compile(optimizer="adam", loss="binary_crossentropy",
              metrics=["categorical_accuracy"])

以下是训练的过程(蓝色是损失): 模型拟合历史

我不确定出了什么问题-我是否正确使用了班级权重?如果没有类权重,该模型将一直预测主导类,而准确度将作为具有主导类的样本比例的基线。但看起来它现在比随机更差。

以防万一它有帮助,这是我的model.summary()输出:

Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, None, 128)         0         
_________________________________________________________________
lstm_1 (LSTM)                (None, 192)               246528    
_________________________________________________________________
dense_1 (Dense)              (None, 160)               30880     
_________________________________________________________________
dense_2 (Dense)              (None, 128)               20608     
_________________________________________________________________
dense_3 (Dense)              (None, 128)               16512     
_________________________________________________________________
dense_4 (Dense)              (None, 64)                8256      
_________________________________________________________________
dense_top_1 (Dense)          (None, 64)                4160      
_________________________________________________________________
dropout_42 (Dropout)         (None, 64)                0         
_________________________________________________________________
dense_top_2 (Dense)          (None, 64)                4160      
_________________________________________________________________
dropout_43 (Dropout)         (None, 64)                0         
_________________________________________________________________
dense_top_3 (Dense)          (None, 64)                4160      
_________________________________________________________________
dropout_44 (Dropout)         (None, 64)                0         
_________________________________________________________________
dense_top_4 (Dense)          (None, 64)                4160      
_________________________________________________________________
dropout_45 (Dropout)         (None, 64)                0         
_________________________________________________________________
dense_top_5 (Dense)          (None, 32)                2080      
_________________________________________________________________
out (Dense)                  (None, 23)                759       
=================================================================
Total params: 342,263
Trainable params: 19,479
Non-trainable params: 322,784

不可训练参数的原因是我正在使用迁移学习:第一组层来自另一个模型,该模型对相同数据进行二进制分类,用于相关标签集('做一个样本x有标签集 A 和标签集 B 中的任何标签吗?')。以防万一我还在True一个单独的实例中将 trainable 设置为,但它对训练和让模型工作没有帮助。

0个回答
没有发现任何回复~