🔥알림🔥
① 테디노트 유튜브 -
구경하러 가기!
② LangChain 한국어 튜토리얼
바로가기 👀
③ 랭체인 노트 무료 전자책(wikidocs)
바로가기 🙌
④ RAG 비법노트 LangChain 강의오픈
바로가기 🙌
⑤ 서울대 PyTorch 딥러닝 강의
바로가기 🙌
[pytorch] Early Stopping 조기종료 구현 및 적용
조기 종료(Early Stopping)는 학습시 일정기간(여기서 기간은 보통 N번의 Epoch을 기준으로 합니다)동안 Loss 나 Score 기준으로 개선이 일어나지 않으면 학습을 조기에 종료해 주는 기능입니다. 만약, 20번의 Epoch 동안 학습이 진행한다고 가정했을 때, 아래 그림처럼 Epoch=5
이후에 지속해서 Loss가 상승하면서 개선이 안 일어나면 굳이 남은 학습을 지속할 이유가 없습니다.
이럴때 조기종료 기능으로 중간에 N번의 Epoch 동안 개선이 일어나지 않으면 종료해 주면 됩니다. 여기서, “개선이 일어나지 않은 N번의 Epoch” 을 patience
라고 합니다.
조기종료(EarlyStopping) 코드 구현
import numpy as np
class EarlyStopping:
def __init__(self, patience=3, delta=0.0, mode='min', verbose=True):
"""
patience (int): loss or score가 개선된 후 기다리는 기간. default: 3
delta (float): 개선시 인정되는 최소 변화 수치. default: 0.0
mode (str): 개선시 최소/최대값 기준 선정('min' or 'max'). default: 'min'.
verbose (bool): 메시지 출력. default: True
"""
self.early_stop = False
self.patience = patience
self.verbose = verbose
self.counter = 0
self.best_score = np.Inf if mode == 'min' else 0
self.mode = mode
self.delta = delta
def __call__(self, score):
if self.best_score is None:
self.best_score = score
self.counter = 0
elif self.mode == 'min':
if score < (self.best_score - self.delta):
self.counter = 0
self.best_score = score
if self.verbose:
print(f'[EarlyStopping] (Update) Best Score: {self.best_score:.5f}')
else:
self.counter += 1
if self.verbose:
print(f'[EarlyStopping] (Patience) {self.counter}/{self.patience}, ' \
f'Best: {self.best_score:.5f}' \
f', Current: {score:.5f}, Delta: {np.abs(self.best_score - score):.5f}')
elif self.mode == 'max':
if score > (self.best_score + self.delta):
self.counter = 0
self.best_score = score
if self.verbose:
print(f'[EarlyStopping] (Update) Best Score: {self.best_score:.5f}')
else:
self.counter += 1
if self.verbose:
print(f'[EarlyStopping] (Patience) {self.counter}/{self.patience}, ' \
f'Best: {self.best_score:.5f}' \
f', Current: {score:.5f}, Delta: {np.abs(self.best_score - score):.5f}')
if self.counter >= self.patience:
if self.verbose:
print(f'[EarlyStop Triggered] Best Score: {self.best_score:.5f}')
# Early Stop
self.early_stop = True
else:
# Continue
self.early_stop = False
예시 데이터 (Epoch 별 Loss)
losses = [
0.1, # save
0.25, # patience #1
0.33, # patience #2
0.09, # save
0.4, # patience #1
0.08, # save
0.5, # patience #1
0.55, # patience #2
0.6, # patience #3 <== Early Stop
0.05,
0.89,
0.99
]
es = EarlyStopping(patience=3,
delta=0,
mode='min',
verbose=True
)
for loss in losses:
es(loss)
# Early Stop Check
if es.early_stop:
break
[EarlyStopping] (Update) Best Score: 0.10000 [EarlyStopping] (Patience) 1/3, Best: 0.10000, Current: 0.25000, Delta: 0.15000 [EarlyStopping] (Patience) 2/3, Best: 0.10000, Current: 0.33000, Delta: 0.23000 [EarlyStopping] (Update) Best Score: 0.09000 [EarlyStopping] (Patience) 1/3, Best: 0.09000, Current: 0.40000, Delta: 0.31000 [EarlyStopping] (Update) Best Score: 0.08000 [EarlyStopping] (Patience) 1/3, Best: 0.08000, Current: 0.50000, Delta: 0.42000 [EarlyStopping] (Patience) 2/3, Best: 0.08000, Current: 0.55000, Delta: 0.47000 [EarlyStopping] (Patience) 3/3, Best: 0.08000, Current: 0.60000, Delta: 0.52000 [EarlyStop Triggered] Best Score: 0.08000
(옵션) patience
-
loss or score가 개선된 후 기다리는 기간
-
default:
3
예시 데이터 (Epoch 별 Loss)
losses = [
0.1, # save
0.25, # patience #1
0.33, # patience #2
0.09, # save
0.4, # patience #1
0.08, # save
0.5, # patience #1
0.55, # patience #2
0.6, # patience #3
0.05, # save
0.89, # patience #1
0.99 # patience #2
]
기본 사용 방법
es = EarlyStopping(patience=5,
delta=0,
mode='min',
verbose=True
)
Training Loop 안에서 es(loss)
를 실행 후 early_stop
여부를 체크합니다.
for loss in losses:
es(loss)
# Early Stop Check
if es.early_stop:
break
[EarlyStopping] (Update) Best Score: 0.10000 [EarlyStopping] (Patience) 1/5, Best: 0.10000, Current: 0.25000, Delta: 0.15000 [EarlyStopping] (Patience) 2/5, Best: 0.10000, Current: 0.33000, Delta: 0.23000 [EarlyStopping] (Update) Best Score: 0.09000 [EarlyStopping] (Patience) 1/5, Best: 0.09000, Current: 0.40000, Delta: 0.31000 [EarlyStopping] (Update) Best Score: 0.08000 [EarlyStopping] (Patience) 1/5, Best: 0.08000, Current: 0.50000, Delta: 0.42000 [EarlyStopping] (Patience) 2/5, Best: 0.08000, Current: 0.55000, Delta: 0.47000 [EarlyStopping] (Patience) 3/5, Best: 0.08000, Current: 0.60000, Delta: 0.52000 [EarlyStopping] (Update) Best Score: 0.05000 [EarlyStopping] (Patience) 1/5, Best: 0.05000, Current: 0.89000, Delta: 0.84000 [EarlyStopping] (Patience) 2/5, Best: 0.05000, Current: 0.99000, Delta: 0.94000
(옵션) delta
-
개선시 인정되는 최소 변화 수치
-
default:
0.0
예시 데이터 (Epoch 별 Loss)
losses = [
0.1, # save
0.25, # patience #1
0.33, # patience #2
0.09, # 개선은 되었으나 delta=0.02 이상 줄이지 못하였으므로.. Early Stop!
0.4,
0.08,
0.5,
0.55,
0.6,
0.05,
0.89,
0.99
]
es = EarlyStopping(patience=3,
delta=0.02,
mode='min',
verbose=True
)
for loss in losses:
es(loss)
# Early Stop Check
if es.early_stop:
break
[EarlyStopping] (Update) Best Score: 0.10000 [EarlyStopping] (Patience) 1/3, Best: 0.10000, Current: 0.25000, Delta: 0.15000 [EarlyStopping] (Patience) 2/3, Best: 0.10000, Current: 0.33000, Delta: 0.23000 [EarlyStopping] (Patience) 3/3, Best: 0.10000, Current: 0.09000, Delta: 0.01000 [EarlyStop Triggered] Best Score: 0.10000
(옵션) mode
-
개선시 최소/최대값 기준 선정
-
선택 가능 옵션:
'min'
,'max'
-
default:
'min'
Epoch별 Score (예시)
scores = [
0.1, # save
0.25, # save
0.33, # save
0.09, # patience #1
0.4, # save
0.08, # patience #1
0.5, # save
0.55, # save
0.6, # save
0.05, # patience #1
0.89, # save
0.99 # save
]
es = EarlyStopping(patience=3,
delta=0.0,
mode='max',
verbose=True
)
for score in scores:
es(score)
# Early Stop Check
if es.early_stop:
break
[EarlyStopping] (Update) Best Score: 0.10000 [EarlyStopping] (Update) Best Score: 0.25000 [EarlyStopping] (Update) Best Score: 0.33000 [EarlyStopping] (Patience) 1/3, Best: 0.33000, Current: 0.09000, Delta: 0.24000 [EarlyStopping] (Update) Best Score: 0.40000 [EarlyStopping] (Patience) 1/3, Best: 0.40000, Current: 0.08000, Delta: 0.32000 [EarlyStopping] (Update) Best Score: 0.50000 [EarlyStopping] (Update) Best Score: 0.55000 [EarlyStopping] (Update) Best Score: 0.60000 [EarlyStopping] (Patience) 1/3, Best: 0.60000, Current: 0.05000, Delta: 0.55000 [EarlyStopping] (Update) Best Score: 0.89000 [EarlyStopping] (Update) Best Score: 0.99000
댓글남기기