【Pytorch】CNNの畳み込み層を実装するコード【CNN】
CNNをライブラリを極力使わずに自力で実装する場合のコードをまとめておく。
nn.Moduleをベースに実装していく。
畳み込み層を実装する
まずはCNNの実装で使いそうなライブラリをインポートしておく。
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import torch.autograd as autograd
import torch.nn.functional as F
from torchvision import datasets, transforms, models
from sklearn.utils import shuffle
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
rng = np.random.RandomState(1234)
random_state = 42
畳み込み層は以下のように実装できる。
ここではHeの初期化を使用している。
class Conv(nn.Module):
def __init__(self, filter_shape, function=lambda x: x, stride=(1, 1), padding=0):
super().__init__()
# Heの初期値
fan_in = filter_shape[1] * filter_shape[2] * filter_shape[3]
# filter_shape: (出力チャンネル数)x(入力チャンネル数)x(縦の次元数)x(横の次元数)
fan_out = filter_shape[0] * filter_shape[2] * filter_shape[3]
self.W = nn.Parameter(torch.tensor(rng.uniform(
-np.sqrt(6/fan_in),
np.sqrt(6/fan_in),
size=filter_shape
).astype('float32')))
# バイアスはフィルタごとなので, 出力フィルタ数と同じ次元数
self.b = nn.Parameter(torch.tensor(np.zeros((filter_shape[0]), dtype='float32')))
self.function = function
self.stride = stride
self.padding = padding
def forward(self, x):
u = F.conv2d(x, self.W, bias=self.b, stride=self.stride, padding=self.padding)
return self.function(u)
プーリング層を実装する
プーリング層は以下のように実装できる。
class Pooling(nn.Module):
def __init__(self, ksize=(2, 2), stride=(2, 2), padding=0):
super().__init__()
self.ksize = ksize
self.stride = stride
self.padding = padding
def forward(self, x):
return F.avg_pool2d(x, kernel_size=self.ksize, stride=self.stride, padding=self.padding)
平滑下層を実装する(4次元→2次元)
平滑下層は以下のように実装できる。
class Flatten(nn.Module):
def __init__(self):
super().__init__()
def forward(self, x):
return x.view(x.size()[0], -1)
全結合層を実装する
全結合層は以下のように実装できる。
class Dense(nn.Module):
def __init__(self, in_dim, out_dim, function=lambda x: x):
super().__init__()
# He Initialization
# in_dim: 入力の次元数、out_dim: 出力の次元数
self.W = nn.Parameter(torch.tensor(rng.uniform(
-np.sqrt(6/in_dim),
np.sqrt(6/in_dim),
size=(in_dim, out_dim)
).astype('float32')))
self.b = nn.Parameter(torch.tensor(np.zeros([out_dim]).astype('float32')))
self.function = function
def forward(self, x):
return self.function(torch.matmul(x, self.W) + self.b)
以上がCNNに必要な層の実装。
人気記事
人気記事はこちら。