重写transformers.Trainer的compute_metrics方法计算评价指标时,形参如何包含自定义的数据

  这个问题苦恼我几个月,之前一直用替代方案。这次实在没替代方案了,transformers源码和文档看了一整天,终于在晚上12点找到了。。。


解决方案:在TrainingArguments中指定label_namesremove_unused_columnsinclude_inputs_for_metrics三个参数


问题描述

  使用transformers.Trainer就图个快和优雅,它包装了一整套的训练逻辑,让我们不用从数据加载、模型训练、评估、预测、保存模型、计算评价指标等等一整套写完。

  但是显然,模型和任务一复杂的时候,loss的计算、评价指标的实现,我们还是需要重写的。于是问题就来了:

  在计算评价指标时,即重写compute_metrics方法时,形参predEvalPrediction类,然而它只提供三个变量:(predictions=all_preds, label_ids=all_labels, inputs=all_inputs),但是我们还需要其他的数据来算评价指标怎么办??

解决方案

  在TrainingArguments中添加以下三个参数

args = TrainingArguments(
	...
    label_names=['labels','自定义数据名'],
    remove_unused_columns= False, # 在compute_loss 时需要额外输入
    include_inputs_for_metrics= True # compute_metrics 时需要原始输出来计算评价指标
)

  然后你会发现,compute_metrics的形参的label_ids存的就不知原始标签了,现在存的是元组,就是你指定的label_names里面的数据。

详细使用方法

  1、在构建输入的时候,除了PLM模型本身就需要的数据,还要有我们想使用的自定义数据,格式如下:

feature_dict = {
    
    
// PLM规定的输入
'input_ids': torch.tensor([f.input_ids for f in features], dtype=torch.long),
'attention_mask': torch.tensor([f.attention_mask for f in features], dtype=torch.long),
'token_type_ids': torch.tensor([f.token_type_ids for f in features], dtype=torch.long),
'labels': torch.tensor([f.labels for f in features], dtype=torch.long),
// 自定义的输入
'自定义名': torch.tensor([f.自定义名 for f in features], dtype=torch.long)
}

  2、在TrainingArguments中设置remove_unused_columns= False,意思是在重写compute_loos方法时,不会删除我们自定义的列。

  这样,在compute_loos方法中,我们就可以使用自定义的列的数据了。但是要注意在把输入喂给model的时候,要把自定义列摘出来,不然会报错:

def compute_loss(self, model, inputs, return_outputs=False):
    # 运行模型
    new_inputs = {
    
    k:v for k, v in inputs.items() if k not in ['自定义名']}
    outputs = model(**new_inputs)
    ...

  3、在TrainingArguments中设置label_names=['labels','自定义数据名'],意思是在重写compute_metrics方法时,形参的label_ids属性会存入我们设置的那些列。使用方法:

# 重写评价指标计算
def compute_metrics(pred):
    labels, 自定义数据名 = pred.label_ids
    ...

Prompt最近这么火,一个方向的朋友一定会出现和我一样的问题,看到这篇帖子麻烦评论个1,哈哈哈哈

猜你喜欢

转载自blog.csdn.net/qq_43592352/article/details/131148273