이 블로그글은 2019년 조재영(Kevin Jo), 김승수(SeungSu Kim)님의 딥러닝 홀로서기 세미나를 수강하고 작성한 글임을 밝힙니다.
→ Adam은 기본적으로 RMSprop보다 낮은 학습률을 사용한다. Adam은 학습률 변화에 더 민감하기 때문에, RMSprop보다 상대적으로 더 낮은 학습률을 설정하는 경우가 많다.
하드 보팅 (Hard Voting)
from collections import Counter
def hard_voting_ensemble(net_list, partition, args):
# 테스트 데이터 로더 생성
testloader = torch.utils.data.DataLoader(partition['test'],
batch_size=args.test_batch_size,
shuffle=False, num_workers=2)
correct = 0
total = 0
with torch.no_grad():
for images, labels in testloader:
images, labels = images.cuda(), labels.cuda()
# 모델들의 예측값을 저장할 리스트 초기화
predictions_list = []
# 각 모델의 예측값 수집
for net in net_list:
net.eval() # 모델을 평가 모드로 전환
outputs = net(images) # 모델의 출력 계산
predictions = outputs.argmax(dim=1) # 최종 클래스 예측
predictions_list.append(predictions.cpu().numpy()) # CPU로 이동 후 리스트에 저장
# 다수결(majority voting)로 최종 예측 계산
final_predictions = torch.tensor([
Counter(predictions).most_common(1)[0][0] for predictions in zip(*predictions_list)
]).cuda()
# 정확도 계산
correct += (final_predictions == labels).sum().item()
total += labels.size(0)
# 최종 앙상블 정확도 계산
test_acc = 100 * correct / total
print(f"Hard Voting Ensemble test accuracy: {test_acc:.2f}%")
return test_acc
소프트 보팅 (Soft Voting)
def soft_voting_ensemble(net_list, partition, args):
testloader = torch.utils.data.DataLoader(partition['test'],
batch_size=args.test_batch_size,
shuffle=False, num_workers=2)
correct = 0
total = 0
with torch.no_grad(): # 그래디언트 계산 비활성화 (평가 모드)
for images, labels in testloader:
images, labels = images.cuda(), labels.cuda()
# 앙상블 예측을 위한 확률 텐서 초기화
ensemble_probs = torch.zeros(images.size(0), num_classes).cuda()
# 모든 모델에서 softmax 확률 수집
for net in net_list:
net.eval() # 모델을 평가 모드로 전환
outputs = net(images) # 모델의 출력 계산
probabilities = torch.nn.functional.softmax(outputs, dim=1) # softmax 확률 계산
ensemble_probs += probabilities # 확률 누적
# 모델 간 확률 평균화
ensemble_probs /= len(net_list)
# 평균 확률 중 가장 높은 값을 가진 클래스 선택
final_predictions = ensemble_probs.argmax(dim=1)
# 정확도 계산 업데이트
correct += (final_predictions == labels).sum().item()
total += labels.size(0)
# 최종 앙상블 정확도 계산
test_acc = 100 * correct / total
print(f"Ensemble test accuracy: {test_acc:.2f}%")
return test_acc
특징 | 소프트 보팅 (Soft Voting) | 하드 보팅 (Hard Voting) |
---|---|---|
기본 원리 | 클래스 확률 평균화 | 다수결(최빈값) |
정교함 | 확률 정보를 활용하므로 더 정교 | 확률 정보를 사용하지 않음 |
성능 | 일반적으로 더 나은 성능 | 간단한 문제에서 적합 |
확률 정보 필요 여부 | 필요 | 필요 없음 |
StepLR (스텝 학습률 감소)
from torch.optim.lr_scheduler import StepLR
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
for epoch in range(100):
train(model, optimizer)
scheduler.step()
step_size
: 학습률을 감소시킬 주기.gamma
: 학습률 감소 비율 (0.1이면 학습률을 0.1배로 감소)ExponentialLR (지수 학습률 감소)
from torch.optim.lr_scheduler import ExponentialLR
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
scheduler = ExponentialLR(optimizer, gamma=0.95)
for epoch in range(100):
train(model, optimizer)
scheduler.step()
gamma
: 매 에폭마다 학습률을 곱할 비율(0.95
이면 매 에폭마다 학습률이 95%로 감소)ReduceLROnPlateau (성능 향상 없음 시 학습률 감소)
from torch.optim.lr_scheduler import ReduceLROnPlateau
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
scheduler = ReduceLROnPlateau(optimizer, 'min', patience=5, factor=0.1)
for epoch in range(100):
train(model, optimizer)
val_loss = validate(model)
scheduler.step(val_loss)
mode
: 지표의 변화 방향을 지정하는 것patience
: 성능 향상이 없는 에폭 수factor
: 학습률 감소 비율 (0.1이면 성능 향상이 없을 때 학습률을 0.1배로 감소)스케줄러 이름 | 설명 | 주요 파라미터 | 장점 | 단점 |
---|---|---|---|---|
StepLR | 일정 에폭마다 학습률을 고정 비율로 감소시킴 | step_size (학습률 감소 주기), gamma (감소 비율) | 구현이 간단하고, 과적합을 방지하는 데 유용 | 학습률 감소 시점을 정확히 조절하기 어려움 |
ExponentialLR | 매 에폭마다 학습률을 지수적으로 감소시킴 | gamma (학습률 감소 비율) | 점진적인 학습률 감소로 후반에 정밀 학습 가능 | 학습률이 너무 빨리 감소하면 학습이 멈출 수 있음 |
ReduceLROnPlateau | 성능 향상이 없을 때 학습률을 감소시킴 | mode , patience , factor | 성능 향상이 없을 때만 학습률 감소 | 너무 자주 감소할 수 있음, 성능 향상 판별 어려움 |