首页 > 解决方案 > 将两个评估数据集传递给 HuggingFace Trainer 对象

问题描述

有什么方法可以将两个评估数据集传递给 HuggingFace Trainer 对象,以便在训练期间可以在两个不同的集合(例如分布内和分布外集)上评估经过训练的模型?这是对象的实例化,它只接受一个eval_dataset

trainer = Trainer(
    model,
    args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    tokenizer=tokenizer
)

标签: huggingface-transformers

解决方案


我也在寻找解决方案。与此同时,我可以提出这个解决方法:

Trainer在评估期间不会打乱数据集中的示例。因此,您可以使用它来合并两个数据集,只要您控制此合并并知道组成数据集的示例数量即可。然后,您稍后在计算指标时将示例分开。

为此,您必须实现自己的compute_metrics可调用对象并通过trainer = Trainer(compute_metrics=myComputeMertics). 请注意,您不控制此函数的参数,因此最好将其实现为某个类的方法,并在构造函数中传递您的数据集比率/组合。

我可以想象做这样的事情(不确定张量的形状和轴是否正确):

class MetricCollection:
    def __init__(self, dataset_1_size):
        self.dataset_1_size = dataset_1_size

    def mymetric(labels, predicted_scores):
        ...
        return result

    def compute_metrics(self, p: EvalPrediction) -> Dict:
        metrics = {}

        labels_1 = p.label_ids[:self.dataset_1_size]
        labels_2 = p.label_ids[self.dataset_1_size:]

        predictions_1 = p.predictions[:self.dataset_1_size, :]
        predictions_2 = p.predictions[self.dataset_1_size:, :]

        metrics['mymetric_dataset_1'] = mymetric(labels_1, predictions_1)
        metrics['mymetric_dataset_2'] = mymetric(labels_2, predictions_2)

        return metrics

然后在你的主代码中

metric_calculator = MetricCollection(dataset_1_size)

trainer = Trainer(
    model,
    args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    tokenizer=tokenizer,
    compute_metrics=metric_calculator.compute_metrics()
)

推荐阅读