No PyTorch, autograd é o conteúdo principal de todas as redes neurais e fornece métodos de derivação automática para todas as operações do tensor.
É uma estrutura definida pela maneira como é executada, o que significa que o backprop é definido pela maneira como o código é executado.
、 、 Variável
autograd.Variable é a classe principal no autograd. Ele envolve um tensor e suporta quase todas as operações definidas nele. Após a conclusão do cálculo, você pode chamar .backward () para calcular automaticamente todos os gradientes.
A variável possui três atributos: dados, graduação e criador.
Acesse o tensor original usando o atributo .data; o gradiente dessa variável é focado em .grad; .creator reflete o criador e identifica se ele é criado diretamente pelo usuário usando .Variable (nenhum).
Há também uma classe que é muito importante para a implementação da função autograd. Os números de variável e função são relacionados entre si e estabelecem um gráfico acíclico para codificar o processo completo de cálculo. Cada variável possui um atributo .grad_fn que referencia a função que criou a variável (exceto as variáveis criadas pelo usuário cujo grad_fn é Nenhum).
import torch
from torch.autograd import Variable
Crie a variável x:
x = Variable(torch.ones(2, 2), requires_grad=True)
print(x)
Resultado de saída:
Variable containing:
1 1
1 1
[torch.FloatTensor of size 2x2]
Opere com base em x:
y = x + 2
print(y)
Resultado de saída:
Variable containing:
3 3
3 3
[torch.FloatTensor of size 2x2]
查看x的
city_fn :
print(x.grad_fn)
Resultado de saída:
None
查看y的
city_fn :
print(y.grad_fn)
Resultado de saída:
<torch.autograd.function.AddConstantBackward object at 0x7f603f6ab318>
可以看到y是作为运算的结果产生的,所以y有
grad_fn,而x是直接创建的,所以x没有grad_fn。
Calcular com base em y:
z = y * y * 3
out = z.mean()
print(z, out)
Resultado de saída:
Variable containing:
27 27
27 27
[torch.FloatTensor of size 2x2]
Variable containing:
27
[torch.FloatTensor of size 1]
、 、 Gradientes
如果Variable是一个标量(例如它包含一个单元素数据),你无需对backward()指定任何参数.
out.backward()
É equivalente aout.backward(torch.Tensor([1.0])).
out.backward()
print(x.grad)
Resultado de saída:
Variable containing:
4.5000 4.5000
4.5000 4.5000
[torch.FloatTensor of size 2x2]
Se houver mais elementos (vetores), você precisará especificar um parâmetro grad_output que corresponda à forma do tensor (a derivada de y projetada em x na direção especificada)
x = torch.randn(3)
x = Variable(x, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
y = y * 2
print(y)
Resultado de saída:
Variable containing:
-1296.5227
499.0783
778.8971
[torch.FloatTensor of size 3]x = torch.randn(3)
x = Variable(x, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
y = y * 2
print(y)
Resultado de saída:
Variable containing:
-1296.5227
499.0783
778.8971
[torch.FloatTensor of size 3]
Sem parâmetros:
y.backward()
print(x.grad)
Resultado de saída:
RuntimeError: grad can be implicitly created only for scalar outputs
None
Parâmetros de entrada:
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
Resultado de saída:
Variable containing:
102.4000
1024.0000
0.1024
[torch.FloatTensor of size 3]
Simplesmente teste o efeito de diferentes parâmetros:
Parâmetro 1: [1,1,1]
x=torch.FloatTensor([1,2,3])
x = Variable(x, requires_grad=True)
y = x * x
print(y)
gradients = torch.FloatTensor([1,1,1])
y.backward(gradients)
print(x.grad)
Resultado de saída:
Variable containing:
1
4
9
[torch.FloatTensor of size 3]
Variable containing:
2
4
6
[torch.FloatTensor of size 3]
Parâmetro 2: [3,2,1]
x=torch.FloatTensor([1,2,3])
x = Variable(x, requires_grad=True)
y = x * x
print(y)
gradients = torch.FloatTensor([3,2,1])
y.backward(gradients)
print(x.grad)
Resultado de saída:
Variable containing:
1
4
9
[torch.FloatTensor of size 3]
Variable containing:
6
8
6
[torch.FloatTensor of size 3]