当对通过Dataloader得到的数据进行enumerate()索引运算时,出现““_pickle.UnpicklingError: pickle data was truncated”错误
当运行代码如下:
for i, (images, labels) in enumerate(train_data_loader,0):
出现了上述的错误
在程序中并没有直接用到pickle库,出现上面错误不明就里。有一次我将电脑重启后,发现可以运行,我怀疑是因为在运行过程中某些变量没有清理完整,再次运行会与之前存储的数据发生冲突。也有可能是因为用Dataloader生成的train_data_loader的数量过大造成了溢出或者是直接截断(truncate)产生错误。我试着Dataloader中的batch_size的大小。
train_data_loader = DataLoader(dataset=train_data,
num_workers=1,
batch_size=16, #目标将batch_size=64改为16,解决了enumerate过程出错的问题,同时也防止通过CUDA利用GPU运算时内存不够的问题
shuffle=True,
pin_memory=True)
目标将batch_size=64改为16,解决了enumerate过程出错的问题,同时也防止通过CUDA利用GPU运算时内存不够的问题。
成功运行,解除错误
330
331
Epoch [1], Iter[332], Time:385.329348326, learning rate : 0.000199897, Train Loss: 0.461626321 Test Loss: 0.031681120
除此之外,为了防止内存不够的问题,一方面我们要减小模型参数的数量,为了保证深度神经网络的性能,模型参数量不会太小。造成内存溢出的主要原因是tensor中的无用内容没有得到及时清理,因为tensor类型的数据会自动地存储梯度信息,所以我们可以直接用tensor.backward()直接反向传播。在检验和测试过程,不对模型进行训练,所以没必要存储中间变量的梯度信息。我们可以用“with torch.no_grad():”
with torch.no_grad():
input_var = torch.autograd.Variable(input)
with torch.no_grad():
target_var = torch.autograd.Variable(target)
"with torch.no_grad():"表示后面的执行代码得到的结果不会参与反向传播,因此我们只需要知道forword的结果就可以了,不需要记录网络参数。在交叉检验或者测试过程中我们只需要网络输出的结果,不需要记录传播过程的参数,因此会节约内存。