PytorchによるVGG-16実装
こんばんは。
今回はILSVRCという大規模な画像コンペティションで優秀な成績を収めたDeep LearningのCNNモデルであるVGG-16を実装したのでメモ的な意味で残しておきます。研究でも使っているPytorchで実装しました。
必要なライブラリのインポート
まず、Pytorchでネットワークモデルを作成するために必要なライブラリをインポートします。
import torch import torch.nn as nn
ネットワークのクラスの作成
pytorchでネットワークモデルを作成する際にはいくつかルールがあります。
- nn.Moduleを継承する
- __init__を実装
- forwardを実装
以下に実装例を載せておきます。これらはほぼおまじないみたいな感じで覚えていれば良いです。
class vgg(nn.Module): def __init__(self): super(vgg, self).__init__() def forward(self, input): pass
__init__の中身には構成したい畳み込み層、活性化関数やプーリング層を記述していきます。forwardの中身には__init__で構成したものを使ってデータがどのように流れていって出力されるのかについて記述します。では具体的な書き方について説明していきます。
ネットワークの構成
ネットワークの構成ですが、下記の画像のような構成になっています。VGG-16 のネットワークは16個の畳み込み層を用いて実装されています。
【畳み込み層】→【活性化関数(ReLU)】→【プーリング層】が次々と重ねられています。
実装の方法ですが、nn.Sequential()を用いて実装します。これを用いて実装したほうがforward()に書く部分がスッキリするのでオススメです。
def __init__(self): super(vgg_fcn, self).__init__() self.features = nn.Sequential( nn.Conv2d( in_channels=3, out_channels=64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), ), nn.ReLU(inplace=True), nn.Conv2d(64, 64, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.MaxPool2d( kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False ), nn.Conv2d(64, 128, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.Conv2d(128, 128, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.MaxPool2d(2, 2, 0, 1, False), nn.Conv2d(128, 256, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.Conv2d(256, 256, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.Conv2d(256, 256, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.MaxPool2d(2, 2, 0, 1, False), nn.Conv2d(256, 512, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.MaxPool2d(2, 2, 0, 1, False), nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.Conv2d(512, 512, (3, 3), (1, 1), (1, 1)), nn.ReLU(inplace=True), nn.MaxPool2d(2, 2, 0, 1, False), ) self.avgpool = nn.AdaptiveAvgPool2d(output_size=(7, 7)) self.classifier = nn.Sequential( nn.Linear(in_features=25088, out_features=4096), nn.ReLU(inplace=True), nn.Dropout(), nn.Linear(in_features=4096, out_features=4096, bias=True), nn.ReLU(inplace=True), nn.Dropout(p=0.5, inplace=True), nn.Linear(in_features=4096, out_features=1000, bias=True), ) def forward(self, input): output = self.features(input) output = self.avgpool(output) output = output.view(input.shape[0], -1) output = self.classifier(output) return output
以上がVGG-16の構成です。