如何将 'collate_fn' 与数据加载器一起使用?
How to use 'collate_fn' with dataloaders?
我正在尝试使用 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() argument must have dict attribute
现在我发现这可能是因为我在使用 DataLoader
时没有使用 collate_fn
,但是我真的找不到可以帮助我正确定义它的来源,所以培训师了解我输入的不同张量。
谁能指出我正确的方向?
基本上,如果您的 __getitem__
函数来自 Dataset 子类 returns 一个元组,collate_fn
会收到一个元组列表,或者如果您的 Dataset 子类 [=32] 只是一个普通列表=] 只有一个元素。它的主要 objective 是创建您的批次,而无需花费太多时间手动实施它。尝试将其视为您指定示例在批次中粘合在一起的方式的粘合剂。如果你不使用它,PyTorch 只会像使用 torch.stack 一样将 batch_size
个示例放在一起(不完全是,但它很简单)。
例如,假设您要创建不同维度张量列表的批次。下面的代码用 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() 函数时,您需要使用长度来取回原始数据,而不是在计算中使用那些无意义的零。
我正在尝试使用 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() argument must have dict attribute
现在我发现这可能是因为我在使用 DataLoader
时没有使用 collate_fn
,但是我真的找不到可以帮助我正确定义它的来源,所以培训师了解我输入的不同张量。
谁能指出我正确的方向?
基本上,如果您的 __getitem__
函数来自 Dataset 子类 returns 一个元组,collate_fn
会收到一个元组列表,或者如果您的 Dataset 子类 [=32] 只是一个普通列表=] 只有一个元素。它的主要 objective 是创建您的批次,而无需花费太多时间手动实施它。尝试将其视为您指定示例在批次中粘合在一起的方式的粘合剂。如果你不使用它,PyTorch 只会像使用 torch.stack 一样将 batch_size
个示例放在一起(不完全是,但它很简单)。
例如,假设您要创建不同维度张量列表的批次。下面的代码用 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() 函数时,您需要使用长度来取回原始数据,而不是在计算中使用那些无意义的零。