2017-04-02 67 views
6

我构造的顺序keras模型35000个输入样本和20个预测,测试数据输出类分布为:Keras多类别预测输出被限制为一个类

  • Class_0 = 5.6%
  • Class_1 = 7.7%
  • Class_2 = 35.6%
  • Class_3 = 45.7%
  • Class_4 = 5.4%

利用(np_utils.to_categorical)将输出转换为二元类矩阵后,训练精度约为54%,当我对测试数据(15000个样本)进行模型拟合时,所有的预测(100%)碰巧是针对同一类这是class_3“在训练输出中最高的发生率”,这种偏见的原因是什么,并且没有针对其他类的单一预测?如何使模型对预测较少的类敏感,并提高准确度,特别是如果训练数据的一致性较低,如1 - 3%。

model = Sequential() 
model.add(Dense(40, input_dim=20, activation='relu')) 
model.add(Dropout(0.2)) 
model.add(Dense(10, activation='relu')) 
model.add(Dense(5, activation='softmax')) 
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy']) 

model.fit(X, Y, epochs=500, verbose=1) 

回答

3

来平衡你的损失的最简单的方法是:

  1. 定义class_weights字典:

    class_weights_dict = {0: 1.0/0_class_freq, 1: 1.0/1_class_freq, ... } 
    

    哪里i_class_freqi-th类的频率。

  2. 更改fit功能:

    model.fit(X, Y, epochs=500, verbose=1, class_weight=class_weights_dict) 
    

以上定义应该是等同于Bayessian模型该模型重新加权类。

0

解决问题的一种方法是在代表的类示例下进行过采样。 即,如果您有两个类A(66.6%)和B(33.3%),则您将样本B与A进行比较两次。 为了使其更简单,您可以通过复制一次B并使数据集如A + 2 * B。

或者,您可以修改您的损失函数,以便在对代表性不足的类进行错误分类时提供更多权重。

+0

vikasreddy,ty的建议。你能否更详细地阐述修改损失函数以给予更多的权重,以及对于问题的第一部分,解释为什么网络忽略预测剩余(54.3%)的其他类别,特别是具有大量观察的类别_2 %)?? – Ray

+0

我能想到的一个原因是,模型不够复杂,不能完全最小化损失函数,因此它保持在局部最小值,这恰好可以预测所有的例子在class_3中。 – vikasreddy

+0

由于加权损失函数的实现请参考https://github.com/fchollet/keras/issues/2115#issuecomment-204060456 – vikasreddy