0:Pytorch和Numpy中默认数据类型的区别
来源:https://blog.csdn.net/yyb19951015/article/details/84781434
问题:
RuntimeError: Expected object of type torch.cuda.DoubleTensor but found type torch.cuda.FloatTensor for argument #3 'other'
这种错误是由于数据类型不匹配造成的。这种不匹配可能来自Pytorch各个层之间,
也可能来自于使用Dataset和Dataloader导入来自Numpy的数据。后者有时更难以发现。
原因:
在Numpy中,小数的默认数据类型是np.float,但np.float与np.float64等价;
在Pytorch中,默认数据类型是torch.float,但float与torch.float32等价。
如果不加转换地使用torch.from_numpy,numpy中的数组将会被转换成pytorch中的torch.double类型。
而网络的其他部分如果有torch.float32类型,这就造成了数据类型的不匹配。
解决:
将Numpy的输入数据类型改为np.float32类型即可。
在输入数据加后.astype(np.float32)就可保证两边的数据类型统一。
1:python int转换为numpy.int64
来源:https://www.cnpython.com/qa/38838
分析:
Python的数据类型和numpy中的默认数据类型长度是不同的
解决:
2:pytorch int转换为float
>>> import torch as t
>>> d = t.arange(12).view(1,3,2,2)
>>> d.dtype
torch.int64
>>> d
tensor([[[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]],
[[ 8, 9],
[10, 11]]]])
>>> e = d.to(t.float32)
>>> e
tensor([[[[ 0., 1.],
[ 2., 3.]],
[[ 4., 5.],
[ 6., 7.]],
[[ 8., 9.],
[10., 11.]]]])
>>> e.dtype
torch.float32
>>>
3:Pytorch中Tensor和tensor的区别
来源:https://blog.csdn.net/tfcy694/article/details/85338745
Tensor
torch.Tensor()是python类,更明确地说,是默认张量类型torch.FloatTensor()的别名,
torch.Tensor([1,2])会调用Tensor类的构造函数__init__,生成单精度浮点类型的张量。
>>> a=torch.Tensor([1,2])
>>> a.type()
'torch.FloatTensor'
tensor
torch.tensor()仅仅是python函数:https://pytorch.org/docs/stable/torch.html#torch.tensor ,函数原型是:
torch.tensor(data, dtype=None, device=None, requires_grad=False)
其中data可以是:list, tuple, NumPy ndarray, scalar和其他类型。
torch.tensor会从data中的数据部分做拷贝(而不是直接引用),
根据原始数据类型生成相应的torch.LongTensor、torch.FloatTensor和torch.DoubleTensor。
>>> a=torch.tensor([1,2])
>>> a.type()
'torch.LongTensor'
>>> a=torch.tensor([1.,2.])
>>> a.type()
'torch.FloatTensor'
>>> a=np.zeros(2,dtype=np.float64)
>>> a=torch.tensor(a)
>>> a.type()
'torch.DoubleTensor'
这里再说一下torch.empty(),根据 https://pytorch.org/docs/stable/torch.html?highlight=empty#torch.empty ,我们可以生成指定类型、指定设备以及其他参数的张量,由于torch.Tensor()只能指定数据类型为torch.float,所以torch.Tensor()可以看做torch.empty()的一个特殊情况。
最后放一个小彩蛋
>>> a=torch.tensor(1)
>>> a
tensor(1)
>>> a.type()
'torch.LongTensor'
>>> a=torch.Tensor(1)
>>> a
tensor([0.])
>>> a.type()
'torch.FloatTensor'
我把a=torch.Tensor(1)改成a=torch.Tensor([1]),a就是一个数值为1的tensor了,而不是0
标量1是作为size传入的,向量1是作为value传入的
4:Pytorch中item和data的区别
来源:https://blog.csdn.net/weixin_38316806/article/details/104971419?
.data返回的是一个tensor
.item()返回的是一个具体的数值,注意只能是一个值,适合返回loss,acc
实验:
import torch
a = torch.ones([1,3])
print(a)
print(a.data)
print(a.data[0,1])
print(a.data[0,1].item())
# print(a.item()) 运行该行代码会报错
结果:
5:torch.load提示 ModuleNotFoundError: No module named 'models'
来源:https://blog.csdn.net/j___t/article/details/99618915?
原因:
the serialized data is bound to the specific classes and the exact directory structure used,
so it can break in various ways when used in other projects, or after some serious refactors.
也就是说,当使用这个函数的时候,pytorch序列化的是参数以及model class的路径。
所以使用这个函数之前,必须保证定义model的文件目录结构相同。
一般来说,model.py只要和要运行的py文件在同个目录就不会报这个错。
解决:
https://github.com/pytorch/pytorch/issues/18325
6:torch.load提示 'torch.nn.modules.container.Sequential' has changed.
/opt/conda/lib/python3.7/site-packages/torch/serialization.py:649: SourceChangeWarning: source code of class 'torch.nn.modules.container.Sequential' has changed. you can retrieve the original source code by accessing the object's source attribute or set `torch.nn.Module.dump_patches = True` and use the patch tool to revert the changes.
warnings.warn(msg, SourceChangeWarning)
解决:
提示的已经很清晰了,因为是torch.nn.modules.container.Sequential 改动了,所以要么torhc版本适配,要么下载新的torchvision
7:提示 detectron2/utils/collect_env.py", line 136, in collect env info msg = " - invalid!" if not os.path.isdir(CUDA_HOME) else ""
参考:https://github.com/facebookresearch/detectron2/issues/2254
临时方案:
将CUDA_HOME随意赋值,使其不为空
6:pytorch自定义权重数值
自定义权重数值:核心思想就是构造和该层权重同一尺寸的矩阵去对该层权重赋值。pytorch中各层权重的数据类型是nn.Parameter,而不是Tensor或者Variable。
weight的类型为torch.nn.parameter.Parameter,必须是一个浮点数类型的tensor
方法1:使用内置函数
>> conv = nn.Conv2d(in_channels=2, out_channels=1, kernel_size=3)
# 此时weight以及bias已由nn.Conv2d初始化
>> conv.weight, conv.bias
>> (Parameter containing:
tensor([[[[-0.0335, 0.0855, -0.0708],
[-0.1672, 0.0902, -0.0077],
[-0.0838, -0.1539, -0.0933]],
[[-0.0496, 0.1807, -0.1477],
[ 0.0397, 0.1963, 0.0932],
[-0.2018, -0.0436, 0.1971]]]], requires_grad=True),
Parameter containing:
tensor([-0.1963], requires_grad=True))
# 手动设定
# conv.weight.data 以及 conv.bias.data属性为torch.tensor
# 因此只要获取conv.weight.data以及conv.bias.data属性,后续调用torch.tensor的不同方法即可进行修改
# 例如:全部修改为0
>> conv.weight.data.zero_(), conv.bias.data.zero_()
>> conv.weight, conv.bias
>> (Parameter containing:
tensor([[[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]]], requires_grad=True),
Parameter containing:
tensor([0.], requires_grad=True))
其他方式:
new_weight = torch.empty_like(the_module.weight)
new_weight=my_weight_method(new_weight)
new_weight=torch.nn.Parameter(new_weight)
the_module.weight=new_weight
ones=torch.Tensor(np.ones([2,2,3,3])) # 先创建一个自定义权值的Tensor,这里为了方便将所有权值设为1
w.weight=torch.nn.Parameter(ones) # 把Tensor的值作为权值赋值给Conv层,这里需要先转为torch.nn.Parameter类型,否则将报错