深層学習(Deep Learning)で物体認識を行うプログラム(AI)をなるべくわかりやすく解説

深層学習(Deep Learning)で物体認識を行うプログラム(AI)をなるべくわかりやすく解説

今回の記事では,10カテゴリの物体を認識するプログラム(AI)を深層学習を用いて作成しようかと思います.前回の記事では,手書きの数字を認識するプログラムを実際に作成してみました.よろしければこちらも参考にしてみて下さい.

今回もプログラミング言語はPython,深層学習用ライブラリはPyTorchを使用します.まだこれらのインストールや設定が完了していない方はこちらの記事を参考に,設定をしてみて下さい.

スポンサーリンク

使用するデータセット

今回使用するデータセットは,CIFAR-10と呼ばれる画像データセットになります.CIFAR-10もMNIST同様に,深層学習界隈ではとてもよく使用されているデータセットになります.

CIFAR-10の詳細は以下の通りです.

  • 50000枚の学習用データと10000枚のテスト用データで構成
  • 1枚の画像は\(32\times 32\)画素のカラー画像
  • 10クラスの物体カテゴリ(下記画像参照)
CIFAR-10の画像例.10カテゴリ.

CIFAR-10を用いた物体認識

それでは実際にCIFAR-10を用いて物体認識を行うプログラムを実装したいと思います.といっても実は,MNISTのプログラムと大体同じです.

全体のプログラム

まず最初に全体のプログラムを以下に載せます.このプログラムを実行することで,CIFAR-10上でCNNを用いた物体認識が実行されます.

プログラムはこちらでも公開していますので,必要であればダウンロードしてみて下さい.

# ライブラリのインポート
import torch
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
# train data
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2)
# test data
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

# CNN
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(16, 32, 5)
        self.gap = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Linear(32, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.gap(x)
        x = x.view(-1, 32)
        x = self.fc(x)
        return x



use_cuda = torch.cuda.is_available()
device = torch.device("cuda" if use_cuda else "cpu")

model = CNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

epoch_num = 100
for epoch in range(epoch_num):
    running_loss = 0.0
    for i, (data, labels) in enumerate(trainloader):
        data, labels = data.to(device), labels.to(device)
        optimizer.zero_grad()
        outputs = model(data)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()
    print('[%d] loss: %.3f' % (epoch + 1, running_loss / len(trainloader.dataset)))
    running_loss = 0.0

    # 学習中のモデルをテストデータ上で評価
    if epoch % 1 ==0:
        correct = 0
        total = 0
        with torch.no_grad():
            for _, (data, labels) in enumerate(testloader):
                data, labels = data.to(device), labels.to(device)
                outputs = model(data)
                _, predicted = torch.max(outputs.data, 1)
                total += labels.size(0)
                correct += (predicted == labels).sum().item()
        print('Accuracy of the network on the test images: %d %%' % (100 * correct / total))

実行結果

上記のプログラムを実行すると,以下のようにCNNの学習が進んでいく様子がみれるかと思います.lossの値が段々と下がっていき,テストデータ上での分類精度が上昇していくのがわかります.

[1] loss: 0.412
Accuracy of the network on the test images: 43 %
[2] loss: 0.354
Accuracy of the network on the test images: 51 %
[3] loss: 0.329
Accuracy of the network on the test images: 54 %
[4] loss: 0.313
Accuracy of the network on the test images: 56 %
[5] loss: 0.301
Accuracy of the network on the test images: 57 %
[6] loss: 0.292
Accuracy of the network on the test images: 57 %
[7] loss: 0.285
Accuracy of the network on the test images: 59 %
[8] loss: 0.279
Accuracy of the network on the test images: 60 %
[9] loss: 0.273
Accuracy of the network on the test images: 58 %
[10] loss: 0.269
Accuracy of the network on the test images: 62 %
スポンサーリンク

CIFAR-10のインポート

MNISTと同様に,PyTorchのライブラリを使用すれば簡単にCIFAR-10をダウンロードすることが可能です.

# train data
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True)
# test data
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False)

CNNの構築

今回はMNISTの時とは異なるCNNを使用してみました.

工夫点としては,ネットワークの最終層の直前にGlobal Average Pooling (GAP)を使用することが挙げられます.GAPは入力画像サイズと同じサイズのフィルタを用いてAverage Poolingをすることに相当しますが,これを最終層の直前に用いることで,

  • 入力画像サイズに依らないネットワーク構造になる
  • 全結合層のパラメータを減らすことができ,学習が安定する

といった利点があります.

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(16, 32, 5)
        self.gap = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Linear(32, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.gap(x)
        x = x.view(-1, 32)
        x = self.fc(x)
        return x

まとめ

今回は,10カテゴリの物体認識を行うプログラム(AI)を作成してみましたが,いかがだったでしょうか.深層学習ライブラリであるPyTorchを用いることで,驚くほど簡単にプログラムを作成できることがわかったかと思います.

今後もほかのタスクに焦点を当てて,プログラムの解説を行っていこうと思います.

タイトルとURLをコピーしました