样本加权无助于数据均衡训练

时间:2019-09-10 19:23:36

标签: keras imbalanced-data

我正在训练一个两层LSTM网络,每层中有16到32个单元,并且训练的数据集非常不平衡。根据我的七个班次频率,通过total_samples / class_frequency的简单公式计算出的样本权重为[3.7、5.6、26.4、3.2、191.6、8.4、13.2],我将每个样本的权重加到(data (标签))运行我的Keras model.fit()函数的数据集生成器的输出。培训代码为:

model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
mc = ModelCheckpoint(model_file, monitor='val_acc', mode='max', verbose=1, save_best_only=True)
es = EarlyStopping(monitor='val_acc', mode='max', verbose=1, patience=50)
history = model.fit(train_data, epochs=epochs, steps_per_epoch = train_steps, validation_data=val_data,
                            validation_steps = val_steps, verbose=verbose, callbacks=[es, mc])

然后我使用保存得最好的模型来评估它,并通过此代码计算性能统计信息(我的数据在tensorflow数据集中):

saved_model = load_model(model_file)
iterator = test_data.make_one_shot_iterator()
next_element = iterator.get_next()
y_test = y_pred = np.empty(0)
for i in range(test_steps):
    batch = sess.run(next_element)
    x_test_batch = batch[0]
    y_test_batch = batch[1]
    y_pred_batch = saved_model.predict_on_batch(x_test_batch)
    y_test = np.append(y_test, np.argmax(y_test_batch, axis=1))
    y_pred = np.append(y_pred, np.argmax(y_pred_batch, axis=1))
print('\nTest data classification report:\n{}\n'.format(classification_report(y_test, y_pred)))

但是我在输出统计数据中看到的是,加权统计总体上比未加权统计更差(将所有权重均等设置为1),即使对于稀有类(最高权重)也是如此。统计信息:

对于加权跑步:

     class     prec.     recall    f1       support
     0.0       1.00      0.97      0.98     79785
     1.0       0.89      0.88      0.88     52614
     2.0       0.61      0.76      0.68     11090
     3.0       0.96      0.93      0.95     91160
     4.0       0.59      0.92      0.72      1530
     5.0       0.89      0.90      0.89     34746
     6.0       0.81      0.87      0.84     22289

accuracy                           0.92    293214
macro avg      0.82      0.89      0.85    293214

对于非加权运行:

     class     prec.     recall    f1       support
     0.0       0.99      0.98      0.99     79785
     1.0       0.89      0.90      0.90     52614
     2.0       0.79      0.66      0.72     11090
     3.0       0.95      0.96      0.95     91160
     4.0       0.85      0.82      0.83      1530
     5.0       0.89      0.92      0.90     34746
     6.0       0.88      0.86      0.87     22289

accuracy                           0.93    293214
macro avg      0.89      0.87      0.88    293214

这是怎么了?

1 个答案:

答案 0 :(得分:0)

您应该使用class_weight函数中的fitfit_generator将权重应用于您的班级。

首先,您必须创建label:weight格式的字典:

class_weight = {0: 3.7,
            1: 5.6,
            2: 2.64,...}

然后将其应用于您的健身功能:

history = model.fit(train_data, epochs=epochs, steps_per_epoch = train_steps, validation_data=val_data, 
                        class_weight=class_weight, validation_steps = val_steps, verbose=verbose, callbacks=[es, mc])

如果要为每个实例应用权重,则需要创建一个数组,在训练数据中包含相应实例的权重,并在健身功能的sample_weight中对其进行设置。