konchangakita

Xi IoTを一番楽しんでるブログ 会社の看板を背負いません 転載はご自由にどうぞ

PyTorchを使ったDeep Learningのお勉強 TensorBoard編

※基本的に独学なのでちょいちょい間違っているかもしれません、怪しいところあればご指摘くださいまし

PyTorch / pytorch_lightning を使った学習はめっちゃシンプル化されます
ただ前回までのそのまんまではあまりにシンプルであっという間に結果が出力されて、学習の過程が見れないので可視化に取り組んでみます

PyTorch お勉強シリーズ
第1回 PyTorchを使ってDeep Learningのお勉強 基礎編
第2回 PyTorchを使ったDeep Learningのお勉強 PyTorch Lightning編
第3回 PyTorchを使ったDeep Learningのお勉強 TensorBoard編(イマココ)
第4回 PyTorchを使ったDeep Learningのお勉強 画像認識編(MNIST)


Pytorch でも TensorFlow でお馴染みな TensorBoard が使えるとのことで、その実験過程をご紹介

まずは

TensorBoad のインストール

自分の anaconda 環境には、デフォルトなのか PyTorchをインストールした時か tensorboard がインストールされていました
f:id:konchangakita:20200426145729p:plain

インストールされていなかった場合は、JupyterLab を開いて

conda install tensorboard 

で、インストールです
f:id:konchangakita:20200426150005p:plain

TensorBoard の実行は、同じくコマンドラインから

tensorboard --dir="ログの場所"

TensorBoard でグラフを表示するためには、TensorBoard 用にログを出力してやる必要あります

TensorBoard 用のログ出力

学習クラス、検証クラスの結果の返り値に 'log' に値を格納してやるとよいみたいです
(ソース読もうとしたけど挫折した)

学習用クラスと検証用クラスそれぞれに、"accuracy"(正解率)と"loss"(損失関数の結果)を出力させてやります

# 学習データ用クラス
class TrainNet(pl.LightningModule):
    
    @pl.data_loader
    def train_dataloader(self):
        return torch.utils.data.DataLoader(train, self.batch_size, shuffle=True)
    
    def training_step(self, batch, batch_nb):
        x, t = batch
        y = self.forward(x)
        loss = self.lossfun(y, t)
        y_label = torch.argmax(y, dim=1)
        acc = torch.sum(t == y_label) * 1.0 / len(t)

        # *new*
        tensorboard_logs = {'train/train_loss': loss, 'train/train_acc': acc} # tensorboard
        results = {'loss': loss, 'log': tensorboard_logs}
        
        return results
# 検証データ用クラス
class ValidationNet(pl.LightningModule):

    @pl.data_loader
    def val_dataloader(self):
        return torch.utils.data.DataLoader(val, self.batch_size)

    def validation_step(self, batch, batch_nb):
        x, t = batch
        y = self.forward(x)
        loss = self.lossfun(y, t)
        y_label = torch.argmax(y, dim=1)
        acc = torch.sum(t == y_label) * 1.0 / len(t)
        results = {'val_loss': loss, 'val_acc': acc}
        return results

    def validation_end(self, outputs):
        avg_loss = torch.stack([x['val_loss'] for x in outputs]).mean()
        avg_acc = torch.stack([x['val_acc'] for x in outputs]).mean()

        # *new*
        tensorboard_logs = {'val/avg_loss': avg_loss, 'val/avg_acc': avg_acc}
        results = {'val_loss': avg_loss, 'val_acc': avg_acc, 'log': tensorboard_logs}

        return results

こんな感じで、出力したい log を 'タグ名/ログ名' で return してやります
早速実行してみる

# 学習に関する一連の流れを実行
net = Net()
trainer = Trainer(max_epochs=20)
trainer.fit(net)

次に Tensorboard を起動しましょう
別のコンソール(JupyterLabでOK)で、下記を実行しましょう
(pytorch_lightningはデフォルトで ./lightning_logs にログフォルダ作られます)

PS C:\Users\xxx> tensorboard.exe --logdir="ログの場所\lightning_logs"

f:id:konchangakita:20200426212043p:plain


起動後、ブラウザで http://localhost:6006/ にアクセスしてみましょう
f:id:konchangakita:20200426212116p:plain

学習が進んでいっている状況が可視化されました!
matplotlib でポチポチやっていくことを考えると、こんなに簡単でちょっと感動

Tagの説明

logを格納する時に、train/train_loss、 train/train_acc のように タグ名/グラフタイトル としておけば、タグ名でまとめて表示してくれます
f:id:konchangakita:20200427214150p:plain:w400


これはホンマにラクチンになるので、Deep Leaningのお勉強ではこれからも必須なヨカンです
コードの全体像はコチラ


TensorBoard はもっといろいろな表示(画像とか)ができるようなので、継続してお勉強が必要ですね