2023年11月29日发(作者:)

PyTorch编写代码遇到的问题及解决⽅案

PyTorch编写代码遇到的问题

错误提⽰:no module named xxx

xxx为⾃定义⽂件夹的名字

因为搜索不到,所以将当前路径加⼊到包的搜索⽬录

解决⽅法:

import sys

('..') #将上层⽬录加⼊到搜索路径中

('/home/xxx') # 绝对路径

import os

(()) # #将当前⼯作路径加⼊到搜索路径中

还可以在当前终端的命令⾏设置

export PYTHONPATH=$PYTHONPATH:./

错误提⽰:AttributeError: ‘NoneType' object has no attribute ‘shape' height, width, channel =

Linux系统下报错AttributeError: ‘NoneType' object has no attribute ‘shape'

img=(),读取⼀张图⽚时,是包含三个量的元组,分别是:

[0]:图像的⾼度

[1]:图像的宽度

[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 (Tensor) and weight type (ensor) should be the same

以下三⼩段分别是Data type CPU tensor GPU tensor

32-bit floating point ensor ensor

64-bit floating point Tensor Tensor

出错在类型转换

更改为32

import orms as transforms

import numpy as np

transform = or()

版本问题 旧式写法

import torch

x = (0.1)

y = (0.2)

z = ((x, y))

改成新式写法

x = ([0.1])

y = ([0.2])

z = ((x, y))

print(z)

结果

tensor([0.1000, 0.2000])

错误提⽰:TypeError: ‘float' object is not subscriptable

多了下标 a = ()[0]

去除下标 a = ()

错误提⽰:argument ‘input' (position 1) must be Tensor, not list

需要将list转换成tensor

假设alist

suppress = ((n_above_min_score), dtype=).to(device)

UserWarning: volatile was removed and now has no effect. Use with _grad(): instead.

#之前旧版本

...

x = Variable((1), volatile=True)

return x

#新版

with _grad():

...

x = (1)

return x

错误提⽰

RuntimeError: Attempting to deserialize object on CUDA device 1 but _count() is 1. Please use

with map_location to map your storages to an existing device.

或者是 RuntimeError: expected device cuda:0 but got device cuda:1

错误原因之⼀

使⽤了CUDA 1显卡训练保存的模型⽂件,使⽤CUDA 0验证

代码中写了

device = (“cuda” if _available() else “cpu”)

可以在命令⾏设置让哪些GPU可见

export CUDA_VISIBLE_DEVICES=1 #GPU编号

export CUDA_VISIBLE_DEVICES=0,1,2,3#4张显卡可见

也可以在代码⾥改成

checkpoint = (checkpoint,map_location=‘cuda:0')

错误提⽰

raise ConnectionError(e, request=request)

tionError: HTTPConnectionPool(host='localhost', port=8097): Max retries exceeded

with url: /update (Caused by NewConnectionError('

Tensor:

model = Model()

tensor = ([2, 3, 10, 10])

()

()

tensor_cuda = ()

model(tensor) # 会报错

model(tensor_cuda) # 正常运⾏

不同,调⽤ 只是返回这个 tensor 对象在 GPU 内存上的拷贝,⽽不会对⾃⾝进⾏改变。因此必须对

tensor 进⾏重新赋值,即 tensor = ()

PyTorch 0.4 计算累积损失的不同

以⼴泛使⽤的模式 total_loss += [0] 为例。Python0.4.0 之前,loss 是⼀个封装了 (1,) 张量的 Variable,但

Python0.4.0 loss 现在是⼀个零维的标量。对标量进⾏ 索引是没有意义的(似乎会报 invalid index to scalar variable 的错

误)。使⽤ () 可以从标量中获取 Python 数字。所以改为:

total_loss = total_loss + ()

如果在累加损失时未将其转换为 Python 数字,则可能出现程序内存使⽤量增加的情况。这是因为上⾯表达式的右侧原本是⼀

Python 浮点数,⽽它现在是⼀个零维张量。因此,总损失累加了张量和它们的梯度历史,这可能会产⽣很⼤的 autograd

图,耗费内存和计算资源。

⾃适应 CPU GPU设备的 trick

device = ("cuda" if _available() else "cpu")

model = Model().to(device)

total_loss = 0

for input, target in train_loader:

input, target = (device), (device)

...

total_loss = total_loss + ()

with _grad():

for input, target in test_loader:

...

的使⽤

官⽅说明:Returns a new Tensor, detached from the current graph,The result will never require gradient

假设有模型 A 和模型 B,我们需要将 A 的输出作为 B 的输⼊,但训练时我们只训练模型 B. 那么可以这样做:

input_B = output_

它可以使两个计算图的梯度传递断开,从⽽实现我们所需的功能。

pytorchloss函数的参数设置

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,返回 .

如果 size_average = False,返回 .

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 来判断!为了安全起见统⼀使⽤ 或者 吧。

import numpy as np

if ((().numpy())):

print("Input data has NaN!")

if((())):

print("Loss value is NaN!")

pytorch 内存泄漏

_tensor(data, dtype=None,device=None)->Tensor : data⽣成tensor

如果data已经是tensor,且dtypedevice与参数相同,则⽣成的tensor会和data共享内存。如果datandarray,dtype

应,devicescpu,则同样共享内存。其他情况则不共享内存。

import torch

import numpy

a = ([1, 2, 3])

t = _tensor(a)

以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。