PyTorch メモ

# About PyTorch

テンソル計算とニューラルネットワークのためのPythonライブラリ。([公式](https://pytorch.org/))

# autograd

* ドキュメント
  - [(公式チュートリアル) AUTOGRAD: AUTOMATIC DIFFERENTIATION](https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html)
  - [(公式doc) AUTOMATIC DIFFERENTIATION PACKAGE - TORCH.AUTOGRAD](https://pytorch.org/docs/stable/autograd.html)

* [`backward()`](https://pytorch.org/docs/stable/autograd.html#torch.autograd.backward), [`tensor.backward()`](https://pytorch.org/docs/stable/autograd.html#torch.Tensor.backward)で、各パラメタのgradientを計算する。
  - [ただ計算して各パラメタのgradientに加算していくだけで、各パラメタの値は更新しない](https://discuss.pytorch.org/t/how-are-optimizer-step-and-loss-backward-related/7350/2)。
  - 計算のたびに加算していくので、最初に[`zero_grad()`](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer.zero_grad)で[ゼロリセットしておく必要がある](https://stackoverflow.com/a/48009142)。

* [`optimizer.step()`](https://pytorch.org/docs/stable/optim.html#taking-an-optimization-step)で、各パラメタの値を更新する。
  - `backward()`実行後に[`optimizer.step()`](https://pytorch.org/docs/stable/optim.html#taking-an-optimization-step)を実行すると、計算済gradientを使って、[**optimizerが担当するパラメタのみ**更新する](https://twitter.com/pytorch/status/1006917257228779520)。
  - いくらgradientを計算しようと、optimizerの対象にして`step()`しないと値は変わらない。
  - モデルの一部のみ更新したければ、一部のパラメタのみをoptimizerに渡せば良い。([1](https://discuss.pytorch.org/t/should-i-use-model-eval-when-i-freeze-batchnorm-layers-to-finetune/39495/3), [2](https://discuss.pytorch.org/t/should-i-use-model-eval-when-i-freeze-batchnorm-layers-to-finetune/39495/4))
  - モデルをfreezeしたければ、単にoptimizer.step()をそのモデルに対して実行しなければ良い。
  - [`module.eval()`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module.eval)はbatch normやdropoutなどの一部moduleでのみ意味があり、[freezingとは無関係](https://twitter.com/pytorch/status/1006917257228779520)。
     - とはいえ、基本freezeするときは`eval()`モードにするのが無難だと思う。

* [`requires_grad = False`](https://pytorch.org/docs/stable/notes/autograd.html)で、不要なgradient計算を省く。
  - [`autograd.no_grad`](https://pytorch.org/docs/stable/autograd.html#torch.autograd.no_grad), [`autograd.set_grad_enabled`](https://pytorch.org/docs/stable/autograd.html#torch.autograd.set_grad_enabled), [`requires_grad = False`](https://pytorch.org/docs/stable/notes/autograd.html)を設定するのは、`backward()`する気がない場合に[余計な計算をしないようにするため](https://pytorch.org/docs/stable/autograd.html#torch.autograd.no_grad)。
  - freeze時など、gradient計算が不要と分かっている場合はできるだけ設定する。

* `detach`, `clone`
  - [(PyTorch Forum) Detach, no_grad and requires_grad](https://discuss.pytorch.org/t/detach-no-grad-and-requires-grad/16915/14)
  - [(PyTorch Forum) Clone and detach in v0.4.0](https://discuss.pytorch.org/t/clone-and-detach-in-v0-4-0/16861/2)
  - [(PyTorch Forum) Difference between detach().clone() and clone().detach()](https://discuss.pytorch.org/t/difference-between-detach-clone-and-clone-detach/34173)
     * 結果は同じなので、`detach().clone()`の方が余計な情報をコピーしなくて済むよ、とのこと。

# 学習の可視化

* TensorBoard
  - [公式doc](https://pytorch.org/docs/stable/tensorboard.html)
  - [公式チュートリアル](https://pytorch.org/tutorials/intermediate/tensorboard_tutorial.html)
  - [tensorboardX](https://github.com/lanpa/tensorboardX)

* Visdom
  - [Github repo](https://github.com/facebookresearch/visdom)

# 最後に

ほぼ自分用メモで、未完成で、まとまっていませんが、間違い等あればご指摘いただければとても有難いです。