2019-07-11こしあんTweetPocket学習率の調整は大事です。エポック後に学習率を減衰させる際、現在のエポックを引数として更新後の学習率を返す関数を与えると便利なことが多いです。この操作はKeras,PyTorchどちらでもできますが、扱い方が微妙に違うところがあります。ここを知らないでKerasの感覚のままPyTorchでやったらハマりまくったのでメモとして書いておきます。目次Kerasの場合は「更新後の学習率」を返すPyTorchの場合は「ベースの学習率に対する倍率」を返すまとめKerasの場合は「更新後の学習率」を返すKerasの場合はわかりやすいです。エポックを引数として、更新後の学習率をそのまま返す関数を用意すればよいです。以下のコードの場合は「lr_scheduler」という関数ですね。train()これはMNIST+多層パーセプトロンの例です。PrintCallbackというコールバックで現在の学習率を確認しています。確認用なので大した意味はないです。学習率は初期を1e-3として、最終的にほぼ0になるように線形で落としています。10エポック訓練させます。出力は次のようになります。9.9999e-05うまくいきました。Kerasの場合は更新後の学習率を返せばいいです。PyTorchの場合は「ベースの学習率に対する倍率」を返す似たようなことはPyTorchのLambdaLRを使えばいいですが、こちらはベースの学習率に対する倍率を指定します。Kerasのように更新後の学習率をダイレクト指定ではないです。train()ベースの学習率とはオプティマイザを定義したときに与えたlrの値です。ここでは1e-3です。lr_schedulingという関数に注目しましょう。ここで初期学習率の値は一切でていません。いうとPyTorchのソースを見てみましょう。LambdaLRの実際に更新後の学習率を取得する部分です。self.base_lrs)]「self.base_lrs」には学習率更新の関数のリストが記録されています。ベースの学習率に対する比ですよね。実際最初に出したコードの出力を確認すると次のようになります。0.017641670887172223正しく学習率が更新されているのが確認できます。LambdaLRでKerasの感覚で実際の学習率を返してしまうと、学習率が2乗されてしまい、学習率がものすごく低くなってしまいます。勾配が消失しているように見えますが、これは勾配消失ではなく、ただ単に学習率のスケジューリングが正常に動作していないというだけです。ここ知らなくてハマりました。Commentコメントをキャンセルメールアドレスが公開されることはありません。