1

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

这里有什么问题?

4

1 回答 1

0

您应该使用class_weightinfit函数或fit_generator将权重应用于您的类。

首先,您必须创建一个具有label:weight以下格式的字典:

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

然后将其应用于您的 fit 函数:

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在 fit 函数中。

于 2019-09-11T06:44:57.423 回答