PyTorch的高阶偏导数 您所在的位置:网站首页 高阶导数怎么求 PyTorch的高阶偏导数

PyTorch的高阶偏导数

2024-01-28 10:57| 来源: 网络整理| 查看: 265

介绍

本文介绍了如何使用PyTorch查找更高的偏导数。

导数系数不高

例如,假设您要查找$ \\左\\ Frac {df(x)} {dx} \\右| _ {x = 4} $对于函数$ f(x)= x ^ 3 $。

123456>>> import torch >>> x = torch.tensor([4.], requires_grad=True) >>> f = x ** 3 >>> f.backward() >>> print(x.grad) tensor([48.])

您所要做的就是调用

backward(),这就是你们通常所做的。 (此后,省略import torch。)

当仅处理一个变量时

二阶导数

对于函数$ f(x)= x ^ 3 $,二阶导数$ \\左\\ Frac {d ^ 2f(x)} {dx ^ 2} \\右为$ x = 4 $假设您要查找| _ {x = 4} $。

123456789101112>>> x = torch.tensor([4.], requires_grad=True) >>> f = x ** 3 >>> g = torch.autograd.grad(f, x, create_graph=True) >>> g (tensor([48.], grad_fn=),) >>> g.backward() Traceback (most recent call last):   File "", line 1, in AttributeError: 'tuple' object has no attribute 'backward' >>> g[0].backward() >>> x.grad tensor([24.])

关键是在调用

torch.autograd.grad()时使用create_graph=True。 这样,不仅是导数(在上述情况下为48),而且 它为$ f $相对于$ x $的导数创建一个计算图,并将其返回。 然后,通过使用计算图,可以计算二阶微分系数。

在上面的示例中,输入g时,

1(tensor([48.], grad_fn=),)

它显示为

。 48是一阶导数。如果未设置create_graph=True,则仅返回此值。实际上,

12345>>> x = torch.tensor([4.], requires_grad=True) >>> f = x ** 3 >>> g = torch.autograd.grad(f, x) >>> g (tensor([48.]),)

变为

。在上一个示例中,grad_fn=的可疑(?)显示为 证明了计算图也是一起绘制的。

另外,我有意发出了错误 现在,我只区分一个变量$ x $,但是 torch.autograd.grad()基本上处理多个变量中的每个变量部分区分的情况。 因此,元组总是返回。 即使只考虑一个变量,您也将获得仅包含一个元素的元组。 因此,

1>>> g[0].backward()

如果未指定

和下标0使用元组的第一个元素,则会发生错误。

三阶导数

对于函数$ f(x)= x ^ 3 $,三阶导数$ \\左\\ Frac {d ^ 3f(x)} {dx ^ 3} \\右为$ x = 4 $假设您要查找| _ {x = 4} $。

123456789>>> x = torch.tensor([4.], requires_grad=True) >>> f = x ** 3 >>> g = torch.autograd.grad(f, x, create_graph=True) >>> h = torch.autograd.grad(g, x, create_graph=True) >>> h (tensor([24.], grad_fn=),) >>> h[0].backward() >>> x.grad tensor([6.])

首先调用torch.autograd.grad(),并按原样返回计算图, 在下一个torch.autograd.grad()调用中使用它。 然后,该第二次调用将返回一个二阶导数计算图。 如果backward()关于它,则可以计算三阶导数。 答案显示为6.。这是因为当$ x ^ 3 $相差三倍$ x $时,它变为常数$ 6 $。

处理两个或多个变量时

二阶偏导数

对于函数$ f(x,y)=(x 2w)^ 3 $,第一个$ \\左\\ Frac {\\部分^ 2f(x,y)} {\\部分x ^ 2} \\右| _ {x = 4,y = 3} $和

$ \\左\\ Frac {\\部分^ 2 f(x,y)} {\\部分x \\部分y} \\右| _ {x = 4,y = 3} $。

1234567891011>>> x = torch.tensor([4.], requires_grad=True) >>> y = torch.tensor([3.], requires_grad=True) >>> f = (x + 2 * y) ** 3 >>> g = torch.autograd.grad(f, x, create_graph=True) >>> g (tensor([300.], grad_fn=),) >>> g[0].backward() >>> x.grad tensor([60.]) >>> y.grad tensor([120.])

$ \\左\\ Frac {\\部分^ 2f(x,y)} {\\部分x ^ 2} \\右| _ {x = 4,y = 3} = 60 $,

$ \\左\\ Frac {\\部分^ 2 f(x,y)} {\\部分x \\部分y} \\右| _ {x = 4,y = 3} = 120 $。

中,然后是$ \\左\\ Frac {\\部分^ 2f(x,y)} {\\部分y \\部分x} \\右| _ {x = 4,y = 3} $和

$ \\左\\ Frac {\\部分^ 2 f(x,y)} {\\部分y ^ 2} \\右| _ {x = 4,y = 3} $。

1234567891011>>> x = torch.tensor([4.], requires_grad=True) >>> y = torch.tensor([3.], requires_grad=True) >>> f = (x + 2 * y) ** 3 >>> g = torch.autograd.grad(f, y, create_graph=True) >>> g (tensor([600.], grad_fn=),) >>> g[0].backward() >>> x.grad tensor([120.]) >>> y.grad tensor([240.])

当然,$ \\左\\ Frac {\\部分^ 2 f(x,y)} {\\部分x \\部分y} \\右| _ {x = 4,y = 3} $和

$ \\ left。\\ Frac {\\ partial ^ 2f(x,y)} {\\ partial y \\ partial x} \\ right | _ {x = 4,y = 3} $将具有相同的值120。 。

当我尝试同时执行以上两个任务时????

12345678910111213141516171819202122232425>>> x = torch.tensor([4.], requires_grad=True) >>> y = torch.tensor([3.], requires_grad=True) >>> f = (x + 2 * y) ** 3 >>> g = torch.autograd.grad(f, (x, y), create_graph=True) >>> g (tensor([300.], grad_fn=), tensor([600.], grad_fn=)) >>> g[0].backward() >>> x.grad tensor([60.]) >>> y.grad tensor([120.]) >>> g[1].backward() Traceback (most recent call last):   File "", line 1, in   File "/data10/masada/anaconda3/lib/python3.6/site-packages/torch/tensor.py", line 93, in backward     torch.autograd.backward(self, gradient, retain_graph, create_graph)   File "/data10/masada/anaconda3/lib/python3.6/site-packages/torch/autograd/__init__.py", line 90, in backward     allow_unreachable=True)  # allow_unreachable flag RuntimeError: Trying to backward through the graph a second time, but the buffers have already been freed. Specify retain_graph=True when calling backward the first time. >>> g = torch.autograd.grad(f, (x, y), create_graph=True) >>> g[1].backward() >>> x.grad tensor([180.]) >>> y.grad tensor([360.])

,我遇到一个错误。 设置要获取相对于(x,y)和元组的偏微分的两个变量 如果将其传递给torch.autograd.grad(),

12>>> g (tensor([300.], grad_fn=), tensor([600.], grad_fn=))

部分中可以看到,它以元组的形式返回每个变量的一阶导数。 但是,我在g[0].backward()之后运行g[1].backward(),这导致了错误。 上例中的

1>>> g = torch.autograd.grad(f, (x, y), create_graph=True)

我再次调用

和torch.autograd.grad()。

(注意:x.grad.zero_()和y.grad.zero_(),因为未编写初始化为零的过程,所以 对于x.grad和y.grad,g[0].backward()和g[1].backward()的值均为 它已成为一种补充。 )

但是,如上所述,torch.autograd.grad()返回的渐变 您不会用它来区分不同的元素。

12345678910>>> x = torch.tensor([4.], requires_grad=True) >>> y = torch.tensor([3.], requires_grad=True) >>> f = (x + 2 * y) ** 3 >>> g = torch.autograd.grad(f, (x, y), create_graph=True) >>> h = g[0] + g[1] >>> h.backward() >>> x.grad tensor([180.]) >>> y.grad tensor([360.])

这样,如果您制作包含g[0]和g[1]的计算图并为其调用backward(),则 没有特别的问题。通常,您会像这样使用它。

torch.autograd.grad()是关于多个变量的偏微分结果, 换句话说,它将梯度作为元组返回。 通过合并该元组的元素来创建计算图, 我认为用它再次区分是正常的。

例如,对于WGAN中使用的梯度的L2范数, 组合torch.autograd.grad(),返回的元组元素 您正在制作一个计算图。

结论

PyTorch的自动区分非常方便。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有