首页 欧洲联赛正文

马尔代夫旅游,PyTorch代码调试利器:主动print每行代码的Tensor信息,大黄的功效与作用

机器之心发布

作者:zasdfgbnm

本文介绍一个用于 PyTorch 代码的实用东西 TorchSnoopggdb我国官网er。作者是TorchSnooper的作者,也是PyTorch开发者之一

GitHub 项目地址: https://github.com/zasdfgbnm/TorchSnooper

咱们或许遇到这姿态的困扰:比方说运转自己编写的 PyTorch 代码的时分,PyTorch 提示你说数据类型不匹配,需求一个 double 的 tensor 可是你给的却是 float;再或许便是需求一个 CUDA tensor, 你给的却是个 CPU tensor。比方下面这种:

RuntimeError: Expected object of scalar type Doub火车危机圣诞节版le but got scalar type Float

这种问题调试起来很费事,因为你不知道从哪里开端出问题的。比方你或许在代码的第三行用 torch.zeros 新建了一个 CPU tensor, 然后这个 tensor 进行了若干运算,满是在 CPU 上进行的,一向没有报错,直到第十行需求跟你作为输入传进来的 CUDA tensor 进行运算的时分,才报错。要调试这种过错,有时分就不得不一行行地手写 print 句子,十分费事。

再或许,你或许脑子里幻想着将一个 tensor 进行什么姿态的操作,就会得到什么姿态的成果,可是 PyTorch 半途报错说 tensor 的形状不匹配,或许压根没报错可是终究出来的形状不是咱们想要的。这个时分,咱们往往也不知道是什么当地开端跟咱们「预期的发作违背的」。我地中海沙龙官网们有时分也得需求刺进一大堆 print 句子才干找到原因。

Torc马尔代夫旅行,PyTorch代码调试利器:自动print每行代码的Tensor信息,大黄的成效与效果hSnooper 便是一个规划了用来处理这个问题的东西。TorchSnooper 的装置十分简略,只需求履行规范的 Python 包装置指令就好:

pip install torchsnooper

装置完了今后,只需求用 @torchsnooper.snoop() 装修一下要调试的函数,这个函数在履行的时分,就会自动 print 出来每一行的履行成果的 tenso马尔代夫旅行,PyTorch代码调试利器:自动print每行代码的Tensor信息,大黄的成效与效果r 的形状、数据类型、设备、是否需求梯度的信息。

装置完了今后,下面就用两个比如来阐明一下怎样运用。

比如1

比方说咱们写了一个十分简略的函数:

def myfunc(mask, x):
y = torch.zeros(6)
y.masked_scatter_(mask, x)
return y

咱们是这姿态运用这个函数的:

mask = torch.te兵王觉悟之龙魂利刃nsor([0, 1, 0, 1, 1, 0], device='cuda')
source = torch.tensor([1.0, 2.0, 3.0], device='cuda')
y = myfunc(mask, source)

上面的代码看起来好像没啥问题,可是实际上跑起来,却报错了:

RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 'mask'

问题在哪里呢?让咱们 snoop 一下!用 @torchsnooper.snoop() 装修一下 myfunc 函数:

import torch
import torchsnooper
@torchsnooper.snoop()
def myfunc(mask, x):
y = torch.zeros(6)
y.masked_scatter_(mask, x)
return y
mask = torch.tensor([0, 1, 0, 1, 1, 0], device='cuda')
source = torch.tensor([1.0, 2.0, 3.0], device='cuda')
y = myfunc(mask, source)

然后运转咱们的脚本,咱们看到了这样的输出:

Starting var:.. mask = tensor<(6,), int64, cuda:0>
Starting var:.. x = tensor<(3,), float32, cuda:0>
21:41:42.941668 call 5 def myfunc(mask, x):
21:41:42.941834 line 6 y = torch.zeros(6)
New var:....... y = tensor<(6,), float32, cpu>
21:41:42.943443 line 7 y.masked_scatter_(mask, x)
21:41:42.944404 exception 7 y.masked_scatter_(mask, x)

结合咱们的过错,咱们首要去看输出的每个变量的设备,找找最早从哪个变量开端1927之帝国复兴是在 CPU 上的。咱们注意到这一行:

New var:....... y = tensor<(6,), float32, cpu>

这一行直接告知咱们,咱们创立了一个新变量 y, 并把一个 CPU tensor 赋值给了这个变量。这一行对应代码中的 y = torch.zeros(6)。所以咱们意识到,在运用 torch.zeros 的时分,假如不人为指定设备的话,默许创立的 tensor 是在 CPU 上的。咱们把这一行改成 y = torch.zeros(6, device='cuda'),这一行的问题就修正了。

这一行的问题尽管修正了,咱们的问题并没有处理完好,再跑修改正的代码马尔代夫旅行,PyTorch代码调试利器:自动print每行代码的Tensor信息,大黄的成效与效果仍是报错,可是这个时分过错变成了:

RuntimeError: Expected obje幼女在线ct of scalar type Byte but got scalar type Long for argument #2 'mask'

好吧,这btkt次过错出在了数据类型上。这次过错报告比较有提示性,咱们大约能知道是咱们的 mask 的数据类型错了。再看一遍 TorchSnooper 的输出,咱们注意到:

Starting var:.. mask = tensor<(6,), int64, cuda:0>

公然,咱们的 mask 的类型是 int64, 而不该该是应有的 uint8。咱们把 mask 的界说修改好:

mask = torch.tensor([0, 1, 0, 1, 1, 0], device='cuda', dtype=torch.uint8)

然后就能够运转了。

比如 2

这次咱们要构建一个简略的线性模型:

model = torch.nn.Linear(2, 1)

咱们想要拟合一个平面 y = x1 + 2 * x2 + 3,所以咱们创立了这样马尔代夫旅行,PyTorch代码调试利器:自动print每行代码的Tensor信息,大黄的成效与效果一个数据集:

x = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
y = torch.tensor([3.0, 5.0, 4.0, 6.0])

咱们运用最一般的 SGD 优化器来进行优化,完好的代码如下:

import torch
model = torch.nn.Linear(2, 1)
x = torch.tensor([[0.0, 0.0], [0plumper.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
y = torch.tensor([3.0, 5.0, 4.0, 6.0])
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
for _ in range(10):
optimizer.ze马尔代夫旅行,PyTorch代码调试利器:自动print每行代码的Tensor信息,大黄的成效与效果ro_grad()
pred = model(x)
squared_36岁杀人鲸逝世diff = (y - pred) ** 2
loss = squared_马尔代夫旅行,PyTorch代码调试利器:自动print每行代码的Tensor信息,大黄的成效与效果diff.mean()
print(loss.item())
loss.backward()
optimizer.step()

可是运转的进程咱们发现,loss 降到 1.5 左右就不再降了。这是很不正常的,因为咱们构建的数据都是无差错落在要拟合的平面上的,loss 应该降到 0 才算正常。

乍看上去,不知道问题在哪里。抱着试试看的主意,咱们来 snoop 一会儿。这个比如中,咱们没有自界说函数,可是咱们能够运用 with 句子来激活 TorchSnooper。把练习的那个循环装进 with 句子中去,代码就变成了:

import torch
import torchsnooper
model = torch.n残妾n.Linear(2, 1)
x = torch.tensor([[0.0, 0.0], [0.0, 1.0], [1.0, 0.0], [1.0, 1.0]])
y = torch.tensor([3.0, 5.0, 4.0, 6.0])
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
with torchsnooper.snoop():
for _ in range(10):
optimizer.zero_grad()
pred = model(x)
squared_diff = (y - pred) ** 2
苏药在线loss = squared_diff.mean()
print(loss.item马尔代夫旅行,PyTorch代码调试利器:自动print每行代码的Tensor信息,大黄的成效与效果())
loss.backward()
optimizer.step()

运转程序,咱们看到了一长串的输出,一点一点阅读,咱们注意到

New var:....... model = Linear(in_features=2, out_features=1, bias=True)
New var:....... x = tensor<(4, 2), float32, cpu>
New var:....... y = tensor<(4,), float32, cpu>
New var:....... optimizer = SGD (Parameter Group 0 dampening: 0 lr: 0....omentum: 0 nesterov: False weight_deca风流妹逗老司机y: 0)
02:38:02.016826 line 12 for _ in range(村庄精品10):
New var:....... _ = 0
02:38:02.017025 line 13 optimizer.zero_grad()
02:38:02.017156 line 14 pred = model(x)
New var:....... pred = tens舞林争霸肖杰总决赛or<(4, 1), float32, cpu, grad>
02:38:02.018100 line 15 squared_diff = (y - pred) ** 2
New var:....... squared_diff = tensor<(4, 4), float32, cpu, grad>
02:38:02.018397 line 16 loss = squared_diff.mean()
New var:....... loss = tensor<(), float32, cpu, grad>
02:38:02.018674 line 17 print(loss.item())
02:38:02.018852 line 18 loss.backward()
26.979290008544922
02:38:02.057349 line 19 optimizer.step()

仔细观察这里边各个 tensor 的形状,咱们不难发现,y 的形状是 (4,),而 pred 的形状却是 (4, 1),他们俩相减,因为播送的存在,咱们得到的 squared_diff 的形状就变成了 (4, 4)。

这天然不是咱们想要的成果。这个问题修正起来也很简略,把 pred 的界说改成 pred = model(x).squeeze(截获芒果果核象甲) 即可。现在再看修改后的代码的 TorchSnooper 的输出:

New var:....... model = Linear(in_features=2, out_features=1, bias=True)
New var:....... x = tensor<(4, 2), float32, cpu>
New var:....... y = tensor<(4,), float32, cpu>
New var:....... optimizer = SGD (Parameter Group 0 dampe古间圆儿ning: 0 lr: 0....omentum: 0 nesterov: False weight_decay: 0)
02:46:23.545042 line 12 for _ in range(10):
New var:....... _ = 0
02:46:23.545285 line 13 optimizer.zero_grad()
02:46:23.545421 line 14 pred = model段玉良自首(x).squeeze()
New var:....... pred = tensor<(4,), float32, cpu, grad>
02:46:23.546362 line 15 s秋晴小说网quared_diff = (y - pred) ** 2
New var:....... squa老树画画打油诗全集red_diff = tensor<(4,), float32, cpu, grad>
02:46:23.546645 line 16 loss = squared_diff.mean()
New var:....... loss = tensor<(), float32, cpu, grad>
02:46:23.546939 line 17 print(loss.item())
02:46:23.547133 line 18 loss.backward()
02:46:23.591090 line 19 optimizer.step()

现在这个成果看起来就正常了。而且通过测验,loss 现在现已能够降到很挨近 0 了。功德圆满。

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。