0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初めてのPytorch #ニューラルネットワークの構築

0
Posted at

ニューラルネットワークの構築

ニューラルネットワークとは

データに対して演算を実行するレイヤー、モジュールで構成されています。
torch.nnでニューラルネットワークの構築ができる

FashionMNISTデータセットを利用してニューラルネットワークを構築してみよう

必要なライブラリのインポート

import os
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets, transforms

まず、処理に時間がかかるため実行環境の確認

device = torch.accelerator.current_accelerator().type if torch.accelerator.is_available() else "cpu"
print(f"Using {device} device")

Using mps device

mpsを使用していることを確認

クラス

ニューラルネットワークはnn.Moduleのサブクラス化によって定義される。
__init__でレイヤーの初期化を実施
forward入力されたデータを操作する

class NeuralNetwork(nn.Module):
    def __init__(self):
        super().__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

NeuralNetworkのインスタンスを作成し
to(device)でデバイスでの実行に切りかえる。
→CPUでの実行だと時間がかかるため

model = NeuralNetwork().to(device)
print(model)

NeuralNetwork(
(flatten): Flatten(start_dim=1, end_dim=-1)
(linear_relu_stack): Sequential(
(0): Linear(in_features=784, out_features=512, bias=True)
(1): ReLU()
(2): Linear(in_features=512, out_features=512, bias=True)
(3): ReLU()
(4): Linear(in_features=512, out_features=10, bias=True)
)
)

torch.rand(1, 28, 28, device=device)
→28*28ピクセルのランダムな画像を一枚生成
logits = model(X)
→モデルに画像を取り込む※logitsは10個の数字が入ったデータのようなもの
pred_probab = nn.Softmax(dim=1)(logits)
→バラバラなデータ値を合計で100%に変換
y_pred = pred_probab.argmax(1)
→一番大きな値が入っているものを返す

X = torch.rand(1, 28, 28, device=device)
logits = model(X)
pred_probab = nn.Softmax(dim=1)(logits)
y_pred = pred_probab.argmax(1)
print(f"Predicted class: {y_pred}")

Predicted class: tensor([6], device='mps:0')

モデルレイヤー

28*28ピクセルの画像3枚からミニバッチを作成

input_image = torch.rand(3,28,28)
print(input_image.size())

torch.Size([3, 28, 28])

nn.Flattenを使用し28*28画像を784ピクセルの値の連続配列に変換
→フラット処理

flatten = nn.Flatten()
flat_image = flatten(input_image)
print(flat_image.size())

torch.Size([3, 784])

nn.Linear(in_features=28*28, out_features=20)
→28*28の784データを20個のデータ数に凝縮
layer1(flat_image)
→平坦化されたデータを取り込む

layer1 = nn.Linear(in_features=28*28, out_features=20)
hidden1 = layer1(flat_image)
print(hidden1.size())

torch.Size([3, 20])

nn.ReLuは以下の画像のように0未満は全て0として扱う
ReLU.png

print(f"Before ReLU: {hidden1}\n\n")
hidden1 = nn.ReLU()(hidden1)
print(f"After ReLU: {hidden1}")

Before ReLU: tensor([[-0.0833, -0.0873, -0.3112, 0.0640, 0.1106, 0.1902, 0.1830, 0.2539,
-0.1484, 0.0062, -0.0096, 0.1291, -0.0294, -0.0135, 0.1557, 0.2018,
0.0746, 0.1054, 0.1798, -0.2982],
[-0.1108, -0.0929, -0.3736, 0.0069, 0.1355, 0.1841, 0.2582, 0.2416,
-0.1363, 0.0652, 0.0499, -0.0467, 0.0152, -0.1365, 0.2464, 0.1839,
0.0821, 0.0255, 0.1317, -0.2054],
[ 0.0902, -0.0412, -0.2321, -0.0199, -0.0354, 0.1543, 0.0782, 0.2038,
-0.2241, 0.1196, 0.0558, 0.0124, -0.0048, 0.0214, 0.1170, 0.1462,
0.0751, 0.0632, 0.0855, -0.3060]], grad_fn=)

After ReLU: tensor([[0.0000, 0.0000, 0.0000, 0.0640, 0.1106, 0.1902, 0.1830, 0.2539, 0.0000,
0.0062, 0.0000, 0.1291, 0.0000, 0.0000, 0.1557, 0.2018, 0.0746, 0.1054,
0.1798, 0.0000],
[0.0000, 0.0000, 0.0000, 0.0069, 0.1355, 0.1841, 0.2582, 0.2416, 0.0000,
0.0652, 0.0499, 0.0000, 0.0152, 0.0000, 0.2464, 0.1839, 0.0821, 0.0255,
0.1317, 0.0000],
[0.0902, 0.0000, 0.0000, 0.0000, 0.0000, 0.1543, 0.0782, 0.2038, 0.0000,
0.1196, 0.0558, 0.0124, 0.0000, 0.0214, 0.1170, 0.1462, 0.0751, 0.0632,
0.0855, 0.0000]], grad_fn=)

確かにマイナスの値は0へ変換されておりますね。

nn.Sequentialで定義した順序でニューラルネットワークの構造を通過していく。

seq_modules = nn.Sequential(
    flatten,
    layer1,
    nn.ReLU(),
    nn.Linear(20, 10)
)
input_image = torch.rand(3,28,28)
logits = seq_modules(input_image)

nn.Softmax
→予測確率を0から1で表すモジュール

softmax = nn.Softmax(dim=1)
pred_probab = softmax(logits)

モデルパラメータ

どのような順番、パラメータで処理されているかを確認できる。

print(f"Model structure: {model}\n\n")

for name, param in model.named_parameters():
    print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n")

Model structure: NeuralNetwork(
(flatten): Flatten(start_dim=1, end_dim=-1)
(linear_relu_stack): Sequential(
(0): Linear(in_features=784, out_features=512, bias=True)
(1): ReLU()
(2): Linear(in_features=512, out_features=512, bias=True)
(3): ReLU()
(4): Linear(in_features=512, out_features=10, bias=True)
)
)

Layer: linear_relu_stack.0.weight | Size: torch.Size([512, 784]) | Values : tensor([[-0.0141, 0.0296, 0.0188, ..., -0.0072, -0.0260, 0.0188],
[-0.0080, 0.0066, -0.0264, ..., -0.0011, -0.0103, 0.0216]],
device='mps:0', grad_fn=)

Layer: linear_relu_stack.0.bias | Size: torch.Size([512]) | Values : tensor([-0.0057, 0.0293], device='mps:0', grad_fn=)

Layer: linear_relu_stack.2.weight | Size: torch.Size([512, 512]) | Values : tensor([[-0.0316, -0.0375, 0.0118, ..., 0.0259, -0.0312, -0.0413],
[-0.0374, 0.0159, 0.0280, ..., -0.0438, -0.0147, 0.0140]],
device='mps:0', grad_fn=)

Layer: linear_relu_stack.2.bias | Size: torch.Size([512]) | Values : tensor([ 0.0002, -0.0439], device='mps:0', grad_fn=)

Layer: linear_relu_stack.4.weight | Size: torch.Size([10, 512]) | Values : tensor([[ 0.0309, -0.0203, -0.0233, ..., 0.0111, -0.0332, -0.0273],
[-0.0198, -0.0037, -0.0407, ..., 0.0338, -0.0421, -0.0027]],
device='mps:0', grad_fn=)

Layer: linear_relu_stack.4.bias | Size: torch.Size([10]) | Values : tensor([-0.0320, 0.0096], device='mps:0', grad_fn=)

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?