【问题标题】:Sample weighting didn't help in imbalanced data training样本加权对不平衡的数据训练没有帮助
【发布时间】:2020-01-12 13:57:14
【问题描述】:

我正在训练一个两层 LSTM 网络,每层有 16 到 32 个单元,并且有一个相当不平衡的训练数据集。根据我的七个类频率,通过total_samples/class_frequency这个简单公式计算的样本权重是[3.7, 5.6, 26.4, 3.2, 191.6, 8.4, 13.2],我将每个样本的这个权重添加到(数据的元组中) ,标签)我的数据集生成器的输出以运行我的 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

这里有什么问题?

【问题讨论】:

  • 了解你使用的损失函数和拟合函数的代码块会更有帮助
  • 我更新了我的帖子并添加了代码部分。

标签: keras imbalanced-data


【解决方案1】:

您应该在fit 函数或fit_generator 中使用class_weight 将权重应用于您的类。

首先你必须创建一个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])

如果要对每个实例应用权重,则需要创建一个数组,其中包含训练数据中相应实例的权重,并将其设置在 fit 函数中的 sample_weight 中。

【讨论】:

  • 正如我在帖子中提到的,我将每个样本的权重添加到我的数据集生成器函数中。根据 Tensorflow 文档 (tensorflow.org/api_docs/python/tf/keras/Model),它得到了很好的支持,应该没有任何问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
  • 2015-03-16
  • 2016-05-05
  • 2020-09-09
  • 2016-04-21
  • 1970-01-01
  • 2018-04-15
相关资源
最近更新 更多