如何将“collate_fn”与数据加载器一起使用?
Posted
技术标签:
【中文标题】如何将“collate_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 填充序列直到批处理的最大序列大小,这就是我们需要 collate_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 中的 collate_fn 参数,如下例:
DataLoader(toy_dataset, collate_fn=collate_fn, batch_size=5)
使用此 collate_fn 函数,您将始终拥有一个张量,其中所有示例的大小都相同。因此,当您将这些数据提供给 forward() 函数时,您需要使用长度来取回原始数据,而不是在计算中使用那些无意义的零。
来源:Pytorch Forum
【讨论】:
以上是关于如何将“collate_fn”与数据加载器一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
用于各种维度输入的高效 PyTorch DataLoader collate_fn 函数