私は、TensorFlowを割とよく使っていますが、PyTorch最近やってみたいと思って勉強し始めました。新しいライブラリを身に着けようとするとまずはわかりやすい事例の解釈から始めるのが基本だと思います。深層学習の場合は、やっぱり簡単な畳み込みネットワークから始めるのがいいと思います。PyTorchのTutorialページでLeNetというモデルの実装があるのでそれを使ってみて勉強を始めました。(https://pytorch.org/tutorials/beginner/blitz/neural_networks_tutorial.html#sphx-glr-beginner-blitz-neural-networks-tutorial-py)
ただ、途中で各層はどのようにデータを処理しているや出力の形などを確認したくなるので単純にセットアップして回すだけでなんかもの足りないですね。天才開発者だったらnn.Conv2の設定をみて32x32がどのように処理されるの頭の中でイメージできるかもしれませんが、僕は天才じゃないのでどうしても中間の形を見たくなります。
他のもっと効率いい方法はあるかもしれませんが、僕はこの方法で確認しています。説明のためPyTorchのnn.Conv2d層を使います。まず、ipythonを開きます。そして必要なライブラリをインポートします。
import torch # PyTorchをインポート
import torch.nn as nn # conv2dが存在する
その後は、nn.Conv2dを定義します。このconv2dの設定は、上記話したLeNetの最初の層です。
# 入力は1つのチャネル、出力は6つのチャネル、カーネルは3x3
conv1 = nn.Conv2d(1, 6, 3)
そうして想定している入力のダミーデータを作成します。LeNetの入力は 32x32 なのでそのディメンションで作成します。後は、黒白の画像なはずなのでチャネルは一つだけです。
# 1つの画像 (batch_size = 1), 1つのチャネル、32x32のイメージ
x = torch.randn(1, 1, 32, 32)
層を定義してダミーデータを作成しましたので、後はにデータを層に渡すだけです。
x = conv1(x)
Conv2dドキュメンテーションにあるShapeの出力サイズ (Hout, Wout) の関数はこれです。(https://pytorch.org/docs/master/generated/torch.nn.Conv2d.html)
少し複雑に見えるかもしれませんが、HinとWinは入力する際の縦と横のサイズです (32x32)。今回はPaddingを使ってないので 0 です。ドキュメンテーションで確認するとdilationとstrideを設定しないと 1 になります。Kernelサイズは上記のConv2dを設定した時に 3x3 にしましたので kernel_size[0] と kernel_size[1] はどちらも 3 です。
全部関数にいればこうなります:
H = ((32 + 0 - 1 x (3 - 1) - 1) / 1) + 1 = ((32 - 3) / 1) + 1 = 30
W = ((32 + 0 - 1 x (3 - 1) - 1) / 1) + 1 = ((32 - 3) / 1) + 1 = 30
この計算によると私たちが想定している出力の形は (1, 6, 30, 30) です。30, 30 は先計算した HoutとWoutです。6はConv2で設定した出力チャネル数です。そして、一つのイメージしか入力してないので、出力も一つだけです。
出力の形Shapeプロパティーを呼ぶと確認できます。確かに上記の計算は正解でした。
x.shape # (1, 6, 30, 30)
この方法は、Conv2dに限られてなくて基本的にどの層でも試せます。例えばLeNetでConv2dの後にくるmax_pool2dの出力も同じように確認できます。各層で何が起こっているか確認したい時に役に立ちます。