적절한 하이퍼파라미터 값 찾기 및 구현 실습
신경망에는 하이퍼파라미터가 다수 등장.
여기서 말하는 하이퍼파라미터는 뉴런 수, 배치 크기, 매개변수 갱신 시의 학습률, 가중치 감소 등이 존재.
적절한 값을 설정하지 못할 경우 모델 성능이 크게 떨어지기도 함.
하이퍼파라미터 값은 매우 중요하지만, 그 값을 결정하기까지는 일반적으로 많은 시행착오를 겪음.
검증 데이터
데이터셋을 훈련 데이터와 시험 데이터로 분리.
하이퍼파라미터의 성능을 평가할 때는 시험 데이터를 사용해서는 안됨.
- 시험 데이터를 사용하여 하이퍼파라미터를 조정하면 하이퍼파라미터 값이 시험 데이터에 오버피팅되기 때문
하이퍼파라미터를 조정할 때는 하이퍼파라미터 전용 확인 데이터가 필요.
- 하이퍼파라미터 조정 데이터를 일반적으로 검증 데이터라고 부름
- 하이퍼파라미터의 적절성을 평가하는 데이터.
용어 정리
훈련 데이터: 매개변수 학습
검증 데이터: 하이퍼파라미터 성능 평가
시험 데이터: 신경망의 범용 성능 평가
하이퍼파라미터 최적화
최적의 값이 존재하는 범위를 조금씩 줄여가는 형태로 접근.
범위를 조금씩 줄이려면 우선 대략적인 범위를 설정하고 그 범위에서 무작위로 하이퍼파라미터 값을 골라낸(샘플링)한 후 그 값으로 정확도 평가.
하이퍼파라미터 최적화에서는 그리드 서치 같은 규치적인 탐색 보다는 무작위로 샘플링해 탐색하는 편이 더 좋은 결과를 낸다고 알려져 있음.
하이퍼파라미터 값을 설정할 때는 대략적으로 지정하는 것이 효과적으로 0.001에서 1.000 사이로 설정하며, 매우 오랜 시간이 걸림.
따라서 나쁠 듯한 값은 일찍 포기하는 것이 좋음.
학습을 위한 에폭을 작게 유지해서 1회 평가에 걸리는 시간을 단축하는 것이 효과적.
- 0단계: 하이퍼파라미터 값 범위 설정
- 1단계: 설정된 범위에서 하이퍼파라미터의 값을 무작위로 추출
- 2단계: 1단계에서 샘플링한 하이퍼파라미터 값을 사용하여 학습하고, 검증 데이터로 정확도를 평가 (에폭을 작게)
- 1단계와 2단계를 특정 횟수 반복하여 그 정확도의 결과를 보고 하이퍼파라미터의 범위를 좁힘.
하이퍼파라미터 최적화 방법은 실용적인 방법. 하지만 과학이기보단 직관과 지혜에 의존.
베이즈 최적화는 베이즈 정리를 중심으로 한 수학 이론을 구사하여 더 엄밀하고 효율적으로 최적화를 수행.
하이퍼파라미터 최적화 샘플 코드
훈련 데이터: 매개변수 학습
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import numpy as np
import random
# 재현성을 위한 시드 설정
torch.manual_seed(42)
np.random.seed(42)
random.seed(42)
print("라이브러리 임포트 완료 및 시드 설정 완료.")
# 데이터 로드 (MNIST 사용)
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
# 모델 정의
class SimpleMLP(nn.Module):
def __init__(self):
super(SimpleMLP, self).__init__()
self.fc1 = nn.Linear(784, 128)
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 10)
def forward(self, x):
x = x.view(-1, 784)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
print("데이터셋 로드 및 모델 클래스 정의 완료.")
def train_and_evaluate(params):
# 하이퍼파라미터 추출
lr = params['learning_rate']
batch_size = params['batch_size']
optimizer_name = params['optimizer']
num_epochs = 5 # 최적화 탐색은 짧은 Epoch으로 빠르게 수행
# 데이터 로더 설정 (배치 크기 적용)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size, shuffle=True)
testloader = torch.utils.data.DataLoader(testset, batch_size=batch_size, shuffle=False)
# 모델 및 최적화 함수 설정
model = SimpleMLP()
criterion = nn.CrossEntropyLoss()
if optimizer_name == 'Adam':
optimizer = optim.Adam(model.parameters(), lr=lr)
elif optimizer_name == 'SGD':
optimizer = optim.SGD(model.parameters(), lr=lr)
else:
raise ValueError("Unknown optimizer")
# 학습 루프
for epoch in range(num_epochs):
model.train()
for data, targets in trainloader:
scores = model(data)
loss = criterion(scores, targets)
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 테스트 정확도 평가
model.eval()
num_correct = 0
num_samples = 0
with torch.no_grad():
for x, y in testloader:
scores = model(x)
_, predictions = scores.max(1)
num_correct += (predictions == y).sum()
num_samples += predictions.size(0)
accuracy = (num_correct / num_samples * 100).item()
return accuracy
# 탐색할 하이퍼파라미터 공간 정의
hyperparameter_space = {
'learning_rate': [0.01, 0.001, 0.0001],
'batch_size': [32, 64, 128],
'optimizer': ['Adam', 'SGD']
}
# 탐색 횟수 설정
NUM_TRIALS = 10
best_accuracy = 0
best_params = {}
results = []
print(f"--- 하이퍼파라미터 랜덤 서치 시작 (시도 횟수: {NUM_TRIALS}) ---")
for i in range(NUM_TRIALS):
# 무작위 조합 선택
params = {
'learning_rate': random.choice(hyperparameter_space['learning_rate']),
'batch_size': random.choice(hyperparameter_space['batch_size']),
'optimizer': random.choice(hyperparameter_space['optimizer'])
}
print(f"\n시도 {i+1}/{NUM_TRIALS}: {params}")
# 학습 및 평가 실행
try:
accuracy = train_and_evaluate(params)
results.append({'params': params, 'accuracy': accuracy})
print(f"-> 정확도: {accuracy:.2f}%")
# 최고 성능 갱신
if accuracy > best_accuracy:
best_accuracy = accuracy
best_params = params
except Exception as e:
print(f"오류 발생: {e}")
continue
print("\n--- 탐색 완료 ---")
print(f"최고 정확도: {best_accuracy:.2f}%")
print(f"최적 파라미터: {best_params}")
아래는 샘플 코드에 대한 결과 해석
라이브러리 임포트 완료 및 시드 설정 완료.
데이터셋 로드 및 모델 클래스 정의 완료.
--- 하이퍼파라미터 랜덤 서치 시작 (시도 횟수: 10) ---
시도 1/10: {'learning_rate': 0.0001, 'batch_size': 32, 'optimizer': 'Adam'}
-> 정확도: 95.09%
시도 2/10: {'learning_rate': 0.0001, 'batch_size': 64, 'optimizer': 'Adam'}
-> 정확도: 94.30%
시도 3/10: {'learning_rate': 0.01, 'batch_size': 32, 'optimizer': 'Adam'}
-> 정확도: 92.79%
시도 4/10: {'learning_rate': 0.0001, 'batch_size': 128, 'optimizer': 'Adam'}
-> 정확도: 93.07%
시도 5/10: {'learning_rate': 0.0001, 'batch_size': 64, 'optimizer': 'Adam'}
-> 정확도: 93.72%
시도 6/10: {'learning_rate': 0.01, 'batch_size': 32, 'optimizer': 'Adam'}
-> 정확도: 93.64%
시도 7/10: {'learning_rate': 0.01, 'batch_size': 128, 'optimizer': 'Adam'}
-> 정확도: 94.84%
...
--- 탐색 완료 ---
최고 정확도: 95.09%
최적 파라미터: {'learning_rate': 0.0001, 'batch_size': 32, 'optimizer': 'Adam'}
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...'AI > DeepLearning' 카테고리의 다른 글
| 오버피팅, 가중치 감소, 드롭아웃 (0) | 2025.11.14 |
|---|---|
| 배치 정규화 Batch Normalization + Pytorch 실습 (0) | 2025.11.13 |
| 신경망 학습에서 초기 가중치 설정 (0) | 2025.11.13 |
| SGD, Momentum, AdaGrad, RMSprop, Adam (0) | 2025.11.09 |
| 활성화 함수 계층 기본 구현 정리 (0) | 2025.11.09 |