Keras中类不平衡多类分类器的损失函数

时间:2019-02-07 13:47:48

标签: python keras lstm

我正在尝试将深度学习应用于目标类别(10K,500K,90K,30K)之间类别高度不平衡的多类别分类问题。我想编写一个自定义损失函数。 这是我目前的模型:

model = Sequential()

model.add(LSTM(
                units=10, # number of units returned by LSTM
                return_sequences=True, 
                input_shape=(timestamps,nb_features),
                dropout=0.2, 
                recurrent_dropout=0.2
              )
         )

model.add(TimeDistributed(Dense(1)))

model.add(Dropout(0.2))

model.add(Flatten())

model.add(Dense(units=nb_classes,
               activation='softmax'))

model.compile(loss="categorical_crossentropy",
              metrics = ['accuracy'],
              optimizer='adadelta')

不幸的是,所有预测都属于1类!该模型始终为任何输入预测1 ...

赞赏有关如何解决此任务的任何指示。

更新

输入数据的维数

94981 train sequences
29494 test sequences
X_train shape: (94981, 20, 18)
X_test shape: (29494, 20, 18)
y_train shape: (94981, 4)
y_test shape: (29494, 4)

基本上在火车数据中,我有94981个样本。每个样本包含20个时间戳的序列。有18个功能。

目标类别(10K,500K,90K,30K)之间的不平衡只是一个例子。我在真实数据集中的比例相似。

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:2)

首先,您有大约10万个样本。从较小的内容开始,例如100个样本和多个历元,然后查看您的模型是否适合此较小的训练数据集(如果不能,则说明您的代码有错误或模型无法为依赖关系建模[我会第二种情况])。认真地,从这个开始。并记住要在这个小型数据集中表示所有类。

第二,LSTM的隐藏大小可能太小,每个序列都有18个特征,而序列的长度为20,而隐藏的长度只有10个。您可以应用dropout使其更完善并进一步规范网络。

此外,您可能希望添加一些密集的输出单位,而不是仅为每个时间戳返回大小为10 x 1的线性层。

最后但并非最不重要的一点是,您可能想对代表性不足的数据进行上采样。 0 class必须重复说50次(或可能是25次),class 2大约要重复4次,而您的大约要重复10-15次,这样就可以对它们进行网络训练。

哦,对您的超参数(例如隐藏的大小,密集单位的数量等)使用交叉验证。

另外,我不知道您已经训练了多少个网络,您的测试数据集是什么(如果没有进行分层,完全有可能只构成第一类)。

我认为这可以帮助您入门,在评论中如有任何疑问,请与我联系。

编辑:涉及指标时,您可能需要检查除准确性以外的其他内容;也许F1分数和您的损失监测+准确性以查看其表现。还有其他可用的选择,您可以选择sklearn's documentation作为启发,因为它们提供了很多选择。