我知道两种从梯度计算中排除计算元素的方法 backward
方法一:使用with torch.no_grad()
with torch.no_grad():
y = reward + gamma * torch.max(net.forward(x))
loss = criterion(net.forward(torch.from_numpy(o)), y)
loss.backward();
Run Code Online (Sandbox Code Playgroud)
方法二:使用.detach()
y = reward + gamma * torch.max(net.forward(x))
loss = criterion(net.forward(torch.from_numpy(o)), y.detach())
loss.backward();
Run Code Online (Sandbox Code Playgroud)
这两者有区别吗?两者都有好处/坏处吗?
我一直遇到这个错误:
RuntimeError:尝试第二次向后遍历图形,但缓冲区已被释放.第一次向后调用时指定retain_graph = True.
我在Pytorch论坛上搜索过,但仍然无法找到我在自定义丢失函数中做错了什么.我的模型是nn.GRU,这是我的自定义丢失函数:
def _loss(outputs, session, items): # `items` is a dict() contains embedding of all items
def f(output, target):
pos = torch.from_numpy(np.array([items[target["click"]]])).float()
neg = torch.from_numpy(np.array([items[idx] for idx in target["suggest_list"] if idx != target["click"]])).float()
if USE_CUDA:
pos, neg = pos.cuda(), neg.cuda()
pos, neg = Variable(pos), Variable(neg)
pos = F.cosine_similarity(output, pos)
if neg.size()[0] == 0:
return torch.mean(F.logsigmoid(pos))
neg = F.cosine_similarity(output.expand_as(neg), neg)
return torch.mean(F.logsigmoid(pos - neg))
loss = map(f, outputs, session)
return -torch.mean(torch.cat(loss))
Run Code Online (Sandbox Code Playgroud)
培训代码:
# zero the parameter gradients
model.zero_grad() …
Run Code Online (Sandbox Code Playgroud) 我想知道如何处理PyTorch中的就地操作.我记得在autograd中使用就地操作一直存在问题.
实际上,我很惊讶下面这段代码可以工作,即使我没有测试它,我相信这段代码会引发版本错误0.3.1
.
基本上我想做的是将张量向量的某个位置设置为某个值,如:
my_tensor[i] = 42
Run Code Online (Sandbox Code Playgroud)
工作示例代码:
# test parameter a
a = torch.rand((2), requires_grad=True)
print('a ', a)
b = torch.rand(2)
# calculation
c = a + b
# performing in-place operation
c[0] = 0
print('c ', c)
s = torch.sum(c)
print('s ', s)
# calling backward()
s.backward()
# optimizer step
optim = torch.optim.Adam(params=[a], lr=0.5)
optim.step()
# changed parameter a
print('changed a', a)
Run Code Online (Sandbox Code Playgroud)
输出:
a tensor([0.2441, 0.2589], requires_grad=True)
c tensor([0.0000, 1.1511], grad_fn=<CopySlices>)
s tensor(1.1511, grad_fn=<SumBackward0>)
changed a tensor([ …
Run Code Online (Sandbox Code Playgroud) 假设我有自定义损失函数,并且我想在神经网络的帮助下拟合某些微分方程的解。因此,在每次前向传递中,我都会计算神经网络的输出,然后通过采用 MSE 和我想要拟合感知器的预期方程来计算损失。
现在我的疑问是:我应该使用grad(loss)
反向loss.backward()
传播来计算和更新我的梯度吗?
我知道,在使用 loss.backward() 时,我必须用 Variable 包装我的张量,并且必须为我想要获取损失梯度的变量设置 require_grad = True 。
所以我的问题是:
grad(loss)
还需要任何此类显式参数来识别梯度计算的变量?如果您能解释这两种方法的实际含义,那就更好了,因为每当我试图在网上找到它时,我都会被很多与我的项目不太相关的东西轰炸。
试图围绕如何表示渐变以及autograd如何工作:
import torch
from torch.autograd import Variable
x = Variable(torch.Tensor([2]), requires_grad=True)
y = x * x
z = y * y
z.backward()
print(x.grad)
#Variable containing:
#32
#[torch.FloatTensor of size 1]
print(y.grad)
#None
Run Code Online (Sandbox Code Playgroud)
为什么它不会产生渐变y
?如果y.grad = dz/dy
,那么它不应该至少产生一个变量y.grad = 2*y
吗?
我在 中使用该autograd
工具PyTorch
,并且发现自己需要通过整数索引访问一维张量中的值。像这样的东西:
def basic_fun(x_cloned):
res = []
for i in range(len(x)):
res.append(x_cloned[i] * x_cloned[i])
print(res)
return Variable(torch.FloatTensor(res))
def get_grad(inp, grad_var):
A = basic_fun(inp)
A.backward()
return grad_var.grad
x = Variable(torch.FloatTensor([1, 2, 3, 4, 5]), requires_grad=True)
x_cloned = x.clone()
print(get_grad(x_cloned, x))
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息:
[tensor(1., grad_fn=<ThMulBackward>), tensor(4., grad_fn=<ThMulBackward>), tensor(9., grad_fn=<ThMulBackward>), tensor(16., grad_fn=<ThMulBackward>), tensor(25., grad_fn=<ThMulBackward>)]
Traceback (most recent call last):
File "/home/mhy/projects/pytorch-optim/predict.py", line 74, in <module>
print(get_grad(x_cloned, x))
File "/home/mhy/projects/pytorch-optim/predict.py", line 68, in get_grad
A.backward()
File "/home/mhy/.local/lib/python3.5/site-packages/torch/tensor.py", line 93, in backward …
Run Code Online (Sandbox Code Playgroud) 该文档不包含任何 gradcheck 示例用例,它在哪里有用?
当我想在验证集上评估模型的性能时,最好使用:
with torch.no_grad:
要么
model.eval()
我仍在努力理解 PyTorch autograd 系统。我正在努力解决的一件事是理解为什么.clamp(min=0)
并且nn.functional.relu()
似乎有不同的向后传球。
它特别令人困惑,因为它.clamp
与relu
PyTorch 教程中的等效用法相同,例如https://pytorch.org/tutorials/beginner/pytorch_with_examples.html#pytorch-nn。
我在分析具有一个隐藏层和 relu 激活(输出层中的线性)的简单全连接网络的梯度时发现了这一点。
据我了解,以下代码的输出应该只是零。我希望有人能告诉我我缺少什么。
import torch
dtype = torch.float
x = torch.tensor([[3,2,1],
[1,0,2],
[4,1,2],
[0,0,1]], dtype=dtype)
y = torch.ones(4,4)
w1_a = torch.tensor([[1,2],
[0,1],
[4,0]], dtype=dtype, requires_grad=True)
w1_b = w1_a.clone().detach()
w1_b.requires_grad = True
w2_a = torch.tensor([[-1, 1],
[-2, 3]], dtype=dtype, requires_grad=True)
w2_b = w2_a.clone().detach()
w2_b.requires_grad = True
y_hat_a = torch.nn.functional.relu(x.mm(w1_a)).mm(w2_a)
y_a = torch.ones_like(y_hat_a)
y_hat_b = x.mm(w1_b).clamp(min=0).mm(w2_b)
y_b = torch.ones_like(y_hat_b)
loss_a = (y_hat_a - y_a).pow(2).sum()
loss_b …
Run Code Online (Sandbox Code Playgroud) 我无法理解grad_outputs
中选项的概念含义torch.autograd.grad
。
文档说:
\n\n\n\n
grad_outputs
应该是一个长度匹配输出的序列,其中包含雅可比向量积中的 \xe2\x80\x9cvector\xe2\x80\x9d ,通常是每个输出的预先计算的梯度。如果输出不\xe2\x80\x99trequire_grad
,则梯度可以是None
)。
我发现这个描述相当神秘。雅可比向量积到底是什么意思?我知道雅可比行列式是什么,但不确定它们在这里意味着什么:元素方式、矩阵乘积,还是其他什么?我无法从下面的例子中看出。
\n为什么“向量”要加引号?事实上,在下面的示例中,当 是向量时我会收到错误grad_outputs
,但当它是矩阵时则不会。
>>> x = torch.tensor([1.,2.,3.,4.], requires_grad=True)\n>>> y = torch.outer(x, x)\n
Run Code Online (Sandbox Code Playgroud)\n为什么我们会观察到以下输出;它是如何计算的?
\n>>> y\ntensor([[ 1., 2., 3., 4.],\n [ 2., 4., 6., 8.],\n [ 3., 6., 9., 12.],\n [ 4., 8., 12., 16.]], grad_fn=<MulBackward0>)\n\n>>> torch.autograd.grad(y, x, grad_outputs=torch.ones_like(y))\n(tensor([20., 20., 20., 20.]),)\n
Run Code Online (Sandbox Code Playgroud)\n然而,为什么会出现这个错误呢?
\n>>> torch.autograd.grad(y, x, grad_outputs=torch.ones_like(x)) \n …
Run Code Online (Sandbox Code Playgroud)