인지야공

인지야공/딥러닝 기초 정리/1번째 글

PyTorch 치트시트 — 실제로 돌려서 검증한 것만 남겼다

치트시트 5종(공식 ptcheat, learnpytorch.io, DataCamp, ZeroToMastery, SlingAcademy)을 조회해 겹치는 핵심만 추린 뒤, 전부 실제로 돌려서 검증한 코드입니다. 실행: python 01_pytorch_cheatsheet.py (검증 환경: torch 2.8.0+cu129, Python 3.13.5, CUDA 사용 가능)


0. 모든 스크립트의 시작 3줄

import torch, torch.nn as nn, torch.nn.functional as F

torch.manual_seed(42)                 # 재현성
torch.cuda.manual_seed_all(42)

device = ("cuda" if torch.cuda.is_available()
          else "mps" if torch.backends.mps.is_available()
          else "cpu")

1. 텐서 만들기

코드뜻
torch.tensor([[1,2],[3,4]])리스트 → 텐서
torch.zeros(2,3) / torch.ones(2,3)0 / 1 채우기
torch.rand(2,3)균등분포 [0,1)
torch.randn(2,3)정규분포 N(0,1)
torch.arange(0,10,2)0,2,4,6,8
torch.linspace(0,1,5)0~1 을 5등분
torch.eye(3)단위행렬
torch.zeros_like(x)x 와 같은 모양

텐서를 보면 항상 3가지를 확인한다.

x.dtype      # torch.float32 / torch.int64 ...
x.shape      # torch.Size([2, 3])
x.device     # cpu / cuda:0

dtype 변환은 .float(), .long(). numpy 는 torch.from_numpy() ↔ .numpy().


2. 모양 바꾸기 — 버그의 90%가 여기서 난다

x = torch.arange(12).reshape(3, 4)

x.view(2, 6)         # (2,6)  연속 메모리일 때만 가능
x.reshape(-1, 2)     # (6,2)  안전한 버전. -1 은 자동 계산
x.transpose(0, 1)    # (4,3)  축 2개만 교환
x.permute(2, 0, 1)   # 축 전체 재배열
x.unsqueeze(0)       # (1,3,4) 차원 추가 - 배치 차원 만들 때
x.squeeze()          # 크기 1인 차원 제거
torch.cat([x, x], 0)   # (6,4)  기존 축에 이어붙임
torch.stack([x, x], 0) # (2,3,4) 새 축을 만들어 쌓음
t.flatten(1)         # (8,3,32,32) -> (8,3072)  CNN → FC 연결

cat 과 stack 의 차이가 핵심: cat 은 차원 수가 그대로, stack 은 차원이 하나 늘어난다.


3. 연산 / 브로드캐스팅 / 행렬곱

A * B            # 원소별 곱 (모양이 같아야 함)
A @ B            # 행렬곱 = torch.matmul(A, B)

torch.zeros(3,4) + torch.ones(4)          # (3,4) 브로드캐스팅
torch.rand(8,5,3) @ torch.rand(8,3,7)     # (8,5,7) 배치 행렬곱 ★어텐션의 핵심

A.sum(dim=0)     # 행 방향으로 합치기(=열별 합)
A.argmax(dim=1)  # 분류 예측 라벨 뽑기
F.softmax(A, dim=1)

dim 은 “그 축을 없앤다” 로 외우면 헷갈리지 않는다.


4. autograd

w = torch.tensor(2.0, requires_grad=True)
y = 3*w**2 + 5*w
y.backward()
w.grad        # 17.0   (손계산 6w+5 = 6*2+5 = 17 과 일치 ✔ 실행 확인)

with torch.no_grad():   # 기울기 추적 끄기
    ...

5. 모델 정의

class MLP(nn.Module):
    def __init__(self, in_dim=4, hidden=16, out_dim=3):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(in_dim, hidden), nn.ReLU(), nn.Dropout(0.1),
            nn.Linear(hidden, out_dim),
        )
    def forward(self, x):
        return self.net(x)      # ★ logits 그대로. 끝에 softmax 넣지 말 것

파라미터 수 세기: sum(p.numel() for p in model.parameters() if p.requires_grad) (위 모델 = 131개, 손계산 4*16+16 + 16*3+3 과 일치 ✔)

주요 레이어 입출력 shape (실행 확인값)

레이어입력출력
nn.Linear(10,5)(2,10)(2,5)
nn.Conv2d(3,16,3,padding=1)(2,3,32,32)(2,16,32,32)
nn.MaxPool2d(2)(2,16,32,32)(2,16,16,16)
nn.BatchNorm2d(16)(2,16,8,8)(2,16,8,8)
nn.Embedding(100,8)(1,3)(1,3,8)
nn.LSTM(10,20,batch_first=True)(2,7,10)(2,7,20)
nn.TransformerEncoderLayer(32,4,batch_first=True)(2,7,32)(2,7,32)

6. Dataset / DataLoader

from torch.utils.data import TensorDataset, DataLoader, random_split

ds = TensorDataset(X, y)
train_ds, test_ds = random_split(ds, [240, 60])
train_dl = DataLoader(train_ds, batch_size=32, shuffle=True)
test_dl  = DataLoader(test_ds,  batch_size=32, shuffle=False)   # 평가는 shuffle=False

커스텀 Dataset 은 메서드 3개면 끝:

class MyDataset(Dataset):
    def __init__(self, X, y): self.X, self.y = X, y
    def __len__(self):        return len(self.X)
    def __getitem__(self, i): return self.X[i], self.y[i]

7. 손실함수 / 옵티마이저 / 스케줄러

문제손실함수모델 마지막 출력정답 dtype
회귀nn.MSELoss(), nn.L1Loss()실수값float
다중분류nn.CrossEntropyLoss()logits (softmax 금지)long (정수 인덱스)
이진분류nn.BCEWithLogitsLoss()logits (sigmoid 금지)float (0.0/1.0)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-2, weight_decay=1e-4)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=30)
  • 기본은 AdamW (Adam + 올바른 weight decay)
  • 스케줄러는 매 epoch 끝에 scheduler.step()

8. 학습 루프 — 이 6줄 순서가 PyTorch의 전부

def train_one_epoch(model, dl, loss_fn, optimizer, device):
    model.train()                        # (1) Dropout/BN 켜기
    for xb, yb in dl:
        xb, yb = xb.to(device), yb.to(device)
        pred = model(xb)                 # (2) 순전파
        loss = loss_fn(pred, yb)         # (3) 손실
        optimizer.zero_grad()            # (4) 기울기 초기화 ★빼먹으면 누적
        loss.backward()                  # (5) 역전파
        optimizer.step()                 # (6) 가중치 갱신

@torch.inference_mode()                  # no_grad 보다 빠른 추론 전용
def evaluate(model, dl, loss_fn, device):
    model.eval()                         # Dropout 끄기, BN 통계 고정
    ...

실제 실행 결과 (3클래스 분류, 30 epoch):

epoch   1 | train loss 0.9838 acc 0.579 | test loss 0.8224 acc 0.733 | lr 0.00997
epoch  10 | train loss 0.2262 acc 0.950 | test loss 0.4134 acc 0.883 | lr 0.00750
epoch  20 | train loss 0.1578 acc 0.963 | test loss 0.3966 acc 0.933 | lr 0.00250
epoch  30 | train loss 0.1819 acc 0.942 | test loss 0.3953 acc 0.950 | lr 0.00000

9. 저장 / 불러오기

torch.save({"model": model.state_dict(),
            "optim": optimizer.state_dict(),
            "epoch": 30}, "ckpt.pt")

ckpt = torch.load("ckpt.pt", map_location=device, weights_only=True)  # 보안상 권장
model2.load_state_dict(ckpt["model"])
model2.eval()

모델 객체 전체를 torch.save(model) 하지 말 것 — 클래스 정의에 묶여 이식성이 없다.


10. 자주 나는 에러 4개

에러원인 / 해결
Expected all tensors to be on the same device데이터·모델 둘 다 .to(device) 했는지
mat1 and mat2 shapes cannot be multipliednn.Linear(in,out) 의 in 이 앞 레이어 출력과 다름. flatten(1) 확인
expected scalar type Long but found FloatCrossEntropyLoss 의 정답은 .long() 정수여야 함
loss 가 안 줄어듦optimizer.zero_grad() 누락 / lr 과다 / 모델 끝에 softmax 를 또 씌움

참고한 치트시트 5종

  1. PyTorch Cheat Sheet (공식 튜토리얼)
  2. PyTorch Cheatsheet — learnpytorch.io (Zero to Mastery)
  3. Deep Learning with PyTorch Cheat Sheet — DataCamp
  4. PyTorch Cheat Sheet + PDF — Zero To Mastery
  5. PyTorch complete cheat sheet — Sling Academy

표시는 이 브라우저에만 남는다. 서버로 가는 것은 없다.