見出し画像

PyTorch - Neural Networks! - 1

このサイトわかりやすいです。

さて、PyTorch 1.5 Tutorialsの3回目のNeural Networksです。

PyTorchで作るニューラルネットワークです。ここで使われているのはいわゆる畳み込みニューラルネットワークです。

ニューラルネットワークのための典型的な訓練手続きは以下のようなものです 
・幾つかの学習可能なパラメータ (or 重み) を持つニューラルネットワークを定義する
・入力のデータセットに渡り反復する
・入力をネットワークを通して処理する
・損失を計算する (出力が正解からどのくらい遠いか)
・勾配をネットワークのパラメータに逆伝播する
・ネットワークの重みを更新する、典型的には単純な更新ルールを使用します  :weight = weight – learning_rate * gradient 

ネットワークの定義です。

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
   def __init__(self):
       super(Net, self).__init__()
      
       self.conv1 = nn.Conv2d(1, 6, 3)
       self.conv2 = nn.Conv2d(6, 16, 3)
       self.fc1 = nn.Linear(16 * 6 * 6, 120) 
       self.fc2 = nn.Linear(120, 84)
       self.fc3 = nn.Linear(84, 10)

   def forward(self, x):
       x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
       x = F.max_pool2d(F.relu(self.conv2(x)), 2)
       x = x.view(-1, self.num_flat_features(x))
       x = F.relu(self.fc1(x))
       x = F.relu(self.fc2(x))
       x = self.fc3(x)
       return x

   def num_flat_features(self, x):
       size = x.size()[1:] 
       num_features = 1
       for s in size:
           num_features *= s
       return num_features

net = Net()
print(net)

Out:

Net(
(conv1): Conv2d(1, 6, kernel_size=(3, 3), stride=(1, 1))
(conv2): Conv2d(6, 16, kernel_size=(3, 3), stride=(1, 1))
(fc1): Linear(in_features=576, out_features=120, bias=True)
(fc2): Linear(in_features=120, out_features=84, bias=True)
(fc3): Linear(in_features=84, out_features=10, bias=True)
)

実際のネットワークは以下の部分です。

def forward(self, x):
       x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
       x = F.max_pool2d(F.relu(self.conv2(x)), 2)
       x = x.view(-1, self.num_flat_features(x))
       x = F.relu(self.fc1(x))
       x = F.relu(self.fc2(x))
       x = self.fc3(x)
       return x

conv1(x)、conv2(x)など"def __init__(self):"で初期化を受けたパラメータにより"ふるい"にかけられます。

データはこの部分で"x"の入力を受け、"x"に結果を入れて出力します。

学習可能なパラメータを確認します。

params = list(net.parameters())
print(len(params))
print(params[0].size()) 

out:

10
torch.Size([6, 1, 3, 3])

ネットワーを作ったので入力します。入力する数字はランダムな数字を作って入れます。

注意ですが

定義しているnet の想定される入力サイズは 32×32 です。MNIST データセット上でこのネットを使用するためには、データセットからの画像を 32×32 にリサイズないとうまくいきません。
input = torch.randn(1,1,32,32)
out = net(input)
print(out)

Out:

tensor([[ 0.0787, 0.0227, -0.0485, -0.1253, 0.0966, 0.1447, 0.0618, 0.0522,
0.0515, 0.0346]], grad_fn=<AddmmBackward>)
ここで4次元のtensorを入力したのでしょうか?
それはこの文面を見ればわかります.

torch.nn only supports mini-batches. The entire torch.nn package only supports inputs that are a mini-batch of samples, and not a single sample.
For example, nn.Conv2d will take in a 4D Tensor of nSamples x nChannels x Height x Width.
If you have a single sample, just use input.unsqueeze(0) to add a fake batch dimension.

つまり, torch.nnはbatch処理しか受け付けないということです.
なので, fakeとして1次元でいいのでbatchの形にしてね, と書いてあります.

torch.randn(1,1,32,32)が4次元になっているのは、

 nn.Conv2d will take in a 4D Tensor of nSamples x nChannels x Height x Width.

ここです。4次元

nSamples x nChannels x Height x Width.

となっています。


この記事が気に入ったらサポートをしてみませんか?