1. 이번 주 학습 주제 요약
이번 주는 딥러닝의 시작점이라 할 수 있는 선형 회귀(Linear Regression) 개념부터 출발하여, 이를 다층 구조로 확장한 MLP(Multi-Layer Perceptron) 모델까지 실제로 구현하며 실습을 진행했다. 특히 예측 함수, 손실 함수, gradient 계산 방식과 같은 수학적 직관도 함께 학습하면서, 단순한 구현을 넘어선 이해를 키울 수 있었다.
또한 과적합(Overfitting)을 방지하기 위한 기법들인 Dropout, Weight Decay, BatchNorm, Validation / Early Stopping 등의 핵심 개념도 함께 다뤘고, 마지막에는 MNIST 손글씨 분류를 통해 실제 학습 흐름을 구현했다.
2. 핵심 개념 정리
🔹 선형 회귀란?
가장 기본적인 예측 모델로, 입력 x에 대해 y = wx + b 형태로 결과를 예측한다. 여기서의 목표는 실제값 y와 예측값의 오차를 줄이는 w, b를 찾는 것.
예측 함수: pred(w, b, x)
손실 함수: loss(w, b, x, y)는 평균 제곱 오차(MSE)를 사용
기울기 계산: 오차 × 입력값 → 각 파라미터가 손실에 얼마나 영향을 주는지 반영
🔹 MLP (Multi-Layer Perceptron)
선형 회귀만으로는 XOR 같은 문제 해결이 불가능하다.
그래서 은닉층을 하나 이상 추가하고, 비선형 함수(ReLU 등)를 통해 복잡한 결정 경계를 만들 수 있도록 한 것이 MLP이다.
구성:
입력층 → 은닉층 1~n → 출력층
각 층 사이에는 활성화 함수 사용
torch.nn.Linear, torch.nn.ReLU 등을 활용
🔹 활성화 함수와 비선형성
비선형성이 없으면 여러 개의 선형 함수를 이어붙여도 결국 선형이다.
따라서 ReLU와 같은 비선형 함수를 사이에 넣어야만 더 복잡한 함수를 표현할 수 있다.
ReLU: 0보다 크면 그대로, 작으면 0으로 만드는 함수
Leaky ReLU: 음수도 아주 작게 통과시킴 (기울기 소실 방지)
GELU: Transformer에서 많이 쓰는 확률 기반 활성화 함수
3. 과적합과 정규화 기법
Overfitting이란?
학습 데이터에는 잘 맞지만, 새로운 데이터에서는 성능이 떨어지는 현상
원인: 너무 많은 파라미터, 너무 적은 데이터, 반복 학습 등
해결 방법:
Validation 데이터 사용: 모델이 잘 학습되고 있는지 점검
Early Stopping: validation 성능이 나빠지면 학습 조기 종료
Weight Decay (L2 Regularization): 가중치를 작게 유지하여 복잡한 모델 방지
Dropout: 학습 시 일부 뉴런을 랜덤하게 꺼서 특정 뉴런 의존도 낮춤
BatchNorm: 각 layer의 출력을 정규화해서 학습 안정화
4. Optimizer와 학습 방식
Adam Optimizer
Momentum: 이전 gradient 방향을 반영해 가속
Adaptive Learning Rate: 파라미터마다 learning rate 조절
gradient가 크면 learning rate 줄이고, 작으면 크게 해서 효율적인 학습 가능
5. 실습: MNIST 손글씨 분류
28x28 크기의 흑백 이미지 (0~9 숫자)
torchvision.datasets.MNIST로 데이터 로드
transforms.ToTensor()로 정규화
모델 구성:
class Model(nn.Module):
def __init__(self, input_dim, n_dim):
super().__init__()
self.layer1 = nn.Linear(input_dim, n_dim)
self.layer2 = nn.Linear(n_dim, n_dim)
self.layer3 = nn.Linear(n_dim, 10) # 클래스 10개
self.act = nn.ReLU()
def forward(self, x):
x = torch.flatten(x, start_dim=1)
x = self.act(self.layer1(x))
x = self.act(self.layer2(x))
x = self.layer3(x)
return x
손실 함수: nn.CrossEntropyLoss()
Optimizer: Adam(model.parameters(), lr=0.001)
정확도 측정 함수:
def accuracy(model, dataloader):
cnt = 0
acc = 0
model.eval() # 평가 모드로 설정 (일관된 추론 결과를 보장)
with torch.no_grad():
for inputs, labels in dataloader:
inputs, labels = inputs.to('cuda'), labels.to('cuda')
preds = model(inputs)
preds = torch.argmax(preds, dim=-1)
cnt += labels.shape[0]
acc += (labels == preds).sum().item()
model.train() # 다시 학습 모드로 복귀
return acc / cnt
정확도 시각화:
def plot_acc(train_accs, test_accs, label1='train', label2='test'):
x = np.arange(len(train_accs))
plt.plot(x, train_accs, label=label1)
plt.plot(x, test_accs, label=label2)
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.title('Train vs Test Accuracy')
plt.legend()
plt.grid(True)
plt.show()
6. 어려웠던 점 & 배운 점
CrossEntropyLoss 사용 시 예측값은 softmax 전의 logit 상태여야 하고, 정답은 정수 인덱스여야 한다는 걸 몰라 에러가 났었다.
Dropout을 왜 학습 때는 켜고 테스트 때는 끄는지 헷갈렸지만, 여러 모델을 실험하고 평균을 취하는 방식이라는 개념이 명확해졌다.
학습 과정에서 .zero_grad() → forward → loss.backward() → optimizer.step() 순서를 반복한다는 구조를 몸으로 익힘.
7. 느낀 점
단순히 구현하는 걸 넘어서, 수학적 이유와 개념적 원리를 함께 학습할 수 있어 재미있고 유익했다.
PyTorch의 구성 요소들이 점점 익숙해지고, 각 개념이 어떤 문제를 해결하기 위해 나왔는지 이해되니 더 흥미로웠다.
앞으로 더 깊은 주제와 실습이 기다리고 있지만, 이번 주의 기반이 큰 도움이 될 것 같아 기대된다.
#항해99 #항해플러스AI후기 #개발자커뮤니티 #LLM
다음 내용이 궁금하다면?
이미 회원이신가요?
2025년 3월 30일 오전 12:35