PyTorch: «Ошибка типа: обнаружена ошибка типа в рабочем процессе загрузчика данных 0».

#python-3.x #deep-learning #nlp #bert-language-model #roberta

#python-3.x #глубокое обучение #nlp #bert-language-model #роберта

Вопрос:

Я пытаюсь реализовать модель Роберта для анализа настроений. Сначала я объявил GPReviewDataset для создания набора данных PyTorch.

 MAX_LEN = 160
class GPReviewDataset(Dataset):
  def __init__(self, reviews, targets, tokenizer, max_len):
    self.reviews = reviews
    self.targets = targets
    self.tokenizer = tokenizer
    self.max_len = max_len
  def __len__(self):
    return len(self.reviews)
  def __getitem__(self, item):
    review = str(self.reviews[item])
    target = self.targets[item]
    encoding = self.tokenizer.encode_plus(
      review,
      add_special_tokens=True,
      max_length=self.max_len,
      return_token_type_ids=False,
      pad_to_max_length=True,
      return_attention_mask=True,
      return_tensors='pt',
    )
    return {
      'review_text': review,
      'input_ids': encoding['input_ids'].flatten(),
      'attention_mask': encoding['attention_mask'].flatten(),
      'targets': torch.tensor(target, dtype=torch.long)
    }
 

Далее я реализую create_data_loader создание пары загрузчиков данных. Вот вспомогательная функция для этого:

 def create_data_loader(df, tokenizer, max_len, batch_size):
  ds = GPReviewDataset(
    reviews=df.text.to_numpy(),
    targets=df.sentiment.to_numpy(),
    tokenizer=tokenizer,
    max_len=max_len
  )
  return DataLoader(
    ds,
    batch_size=batch_size,
    num_workers=4
  )
 
 BATCH_SIZE = 16
train_data_loader = create_data_loader(df_train, tokenizer, MAX_LEN, BATCH_SIZE)
val_data_loader = create_data_loader(df_val, tokenizer, MAX_LEN, BATCH_SIZE)
test_data_loader = create_data_loader(df_test, tokenizer, MAX_LEN, BATCH_SIZE)
 
 dt = next(iter(train_data_loader))
 

Однако, когда я запускаю этот код, он останавливается и выдает мне эти ошибки:

 TypeError                                 Traceback (most recent call last)
<ipython-input-35-a673c0794f60> in <module>()
----> 1 dt = next(iter(train_data_loader))

3 frames
/usr/local/lib/python3.6/dist-packages/torch/utils/data/dataloader.py in __next__(self)
    433         if self._sampler_iter is None:
    434             self._reset()
--> 435         data = self._next_data()
    436         self._num_yielded  = 1
    437         if self._dataset_kind == _DatasetKind.Iterable and 

/usr/local/lib/python3.6/dist-packages/torch/utils/data/dataloader.py in _next_data(self)
   1083             else:
   1084                 del self._task_info[idx]
-> 1085                 return self._process_data(data)
   1086 
   1087     def _try_put_index(self):

/usr/local/lib/python3.6/dist-packages/torch/utils/data/dataloader.py in _process_data(self, data)
   1109         self._try_put_index()
   1110         if isinstance(data, ExceptionWrapper):
-> 1111             data.reraise()
   1112         return data
   1113 

/usr/local/lib/python3.6/dist-packages/torch/_utils.py in reraise(self)
    426             # have message field
    427             raise self.exc_type(message=msg)
--> 428         raise self.exc_type(msg)
    429 
    430 

TypeError: Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/worker.py", line 198, in _worker_loop
    data = fetcher.fetch(index)
  File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/fetch.py", line 44, in fetch
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "/usr/local/lib/python3.6/dist-packages/torch/utils/data/_utils/fetch.py", line 44, in <listcomp>
    data = [self.dataset[idx] for idx in possibly_batched_index]
  File "<ipython-input-18-1e537ce5a428>", line 25, in __getitem__
    'targets': torch.tensor(target, dtype=torch.long)
TypeError: new(): invalid data type 'str'
 

Я не понимаю, почему это происходит, может кто-нибудь, пожалуйста, помочь мне и объяснить.

Комментарии:

1. Что это за тип df.sentiment ?

Ответ №1:

Вам нужно определить свои классы как целочисленные. Я предполагаю, что вы работаете над проблемой классификации. Но, похоже, вы определили свои классы как строки. Вам необходимо преобразовать ваши классы из string в integer . Например, если df.sentiment соответствует положительному, вы должны представить с 0 или df.sentiment соответствует отрицательному, вам нужно представить с 1 в новом столбце.

 def to_int_sentiment(label):
  if label == "positive":
    return 0
  elif label == "negative":
    return 1

df['int_sentiment'] = df.sentiment.apply(to_int_sentiment)
 

Затем вы должны использовать столбец df.int_sentiment вместо df.sentiment. Итак, вам нужно изменить функцию create_data_loader следующим образом.

 def create_data_loader(df, tokenizer, max_len, batch_size):
  ds = GPReviewDataset(
    reviews=df.text.to_numpy(),
    targets=df.int_sentiment.to_numpy(),
    tokenizer=tokenizer,
    max_len=max_len
  )
  return DataLoader(
    ds,
    batch_size=batch_size,
    num_workers=4
  )