我正在尝试将深度学习应用于目标类别(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)之间的不平衡只是一个例子。我在真实数据集中的比例相似。
答案 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作为启发,因为它们提供了很多选择。