Mugichoko's blog

Mugichoko’s blog

しがない研究者のプログラミングを中心としたメモ書き.

今更PyTorchマスターへの道 (2) - 基本操作とAutograd

Docker環境を構築した前回の続き.とりあえず,Python Engineerさんのチュートリアルを通してPyTorchを動かしてみます.

目標

Python Engineer / PyTorch BeginnerシリーズからTutorialをいくつかやっていく.

Dockerコンテナ内のファイルへのアクセス

まずは下準備.仮想環境のDockerコンテナ上にあるファイルにWindows側からアクセスするために,OpenSSHでも使おうかと思ったのですが,ちょっと面倒そう... とりあえずは,ドライブをマウントしてFile Exploreからアクセスする戦法でいきます.

下記の例では,Windows上のD:/DockerData/ubuntu18_cudaフォルダとDockerコンテナでのhomeを紐づけています.なので,home内に置いたファイルをWindows上から直接編集できます.

docker run --gpus all -it --name ubuntu18_cuda -v D:/DockerData/ubuntu18_cuda:/home/ nvidia/cuda:10.2-devel-ubuntu18.04 bash
# その後は docker exec -it ubuntu18_cuda bash

Tutorial 02

Tensor Basics - PyTorch Beginner 02

Tutorial 03

Autograd - PyTorch Beginner 03

  • auto_grad = Trueに設定したtensorはその後に行われる計算が全て計算グラフ (Computational Graph) に保存される(トラッキングされる)様子
  • これによって誤差逆伝搬 (Back Propagation) が行われるっぽい
x = torch.randn(3, requires_grad=True)
y = x + 2
z = y * y * 3
z = z.mean()
  • 上記の計算をして,それぞれの変数を出力してみると以下のようにトラッキングされていることが分かる
    • AddBackward0MeanBackward0に注目!
x: tensor([ 0.7531, -1.5306, -0.5860], requires_grad=True)
y: tensor([2.7531, 0.4694, 1.4140], grad_fn=<AddBackward0>)
z: tensor(9.7995, grad_fn=<MeanBackward0>)
  • 誤差逆伝搬 (Back propagation) は最終的に計算したtensorに対して.backward()
  • 求まった勾配ベクトルは最初のtensor.gradに入っている
  • PyTorch / torch.autogradが連鎖律を使って偏微分を行ってくれる
  • 偏微分値は蓄積されるので,学習などでループする際には,各ループの最後でこれをゼロにする必要あり
import torch

weights = torch.ones(4, requires_grad=True)
for epoch in range(3):
    model_output = (weights*3).sum()
    model_output.backward()
    print(weights.grad)
    # weights.grad.zero_()
  • 4次元ベクトルweightsの各要素の偏微分は3となり(5行目の式に注目)
  • コメントアウト部分のままだと,3回のループで蓄積されるとのこと
    • この蓄積が起きる原因は連鎖律を実行(各連鎖での結果を蓄積)するための仕様か?
  • これを各ループで0にリセットする
# コメントアウトのままの状態で実行
tensor([3., 3., 3., 3.])
tensor([6., 6., 6., 6.])
tensor([9., 9., 9., 9.])
# コメントアウトの部分を入れた状態で実行
tensor([3., 3., 3., 3.])
tensor([3., 3., 3., 3.])
tensor([3., 3., 3., 3.])