pytorch 기초

deep learning
공개

2025년 12월 17일

특징

  1. 동적 계산 그래프(Dynamic Computation Graph)
    • 파이토치는 동적 계산 그래프를 사용하여 모델을 정의하고 수정할 수 있다. 모델의 구조를 실행 시점에 변경할 수 있다.
  2. GPU 가속 지원
  3. 직관적 인터페이스
    • 실행모드를 지원하고, 계산 그래프를 빌드하지 않고 코드를 실행할 수 있다.
  4. 제한된 프로덕션 지원
    • 주로 연구 목적이다.

텐서

import torch

tensor = torch.rand(1, 2)

print(tensor)
print(tensor.shape) # 크기
print(tensor.dtype) # 자료형
print(tensor.device) # GPU 가속 여부
tensor([[0.1930, 0.8300]])
torch.Size([1, 2])
torch.float32
cpu

장치 설정

device = "cuda" if torch.cuda.is_available() else "cpu"
cpu = torch.FloatTensor([1, 2, 3])
gpu = torch.cuda.FloatTensor([1, 2, 3]) # GPU 가속 지정 방법 1. MAC에서는 지원이 안될 수도 있다.
tensor = torch.rand((1, 1), device=device) # GPU 가속 지정 방법 2
print(device)
print(cpu)
print(gpu)
print(tensor)
cuda
tensor([1., 2., 3.])
tensor([1., 2., 3.], device='cuda:0')
tensor([[0.9628]], device='cuda:0')
  • cpu 텐서와 gpu 텐서는 상호 간 연산이 불가능하다.
  • numpy 배열은 cpu 텐서와의 연산만 가능

장치 변환

cpu = torch.FloatTensor([1, 2, 3])
gpu = cpu.cuda() # cpu -> gpu
cpu2 = gpu.cpu() # gpu -> cpu
gpu2 = cpu.to("cuda") # cpu -> gpu 2 MAC에서도 지원이 되니까 이 방법으로 사용하자
print(cpu)
print(cpu2)
print(gpu)
print(gpu2)
tensor([1., 2., 3.])
tensor([1., 2., 3.])
tensor([1., 2., 3.], device='cuda:0')
tensor([1., 2., 3.], device='cuda:0')
import numpy as np

ndarray = np.array([1, 2, 3], dtype=np.uint8)
yo = torch.from_numpy(ndarray)
print(yo)
print(yo.to("cuda"))
tensor([1, 2, 3], dtype=torch.uint8)
tensor([1, 2, 3], device='cuda:0', dtype=torch.uint8)
ndarray = yo.detach().cpu().numpy() # detach: graph에서 분리된 새로운 텐서 반환
print(ndarray)
print(type(ndarray))
[1 2 3]
<class 'numpy.ndarray'>

단순 선형회귀

from torch import optim

x = torch.FloatTensor([
    [1], [2], [3], [4], [5], [6], [7], [8], [9], [10],
    [11], [12], [13], [14], [15], [16], [17], [18], [19], [20],
    [21], [22], [23], [24], [25], [26], [27], [28], [29], [30]
])
y = torch.FloatTensor([
    [0.94], [2.05], [2.87], [4.10], [5.01], [6.15], [6.95], [8.12], [9.05], [10.11],
    [11.03], [12.20], [12.89], [14.15], [15.02], [16.18], [16.95], [18.22], [19.10], [20.05],
    [21.01], [22.20], [22.89], [24.10], [25.05], [26.15], [26.95], [28.12], [29.05], [30.10]
])
weight = torch.zeros(1, requires_grad=True)
bias = torch.zeros(1, requires_grad=True)
learning_rate = 0.001
optimizer = optim.SGD([weight, bias], lr=learning_rate)

for epoch in range(1000):
    hypothesis = x * weight + bias
    cost = torch.mean((hypothesis - y) ** 2)

    optimizer.zero_grad()
    cost.backward()
    optimizer.step()

    if (epoch + 1) % 100 == 0:
        print(f"Epoch {epoch+1}/1000 | Cost: {cost.item():.4f} | Weight: {weight.item():.4f} | Bias: {bias.item():.4f}")
Epoch 100/1000 | Cost: 0.0089 | Weight: 1.0010 | Bias: 0.0482
Epoch 200/1000 | Cost: 0.0089 | Weight: 1.0010 | Bias: 0.0473
Epoch 300/1000 | Cost: 0.0089 | Weight: 1.0011 | Bias: 0.0463
Epoch 400/1000 | Cost: 0.0088 | Weight: 1.0011 | Bias: 0.0455
Epoch 500/1000 | Cost: 0.0088 | Weight: 1.0012 | Bias: 0.0446
Epoch 600/1000 | Cost: 0.0088 | Weight: 1.0012 | Bias: 0.0438
Epoch 700/1000 | Cost: 0.0088 | Weight: 1.0013 | Bias: 0.0430
Epoch 800/1000 | Cost: 0.0088 | Weight: 1.0013 | Bias: 0.0423
Epoch 900/1000 | Cost: 0.0088 | Weight: 1.0013 | Bias: 0.0416
Epoch 1000/1000 | Cost: 0.0088 | Weight: 1.0014 | Bias: 0.0409
from torch import nn

model = nn.Linear(1, 1, bias=True)
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.001)

for epoch in range(1000):
    hypothesis = model(x)
    cost = criterion(hypothesis, y)

    optimizer.zero_grad()
    cost.backward()
    optimizer.step()

    if (epoch + 1) % 100 == 0:
        print(f"Epoch {epoch+1}/1000 | Cost: {cost:.4f} | Model: {list(model.parameters())}")
Epoch 100/1000 | Cost: 0.0136 | Model: [Parameter containing:
tensor([[0.9950]], requires_grad=True), Parameter containing:
tensor([0.1702], requires_grad=True)]
Epoch 200/1000 | Cost: 0.0132 | Model: [Parameter containing:
tensor([[0.9953]], requires_grad=True), Parameter containing:
tensor([0.1636], requires_grad=True)]
Epoch 300/1000 | Cost: 0.0128 | Model: [Parameter containing:
tensor([[0.9956]], requires_grad=True), Parameter containing:
tensor([0.1573], requires_grad=True)]
Epoch 400/1000 | Cost: 0.0124 | Model: [Parameter containing:
tensor([[0.9959]], requires_grad=True), Parameter containing:
tensor([0.1513], requires_grad=True)]
Epoch 500/1000 | Cost: 0.0121 | Model: [Parameter containing:
tensor([[0.9962]], requires_grad=True), Parameter containing:
tensor([0.1455], requires_grad=True)]
Epoch 600/1000 | Cost: 0.0118 | Model: [Parameter containing:
tensor([[0.9965]], requires_grad=True), Parameter containing:
tensor([0.1400], requires_grad=True)]
Epoch 700/1000 | Cost: 0.0115 | Model: [Parameter containing:
tensor([[0.9967]], requires_grad=True), Parameter containing:
tensor([0.1348], requires_grad=True)]
Epoch 800/1000 | Cost: 0.0113 | Model: [Parameter containing:
tensor([[0.9970]], requires_grad=True), Parameter containing:
tensor([0.1298], requires_grad=True)]
Epoch 900/1000 | Cost: 0.0110 | Model: [Parameter containing:
tensor([[0.9972]], requires_grad=True), Parameter containing:
tensor([0.1251], requires_grad=True)]
Epoch 1000/1000 | Cost: 0.0108 | Model: [Parameter containing:
tensor([[0.9974]], requires_grad=True), Parameter containing:
tensor([0.1205], requires_grad=True)]

데이터 로드

from torch.utils.data import TensorDataset, DataLoader

train_x = torch.FloatTensor([
    [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7]
])
train_y = torch.FloatTensor([
    [0.1, 1.5], [1, 2.8], [1.9, 4.1], [2.8, 5.4], [3.7, 6.7], [4.6, 8]
])
train_dataset = TensorDataset(train_x, train_y)
train_dataloader = DataLoader(train_dataset, batch_size=2, shuffle=True, drop_last=True)
model = nn.Linear(2, 2, bias=True)
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.001)

for epoch in range(1000):
    cost = 0
    for batch in train_dataloader:
        x, y = batch
        output = model(x)
        loss = criterion(output, y)

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        cost += loss

    cost = cost / len(train_dataloader)

    if (epoch + 1) % 100 == 0:
        print(f"Epoch {epoch+1}/1000 | Cost: {cost:.4f} | Model: {list(model.parameters())}")
Epoch 100/1000 | Cost: 0.1810 | Model: [Parameter containing:
tensor([[0.3308, 0.2977],
        [0.8800, 0.2466]], requires_grad=True), Parameter containing:
tensor([0.0446, 0.6826], requires_grad=True)]
Epoch 200/1000 | Cost: 0.1563 | Model: [Parameter containing:
tensor([[0.3674, 0.2787],
        [0.9034, 0.2345]], requires_grad=True), Parameter containing:
tensor([-0.0109,  0.6471], requires_grad=True)]
Epoch 300/1000 | Cost: 0.1366 | Model: [Parameter containing:
tensor([[0.4018, 0.2612],
        [0.9254, 0.2234]], requires_grad=True), Parameter containing:
tensor([-0.0628,  0.6140], requires_grad=True)]
Epoch 400/1000 | Cost: 0.1195 | Model: [Parameter containing:
tensor([[0.4339, 0.2448],
        [0.9458, 0.2129]], requires_grad=True), Parameter containing:
tensor([-0.1114,  0.5830], requires_grad=True)]
Epoch 500/1000 | Cost: 0.1056 | Model: [Parameter containing:
tensor([[0.4636, 0.2291],
        [0.9649, 0.2029]], requires_grad=True), Parameter containing:
tensor([-0.1568,  0.5540], requires_grad=True)]
Epoch 600/1000 | Cost: 0.0913 | Model: [Parameter containing:
tensor([[0.4916, 0.2147],
        [0.9827, 0.1936]], requires_grad=True), Parameter containing:
tensor([-0.1992,  0.5269], requires_grad=True)]
Epoch 700/1000 | Cost: 0.0799 | Model: [Parameter containing:
tensor([[0.5178, 0.2012],
        [0.9994, 0.1851]], requires_grad=True), Parameter containing:
tensor([-0.2389,  0.5016], requires_grad=True)]
Epoch 800/1000 | Cost: 0.0704 | Model: [Parameter containing:
tensor([[0.5421, 0.1884],
        [1.0150, 0.1769]], requires_grad=True), Parameter containing:
tensor([-0.2760,  0.4779], requires_grad=True)]
Epoch 900/1000 | Cost: 0.0606 | Model: [Parameter containing:
tensor([[0.5650, 0.1766],
        [1.0296, 0.1694]], requires_grad=True), Parameter containing:
tensor([-0.3107,  0.4558], requires_grad=True)]
Epoch 1000/1000 | Cost: 0.0531 | Model: [Parameter containing:
tensor([[0.5864, 0.1657],
        [1.0432, 0.1624]], requires_grad=True), Parameter containing:
tensor([-0.3431,  0.4351], requires_grad=True)]

모듈 클래스

from torch.utils.data import Dataset
import pandas as pd

class CustomDataset(Dataset):
    def __init__(self, file_path):
        df = pd.read_csv(file_path)
        self.x = df.iloc[:, 0].values
        self.y = df.iloc[:, 1].values
        self.length = len(df)

    def __getitem__(self, index):
        x = torch.FloatTensor([self.x[index] ** 2, self.x[index]])
        y = torch.FloatTensor([self.y[index]])
        return x, y

    def __len__(self):
        return self.length

class Model(nn.Module):
    def __init__(self):
        super().__init__()
        self.conv1 = nn.Conv2d(1, 20, 5)
        self.conv2 = nn.Conv2d(20, 20, 5)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.relu(self.conv2(x))
        return x
맨 위로