具体报错信息:
/pytorch/aten/src/THC/THCTensorScatterGather.cu:188: void THCudaTensor_scatterFillKernel(TensorInfo<Real, IndexType>, TensorInfo<long, IndexType>, Real, int, IndexType) [with IndexType = unsigned int, Real = float, Dims = -1]: block: [72,0,0], thread: [32,0,0] Assertion `indexValue >= 0 && indexValue < tensor.sizes[dim]` failed.
问题描述及解决办法:
可以看出Assertion `indexValue >= 0 && indexValue < tensor.sizes[dim]这个断定错误,也就是说标签出现了小于0或者大于总数的情况,越界了。当使用ImageFolder方式构建数据集或者我们自己制作datasets时的时候应该注意标签的范围:pytorch会自己扫描train_path下的每一个文件夹(每类图片都位于其类别的文件夹下),并将每一个类映射成数值,比如有4类,类别标签就是[0,1,2,3]。但是标签却映射成[1,2,3,4]时,就会报错,这时候我们应该对标签进行修改。
在程序运行到“loss.backward()”的时候报错,具体报错信息:
RuntimeError: expected dtype Double but got dtype Float (validate_dtype at ..\aten\src\ATen\native\TensorIterator.cpp:143)(no backtrace available)
问题描述及解决办法:
该错误来自于输入数据的类型和模型参数类型不一致,因此最好在程序开始统一数据类型。可以在全局加上
torch.set_default_tensor_type(torch.DoubleTensor)
这样之后创建的变量类型都是Double类型(torch.float64)。
如果想要创建变量类型都是Float类型,在全局加上
torch.set_default_tensor_type(torch.FloatTensor)
还需要在创建变量的时候将其转化为float类型
train_data_split = torch.from_numpy(train_data_split).float()
这样就不会报错了。
问题描述及解决办法:
该警告信息属于我们输入的数据格式跟网络中要求的数据格式不一致,如果不做处理的话,网络也可以进行训练。处理时可以根据网络中要求的数据格式相应的变化我们送入网络的数据。
labels = torch.from_numpy(labels)
labels = labels.type(torch.FloatTensor)
labels = labels.cuda()
问题描述及解决办法:
第一个矩阵的第1维度和第二个矩阵的第2维度不匹配,我出错的网络结构是resnet18,这个是卷积网络卷积计算后的数据shape不适合进行torch.addmm()运算,这是functional.py文件中的一个函数,用于矩阵相乘,用于处理数据。讲网络的每一层的shape输出,观察数据大小跟定义的网络结构大小是否一致,最终发现需要将input的shape和weight.t()的shape调整为适合矩阵相乘,在resnet18的fc层将输入通道的大小改为跟数据大小一致即可。
问题描述及解决办法:
使用多张GPU去训练,出现这个错误,主要问题是出现在DataParrallel上。当在多个gpu上跑代码的时候就可能遇到这个问题,避开方法就是用一块GPU跑。
问题描述及解决办法:
这个错误是输入的tensor类型跟模型当中所需要的tensor类型不一致,需要将输入类型变成cuda就可以。实现代码
data.cuda()
问题描述及解决办法:
这个问题中 ,‘XXX’ 一般就是代码里面的需要优化的模型名称,当我们训练完模型后,再次导包获取某一层feature时,直觉写成mode.xxx
,这时候就会报这个错误。模型的名称与我们在代码中定义的不一样,需要在model
后增加module,即将名称改为:
model.module.xxx
问题描述及解决办法:
上面标注的部分,说明我们输入的数据类型不是所需要的,也就是说我们需要将数据类型变成我们需要的,在代码中找到报错的地方,然后修改代码。修改方式如下:
#c错误代码
loss = criterion(outputs,labels)
# 将错误代码中的label后面加上.long()
loss = criterion(outputs,labels.long())
问题描述及解决方法:
标题中黄色标注部分是给我们的提示,我尝试过后并没有什么用
问题描述及解决办法:
程序在试图执行backward的时候,发现计算图的缓冲区已经被释放。解决方法:在backward()
函数中添加参数retain_graph=True
loss.backward(retain_graph=True)
问题描述及解决办法:
我的问题出现在loss.backward()
上,原因是我的loss是两个loss的相加这里显示需要的torch.double
类型的数据,但是我们输入的是torch.float
类型的数据,这里需要将数据类型改成double,但是我们使用tensor中数据格式转换的方法时,会将数据变成torch.float64
类型的,这样子并没有解决这个问题,我的解决方法是:全局声明使用torch.double类型,这时需要注意我们模型的输入也需要变成double类型的,这时使用传统的tensor转变格式就不会出现这个问题。
## 在全局进行声明
torch.set_default_tensor_type(torch.DoubleTensor)
## 记得将输入改成torch.double类型的
inputs = inputs.cuda().double()
**tip:**使用torch.double的数据,会占用很多的现存,甚至出现爆卡现象
问题描述及解决办法:
x1,x2,x3 = torch.split(x,1,dim=1)
batch_size,h,w,c = x1.shape
out1 = self.feature(x1)
out2 = self.feature(x2)
out3 = self.feature(x3)
cat_scale = torch.cat([out1,out2,out3],3)
#报错位置在这里
cat_scale = cat_scale.view(batch_size,-1)
这是因为view()
需要Tensor中的元素地址是连续的,但可能出现Tensor不连续的情况,所以先用 .contiguous()
将其在内存中变成连续分布:
cat_scale = cat_scale.contiguous().view(batch_size,-1)
问题描述解决办法:
出现该问题的地方在于我们使用loss = F.l1_loss(pred, labels)
的时候,默认的requires_grad
是False
,梯度是不向后传播的,这个时候我们需要将requires_grad
设置为True
,这样就可以使损失函数正常的向后传播。代码修改如下:
loss = F.l1_loss(pred, labels).requires_grad_()
问题描述及解决办法:
这个报错提示是说mean()
只能计算类型为float
的数据,但是得到的是long
型的,我们只需要将数据类型由long
换成float
即可,代码实现:
tensor.float()
问题描述及解决办法:
该问题是多线程冲突导致我们的程序终止,问题与DataLoader
这个数据加载器有关,解决方法是修改调用torch.utils.data.DataLoader()
函数时的 num_workers
参数,将这个参数设置为0,或者设置一个比较小的数:
train_data_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=batch_size, shuffle=True, num_workers = 0)
问题描述及解决办法:
该问题出现在加载模型函数那一块torch.load('模型参数路径')
,原因是我们在训练模型时,使用GPU去训练,导致训练出来的模型参数是cuda()类型的,这时候再用cpu去加载模型参数,就会出现这个问题,这时候我们要将模型参数映射到cpu上,只需要在代码中加上参数torch.load('模型参数路径',map_location='cpu')
,这时就可以解决这个问题。
问题描述及解决办法:
有一篇关于《pytorch Dataset, DataLoader产生自定义的训练数据》的博客,但存在一个问题,我们不能在Dataset做一些数据清理,如果我们传递给Dataset数据,本身存在问题,那么迭代过程肯定出错的。比如我把很多图片路径都传递给Dataset,如果图片路径都是正确的,且图片都存在也没有损坏,那显然运行是没有问题的;但倘若传递给Dataset的图片路径有些图片是不存在,这时你通过Dataset读取图片数据,然后再迭代返回,就会出现类似如的错误。