pytorch 当我将一个Transformer数据集传递给Trainer时,如何使用切片?

aiazj4mn  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(147)

参考this colab notebook(来自Huggingface Transformer课程here),如果我运行

tokenized_datasets["train"][:8]

dtypedict而不是Dataset,并且切片将返回一些数据。如果我在这里传递切片,我会得到一个Key错误,我假设这与我不再传递数据集的事实有关。

from transformers import Trainer

trainer = Trainer(
    model,
    training_args,
    train_dataset=tokenized_datasets["train"][:8],
    eval_dataset=tokenized_datasets["validation"],
    #data_collator=data_collator,
    tokenizer=tokenizer,
)


trainer.train()
***** Running training *****
  Num examples = 7
  Num Epochs = 3
  Instantaneous batch size per device = 8
  Total train batch size (w. parallel, distributed & accumulation) = 8
  Gradient Accumulation steps = 1
  Total optimization steps = 3
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-20-3435b262f1ae> in <module>()
----> 1 trainer.train()

有没有一种简单的方法可以只传递Dataset行的一个子集来进行训练或验证?

vhipe2zx

vhipe2zx1#

import transformers
from datasets import load_dataset

datasets = load_dataset('squad')
datasets

产出:

DatasetDict({
    train: Dataset({
        features: ['id', 'title', 'context', 'question', 'answers'],
        num_rows: 87599
    })
    validation: Dataset({
        features: ['id', 'title', 'context', 'question', 'answers'],
        num_rows: 10570
    })
})

然后我们可以对部分数据集进行采样:

train_datasets_sampled =  datasets["train"].shuffle(seed=42).select(range(2000))
eval_dataset_sampled = datasets["validation"].shuffle(seed=42).select(range(500))

train_datasets_sampled, eval_dataset_sampled

得到以下结果:

(Dataset({
     features: ['id', 'title', 'context', 'question', 'answers'],
     num_rows: 2000
 }), Dataset({
     features: ['id', 'title', 'context', 'question', 'answers'],
     num_rows: 500
 }))

来源:https://github.com/huggingface/notebooks/blob/master/transformers_doc/training.ipynb

rhfm7lfc

rhfm7lfc2#

您可以尝试从torch使用Subset,如:

from torch.utils.data import Subset
train_dataset = Subset(tokenized_datasets["train"], list(range(8)))
...  # init trainer

这应该为您提供给予一个数据集的子集,因此您仍然满足接口要求。(如果HuggingFace的变形金刚遵循它,我认为他们会这样做。

hkmswyz6

hkmswyz63#

也有可能进行分片:

dataset.shard(num_shards=10, index=0)

其中dataset.shard()是就地操作,index是你希望它返回的分片索引。它确实在幕后使用了.select()来实现这一点。
例如,如果你的数据集有1000个元素,而你只想得到其中的100个元素,通过将它分片成10个(1000 // 10) = 100,你将得到每个分片100个元素。

相关问题