【问题标题】:Where in the code of pytorch or huggingface/transformer label gets "renamed" into labels?在 pytorch 或 huggingface/transformer 标签的代码中哪里被“重命名”为标签?
【发布时间】:2020-10-07 15:03:40
【问题描述】:

我的问题是关于这个例子,可以在伟大的 huggingface/transformers 库中找到。

我正在使用库创建者提供的notebook 作为我管道的起点。它提出了一个微调 BERT 以在 Glue 数据集上进行句子分类的管道。

在进入代码时,我注意到一个非常奇怪的事情,我无法解释。

在示例中,输入数据作为来自here 的InputFeatures 类的实例引入模型:

这个类有4个属性,包括label属性:

class InputFeatures:
    ...
    input_ids: List[int]
    attention_mask: Optional[List[int]] = None
    token_type_ids: Optional[List[int]] = None
    label: Optional[Union[int, float]] = None

稍后作为输入字典传递给模型的forward() 方法。这是由Trainer 类完成的,例如在573-576 行中here:

    def _training_step(
        self, model: nn.Module, inputs: Dict[str, torch.Tensor], optimizer: torch.optim.Optimizer
    ) -> float:
        model.train()
        for k, v in inputs.items():
            inputs[k] = v.to(self.args.device)

        outputs = model(**inputs)  

但是,forward() 方法需要 labels(注意复数形式)输入参数(取自 here):

    def forward(
        self,
        input_ids=None,
        attention_mask=None,
        head_mask=None,
        inputs_embeds=None,
        labels=None,
        output_attentions=None,
    ):

所以我的问题是标签在这个管道中在哪里变成标签?

为了提供一些关于这个问题的额外信息,我创建了自己的管道,它不使用任何与 Glue 数据和管道相关的东西,基本上它只依赖于 Trainer 类转换器。我什至使用另一个模型(福楼拜)。我复制了 InputFeature 类,我的代码适用于以下两种情况:

class InputFeature:
    def __init__(self, text, label):
        self.input_ids = text
        self.label = label

class InputFeaturePlural:
    def __init__(self, text, label):
        self.input_ids = text
        self.labels = label

但是,如果我将第二个属性命名为 self.labe 或任何其他名称,则它不起作用。 为什么可以同时使用两个属性名?

在我的情况下它并不是非常重要,但我觉得在变量中传递数据感到不舒服,这会在某个地方“更改名称”。

【问题讨论】:

    标签: python pytorch huggingface-transformers


    【解决方案1】:

    重命名发生在collator。在trainer init 中,当data_collator 为None 时,使用默认值:

    class Trainer:
        # ...
        def __init__(...):
            # ...
            self.data_collator = data_collator if data_collator is not None else default_data_collator
            # ...
    

    仅供参考,self.data_collator 稍后会在您获得 dataloader 时使用:

    data_loader = DataLoader(
        self.train_dataset,
        batch_size=self.args.train_batch_size,
        sampler=train_sampler,
        collate_fn=self.data_collator,              # <-- here
        drop_last=self.args.dataloader_drop_last,
    )
    

    默认整理器有一个special handling for labels,如果需要,它会进行重命名:

    # Special handling for labels.
    # Ensure that tensor is created with the correct type
    # (it should be automatically the case, but let's make sure of it.)
    if hasattr(first, "label") and first.label is not None:
        if type(first.label) is int:
            labels = torch.tensor([f.label for f in features], dtype=torch.long)
        else:
            labels = torch.tensor([f.label for f in features], dtype=torch.float)
        batch = {"labels": labels}  # <-- here is where it happens
    elif hasattr(first, "label_ids") and first.label_ids is not None:
        if type(first.label_ids[0]) is int:
            labels = torch.tensor([f.label_ids for f in features], dtype=torch.long)
        else:
            labels = torch.tensor([f.label_ids for f in features], dtype=torch.float)
        batch = {"labels": labels}
    else:
        batch = {}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 2020-01-26
      相关资源
      最近更新 更多