# enumerate(data_loader)处报错

enumerate(data_loader)处报错

问题关键词:

  1. UnicodeDecodeError: ‘utf-8’ codec can’t decode bytes in position 1022-1023: unexpected end of data
  2. enumerate(data_loader)报错
  3. num_workers设置为大于1报错

在训练Swin-Transformer的时候突然出现这问题,让人很是烦,因为之前运行的时候还是好好地,突然就报错了,报错的位置就是enumerate(data_loader),之前遇到过这问题但是没有记录下来,又遇到了忘得干干净净。今天记录一下。

train_loader = torch.utils.data.DataLoader(train_dataset,
                                           batch_size=batch_size,
                                           shuffle=True,
                                           pin_memory=True,
                                           num_workers=nw,
                                           collate_fn=train_dataset.collate_fn)

DataLoader有个参数num_workers

  1. 每次dataloader加载数据时:dataloader一次性创建num_worker个worker,(也可以说dataloader一次性创建num_worker个工作进程,worker也是普通的工作进程),并用batch_sampler将指定batch分配给指定worker,worker将它负责的batch加载进RAM。
  2. 然后,dataloader从RAM中找本轮迭代要用的batch,如果找到了,就使用。如果没找到,就要num_worker个worker继续加载batch到内存,直到dataloader在RAM中找到目标batch。一般情况下都是能找到的,因为batch_sampler指定batch时当然优先指定本轮要用的batch。
  3. num_worker设置得大,好处是寻batch速度快,因为下一轮迭代的batch很可能在上一轮/上上一轮…迭代时已经加载好了。坏处是内存开销大,也加重了CPU负担(worker加载数据到RAM的进程是CPU复制的嘛)。num_workers的经验设置值是自己电脑/服务器的CPU核心数,如果CPU很强、RAM也很充足,就可以设置得更大些。
  4. 如果num_worker设为0,意味着每一轮迭代时,dataloader不再有自主加载数据到RAM这一步骤(因为没有worker了),而是在RAM中找batch,找不到时再加载相应的batch。缺点当然是速度更慢。

这个地方有几个坑:

  • 如果我们运行的时候吗,没有把代码放到if __name__ == '__main__': 会报错:
Traceback (most recent call last):
  File "G:\PyCharm 2021.2.2\plugins\python\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 303, in _on_run
    r = r.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 1022-1023: unexpected end of data
Traceback (most recent call last):
  File "", line 1, in <module>
  File "G:\PyCharm 2021.2.2\plugins\python\helpers\pydev\pydevd.py", line 1697, in settrace
    stop_at_frame,
  File "G:\PyCharm 2021.2.2\plugins\python\helpers\pydev\pydevd.py", line 1764, in _locked_settrace
    time.sleep(0.1)  # busy wait until we receive run command
KeyboardInterrupt

  • 如果我们debug的时候,num_worker 设置大于1有可能会堵塞,进程不动了,控制台输出:

    or from the matplotlib source distribution
    Traceback (most recent call last):
      File "G:\PyCharm 2021.2.2\plugins\python\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 303, in _on_run
        r = r.decode('utf-8')
    UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 1022-1023: unexpected end of data
    Traceback (most recent call last):
      File "G:\PyCharm 2021.2.2\plugins\python\helpers\pydev\_pydevd_bundle\pydevd_comm.py", line 303, in _on_run
        r = r.decode('utf-8')
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 1023: unexpected end of data
    

但是这个输出和堵塞是没有关系,我一直以为是报错,结果查了半天,浪费很多时间。具体为什么会堵塞,大家自家查查吧。

你可能感兴趣的:(pytorch,深度学习,pytorch,transformer)