파이토치 라이트닝 모듈 클래스에는 self.save_hyperparameter
이라는 메서드가 있다. 이 메서드를 사용하면 self.hparams
라는 변수에 NameSpace
가 할당된다. NameSpace
는 쉽게 말해 딕셔너리인데, 원소에 접근할 때 dict[’key’]
와 같은 방식 대신 dict.key
와 같은 방식으로 접근할 수 있음을 의미한다.
self.save_hyperparameter
이 좋은 이유는 일관된 방식으로 하이퍼파라미터를 관리할 수 있기 때문이다. 여기에 값을 잘 저장해 둔다면 체크포인트를 다시 불러올 때 하이퍼파라미터도 알아서 불러와지도록 만들 수 있다는 것도 장점이다(ref2). 이 글에서는 체크포인트 관련 내용을 다루지 않는다. 파이토치 라이트닝 로거 백엔드로 사용될 수 있는 텐서보드에 이 하이퍼파라미터를 어떻게 엮을 수 있는지를 설명할 것이다.
wandb 를 사용하던 나는 최근 회사 일을 하면서 라이선스 문제 때문에 텐서보드를 반 강제로 사용하는 중이다. wandb 가 특히 강점을 보이는 기능들 중 하나는 하이퍼파라미터별로 metric 을 쉽게 비교할 수 있다는 것이다. wandb 를 사용하지 못하는 상황에서 텐서보드로 시각화를 더 잘 할 방법은 없나 알아보던 중 HPARAMS
기능이 비슷한 역할을 수행함을 알게 되었다.
텐서보드에 HPARAMS
를 등록하기 위해서는 어떤 하이퍼파라미터를 추적할 것인지, 하이퍼파라미터를 어떤 메트릭과 함께 추적할 것인지에 대한 정보가 모두 필요하다. 텐서보드에 값을 쓰는 방식은 self.logger.log_hyperparams
메서드를 통해 수행된다(ref3). 어떤 파라미터를 어떤 메트릭과 엮을 것인지는 모델 학습 사이클에서 처음 한 번만 등록하면 되는 경우가 대부분이다. 따라서 나는 on_fit_start
단계에서 실행되도록 만들었다. 예시 코드는 아래와 같다.
def on_fit_start(self):
super().on_fit_start()
self.logger.log_hyperparams(
params=self.hparams,
metrics={'메트릭a': 0, '메트릭b': 0},
)
처음에는 위와 같이 그냥 0으로 적어 초기화한다. 이 메트릭들은 추후 아래와 같이 self.log
을 사용해서 training_step
, validation_step
등의 훅에서 업데이트하기만 하면 된다.
self.log('메트릭a', a)
self.log('메트릭b', b)
이때 주의해야 할 점을 알아두면 삽질을 줄일 수 있다.
hparams.yaml
파일로 저장되었음에도 하이퍼파라미터를 등록할 때 metric 을 지정하지 않으면 하이퍼파라미터를 찾을 수 없다고 나온다. 텐서보드는 이 파일이 없다고 하는 것이 아니라 연결된 메트릭이 없다고 하는 것이다. 이 오류 메시지는 나중에 개선될 것이라고 한다(ref1).parse me : 언젠가 이 글에 쓰이면 좋을 것 같은 재료을 보관해 두는 영역입니다.
None
from : 과거의 어떤 원자적 생각이 이 생각을 만들었는지 연결하고 설명합니다.
supplementary : 어떤 새로운 생각이 이 문서에 작성된 생각을 뒷받침하는지 연결합니다.