Pytorch LightningのNeptuneLoggerでfoldごとにlogを分ける
やりたいこと
Pytorch LightningのNeptuneLoggerで,closs validationのfoldごとに学習曲線などのlogを分けてloggingしたい
背景
TensorBoardLoggerでは,versionという引数の設定で,
If version is not specified the logger inspects the save directory for existing versions, then automatically assigns the next available version.
とあるように,自動でバージョンがインクリメントされるようになっており,これで実質的にfoldごとにlogが分かれて保存されることになる。
しかしNeptuneLoggerではversionの引数はなく,TensorBoardLoggerと同じような使い方をすると,全てのfoldが一つのグラフになってloggingされてしまう。
そこで,foldごとに別の学習曲線のグラフに分かれるようにしたい。
やり方
from pytorch_lightning import Trainer
from pytorch_lightning.loggers import NeptuneLogger
# create NeptuneLogger
neptune_logger = NeptuneLogger(
api_key="ANONYMOUS", # replace with your own
project="common/pytorch-lightning-integration", # "<WORKSPACE/PROJECT>"
tags=["training", "resnet"], # optional
)
neptune_logger.log_hyperparams(config)
for fold, (train_idx, val_idx) in enumerate(splits):
# change prefix
neptune_logger._prefix = f"fold_{fold}"
# pass it to the Trainer
trainer = Trainer(max_epochs=10, logger=neptune_logger)
# run training
trainer.fit(my_model, my_dataloader)
NeptuneLoggerのコンストラクタでは,prefixのデフォルトに'training'が設定されている。
この状態でlog_hyperparamsを呼び出し,training配下にhyperparamsを設定する。
その後,各foldごとにNeptuneLoggerのインスタンス変数であるneptune_logger._prefixを直接書き換える事により,fold_x配下にfoldごとの学習曲線などをloggingできるようになる。
ただし,neptune_logger._prefixはPEP8で“内部でだけ使う”ことを示す_single_leading_underscoreにあたるため,本来は外部からアクセスしてはいけないので,他にいいやり方があるはず。
ハマったこと
NeptuneLoggerのインスタンス変数experimentはNeptuneのrun objectであり,NeptuneLoggerのコンストラクタにはNeptuneのrun objectを受け取る引数であるrunがあるため,closs validationの外でインスタンス化したloggerのexperimentを各fold内で新たにインスタンス化したNeptuneLoggerのrunに設定すればいいと思ったのだが,
ValueError: When an already initialized run object is provided you can't provide other neptune.init() parameters.
と出てしまい,新たにfoldのNeptuneLoggerをインスタンス化することができなかった。
参考
Discussion