PyTorch编写代码遇到的问题及解决⽅案PyTorch编写代码遇到的问题
错误提⽰:no module named xxx
xxx为⾃定义⽂件夹的名字
因为搜索不到,所以将当前路径加⼊到包的搜索⽬录
解决⽅法:
import sys
sys.path.append('..') #将上层⽬录加⼊到搜索路径中
sys.path.append('/home/xxx') # 绝对路径
import os
sys.path.wd()) # #将当前⼯作路径加⼊到搜索路径中
还可以在当前终端的命令⾏设置
export PYTHONPATH=$PYTHONPATH:./
错误提⽰:AttributeError: ‘NoneType' object has no attribute ‘shape' height, width, channel = img.shape
在Linux系统下img.shape报错AttributeError: ‘NoneType' object has no attribute ‘shape'
img=cv2.imread(),读取⼀张图⽚时,img.shape是包含三个量的元组,分别是:
img.shape[0]:图像的⾼度
img.shape[1]:图像的宽度
img.shape[2]:图像的通道数
解决⽅法:读的⽂件出错或者查看⽂件路径是否正确
错误提⽰:TypeError: slice indices must be integers or None or have an index method
cropped_im = img[ny1 : ny2, nx1 : nx2, :]
解决⽅法:需要将ny1 : ny2, nx1 : nx2转换成int类型
错误提⽰:Input type (torch.cuda.DoubleTensor) and weight type (torch.cuda.FloatTensor) should be the same 以下三⼩段分别是Data type CPU tensor GPU tensor
32-bit floating point torch.FloatTensor torch.cuda.FloatTensor
64-bit floating point torch.DoubleTensor torch.cuda.DoubleTensor
出错在类型转换
np.float更改为np.float32
ansforms as transforms
import numpy as np
transform = transforms.ToTensor()
def convert_image_to_tensor(image):
"""convert an image to pytorch tensor
image: numpy array , h * w * c
image_tensor: pytorch.FloatTensor, c * h * w
"""
image = image.astype(np.float32)
return transform(image)
错误提⽰:RuntimeError: zero-dimensional tensor (at position 0) cannot be concatenated
版本问题旧式写法
import torch
x = sor(0.1)
y = sor(0.2)
z = torch.cat((x, y))
改成新式写法
x = sor([0.1])
y = sor([0.2])
z = torch.cat((x, y))
print(z)
结果
tensor([0.1000, 0.2000])
错误提⽰:TypeError: ‘float' object is not subscriptable
多了下标 a = x.tolist()[0]
去除下标 a = x.tolist()
错误提⽰:argument ‘input' (position 1) must be Tensor, not list
需要将list转换成tensor
假设a是list
GPU模型和CPU模型之间的转换
假设原来保存的是GPU模型,要转换为CPU模型
torch.save(model, os.path.join( "./complete.pth"))
cpu_model = torch.load("./complete.pth", map_location=lambda storage, loc: storage)
dummy_input = torch.randn(1, 3, 224, 224)
假设原来保存的是CPU模型,要转换为GPU模型
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
torch.save(model, os.path.join( "./complete.pth"))
gpu_model = torch.load("./complete.pth", map_location=lambda storage, loc: storage.cuda)
dummy_input = torch.randn(1, 3, 224, 224)
dummy_input = (device)
错误提⽰ RuntimeError: Subtraction, the - operator, with a bool tensor is not supported. If you are trying to invert a mask, use the ~ or logical_not() operator instead.
原代码
# Store only unsuppressed boxes for this class
image_boxes.append(class_decoded_locs[1 - suppress])
image_labels.append(torch.LongTensor((1 - suppress).sum().item() * [c]).to(device))
image_scores.append(class_scores[1 - suppress])
更改为
image_boxes.append(class_decoded_locs[~suppress])
image_labels.append(torch.LongTensor((~ suppress).sum().item() * [c]).to(device))
image_scores.append(class_scores[~suppress])
错误提⽰ RuntimeError: Expected object of scalar type Byte but got scalar type Bool for argument #2 ‘other' in call to _th_max
原代码
suppress = s((n_above_min_score), dtype=torch.uint8).to(device)
更改为
suppress = s((n_above_min_score), dtype=torch.bool).to(device)
UserWarning: volatile was removed and now has no effect. Use _grad(): instead.
#之前旧版本
...
x = Variable(torch.randn(1), volatile=True)
return x
#新版
_grad():
...
x = torch.randn(1)
return x
错误提⽰
RuntimeError: Attempting to deserialize object on CUDA device 1 but torch.cuda.device_count() is 1. Please use torch.load with map_location to map your storages to an existing device.
python新手代码错了应该怎么改或者是 RuntimeError: expected device cuda:0 but got device cuda:1
错误原因之⼀
使⽤了CUDA 1显卡训练保存的模型⽂件,使⽤CUDA 0验证
代码中写了
device = torch.device(“cuda” if torch.cuda.is_available() else “cpu”)
可以在命令⾏设置让哪些GPU可见
export CUDA_VISIBLE_DEVICES=1 #GPU编号
export CUDA_VISIBLE_DEVICES=0,1,2,3#4张显卡可见
也可以在代码⾥改成
checkpoint = torch.load(checkpoint,map_location=‘cuda:0')
错误提⽰
raise ConnectionError(e, request=request)
0x7f3111915e80>: Failed to establish a new connection: [Errno 111] Connection refused',))
Exception in user code:
解决⽅案
因为没有启动visdom可视化程序,所有报错
在终端执⾏命令 visdom之后就能看到如下信息
Checking for scripts.
It's Alive!
INFO:root:Application Started
You can navigate to localhost:8097
nn.Module.cuda() 和 Tensor.cuda()
⽆论是对于模型还是数据,cuda() 都能实现从CPU到GPU的内存迁移,但是他们的作⽤效果有所不同。
Model:
model = model.cuda()
model.cuda()
上⾯两句能够达到⼀样的效果,即对model⾃⾝进⾏的内存迁移
Tensor:
model = Model()
tensor = s([2, 3, 10, 10])
model.cuda()
tensor.cuda()
tensor_cuda = tensor.cuda()
model(tensor) # 会报错
model(tensor_cuda) # 正常运⾏
和 nn.Module 不同,调⽤ tensor.cuda 只是返回这个 tensor 对象在 GPU 内存上的拷贝,⽽不会对⾃⾝进⾏改变。因此必须对tensor 进⾏重新赋值,即 tensor = tensor.cuda()
PyTorch 0.4 计算累积损失的不同
以⼴泛使⽤的模式 total_loss += loss.data[0] 为例。Python0.4.0 之前,loss 是⼀个封装了 (1,) 张量的 Variable,但
Python0.4.0 的 loss 现在是⼀个零维的标量。对标量进⾏索引是没有意义的(似乎会报 invalid index to scalar variable 的错误)。使⽤ loss.item() 可以从标量中获取 Python 数字。所以改为:
total_loss = total_loss + loss.item()
如果在累加损失时未将其转换为 Python 数字,则可能出现程序内存使⽤量增加的情况。这是因为上⾯表达式的右侧原本是⼀个 Python 浮点数,⽽它现在是⼀个零维张量。因此,总损失累加了张量和它们的梯度历史,这可能会产⽣很⼤的 autograd 图,耗费内存和计算资源。
⾃适应 CPU 和 GPU设备的 trick
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = Model().to(device)
total_loss = 0
for input, target in train_loader:
input, target = (device), (device)
...
total_loss = total_loss + loss.item()
_grad():
for input, target in test_loader:
...
torch.Tensor.detach的使⽤
官⽅说明:Returns a new Tensor, detached from the current graph,The result will never require gradient
假设有模型 A 和模型 B,我们需要将 A 的输出作为 B 的输⼊,但训练时我们只训练模型 B. 那么可以这样做:
input_B = output_A.detach
它可以使两个计算图的梯度传递断开,从⽽实现我们所需的功能。
pytorch中loss函数的参数设置
以CrossEntropyLoss为例:
CrossEntropyLoss(self, weight=None, size_average=None, ignore_index=-100, reduce=None,
reduction='elementwise_mean')
若 reduce = False,那么 size_average 参数失效,直接返回向量形式的 loss,即batch中每个元素对应的loss.
若 reduce = True,那么 loss 返回的是标量:
如果 size_average = True,返回 an.
如果 size_average = False,返回 loss.sum.
weight : 输⼊⼀个1D的权值向量,为各个类别的loss加权,如下公式所⽰:
ignore_index : 选择要忽视的⽬标值,使其对输⼊梯度不作贡献。如果 size_average = True,那么只计算不被忽视的⽬标的loss的均值。
reduction : 可选的参数有:‘none' | ‘elementwise_mean' | ‘sum', 正如参数的字⾯意思。
多GPU的处理机制
使⽤多GPU时,应该记住 PyTorch 的处理逻辑是:
在各个GPU上初始化模型。
前向传播时,把batch分配到各个GPU上进⾏计算。
得到的输出在主GPU上进⾏汇总,计算loss并反向传播,更新主GPU上的权值。
把主GPU上的模型复制到其它GPU上。
训练时损失出现nan的问题
训练模型时出现损失为 nan 的情况
可能导致梯度出现 nan 的三个原因:
梯度爆炸。也就是说梯度数值超出范围变成 nan. 通常可以调⼩学习率、加 BN 层或者做梯度裁剪来试试看有没有解决。
损失函数或者⽹络设计。⽐⽅说,出现了除 0,或者出现⼀些边界情况导致函数不可导,⽐⽅说log(0)、sqrt(0).
脏数据。可以事先对输⼊数据进⾏判断看看是否存在 nan.
补充⼀下nan数据的判断⽅法:
注意!像 nan 或者 inf 这样的数值不能使⽤ == 或者 is 来判断!为了安全起见统⼀使⽤ math.isnan 或
者 numpy.isnan 吧。
import numpy as np
if np.any(np.isnan(input.cpu().numpy())):
print("Input data has NaN!")
if(np.isnan(loss.item())):
print("Loss value is NaN!")
pytorch 内存泄漏
torch.as_tensor(data, dtype=None,device=None)->Tensor : 为data⽣成tensor。
如果data已经是tensor,且dtype和device与参数相同,则⽣成的tensor会和data共享内存。如果data是ndarray,且dtype对应,devices为cpu,则同样共享内存。其他情况则不共享内存。
import torch
import numpy
a = numpy.array([1, 2, 3])
t = torch.as_tensor(a)
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论