PyTorch

PyTorch Autograd 소개 (자동 미분)

PyExplorer 2025. 4. 5. 08:53
728x90

PyTorch Autograd 소개 (자동 미분)

1. 들어가며

딥러닝 모델을 학습시키는 과정에서 중요한 작업 중 하나는 손실 함수(loss function)의 미분(gradient)을 계산하는 것입니다. PyTorch에서는 autograd라는 자동 미분(Automatic Differentiation) 기능을 제공하여 이러한 과정이 간편하게 이루어집니다.

이번 포스팅에서는 PyTorch의 autograd 모듈에 대해 자세히 알아보고, 어떻게 활용할 수 있는지 살펴보겠습니다.

2. Autograd 개요

PyTorch의 autograd는 동적 계산 그래프(Dynamic Computation Graph, DCG)를 기반으로 작동합니다. 연산이 수행될 때마다 계산 그래프가 생성되며, 역전파(backpropagation) 시에는 이 그래프를 따라 자동으로 미분이 계산됩니다.

기본적으로, 텐서(Tensor) 객체는 requires_grad=True로 설정할 경우 모든 연산을 추적하며, .backward() 함수를 호출하면 해당 텐서에 대한 미분이 자동으로 계산됩니다.

3. Autograd 기본 사용법

3.1 requires_grad 속성

requires_grad=True를 설정하면 해당 텐서와 관련된 모든 연산이 기록됩니다. 기본적으로 requires_grad=False로 설정되어 있어 연산 그래프가 생성되지 않습니다.

import torch

# requires_grad를 True로 설정하면 연산이 추적됨
a = torch.tensor(2.0, requires_grad=True)
b = torch.tensor(3.0, requires_grad=True)

c = a * b  # 연산이 추적됨
d = c + 5  # 추가 연산도 추적됨

print(d)  # tensor(11., grad_fn=<AddBackward0>)

위 코드에서 dgrad_fn 속성을 보면, AddBackward0이라는 값이 출력됩니다. 이는 d가 이전 연산(c + 5)에서 생성되었음을 의미합니다.

3.2 backward()를 이용한 미분 계산

.backward()를 호출하면 해당 변수에 대한 미분이 계산됩니다.

import torch

x = torch.tensor(2.0, requires_grad=True)
y = x ** 2  # y = x^2

y.backward()  # 미분 수행

print(x.grad)  # dy/dx = 2x -> 2 * 2 = 4

위 코드에서 y = x^2이고, y.backward()를 호출하면 x.grad에는 dy/dx = 2x의 결과가 저장됩니다.

3.3 여러 변수에 대한 미분 계산

연산이 여러 개의 변수를 포함하는 경우, 각 변수에 대한 기울기(gradient)를 계산할 수 있습니다.

import torch

x = torch.tensor(2.0, requires_grad=True)
y = torch.tensor(3.0, requires_grad=True)

z = x * y + x ** 2  # z = xy + x^2
z.backward()

print(x.grad)  # dz/dx = y + 2x = 3 + 4 = 7
print(y.grad)  # dz/dy = x = 2

4. Autograd 활용

4.1 Jacobian 행렬 계산

PyTorch의 autograd.grad() 함수를 사용하면 특정 텐서에 대한 기울기만 따로 계산할 수도 있습니다.

import torch

x = torch.tensor([2.0, 3.0], requires_grad=True)
y = x ** 2

gradients = torch.autograd.grad(outputs=y, inputs=x, grad_outputs=torch.ones_like(y))
print(gradients)  # (tensor([4., 6.]),)

이 코드에서 y = [x_1^2, x_2^2]이므로 미분 결과는 [2*x_1, 2*x_2] = [4, 6]이 됩니다.

4.2 Gradient Tape 비활성화 (no_grad)

모델을 평가할 때는 그래디언트가 필요 없으므로, torch.no_grad()를 사용하여 연산 그래프 생성을 비활성화할 수 있습니다.

import torch

x = torch.tensor(2.0, requires_grad=True)

with torch.no_grad():
    y = x ** 2

print(y.requires_grad)  # False

4.3 detach()를 이용한 그래프 분리

detach() 메서드를 사용하면 기존 텐서에서 그래디언트를 추적하지 않는 새로운 텐서를 만들 수 있습니다.

x = torch.tensor(2.0, requires_grad=True)
y = x ** 2

y_detached = y.detach()
print(y_detached.requires_grad)  # False

5. 실제 활용 예제: 신경망 학습

다음은 PyTorch의 autograd를 이용하여 간단한 선형 회귀 모델을 학습하는 예제입니다.

import torch

# 데이터 생성
x = torch.tensor([[1.0], [2.0], [3.0], [4.0]], requires_grad=True)
y = torch.tensor([[2.0], [4.0], [6.0], [8.0]])

# 가중치 초기화
w = torch.randn(1, requires_grad=True)
b = torch.randn(1, requires_grad=True)

# 학습률 설정
lr = 0.01

for i in range(100):
    # 예측값 계산
    y_pred = x * w + b

    # 손실 함수 계산 (MSE)
    loss = ((y_pred - y) ** 2).mean()

    # 역전파 수행
    loss.backward()

    # 가중치 갱신
    with torch.no_grad():
        w -= lr * w.grad
        b -= lr * b.grad

    # 그래디언트 초기화
    w.grad.zero_()
    b.grad.zero_()

    if i % 10 == 0:
        print(f'Iteration {i}, Loss: {loss.item()}')

6. 정리

PyTorch의 autograd 모듈은 신경망 학습에서 필수적인 자동 미분 기능을 제공합니다. requires_grad 속성을 통해 연산을 추적할 수 있으며, .backward() 메서드를 사용하여 손쉽게 그래디언트를 계산할 수 있습니다.

또한 torch.no_grad()를 이용해 연산 그래프를 비활성화하거나, detach()를 통해 그래디언트 추적을 끄는 기능도 지원합니다.

이번 포스팅을 통해 PyTorch의 자동 미분 기능을 이해하고, 실제 신경망 학습 과정에서 어떻게 활용할 수 있는지 확인하셨길 바랍니다.

728x90