如何将“collat​​e_fn”与数据加载器一起使用?

Posted

技术标签:

【中文标题】如何将“collat​​e_fn”与数据加载器一起使用?【英文标题】:How to use 'collate_fn' with dataloaders? 【发布时间】:2021-03-24 12:11:34 【问题描述】:

我正在尝试使用 3 个输入、3 个 input_masks 和一个标签作为我的训练数据集的张量来训练一个预训练的 roberta 模型。

我使用以下代码进行此操作:

from torch.utils.data import TensorDataset, DataLoader, RandomSampler, SequentialSampler
batch_size = 32
# Create the DataLoader for our training set.
train_data = TensorDataset(train_AT, train_BT, train_CT, train_maskAT, train_maskBT, train_maskCT, labels_trainT)
train_dataloader = DataLoader(train_data, batch_size=batch_size)

# Create the Dataloader for our validation set.
validation_data = TensorDataset(val_AT, val_BT, val_CT, val_maskAT, val_maskBT, val_maskCT, labels_valT)
val_dataloader = DataLoader(validation_data, batch_size=batch_size)

# Pytorch Training
training_args = TrainingArguments(
    output_dir='C:/Users/samvd/Documents/Master/AppliedMachineLearning/FinalProject/results',          # output directory
    num_train_epochs=1,              # total # of training epochs
    per_device_train_batch_size=32,  # batch size per device during training
    per_device_eval_batch_size=32,   # batch size for evaluation
    warmup_steps=500,                # number of warmup steps for learning rate scheduler
    weight_decay=0.01,               # strength of weight decay
    logging_dir='C:/Users/samvd/Documents/Master/AppliedMachineLearning/FinalProject/logs',            # directory for storing logs
)

trainer = Trainer(
    model=model,                          # the instantiated ???? Transformers model to be trained
    args=training_args,                   # training arguments, defined above
    train_dataset = train_data,           # training dataset
    eval_dataset = validation_data,       # evaluation dataset
)

trainer.train()

但是这给了我以下错误:

TypeError: vars() 参数必须具有 dict 属性

现在我发现这可能是因为我在使用DataLoader 时没有使用collate_fn,但我真的找不到可以帮助我正确定义这一点的来源,因此培训师了解我所使用的不同张量放进去。

谁能指出我正确的方向?

【问题讨论】:

你在同一个问题上发了三遍,我不确定它是否能帮助你得到答案。我建议编辑您的原始问题。这将有助于读者回答您的问题。 这能回答你的问题吗? Adding class objects to Pytorch Dataloader: batch must contain tensors。它展示了如何使用collate_fn 【参考方案1】:

基本上,如果来自 Dataset 子类的 __getitem__ 函数返回一个元组,则 collate_fn 会接收一个元组列表,或者如果您的 Dataset 子类只返回一个元素,则只会接收一个普通列表。它的主要目标是创建您的批处理,而无需花费太多时间手动实现它。尝试将其视为您指定示例在批次中粘合在一起的方式的粘合剂。如果您不使用它,PyTorch 只会将 batch_size 示例放在一起,就像您使用 torch.stack 一样(不完全是它,但它很简单)。

例如,假设您要创建一批不同维度张量的列表。下面的代码用 0 填充序列直到批处理的最大序列大小,这就是我们需要 collat​​e_fn 的原因,因为标准批处理算法(简单地使用torch.stack)在这种情况下不起作用,我们需要手动填充在创建批次之前,具有可变长度的不同序列到相同大小。

def collate_fn(data):
    """
       data: is a list of tuples with (example, label, length)
             where 'example' is a tensor of arbitrary shape
             and label/length are scalars
    """
    _, labels, lengths = zip(*data)
    max_len = max(lengths)
    n_ftrs = data[0][0].size(1)
    features = torch.zeros((len(data), max_len, n_ftrs))
    labels = torch.tensor(labels)
    lengths = torch.tensor(lengths)

    for i in range(len(data)):
        j, k = data[i][0].size(0), data[i][0].size(1)
        features[i] = torch.cat([data[i][0], torch.zeros((max_len - j, k))])

    return features.float(), labels.long(), lengths.long()

上面的函数被馈送到 DataLoader 中的 collat​​e_fn 参数,如下例:

DataLoader(toy_dataset, collate_fn=collate_fn, batch_size=5)

使用此 collat​​e_fn 函数,您将始终拥有一个张量,其中所有示例的大小都相同。因此,当您将这些数据提供给 forward() 函数时,您需要使用长度来取回原始数据,而不是在计算中使用那些无意义的零。

来源:Pytorch Forum

【讨论】:

以上是关于如何将“collat​​e_fn”与数据加载器一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

用于各种维度输入的高效 PyTorch DataLoader collat​​e_fn 函数

如何将 bootstrap 5 与 webpack 加载器一起使用?

如何将 NGXS 与路由解析器一起使用?

与 GraphQL 数据加载器一起实现内存缓存

如何将 keras 模型与其他数据一起保存并完全加载?

为啥 PIL 经常与 Pytorch 一起使用?