Aprendizaje PyTorch: dos, Autograd (derivada automática)

1. Autogrado: diferenciación automática

El núcleo de todas las redes neuronales en PyTorch es el autogradpaquete. Primero presentamos brevemente este paquete y luego entrenamos nuestra primera red neuronal.

autogradEl paquete proporciona una diferenciación automática para todas las operaciones en el tensor. Es un marco definido en tiempo de ejecución, lo que significa que la propagación hacia atrás se define de acuerdo con la forma en que se ejecuta el código, y cada iteración puede ser diferente.

A continuación, usamos algunos ejemplos simples para ver este paquete:

Tensor

torch.TensorEs la clase principal del paquete. Si establece su propiedad .requires_graden Verdadero, comenzará a rastrear todas las operaciones en él. Después de completar el cálculo, puede llamar .backward()y calcular automáticamente todos los gradientes. El gradiente de este tensor se acumulará en el .gradatributo.

Para evitar que un tensor rastree el historial, puede llamar para .detach()separarlo del historial de cálculos y evitar que se rastreen cálculos futuros.

Para evitar el seguimiento del historial (y el uso de la memoria), también puede usar torch.no_grad () para envolver el bloque de código: esto puede ser particularmente útil al evaluar el modelo, porque el modelo puede tener requires_grad = Trueparámetros entrenables, pero no necesitamos gradientes.

Hay otra clase que es muy importante para la implementación de autogrado-Función.

El tensor y la función están conectados entre sí y construyen un gráfico acíclico para construir un proceso de cálculo completo. Cada tensor tiene un .grad_fnatributo que se refiere a la función del tensor creado (excepto los tensores creados por el usuario, que grad_fnson None).

Si desea calcular la derivada, puede llamarla en Tensor .backward(). Si el tensor es un escalar (es decir, contiene datos de un elemento), no necesita backward()especificar ningún parámetro, pero si tiene más elementos, necesita especificar un parámetro de gradiente, que es un tensor de forma coincidente.

import torch

Cree un tensor y configúrelo requires_grad = Truepara realizar un seguimiento de su cálculo

x = torch.ones(2, 2, requires_grad=True)
print(x)

输出:

tensor([[1., 1.],
        [1., 1.]], requires_grad=True)

 

Realizar operaciones sobre tensores:

y = x + 2
print(y)

输出:

tensor([[3., 3.],
        [3., 3.]], grad_fn=<AddBackward0>)

Debido a que y es creado por una operación, tiene grad_fn y x es creado por el usuario, por lo que su grad_fn es None.

print(y.grad_fn)
print(x.grad_fn)

输出:

<AddBackward0 object at 0x000001E020B794A8>
None

Realice la operación en y

z = y * y * 3
out = z.mean()

print(z, out)

输出:

tensor([[27., 27.],
        [27., 27.]], grad_fn=<MulBackward0>) tensor(27., grad_fn=<MeanBackward1>)

.requires_grad_(...)Cambie el requires_gradlogotipo del Tensor existente en su lugar . Si no se proporciona, el indicador de entrada tiene el valor predeterminado Falso.

a = torch.randn(2, 2)
a = ((a * 3) / (a - 1))
print(a.requires_grad)
a.requires_grad_(True)
print(a.requires_grad)
b = (a * a).sum()
print(b.grad_fn)

输出:

False
True
<SumBackward0 object at 0x000001E020B79FD0>

Gradientes

Ahora realicemos la propagación hacia atrás, que es out.backward()equivalente a ejecutarout.backward(torch.tensor(1.))

out.backward()

Genere el gradiente d (out) / dx de out ax:

print(x.grad)

输出:

tensor([[4.5000, 4.5000],
        [4.5000, 4.5000]])

Veamos ahora un ejemplo de producto vectorial jacobiano:

x = torch.randn(3, requires_grad=True)
y = x * 2
while y.data.norm() < 1000:
    y = y * 2
print(y)

输出:

tensor([  384.5854,   -13.6405, -1049.2870], grad_fn=<MulBackward0>)

Ahora, en este caso, y ya no es un escalar. torch.autogradNo es posible calcular directamente el determinante jacobiano completo, pero si solo queremos el producto vectorial jacobiano, solo necesitamos pasar el vector hacia atrás como parámetro:

v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)

输出:

tensor([5.1200e+01, 5.1200e+02, 5.1200e-02])

También puede usar el código torch.no_grad () y usar .requires_grad = True en el tensor para dejar de usar el historial de seguimiento.

print(x.requires_grad)
print((x ** 2).requires_grad)

with torch.no_grad():
    print((x ** 2).requires_grad)


输出:

True
True
False

 

Supongo que te gusta

Origin blog.csdn.net/qq_40716944/article/details/107790345
Recomendado
Clasificación