各種画像解析モデルの実装をやってみた

## 目次

1. 画像解析モデルの概要
1.YOLOv8
2.SSD(Single Shot multibox Detector)
3.Faster R-CNN
1. Pytorchによる実装方法
1. まとめ
1. 参考文献

# 1. 画像解析モデルの概要
画像解析は、画像の中から意味のある情報を抽出、処理、分類する技術のことを指します。
具体的には、物体抽出やセグメンテーション、パターン認識を行う技術のことになります。
画像解析では、バーコードのようなAI技術を用いない事例もありますが、画像の特徴を自動的に把握することができる、AI技術を活用した画像解析の手法が脚光を浴びています。
今回は、その中でYOLOv8、SSD、Faster R-CNNについてご紹介しようと思います。

# YOLOv8
YOLOv8は、リアルタイム物体検出アルゴリズムのYOLOシリーズになります。[1]
公式ではありませんが、下記のように[YOLOv8による物体検出アーキテクチャ](https://github.com/ultralytics/ultralytics/issues/189)[2]も公開されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937989/8e618fca-01a1-01e9-af18-cc7ca91a5787.png)

YOLOモデルシリーズ全体に言えることですが、このモデルは物体検出の速さに強みを持っており、デファクトスタンダードに使用されている画像解析モデルと言えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937989/6c4b695e-ceb3-439e-20da-def497eeb8cb.png)

# SSD
SSDはYOLO と同じように、領域スキャンのアプローチを使わずに入力画像から CNN で直接物体の位置を検出する One-Stage (Shot) と呼ばれるアプローチの手法になります。
参考に、YOLOとの構造の違いを、[SSDの論文](https://arxiv.org/pdf/1512.02325)[3]に記載のある図を引用いたします。
図に記載のある通り、SSDではサイズの異なる畳込み層を追加することで、様々な物体の検出を可能にしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937989/189ef7dc-3a2f-a733-631c-dbe7bd49b2bd.png)

# Faster R-CNN
2015年にMicrosoft社が開発した、Deep LearningによるEnd-to-Endの学習に成功した初めてのモデルになります。
下図のように、Region Proposal Network（RPN）と呼ばれる物体位置を提案するネットワークを導入しています。これにより、物体の可能性がある領域提案を高速化しています。
また、従来のR-CNNやFast R-CNNと比べて提案領域の生成が高速なため、高精度を保ちつつ検知速度の高速化が実現されています。[4]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937989/d788c150-c8c0-75eb-40af-7bdbb5324342.png)

# 2. Pytorchによる実装
それぞれのモデルの実装方法に関して、簡単ですが下記に記載します。

・YOLOv8
まずは、下記のコードを実行してYOLOv8のインストールを実施します。

```
git clone https://github.com/ultralytics/ultralytics
cd ultralytics
pip install -e '.[dev]'
```
ultralytics社のライブラリよりYOLOクラスをインポートして構築します。

```
from ultralytics import YOLO

# Load a model
model = YOLO("yolov8l.yaml")  # build a new model from scratch
model = YOLO("yolov8l.pt")  # load a pretrained model (recommended for training)

# Use the model
results = model("https://ultralytics.com/images/bus.jpg",save=True)  # predict on an image
```
上記コードを実行すると、テストデータ（bus.jpg）に関して画像解析を実施した結果が、runs/detectディレクトリに保存されます。
私の環境では、下記のように出力されました。
それぞれの対象の物体に対して、精度高く検知できていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937989/59c2276a-ed5d-ad6d-1fa5-b5715db16971.png)

・SSD
SSDはTorchvisionを使用してモデルをロードします。
いくつかモデルがありますが、今回はssd300_vgg16モデルをロードします。

```
# SSDモデルのロード
from torchvision import models, transforms
model = models.detection.ssd300_vgg16(pretrained=True)
model.eval()

# 画像の取得
url = "https://ultralytics.com/images/bus.jpg"
response = requests.get(url)
img = Image.open(BytesIO(response.content)).convert("RGB")
```
試しにYOLOv8と同様の画像で解析してみましたが、YOLOv8と比べると精度で劣るかなといった結果でした。
右側の男性の予測精度が低かったり、右上の自転車を検知できていないようでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937989/966b37db-5c6e-00c9-6b9e-ecee2910bc6c.png)

・Faster R-CNN
Faster R-CNNもSSDと同様に、Torchvisionを使用してモデルロードを実施します。
fasterrcnn_resnet50_fpnをロードしています。
```
from torchvision import models, transforms
# Faster R-CNNモデルのロード
model = models.detection.fasterrcnn_resnet50_fpn(pretrained=True)
model.eval()
```
画像解析の結果ですが、YOLOv8、SSDと比べて予測精度の数値が高く、明確に検出した物体に対して自信をもって検出しているようでした。
しかし、SSDと同様に、右上の自転車の検知はできていないようで、モデル毎に得手不得手があるようでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937989/1cb549e9-39e6-4330-f73b-35412fa415f5.png)

# 3. まとめ
YOLOv8、SSD、Faster R-CNNの3モデルで実装をしましたが、それぞれのモデルに特徴がある結果となりました。
しかし、今回実施したモデルでも追加学習やパラメータチューニングを実施することによってさらなる精度向上が見られると思います。
今後は波に乗り遅れないように、引き続き画像解析分野についてアンテナ高く情報収集をしていき、面白い使い方ができないか検討したいと考えます。

以下、参考文献になります。

# 4. 参考文献
[1] YOLOv8-Ultralytics YOLO ドキュメント
    https://docs.ultralytics.com/ja/models/yolov8/

[2] Brief summary of YOLOv8 model structure
    https://github.com/ultralytics/ultralytics/issues/189
[3] SSD: Single Shot MultiBox Detector
    https://arxiv.org/pdf/1512.02325
[4] Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
    https://arxiv.org/pdf/1506.01497