公式Tutorialに学ぶPyTorch②(Neural Network)|DeepLearningの実装 #10

f:id:lib-arts:20190620151942p:plain

 

連載経緯は#1をご確認ください。

#1はKeras、#2~#7まではTensorFLow、#8からはPyTorchを取り扱っています。

#8ではPyTorchの概要やインストール、簡易実行について、#9はAutogradについて取り扱いました。
https://lib-arts.hatenablog.com/entry/implement_dl8
https://lib-arts.hatenablog.com/entry/implement_dl9
#10では引き続き"Deep Learning with PyTorch: A 60 Minute Blitz"より"Neural Network"について取り扱います。

Neural Networks — PyTorch Tutorials 1.1.0 documentation

以下目次になります。
1. Neural Networkチュートリアルについて
2. 詳細の内容
2-1. Define the network
2-2. Loss Function
2-3. Backprop
2-4. Update the weights
3. まとめ


1. Neural Networkチュートリアルについて
1節ではNeural Networkチュートリアルについて話を進めていきます。

f:id:lib-arts:20190620200734p:plain

Neural Networks — PyTorch Tutorials 1.1.0 documentation

まずはページの概要を知るにあたって冒頭部を要約します。
要約:『torch.nnパッケージを用いることでNeural Networkを構築することができます。nnはモデルの定義(define models)やその微分(differentiate)にあたってautogradに依存しています。nn.Moduleはlayerの情報や、出力(output)を返すforward(input)のメソッドが実装されています。例えば、図のような形式でデジタル画像を分類することができます。』

f:id:lib-arts:20190620201357p:plain
もう少し詳しく見ておく方が良さそうなので、上記も要約します。
要約:『図で説明されているのはシンプルなfeed-fowardネットワークで、何層かの計算を経て最終的にアウトプットを出力しています。ニューラルネットワークの学習手順(training procedure)は下記のようになります。
① 学習可能なパラメータ(重み)を持つニューラルネットワークを定義する
② 入力のデータセットに関して繰り返し(Iterate)処理を行う
③ ネットワークにおいて入力を計算する(process)
④ 出力結果がどのくらい正解と異なっているかを表す誤差関数(loss)を計算する
⑤ ネットワークのパラメータに対して誤差逆伝播を実行する
⑥ "weight = weight - learning_rate * gradient"のようなシンプルなアップデートのルールを用いてネットワークの重みをアップデートする』
これらはニューラルネットワークの学習にあたっての一連の流れについて言及されているので、さほど難しくなさそうです。
ここまでで、Neural Networkチュートリアルで取り扱う話については把握ができたので、2節で実際に詳細について見ていきます。


2. 詳細の内容
2-1. Define the network
2-1節ではDefine the networkについて取り扱っていきます。これは1節で言及したtraining procedureの①にあたっています。早速下記を動かしてみましょう。

f:id:lib-arts:20190620203540p:plain
(中略)

f:id:lib-arts:20190620203557p:plain
実行結果は下記のようになります。

f:id:lib-arts:20190620203642p:plain
ニューラルネットワークのクラスをtorch.nn.Moduleを継承して作成し、__init__関数のところで演算を定義しています。上記ではnetをprintすることで、演算の中身を確認することができます。

f:id:lib-arts:20190620203856p:plain
また、__init__関数のところで作成した演算を用いて、forwardメソッドにおいて入力から出力までの演算が記述されています。

f:id:lib-arts:20190620204518p:plain
上記のように補足説明があるのでこちらも簡単に要約します。
要約:『"forward"関数は必ず定義しなければならないですが、勾配を計算する"backward"関数はautogradを用いることで自動的に定義することができます。"forward"関数の中では任意のTensor演算を行うことができます。モデルの学習可能なパラメータはnet.parametersによって返すことができます。』

f:id:lib-arts:20190620205210p:plain
上記のように実行することで、モデルのパラメータの中身を確認することができます。

f:id:lib-arts:20190620205558p:plain
また、2-2節以降で使うので上記を実行しておきます。データはランダムに作成していますが、MNISTデータを意識して32×32のサイズのデータが生成されています。


2-2. Loss Function
2-2節ではLoss Function部分について確認していきます。

f:id:lib-arts:20190620205830p:plain

まずは冒頭を簡単に要約します。
要約:『誤差関数(loss function)は(予測値(output),実測値(target))のペアを入力とし、予測した値が目的となる実測の値とどのくらい異なっているかについて計算を行います。nnパッケージにはいくつかのloss functionについて実装されています。中でもシンプルな例としては、予測値とターゲットデータの間の平均二乗誤差を計算するnn.MSELossが挙げられます。』
実際にlossを計算すると下記のようになります。

f:id:lib-arts:20190620210513p:plain


2-3. Backprop
2-3節ではBackprop部分について確認を行なっていきます。

f:id:lib-arts:20190620210709p:plain
まずは冒頭を簡単に要約します。
要約:『誤差逆伝播(backpropagate the error)を行うにあたって我々がすべきことは"loss.backward()"を実行することです。』
loss.backward()を実際に動かすと下記のようになります。

f:id:lib-arts:20190620211217p:plain
ここではconv1層のバイアスの勾配を確認しています。


2-4. Update the weights
2-4節では"Update the weights"について確認を行います。

f:id:lib-arts:20190620211636p:plain
まずは簡単に説明部分を要約します。
要約:『実際に用いられる最もシンプルなパラメータ更新(update)のルールは確率的勾配降下法(SGD; Stochastic Gradient Descent)を用いています。図の3行のコードを書くことで、シンプルなPythonコードを用いて実装することができます。しかしながら、AdamやRMSPropなど様々な最適化手法を用いたい時もあると思われるので、"torch.optim"にそれらのメソッドについて実装しました。これらを用いることで、とてもシンプルに最適化の実装を行うことができます。』
実際にチュートリアルのコードを写したのが下記です。

f:id:lib-arts:20190620212157p:plain

上記ではoptimizer.step()を用いて一ステップ分のアップデートを行なっています。


3. まとめ
#10ではニューラルネットワークの実装についてのチュートリアルを確認しました。
#11では引き続き次のチュートリアルである"Training a Classifier"について取り扱います。