실험 : 전에 활용했던 XOR문제를 풀기위한 MLP 코드를 파라미터를 변경해보며 정확도를 올려보자.
day3에서 기존 XOR문제를 MLP에서 해결한 코드에서 성능을 올려보기 위하여 파라미터나 활성함수, 옵티마이저 등을 조금씩 변경해보며 정확도를 올려보자. 기본 설정을 기준으로 하나씩만 변화시킨다. 예를 들면 은닉층 크기만 바꾸거나, lr만 바꾸는 등 한번에 1개 항목만 바꾼다. (loss나 예측값은 소수점 셋째자리까지만 표기한다.)
실험
| 실험 | 은닉층 크기 | 활성화 | 학습률(lr) | Epoch 수 | Optimizer | 비교 포인트 |
| 1 | 4 | ReLU | 0.1 | 1000 | SGD | 기본 설정 (Baseline) |
| 2 | 2 | ReLU | 0.1 | 1000 | SGD | 은닉층 작게 |
| 3 | 8 | ReLU | 0.1 | 1000 | SGD | 은닉층 크게 |
| 4 | 4 | ReLU | 0.01 | 1000 | SGD | lr 줄여서 비교 |
| 5 | 4 | ReLU | 0.1 | 3000 | SGD | epoch 늘려서 비교 |
| 6 | 4 | ReLU | 0.1 | 1000 | Adam | optimizer 변경 비교 |
| 7 | 2 | Tanh | 0.1 | 1000 | SGD | 활성화 함수 비교 (옵션) |
결과
| 실험 | 최종 Loss | 예측값 [0,0] | 예측값 [0,1] | 예측값 [1,0] | 예측값 [1,1] | 비교 포인트 |
| 1 | 0.033 | 0.042 | 0.987 | 0.987 | 0.042 | 기본 설정 (Baseline) |
| 2 | 0.480 | 0.012 | 0.662 | 0.662 | 0.662 | 은닉층 작게 |
| 3 | 0.017 | 0.011 | 0.987 | 0.987 | 0.018 | 은닉층 크게 |
| 4 | 0.650 | 0.454 | 0.484 | 0.563 | 0.484 | lr 줄여서 비교 |
| 5 | 0.004 | 0.002 | 0.996 | 0.995 | 0.003 | epoch 늘려서 비교 |
| 6 | 0.346 | 0.000 | 0.500 | 0.999 | 0.500 | optimizer 변경 비교 |
| 7 | 0.250 | 0.065 | 0.868 | 0.820 | 0.203 | 활성화 함수 비교 (옵션) |
고찰
| 1 (Baseline) | Loss 0.033, 예측 거의 완벽. 구조 안정 |
| 2 (은닉층 작게) | Loss 0.48 → 수렴 불완전. 예측 0.66 수준으로 애매. 은닉층이 작아 표현력 부족 |
| 3 (은닉층 크게) | Loss 0.017 → Baseline보다 더 낮음. 예측값도 거의 완벽. 표현력 좋음 |
| 4 (lr 낮춤) | Loss 0.65 → 거의 수렴 안 됨. 0.01이면 학습 속도가 느려서 epoch가 더 필요함 |
| 5 (epoch 늘림) | Loss 0.004 → Baseline보다 더 낮음. 충분히 수렴. epoch 늘린 효과 |
| 6 (Adam) | Loss 0.346 → SGD(lr=0.1)보다 안 좋음. Adam은 lr를 낮췄어야 함 |
| 7 (Tanh) | Loss 0.250 → ReLU보다 다소 높음. 예측이 살짝 애매. Tanh는 XOR에서는 ReLU보다 효율이 떨어짐 |
은닉층을 키우거나, 학습 횟수를 늘리면 정답률이 높아짐.
Adam이 별로였던 이유
Adam은 파라미터마다 학습률을 자동으로 조절해서 보통 SGD보다 빠르고 안정적으로 수렴하지만 기본 가정인 초기 학습률이 작아야 한다가 깨지면 SGD보다 성능이 떨어질 수 있음. 여기서는 lr이 0.1로 너무 큰 편이었음.
Tanh가 별로였던 이유
Tanh

VS
ReLU

활성함수의 기울기가 0에 가까워지면 손실함수의 기울기도 0에 가까워지게 되고, w값의 변화가 줄어들게 된다. Tanh에서는 값이 너무 크거나 작으면 학습이 멈추게 됨.
MNIST Dataset 다운로드 & 로딩 테스트
코드
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 1. 데이터 변환 정의
transform = transforms.ToTensor() # [0~255] → [0~1]로 바꾸고 tensor로 변환
# 2. 학습 데이터셋 다운로드
train_dataset = datasets.MNIST(
root='./data',
train=True,
transform=transform,
download=True
)
# 3. 데이터로더로 묶기
train_loader = DataLoader(
dataset=train_dataset,
batch_size=32,
shuffle=True
)
# 4. 샘플 한 배치 확인
images, labels = next(iter(train_loader))
print(images.shape) # torch.Size([32, 1, 28, 28])
print(labels[:10])
결과
torch.Size([32, 1, 28, 28])
tensor([5, 7, 3, 5, 7, 5, 5, 1, 9, 9])'ai' 카테고리의 다른 글
| pytorch-Day3 : 단층 퍼셉트론에서 비선형 문제를 완벽하게 풀수 없음을 증명 (3) | 2025.07.30 |
|---|---|
| pytorch-Day5 : MLP로 MNIST 손글씨 분류 – 전체 학습 흐름 구현 (1 Epoch) (1) | 2025.07.28 |
| pytorch-Day2 : Cutom Dataset 만들기, batch size 바꿔가며 학습곡선 비교 (1) | 2025.07.10 |
| pytorch-Day1 : mini-batch 실습 및 loss함수 시각화(by Dataset/DataLoader && matplotlib) (2) | 2025.07.09 |
| pytorch-Day0 (0) | 2025.07.09 |