[250409수343H] 딥러닝 이론 (3) pytorch

윤승호·2025년 4월 9일

파이썬을 처음부터 다시 배우는 기분이다. 이걸로 당장 모델을 구현해야 한다니,,, 숨을 쉴 수가 없다 ㅠㅠ

학습시간 09:00~01:00(당일16H/누적343H)

◆ 학습내용

1. PyTorch

(1) 특징

  • 오픈소스 딥러닝 프레임워크
  • Facebook AI Research(FAIR)에서 개발
  • 동적 계산 그래프(Dynamic Computational Graph) 기반
  • Pythonic한 인터페이스
  • 동적 그래프 지원 (define-by-run)
  • GPU 가속 지원 (CUDA 연동)
  • 강력한 디버깅과 가시성

(2) 구성 요소

A. Tensor

  • 다차원 배열 객체 (NumPy 유사)
  • GPU 연산 지원 (.cuda())
# 0차원 텐서 (스칼라)
np.array(3)

# 1차원 텐서 (벡터)
np.array([1, 2])

# 2차원 텐서 (행렬)
np.array([[1, 2], [3, 4]])

# 3차원 텐서
np.array([[[1, 2], [3, 4]],
          [[5, 6], [7, 8]]])  

B. Autograd

  • 자동 미분 엔진
  • 텐서 연산을 추적하여 역전파 자동 계산

C. nn.Module

  • 신경망 구성 요소 추상 클래스
  • Layer, 모델 구조 정의 시 사용

D. Optim

  • 경사 하강법 기반 최적화 알고리즘 모음
  • SGD, Adam 등

E. DataLoader / Dataset

  • 대용량 데이터 처리 도구
  • 배치, 셔플, 병렬처리 등 제공

(3) 동작 흐름

A. 모델 정의

  • nn.Module 상속 후 forward() 함수 정의

B. 손실 함수 정의

  • nn.CrossEntropyLoss, nn.MSELoss 등 사용

C. 옵티마이저 정의

  • torch.optim 내 최적화 도구 설정

D. 학습 루프 구성

  • 순전파 → 손실 계산 → 역전파 → 파라미터 업데이트 반복

E. 모델 저장/불러오기

  • 저장: torch.save(model.state_dict(), path)
  • 로드: model.load_state_dict(torch.load(path))
항목설명
프레임워크 유형동적 그래프 기반 딥러닝 프레임워크
주요 구성Tensor, Autograd, nn.Module, Optim, DataLoader
핵심 특징Pythonic, GPU 연산, 유연한 디버깅
학습 구조모델 정의 → 손실 계산 → 역전파 → 파라미터 업데이트
확장 도구TorchScript, ONNX, torchvision 등

2. 브로드캐스팅

(1) 특징

  • 서로 다른 크기의 텐서 간 연산을 자동으로 맞춰주는 기능
  • 작은 텐서를 자동으로 반복 확장해서 큰 텐서와 계산 가능하게 만듦
    • ex) [5, 1] 텐서 + [5, 3] 텐서 → [5, 3]으로 연산 가능
  • 텐서 간 shape이 정확히 같지 않아도 연산을 할 수 있어야 할 때
    • 벡터 + 행렬
    • (1, 3) + (4, 3)
    • 스칼라 + 텐서 등

(2) 규칙

규칙 적용 순서

단계규칙 내용
1오른쪽부터 각 차원 비교 시작
2차원이 동일하거나 한 쪽이 1이면 가능
3둘 중 하나가 더 짧으면 앞쪽에 1을 붙여 맞춤
4가능한 경우, 1인 차원을 자동으로 복제하여 연산 진행
5두 차원이 서로 다르고 1도 아니면 오류 발생

규칙 적용 결과

텐서 A shape텐서 B shape브로드캐스팅 결과설명
(3, 1)(3, 5)(3, 5)두 번째 차원만 복제
(1, 5)(3, 5)(3, 5)첫 번째 차원 복제
(1, 1)(3, 5)(3, 5)두 차원 모두 복제
(3, 4)(2, 4)오류첫 번째 차원 불일치 (3 ≠ 2)
(4,)(3, 4)(3, 4)앞에 1 자동 추가 → (1,4)로 간주 후 복제

(3) 코드 예시

import torch

a = torch.tensor([[1], [2], [3]])      # shape: (3, 1)
b = torch.tensor([[10, 20, 30]])       # shape: (1, 3)

result = a * b  # shape: (3, 3)
print(result)


# 출력값 예시
tensor([[10, 20, 30],
        [20, 40, 60],
        [30, 60, 90]])
  • a는 (3,1), b는 (1,3) → 둘 다 2차원이니까 자동으로 (3,3)으로 브로드캐스팅됨!

3 함수

(1) 연산 함수

연산 종류함수명동일한 연산자설명
덧셈torch.add(a, b)a + b요소별 덧셈
뺄셈torch.sub(a, b)a - b요소별 뺄셈
곱셈 (원소곱)torch.mul(a, b)a * b요소별 곱셈
나눗셈torch.div(a, b)a / b요소별 나눗셈
행렬곱torch.matmul(a, b)a @ b행렬 내적 곱
지수 연산torch.pow(a, x)없음각 요소를 x제곱
제곱근torch.sqrt(a)없음각 요소의 제곱근
절댓값torch.abs(a)없음각 요소의 절댓값
최대값torch.max(a, b)없음두 텐서 중 요소별 최대값
최소값torch.min(a, b)없음두 텐서 중 요소별 최소값
비교-같음torch.eq(a, b)a == b요소별 동등 비교
비교-큼torch.gt(a, b)a > b요소별 크기 비교 (a가 b보다 큰가)
비교-작음torch.lt(a, b)a < b요소별 작음 비교
비교-크거나 같음torch.ge(a, b)a >= b요소별 크거나 같음
비교-작거나 같음torch.le(a, b)a <= b요소별 작거나 같음

(2) 타입 변환 함수

변환 목적함수 / 속성설명
자료형 변환tensor.float()float32로 변환
tensor.double()float64로 변환
tensor.int()int32로 변환
tensor.long()int64로 변환
tensor.bool()True/False 논리형으로 변환
tensor.type(torch.자료형)원하는 자료형 직접 지정
자료형 확인tensor.dtype현재 자료형 확인
장치(CPU/GPU) 이동tensor.to("cuda")GPU로 이동
tensor.to("cpu")CPU로 이동
tensor.to(device)device 객체 활용한 일반화 이동
NumPy 변환tensor.numpy()텐서 → 넘파이 배열 (CPU 전용)
torch.from_numpy(array)넘파이 배열 → 텐서
복사tensor.clone()원본 텐서와 독립적인 복사본 생성
메모리 공유 여부tensor.share_memory_()텐서 간 메모리 공유 설정 (고급)

(3) 메모리 관련 함수

함수명설명
tensor.contiguous()비연속 텐서를 메모리상 연속 구조로 재정렬함. .view() 사용 전 필요
tensor.permute(dims)차원 순서 변경 (ex: (0, 2, 1)) → 메모리 순서도 변경됨
tensor.transpose(dim0, dim1)두 차원의 위치만 서로 교환
tensor.clone()메모리까지 복사된 완전한 사본 생성 (원본과 독립)
tensor.detach()텐서를 계산 그래프에서 분리 (역전파 제외용)
tensor.share_memory_()다른 프로세스와 텐서 메모리 공유 설정 (멀티프로세싱 용도)
tensor.storage()텐서가 실제로 저장되는 메모리 영역 확인 (고급용)

(4) 텐서 조작 함수

함수명설명
torch.cat(tensors, dim)여러 텐서를 지정한 차원에서 이어붙임
torch.stack(tensors, dim)여러 텐서를 새 차원으로 쌓음
torch.split(tensor, size)텐서를 지정된 크기로 분할
torch.chunk(tensor, n)텐서를 n개로 균등하게 나눔
tensor.view(shape)텐서 형태 변경 (메모리 연속 필요)
tensor.reshape(shape)텐서 형태 변경 (더 유연, 메모리 복사 발생 가능)
tensor.squeeze(dim)크기 1인 차원 제거
tensor.unsqueeze(dim)새로운 차원 추가
tensor.expand(size)브로드캐스팅 없이 차원 확장
tensor.repeat(*sizes)텐서 복제 (반복)하여 크기 확장

4. PyTorch 코드 예시

(강의 내용 아님)

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms

# 1. 데이터셋 로딩 및 전처리
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

trainset = torchvision.datasets.FashionMNIST(
    root='./data', train=True, download=True, transform=transform
)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)

testset = torchvision.datasets.FashionMNIST(
    root='./data', train=False, download=True, transform=transform
)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)

# 2. 모델 정의
class SimpleNet(nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        self.fc1 = nn.Linear(28*28, 128)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = x.view(-1, 28*28)  # Flatten
        x = self.relu(self.fc1(x))
        x = self.fc2(x)
        return x

model = SimpleNet()

# 3. 손실 함수 및 옵티마이저 설정
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 4. 학습 루프
for epoch in range(5):  # 총 5 에폭
    running_loss = 0.0
    for images, labels in trainloader:
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f"Epoch {epoch+1}, Loss: {running_loss:.4f}")

# 5. 평가 (정확도 계산)
correct = 0
total = 0
with torch.no_grad():
    for images, labels in testloader:
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f"Test Accuracy: {100 * correct / total:.2f}%")
profile
AI Engineer

0개의 댓글