赞
踩
input_val >= zero && input_val <= one
failed.在用服务器跑模型计算loss时,出现如下错误:Assertion input_val >= zero && input_val <= one
failed.和 RuntimeError: CUDA error: device-side assert triggered。
../aten/src/ATen/native/cuda/Loss.cu:118: operator(): block: [307,0,0], thread: [31,0,0] Assertion `input_val >= zero && input_val <= one` failed. 130it [00:49, 2.60it/s] Traceback (most recent call last): File "/home/liuchuang/OPTICc/main.py", line 233, in <module> main(config) File "/home/liuchuang/OPTICc/main.py", line 129, in main train_DG.run() File "/home/liuchuang/OPTICc/train_DG.py", line 138, in run loss_meter.add(loss.sum().item() + 1e-6) RuntimeError: CUDA error: device-side assert triggered CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect. For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
出现这个报错的原因可能有很多种,刚开始碰到感觉是个比较偏门的错误,很少碰见,而且我的问题和大多数的博客的解决办法也不一样,特此作记录,给出问题的小伙伴一些参考价值。
首先这是我的报错截图:
最后错误的提示为:RuntimeError: CUDA error: device-side assert triggered
CUDA kernel errors might be asynchronously reported at some other API call,so the stacktrace below might be incorrect.For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
首先定位到出错的位置,我的代码出错的位置为计算损失函数的这一行:
loss = self.seg_cost(pred, y)
self.optimizer.zero_grad()
loss.backward()
# print(loss.sum().item())
**loss_meter.add(loss.sum().item())**
self.optimizer.step()
中间我打花括号的那一行代码出错:loss_meter.add(loss.sum().item()),这个报错奇怪就在我前面的iteration计算都是正确的,到了这最后一个iteration报错了。因此我将pred和y的shape全部打印出来发现问题了,原来我的最后一个batch只有一个sample,维度为(1,2,256,256),这样在计算的时候就会报错,每一个batch至少大于1个样本,才能计算损失函数。
通过查阅资料有好几种办法可以解决这个问题。以下列举三种:
我的训练样本总数是1041,每个batch的大小是8,这意味着最后一个batch的大小会是1,这可能会导致一些问题,例如如果你在计算损失函数时需要使用到更多的样本,或者在某些层(例如Batch Normalization)需要更多样本的情况。
有几种可能的解决方案:
source_dataloader = DataLoader(dataset=source_dataset,
batch_size=config.batch_size,
shuffle=True,
pin_memory=True,
collate_fn=collate_fn_w_transform,
num_workers=config.num_workers,
drop_last=True)
from torch.nn.utils.rnn import pad_sequence from torch.utils.data import Dataset, DataLoader class MyDataset(Dataset): def __init__(self, data): self.data = data def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index] def collate_fn(batch): batch = pad_sequence(batch, batch_first=True, padding_value=0) return batch # 假设 data 是你的数据 dataset = MyDataset(data) dataloader = DataLoader(dataset, batch_size=8, collate_fn=collate_fn)
这是一些可能的解决方案,我是使用第一种方案解决了问题,当然第一种和第三种都非常好实现,第二种我没有试过,感兴趣的朋友可以自行尝试。
完结!撒花!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。