这个问题苦恼我几个月,之前一直用替代方案。这次实在没替代方案了,transformers
源码和文档看了一整天,终于在晚上12点找到了。。。
解决方案:在TrainingArguments中指定label_names、remove_unused_columns、include_inputs_for_metrics三个参数
问题描述
使用transformers.Trainer就图个快和优雅,它包装了一整套的训练逻辑,让我们不用从数据加载、模型训练、评估、预测、保存模型、计算评价指标等等一整套写完。
但是显然,模型和任务一复杂的时候,loss的计算、评价指标的实现,我们还是需要重写的。于是问题就来了:
在计算评价指标时,即重写compute_metrics
方法时,形参pred
是EvalPrediction
类,然而它只提供三个变量:(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,哈哈哈哈
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net