在这里搭建了一个简易的全链接网络,定义的输入与输出,但是报了这么一个错误。
import torch
import torch.nn.functional as F
# x = torch.linspace(-1, 0, 100)
# x = x.view()
x = torch.squeeze(torch.linspace(-1, 0, 100), dim=1)
y = torch.pow(x, 2)
Traceback (most recent call last):
File "/home/zhangyi/PycharmProjects/pytorch/net_frame.py", line 5, in <module>
x = torch.squeeze(torch.linspace(-1, 0, 100), dim=1)
IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
Process finished with exit code 1
错误原因:pytorch搭建的网络不接受一维张量输入,我们定义的输入x本来是个一维数组,在增加维度时用错了函数:将torch.squeeze() 改为torch.unsqueeze()即可
torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的数去掉第一个维数为一的维度之后就变成(3)行。squeeze(a)就是将a中所有为1的维度删掉。不为1的维度没有影响。a.squeeze(N) 就是去掉a中指定的维数为一的维度。还有一种形式就是b=torch.squeeze(a,N) a中去掉指定的定的维数为一的维度。
torch.unsqueeze()这个函数主要是对数据维度进行扩充。给指定位置加上维数为一的维度,比如原本有个三行的数据(3),在0的位置加了一维就变成一行三列(1,3)。a.squeeze(N) 就是在a中指定位置N加上一个维数为1的维度。还有一种形式就是b=torch.squeeze(a,N) a就是在a中指定位置N加上一个维数为1的维度
import torch
import torch.nn.functional as F
# x = torch.linspace(-1, 0, 100)
# x = x.view()
#x = torch.squeeze(torch.linspace(-1, 0, 100), dim=1)
x = torch.unsqueeze(torch.linspace(-1, 0, 100), dim=1)
y = torch.pow(x, 2)
在我搭建的mobilenetv3_ssd网络中,在运行时第一个卷积层就报错。这样的错误基本上都是forward函数出错,可能是forward函数前缩进不对,没有与init对齐;也可能是错误处调用了其他的类,但是该类中没有定义forward函数或是缩进错误,请仔细检查。
Traceback (most recent call last):
File "G:/PYCHARM/pycharm/projects/ssd-mobilenetv3/train.py", line 75, in <module>
out = net(images)
File "G:\anaconda\anzhuang\envs\python36\lib\site-packages\torch\nn\modules\module.py", line 550, in __call__
result = self.forward(*input, **kwargs)
File "G:\PYCHARM\pycharm\projects\ssd-mobilenetv3\mobilenetv3_ssd.py", line 240, in forward
x = self.conv0(x)
File "G:\anaconda\anzhuang\envs\python36\lib\site-packages\torch\nn\modules\module.py", line 550, in __call__
result = self.forward(*input, **kwargs)
File "G:\anaconda\anzhuang\envs\python36\lib\site-packages\torch\nn\modules\container.py", line 100, in forward
input = module(input)
File "G:\anaconda\anzhuang\envs\python36\lib\site-packages\torch\nn\modules\module.py", line 550, in __call__
result = self.forward(*input, **kwargs)
File "G:\anaconda\anzhuang\envs\python36\lib\site-packages\torch\nn\modules\module.py", line 98, in forward
raise NotImplementedError
NotImplementedError
Process finished with exit code 1
从这段报错中可以看见是conv0层出现了错误,我们定位到该层去看看。
class Mobilenetv3_ssd(nn.Module):
def __init__(self, num_classes, phase):
super(Mobilenetv3_ssd, self).__init__()
self.num_classes = num_classes
self.phase = phase
self.cfg = Config
self.priorbox = PriorBox(self.cfg)
with torch.no_grad():
self.priors = Variable(self.priorbox.forward())
self.conv0 = nn.Sequential( #(300, 300, 3)
nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3, stride=2, padding=1, bias=False), #(150, 150, 16)
nn.BatchNorm2d(16), #(150, 150, 16)
HardSwish() #(150, 150, 16)
)
该conv0层看不出任何的错误,包括定义的类Mobilenetv3_ssd中的forward函数也与init是对齐的,缩进是正确的,但是conv0中调用了一个HardSwish类,我们再转到这个HardSwish类中去看看。
class HardSwish(nn.Module):
def __init__(self):
super(HardSwish, self).__init__()
self.relu6 = nn.ReLU6(inplace=True)
def HardSwish(self, x):
return (x * (self.relu6(x+3))) / 6
从这个类中就会发现,没有定义forward函数,错误就是来自于这里,将def HardSwish(self, x):改为def forward(self, x):就OK啦!!
Traceback (most recent call last):
File "G:/PYCHARM/pycharm/projects/ssd-mobilenetv3/train.py", line 75, in <module>
out = net(images)
File "G:\anaconda\anzhuang\envs\python36\lib\site-packages\torch\nn\modules\module.py", line 550, in __call__
result = self.forward(*input, **kwargs)
File "G:\PYCHARM\pycharm\projects\ssd-mobilenetv3\mobilenetv3_ssd.py", line 316, in forward
loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1)
File "G:\PYCHARM\pycharm\projects\ssd-mobilenetv3\mobilenetv3_ssd.py", line 316, in <listcomp>
loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1)
RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
先看这个错误,这是一个reshape操作,却一直报错。大概原因就是:view()的原理是需要Tensor中的元素地址是连续的,但是有可能出现Tensor不连续的情况,所以先用.contiguous()函数将其在内存中变成连续分布。
loc = torch.cat([o.view(o.size(0), -1) for o in loc], 1)
cls = torch.cat([o.view(o.size(0), -1) for o in cls], 1)
将上面view之前对tensor先进行.contiguous()函数即可,如下面代码所示(亲测有效)。根据错误提示,好像也能改用reshape函数进行reshape操作,没有具体试过,感兴趣的可以自己测试一下。
loc = torch.cat([o.contiguous().view(o.size(0), -1) for o in loc], 1)
cls = torch.cat([o.contiguous().view(o.size(0), -1) for o in cls], 1)
pytorch中进行batchnomolization,需要大于一个样本去计算其中的参数,就会报这样的错误。
检查batch_size是否设置了为1,本文就是由于需要调试找问题讲batch改为了1;另外可能是样本数量/batch=1,即最后一个batch中只有一个样本,此时将dataloader的一个丢弃参数drop_last设置为true,drop_last = true。
这是图片在输入网络时是三维的tensor[C, H, W],需要将图片扩维,因为网络接受的是包括batch这一维度的输入tensor[B, C, H, W],只需要在传入网络前加上 image = image.unsqueeze(0)这句话对图片第一维进行扩维即可。
该问题是由于调用的类没有实例化直接进行传参数。
下面的代码是我在使用pytorch时碰见的,需要将image转化为tensor时调用了ToTensor的类,但是没有实例化直接将image参数传给了该类就会报这个错误。
from torchvision.transforms import ToTensor
img_path = './data/Cat/Dog/1.jpg'
img = Image.open(img_path)
image = ToTensor(img) #未实例化直接传参
将其类先实例化,再传参即可,改为如下:
from torchvision.transforms import ToTensor
to_tensor = ToTensor() #先实例化类
img_path = './data/Cat/Dog/1.jpg'
img = Image.open(img_path)
image = to_tensor(img) #传参
It seems you are trying to pass an input as a ByteTensor (uint8), which is not supported.
大概意思就是你输入的是一个ByteTensor (uint8),不支持,具体的修改就是在进网络前将输入转换为float型即可。 input = input.float()
如下,增加一句image = image.float()即可。
image = batch_sample['image']
label = batch_sample['label']
image = image.float()
image.to(device)
label.to(device)