在 pytorch 或 huggingface/transformer 标签的代码中,在哪里将 "renamed" 放入标签中?
Where in the code of pytorch or huggingface/transformer label gets "renamed" into labels?
我的问题与示例有关,可在很棒的 huggingface/transformers 库中找到。
我正在使用库创建者提供的 notebook 作为我的管道的起点。它提出了一个微调 BERT 的管道,用于 Glue 数据集上的句子分类。
在进入代码时,我注意到一个非常奇怪的事情,我无法解释。
在示例中,输入数据作为 InputFeatures
class 来自 here:
的实例引入模型
这个class有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
class 完成的,例如第 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
class .我什至使用另一个模型(福楼拜)。我复制了 InputFeature class,我的代码适用于以下两种情况:
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
或任何其他名称,它就不起作用。 为什么可以同时使用两个属性名称?
在我的情况下这并不是特别重要,但我觉得在变量中传递数据很不舒服,它会在某个地方“更改名称”。
重命名发生在 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 = {}
我的问题与示例有关,可在很棒的 huggingface/transformers 库中找到。
我正在使用库创建者提供的 notebook 作为我的管道的起点。它提出了一个微调 BERT 的管道,用于 Glue 数据集上的句子分类。
在进入代码时,我注意到一个非常奇怪的事情,我无法解释。
在示例中,输入数据作为 InputFeatures
class 来自 here:
这个class有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
class 完成的,例如第 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
class .我什至使用另一个模型(福楼拜)。我复制了 InputFeature class,我的代码适用于以下两种情况:
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
或任何其他名称,它就不起作用。 为什么可以同时使用两个属性名称?
在我的情况下这并不是特别重要,但我觉得在变量中传递数据很不舒服,它会在某个地方“更改名称”。
重命名发生在 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 = {}