ML,DL,LangChain/02_EDA와 MLP
PyTorch 개론
- -
DEEP LEARNING FRAMEWORK
PyTorch 개론
메타(Meta)가 개발한 딥러닝 라이브러리 · 연구자와 개발자 모두를 위한 선택
📖 tutorials.pytorch.kr →
01
TensorFlow vs PyTorch
TensorFlow
TensorFlow
by Google · 2015년 출시
초기 딥러닝 생태계를 주도한 프레임워크. 복잡한 설정과 정적 그래프(Static Graph) 방식으로 구성돼 있어 개발자 친화적이었어요.
하지만 수식 중심의 AI 연구자들에게는 진입 장벽이 높았답니다. 직관적이지 않은 문법, 디버깅의 어려움 등이 단점으로 꼽혔어요.
하지만 수식 중심의 AI 연구자들에게는 진입 장벽이 높았답니다. 직관적이지 않은 문법, 디버깅의 어려움 등이 단점으로 꼽혔어요.
Google 개발
프로덕션 강점
복잡한 문법
디버깅 어려움
VS
PyTorch
PyTorch
by Meta · 2016년 출시
메타(구 Facebook)가 개발한 라이브러리. 동적 그래프(Dynamic Graph) 방식으로 일반 Python 코드처럼 자연스럽게 작성할 수 있어요.
AI 연구자들이 순전파를 직접 계산하는 대신 "계산 시키고", 미분을 직접 하는 대신 "미분 시키는" 방식으로 매우 간편하게 사용할 수 있어요!
AI 연구자들이 순전파를 직접 계산하는 대신 "계산 시키고", 미분을 직접 하는 대신 "미분 시키는" 방식으로 매우 간편하게 사용할 수 있어요!
Meta 개발
직관적 문법
쉬운 디버깅
연구자 친화적
📈 연구 논문 & 학계에서의 점유율 트렌드
🔥 PyTorch
~80%
🧡 TensorFlow
~20%
* 최근 NeurIPS, ICML 등 주요 AI 학회 논문 기준 — 대부분의 새로운 연구는 PyTorch로 구현돼요!
💡
PyTorch가 사랑받는 핵심 이유
순전파를 "계산 시킨다" — model(x) 한 줄로 끝!
미분을 "시킨다" — loss.backward() 한 줄로 모든 기울기 자동 계산!
수학을 코드로 1:1 변환하듯 쓸 수 있어서 AI 연구자들이 아이디어를 빠르게 실험할 수 있어요.
미분을 "시킨다" — loss.backward() 한 줄로 모든 기울기 자동 계산!
수학을 코드로 1:1 변환하듯 쓸 수 있어서 AI 연구자들이 아이디어를 빠르게 실험할 수 있어요.
02
Tensor — PyTorch의 기본 데이터 단위
📦
Tensor란?
Tensor는 PyTorch에서 모든 데이터를 담는 다차원 배열이에요. NumPy의 ndarray와 비슷하지만,
GPU 가속과 자동 미분(Autograd)을 지원한다는 것이 핵심 차이점이에요!
0D · 스칼라
3.14
shape: ()
1D · 벡터
1.0
2.0
3.0
shape: (3,)
2D · 행렬
1
2
3
4
5
6
shape: (2, 3)
3D · 배치 데이터
…
…
…
…
shape: (batch, H, W)
tensor_basics.py
import torch
# ── 1D 텐서 (벡터) ──────────────────────
v = torch.tensor([1.0, 2.0, 3.0])
print(v) # tensor([1., 2., 3.])
print(v.shape) # torch.Size([3])
print(v[1]) # tensor(2.) ← 인덱싱
# ── 2D 텐서 (행렬) ──────────────────────
M = torch.tensor([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]])
print(M) # tensor([[1., 2., 3.],
# [4., 5., 6.]])
print(M.shape) # torch.Size([2, 3]) ← 2행 3열
print(M[0, 1]) # tensor(2.) ← 0행 1열
print(M[1, :]) # tensor([4., 5., 6.]) ← 1행 전체
# ── nn.Linear 입력은 항상 2D! ───────────
# (배치 크기, 특성 수) 형태로 넣어야 해요
x = torch.randn(4, 5) # 4개 샘플, 각 5개 특성
print(x.shape) # torch.Size([4, 5])
# ── 1D 텐서 (벡터) ──────────────────────
v = torch.tensor([1.0, 2.0, 3.0])
print(v) # tensor([1., 2., 3.])
print(v.shape) # torch.Size([3])
print(v[1]) # tensor(2.) ← 인덱싱
# ── 2D 텐서 (행렬) ──────────────────────
M = torch.tensor([[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0]])
print(M) # tensor([[1., 2., 3.],
# [4., 5., 6.]])
print(M.shape) # torch.Size([2, 3]) ← 2행 3열
print(M[0, 1]) # tensor(2.) ← 0행 1열
print(M[1, :]) # tensor([4., 5., 6.]) ← 1행 전체
# ── nn.Linear 입력은 항상 2D! ───────────
# (배치 크기, 특성 수) 형태로 넣어야 해요
x = torch.randn(4, 5) # 4개 샘플, 각 5개 특성
print(x.shape) # torch.Size([4, 5])
03
nn.Linear — 완전 연결층
🔗
torch.nn.Linear(in_features, out_features)
완전 연결층 (Fully Connected Layer)
입력 텐서에 가중치 행렬(W)을 곱하고 편향(b)을 더하는 연산을 수행해요.
수식으로는 y = xWᵀ + b 이고, 가중치와 편향은 자동으로 초기화 및 학습돼요.
직접 W, b를 선언하고 관리할 필요 없이 nn.Linear 하나로 끝!
수식으로는 y = xWᵀ + b 이고, 가중치와 편향은 자동으로 초기화 및 학습돼요.
직접 W, b를 선언하고 관리할 필요 없이 nn.Linear 하나로 끝!
in_features
입력 벡터의 크기 (이전 층의 노드 수)
out_features
출력 벡터의 크기 (이 층의 노드 수)
nn.Linear(5, 3) — 신경망 시각화
nn_linear.py
import torch
import torch.nn as nn
# 입력 5개 → 출력 3개짜리 선형 층
layer = nn.Linear(5, 3)
x = torch.randn(1, 5) # 배치 1개, 특성 5개
y = layer(x) # 순전파! y.shape → (1, 3)
# 가중치, 편향 확인
print(layer.weight.shape) # torch.Size([3, 5]) ← [out, in]
print(layer.bias.shape) # torch.Size([3])
import torch.nn as nn
# 입력 5개 → 출력 3개짜리 선형 층
layer = nn.Linear(5, 3)
x = torch.randn(1, 5) # 배치 1개, 특성 5개
y = layer(x) # 순전파! y.shape → (1, 3)
# 가중치, 편향 확인
print(layer.weight.shape) # torch.Size([3, 5]) ← [out, in]
print(layer.bias.shape) # torch.Size([3])
04
nn.Sequential — 층을 순서대로 쌓기
🥞
torch.nn.Sequential(*layers)
순차적 레이어 컨테이너
여러 개의 층(Layer)을 순서대로 묶어주는 컨테이너예요.
model(x)를 호출하면 첫 번째 층부터 마지막 층까지 자동으로 순전파가 이루어져요.
간단한 모델을 빠르게 구성할 때 매우 유용하답니다!
model(x)를 호출하면 첫 번째 층부터 마지막 층까지 자동으로 순전파가 이루어져요.
간단한 모델을 빠르게 구성할 때 매우 유용하답니다!
nn.Sequential — Linear(4,5) → ReLU 활성화 → Linear(5,3)
💡 ReLU는 독립된 층이 아닌, 각 노드에 적용되는 활성화 함수(Activation Function)입니다.
선형 변환(Wx+b)의 결과에 max(0, x)를 적용하여 비선형성을 부여합니다.
선형 변환(Wx+b)의 결과에 max(0, x)를 적용하여 비선형성을 부여합니다.
nn_sequential.py
import torch
import torch.nn as nn
# 입력 4 → 은닉 5 (+ ReLU 활성화) → 출력 3
model = nn.Sequential(
nn.Linear(4, 5), # 입력(4) → 은닉층(5): 선형 변환
nn.ReLU(), # 은닉층 노드에 적용하는 활성화 함수
nn.Linear(5, 3), # 은닉층(5) → 출력층(3): 선형 변환
)
x = torch.randn(1, 4) # 입력: (배치 1, 특성 4)
y = model(x) # 순전파 한 줄로 끝! y.shape → (1, 3)
import torch.nn as nn
# 입력 4 → 은닉 5 (+ ReLU 활성화) → 출력 3
model = nn.Sequential(
nn.Linear(4, 5), # 입력(4) → 은닉층(5): 선형 변환
nn.ReLU(), # 은닉층 노드에 적용하는 활성화 함수
nn.Linear(5, 3), # 은닉층(5) → 출력층(3): 선형 변환
)
x = torch.randn(1, 4) # 입력: (배치 1, 특성 4)
y = model(x) # 순전파 한 줄로 끝! y.shape → (1, 3)
✅
Sequential의 장점
forward() 함수를 직접 작성할 필요 없어요! 층을 나열만 하면 자동으로 연결돼요.
단, 복잡한 구조(분기, 스킵 연결 등)는 nn.Module이 필요해요.
단, 복잡한 구조(분기, 스킵 연결 등)는 nn.Module이 필요해요.
05
nn.Module — 모든 신경망의 기반 클래스
🧱
torch.nn.Module
신경망 모듈의 최상위 기반 클래스
PyTorch에서 신경망을 만들 때 상속받는 가장 기본이 되는 클래스예요.
nn.Linear, nn.Sequential 모두 nn.Module을 상속받고 있어요.
커스텀 모델을 만들 때는 nn.Module을 상속받아서 ① __init__에서 레이어 정의, ② forward()에서 순전파 로직을 작성하면 돼요! 역전파(backward)는 PyTorch가 자동으로 처리해줘요 🎉
nn.Linear, nn.Sequential 모두 nn.Module을 상속받고 있어요.
커스텀 모델을 만들 때는 nn.Module을 상속받아서 ① __init__에서 레이어 정의, ② forward()에서 순전파 로직을 작성하면 돼요! 역전파(backward)는 PyTorch가 자동으로 처리해줘요 🎉
SequentialMLP (nn.Module 상속)
└── self.layers = nn.Sequential(
├── nn.Linear(input_dim, hidden_dim) ← 선형 변환
├── nn.ReLU() ← 활성화 함수 (파라미터 없음)
└── nn.Linear(hidden_dim, output_dim) ← 선형 변환
)
forward(x) ← self.layers(x) 한 줄로 순전파 완료
backward() ← PyTorch 자동 처리 ✨
└── self.layers = nn.Sequential(
├── nn.Linear(input_dim, hidden_dim) ← 선형 변환
├── nn.ReLU() ← 활성화 함수 (파라미터 없음)
└── nn.Linear(hidden_dim, output_dim) ← 선형 변환
)
forward(x) ← self.layers(x) 한 줄로 순전파 완료
backward() ← PyTorch 자동 처리 ✨
SequentialMLP(nn.Module) — layers: Linear(4→5) + ReLU 활성화 → Linear(5→3)
💡 ReLU는 fc1의 결과(Wx+b)에 바로 적용되는 활성화 함수입니다.
가중치(파라미터)가 없으며, 새로운 층이 추가되는 것이 아닙니다.
가중치(파라미터)가 없으며, 새로운 층이 추가되는 것이 아닙니다.
nn_module.py
import torch
import torch.nn as nn
class SequentialMLP(nn.Module):
""" nn.Sequential을 내부적으로 활용하는 MLP 모델. 입력층 → 은닉층(ReLU 활성화) → 출력층 구조. """
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__() # nn.Module 초기화 — 반드시 호출!
# nn.Sequential로 층을 순서대로 묶음
# model(x) 호출 시 아래 순서대로 자동 순전파
self.layers = nn.Sequential(
nn.Linear(input_dim, hidden_dim), # ① 선형 변환: (N, input_dim) → (N, hidden_dim)
nn.ReLU(), # ② 활성화 함수: max(0, x) — 파라미터 없음
nn.Linear(hidden_dim, output_dim), # ③ 선형 변환: (N, hidden_dim) → (N, output_dim)
)
def forward(self, x):
# Sequential이 ①②③을 순서대로 처리 — 한 줄로 끝!
return self.layers(x)
# ── 모델 생성 ───────────────────────────────────
model = SequentialMLP(
input_dim=4, # 입력 특성 수
hidden_dim=5, # 은닉층 노드 수
output_dim=3, # 출력 클래스 수
)
# ── 학습 루프 ───────────────────────────────────
optimizer = torch.optim.Adam(model.parameters()) # 파라미터 자동 수집
loss_fn = nn.CrossEntropyLoss()
x = torch.randn(1, 4) # 입력: (배치 1, 특성 4)
pred = model(x) # ① 순전파 — pred.shape → (1, 3)
loss = loss_fn(pred, y) # ② Loss 계산
loss.backward() # ③ 역전파 — 미분 시킨다!
optimizer.step() # ④ 가중치 업데이트
import torch.nn as nn
class SequentialMLP(nn.Module):
""" nn.Sequential을 내부적으로 활용하는 MLP 모델. 입력층 → 은닉층(ReLU 활성화) → 출력층 구조. """
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__() # nn.Module 초기화 — 반드시 호출!
# nn.Sequential로 층을 순서대로 묶음
# model(x) 호출 시 아래 순서대로 자동 순전파
self.layers = nn.Sequential(
nn.Linear(input_dim, hidden_dim), # ① 선형 변환: (N, input_dim) → (N, hidden_dim)
nn.ReLU(), # ② 활성화 함수: max(0, x) — 파라미터 없음
nn.Linear(hidden_dim, output_dim), # ③ 선형 변환: (N, hidden_dim) → (N, output_dim)
)
def forward(self, x):
# Sequential이 ①②③을 순서대로 처리 — 한 줄로 끝!
return self.layers(x)
# ── 모델 생성 ───────────────────────────────────
model = SequentialMLP(
input_dim=4, # 입력 특성 수
hidden_dim=5, # 은닉층 노드 수
output_dim=3, # 출력 클래스 수
)
# ── 학습 루프 ───────────────────────────────────
optimizer = torch.optim.Adam(model.parameters()) # 파라미터 자동 수집
loss_fn = nn.CrossEntropyLoss()
x = torch.randn(1, 4) # 입력: (배치 1, 특성 4)
pred = model(x) # ① 순전파 — pred.shape → (1, 3)
loss = loss_fn(pred, y) # ② Loss 계산
loss.backward() # ③ 역전파 — 미분 시킨다!
optimizer.step() # ④ 가중치 업데이트
파라미터 자동 추적
model.parameters()
자동 역전파
모델 저장/불러오기
🧠
Sequential vs Module — 언제 뭘 쓸까?
nn.Sequential — 단순히 층을 일렬로 쌓는 간단한 모델에 적합해요.
nn.Module — 분기 처리, 스킵 연결(ResNet), 반복 구조(RNN), 조건 로직 등 복잡한 모델을 구현할 때 필요해요.
실제 연구와 프로젝트에서는 대부분 nn.Module을 사용한답니다!
nn.Module — 분기 처리, 스킵 연결(ResNet), 반복 구조(RNN), 조건 로직 등 복잡한 모델을 구현할 때 필요해요.
실제 연구와 프로젝트에서는 대부분 nn.Module을 사용한답니다!
'ML,DL,LangChain > 02_EDA와 MLP' 카테고리의 다른 글
| SequentialMLP 데이터 흐름 (1) | 2026.03.12 |
|---|---|
| 모델 학습 전체 파이프 라인 (0) | 2026.03.10 |
| 교차 검증 (1) | 2026.03.09 |
| ROC Curve (0) | 2026.03.09 |
| 혼동행렬분석 (0) | 2026.03.09 |
Contents
소중한 공감 감사합니다