PyTorchを用いたObject Detectionのページ

PyTorch はディープラーニングを実装する際に用いられるディープラーニング用ライブラリのPython APIの一つです。もともとは、Torch7と呼ばれるLua言語で書かれたライブラリでした。PyTorchは、このTorch7とPreferred Networks社のChainerをベースに2017年2月に作られたPython用ライブラリです。

 ディープラーニング用の代表的なライブラリとしてはCaffe、TensorFlow、Chainerなどが有名です。KerasはTensorFlowやCaffeを使用しやすくするためのwrapperとなります。Chainerは日本のPreferred Networks社が開発したライブラリですが、国際的認知度ではマイナーな印象です。PyTorch は後発にもかかわらず急速に発達して、広範に活用され始めています。

 PyTorchの利点はDefine by Run(動的計算グラフ)と呼ばれる特徴です。Define by Runは入力データのサイズや次元数に合わせてニューラルネットワークの形や計算方法を変更することができます。一方で、TensorFlowの特徴はDefine and Run(静的計算グラフ)と呼ばれます。Define and Runではニューラルネットワークの計算方法をはじめに決めてしまうため、入力データの次元がデータごとに異なる状況に対応しづらいという特徴があります 。Keras + Tensorflowは見やすく簡易で、非常に簡単にネットワークを作成できるので、人工知能の専門家以外の人たちにとって、使いやすい必須の道具となっています。しかし、アップグレードが後方互換性を持たないという欠点と、動作が遅いという問題点もあります。

 他方で、PyTorchは、Define by Runという特徴ゆえに、AIを開発する専門家に必須のアイテムになりつつあります。Object Detection用のライブラリの中では処理速度が最も最速です。

 2019年4月2日時点では、Object Detection用のライブラリのソフトウエア環境は以下の通りにアップグレードされています。

numpyのバージョン:1.16.1
scipyのバージョン:1.1.0
matplotlibのバージョン:2.2.2
PIL(Pillow)のバージョン:5.1.0
opencv-pythonのバージョン:4.0.0
kerasのバージョン:2.2.4
tensorflowのバージョン:1.13.1
です。

動作確認はこの環境下で行っています。とうぜん、TensorflowとKerasは使用しないので、依存しません。

 

Last updated: 2019.4.2


関連記事
TensorflowでObject Detection
Kerasを用いたDeep Learning
Deep Learningと人工知能
scikit-Learnを使った簡単な機械学習
ラズパイに人工知能を組み入れる
PythonのTutorials/Jupyter Notebook
Ubuntu 16.04のインストール/Raspi
ROS(Robot Operating System)/ubuntu
Raspberry Pi Mouseロボットでの操作の実際
RaspberryPi入門
著者のGitHub repositories

**************************************************************
PyTorchのインストールと簡単な利用方法
**************************************************************

以下のインストールでは、anaconda3がインストールされていることを前提にします。まず、PyTorchの公式サイトにアクセスして、「Get Started」のページに行きます。OSの選択をして、condaを選択し、pythn3.6、そして、GPUのnoneを選択すると、run this commandの欄に以下のコマンドが表示されます。

conda install pytorch torchvision -c pytorch


このコマンドを入力します。pytorchのインストールが始まります。PyTorchは、ディレクトリ anaconda3/lib/python3.6/site-packages/ の下に 'torch' とういう名前でインストールされます。

 PyTorchでは、numpyのndarrayと類似した(拡張した)Tensorsという概念を使います。pythonを起動して、以下のコマンドを入力してください。

from __future__ import print_function
import torch
x=torch.Tensor(5,3)
print(x)

以下のように表示されます。

tensor([[ 0.0000e+00, -2.5244e-29, -4.7749e+03], [-8.5920e+09, 6.2369e-30, 1.4013e-45], [ 6.2836e-30, 1.4013e-45, 6.2836e-30], [ 1.4013e-45, 6.2778e-30, 1.4013e-45], [ 6.2821e-30, 1.4013e-45, 3.8576e-32]])

5x3行列のインスタンスを作成してますが、要素を指定してませんので内容は無意味です。明らかに、tensorはnumpyのndarrayの拡張です。次に、要素が空である5x3 行列をtorchで作成します。

x = torch.empty(5, 3)
print(x)


以下のようになります。
tensor([[ 0.0000e+00, -2.5244e-29,  0.0000e+00],
        [-2.5244e-29,  5.6052e-45,  1.7180e+25],
        [ 5.7738e+16,  4.5912e-41,  0.0000e+00],
        [ 0.0000e+00,  0.0000e+00,  1.0951e+21],
        [-5.7835e+03, -1.5849e+29, -5.785


ランダムな値が入った行列を作成することもできます。

x = torch.rand(5, 3)
print(x)

tensor([[ 0.2561,  0.4928,  0.4191],
        [ 0.0556,  0.4421,  0.0621],
        [ 0.8881,  0.8851,  0.2572],
        [ 0.0567,  0.2491,  0.2788],
        [ 0.3648,  0.2398,  0.8449]])

加算をして見ましょう。

y=torch.rand(5,3)
print(x+y)

以下のようになります。

tensor([[ 0.9846,  1.3548,  0.9620],
        [ 0.1496,  1.2262,  0.4178],
        [ 1.2757,  1.3802,  0.8955],
        [ 0.7388,  0.2780,  1.1868],
        [ 0.9870,  0.7609,  1.4777]])


print(torch.add(x, y))


と入力しても、同じ結果が得られます。このように、NumPy like な操作ができます。

 PyTorchで使うパッケージは以下の通りです。
  • torch : 上で説明したNumPyのような配列(テンソル)のライブラリです。GPUでも簡単に使えます。
  • torch.autograd : 自動微分のライブラリです。torchで定義されたすべての関数に対して微分を可能にします。
  • torch.nn : ネットワークを作成するとき使用します。nn.Module は層、そして出力を返すメソッド forward(input) を含みます。
  • torch.optim : パラメータ更新時に使う最適化パッケージです。
  • その他:torch.utils や DataLoaderなど

  • ニューラルネットワークのための典型的な訓練手続きは以下のようなものです 。

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

    下のスクリプトはネットワークを作成するコードの例です。
    
    import torch
    from torch.autograd import Variable
    import torch.nn as nn
    import torch.nn.functional as F
    
    class Net(nn.Module):
    
        def __init__(self):
            super(Net, self).__init__()
            # 1 input image channel, 6 output channels, 5x5 square convolution
            # kernel
            self.conv1 = nn.Conv2d(1, 6, 5)
            self.conv2 = nn.Conv2d(6, 16, 5)
            # an affine operation: y = Wx + b
            self.fc1 = nn.Linear(16 * 5 * 5, 120)
            self.fc2 = nn.Linear(120, 84)
            self.fc3 = nn.Linear(84, 10)
    
        def forward(self, x):
            # Max pooling over a (2, 2) window
            x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
            # If the size is a square you can only specify a single number
            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:]  # all dimensions except the batch dimension
            num_features = 1
            for s in size:
                num_features *= s
            return num_features
    
    net = Net()
    print(net)
    
    

     このコードを実行すると、以下に示されるネットワークが作成されています。
    
    
    Net(
      (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
      (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
      (fc1): Linear(in_features=400, 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)
    )
    
    

    ここで見た通り、モジュール'torch.nn.functional' にはSoftMax, ReLUなどの活性化関数などが用意されています。

     モデルの学習可能なパラメータは net.parameters() で返されます。
    
    params = list(net.parameters())
    print(len(params))
    print(params[0].size())  # conv1's .weight
    
    OUT:
    
    10
    torch.Size([6, 1, 5, 5])
    
    

     詳しくは、PytorchのTutorials
    を読んでください。


    ************************************************************************************
    YOLO(You Only Look Once) in PyTorch framework
    ************************************************************************************


     YOLO(You Only Look Once)とは、畳み込みニューラルネットワーク(CNN:Convolutional Neural Network)を用いた物体検出アルゴリズムです。現時点ではv2、v3までのアップグレードが存在します。また、Tiny YOLOというサイズの小さなバージョンも開発されています。YOLOは、SSDの物体検出アルゴリズムとは異なり、画像をバウンディングボックスで分割してクラス分類を行なっている。

     YOLO(YOLOv1)では、結果として、45FPSの処理速度を実現した。YOLO9000(YOLOv2)では、YOLOv1を改良し、9000種類の物体検出が可能になっている。COCO Datasetに対して、40FPSにおいて、23.7 mAP(mean Average Precision)を達成した。YOLOv3では、220FPSにおいて33.1mAPを実現しています。ちなみに、SSD300では、46FPSにおいて41.2mAPとなっています。

     YOLOの公式サイトはここです。このサイトには、インストールなどの手続きが説明されています。活用できるドキュメントも多数掲載されています。

     PyTorchを使用するので、TensorFlowを必要としません。その代わりに、以下の環境が必要です。

    Python 3.5 or 3.6
    OpenCV3
    PyTorch 0.4

    TensorFlowを使用しないので、処理速度はかなり速くなります。

     まず、パッケージ 'pytorch-yolo-v3' をダウンロードします。 このGitHubからダウンロードしてください。 学習済み重みをダウンロードする必要があります。ここでは、'yolov3.weights'を使います。
    
    wget https://pjreddie.com/media/files/yolov3.weights 
    
    

    サイズは248MBです。このファイルを pytorch-yolo-v3 フォルダーの下に移動してください。物体検出にはコード 'detect.py' を使います。オプションを見るために、
    
    python detect.py -h
    
    

    と打って見てください。検出するときの様々なオプションが表示されます。以下のように入力します。
    
    python detect.py --images imgs --det det 
    
    

    --images flag は検出対象の画像ファイルの指定をします。ここでは、 'imgs' に画像が入っています。--det は検出済みの画像ファイルを保存するフォルダーを指定します。'det' というフォルダーになっています。コマンドが正常に動作して、下のような表示が出ます。
    
    Loading network.....
    Network successfully loaded
    dog.jpg              predicted in  1.781 seconds
    Objects Detected:    bicycle truck dog
    ----------------------------------------------------------
    eagle.jpg            predicted in  1.751 seconds
    Objects Detected:    bird
    ----------------------------------------------------------
    giraffe.jpg          predicted in  1.784 seconds
    Objects Detected:    zebra giraffe giraffe
    ----------------------------------------------------------
    herd_of_horses.jpg   predicted in  1.755 seconds
    Objects Detected:    horse horse horse horse
    ----------------------------------------------------------
    img1.jpg             predicted in  1.847 seconds
    Objects Detected:    person dog
    ----------------------------------------------------------
    img2.jpg             predicted in  1.842 seconds
    Objects Detected:    train
    ----------------------------------------------------------
    img3.jpg             predicted in  1.817 seconds
    Objects Detected:    car car car car car car car truck traffic light
    ----------------------------------------------------------
    img4.jpg             predicted in  1.768 seconds
    Objects Detected:    chair chair chair clock
    ----------------------------------------------------------
    messi.jpg            predicted in  1.812 seconds
    Objects Detected:    person person person sports ball
    ----------------------------------------------------------
    person.jpg           predicted in  1.850 seconds
    Objects Detected:    person dog horse
    ----------------------------------------------------------
    
    SUMMARY
    ----------------------------------------------------------
    Task                     : Time Taken (in seconds)
    
    Reading addresses        : 0.001
    Loading batch            : 3.065
    Detection (11 images)    : 20.594
    Output Processing        : 0.000
    Drawing Boxes            : 0.190
    Average time_per_img     : 2.168
    ----------------------------------------------------------
    
    

    Tensorflowを使うときに比較して処理速度はより速いです。保存された画像の一つは
    YOLO_3.jpg
    です。carとtruckの違いを検出しています。信号機まで検出されています。

     リアルタイムでの物体検出の仕方について説明します。web cameraからの映像を取り込むコードは 'cam_demo.py' です。USB接続されたwebcamからの映像をキャプチャーしたいときは、この 'cam_demo.py' の106行が 'cap = cv2.VideoCapture(0)' となっているときは、 'cap = cv2.VideoCapture(1)' に修正してください。 以下の通りに、シンプルにコマンドを入力します。1回目の入力で実行されないときは、2回目の入力をすると実行されます。
    
    $ python cam_demo.py
    
    FPS of the video is  0.24
    FPS of the video is  0.42
    FPS of the video is  0.56
    FPS of the video is  0.69
    FPS of the video is  0.78
    ------
    

    と表示が現れて、webcamの映像で検出された物体に枠がついた動画がリアルタイムで表示されます。動画映像は保存されません。webcamの映像の動きと連動して、ほとんど瞬間的に検出画像が切り替わります。速い!

    ***** 以下、準備中 ****  

    トップページに戻る