物体検出SSD-1 : 物体検出で使う用語の整理(1)

# 修正
* ボックスでの表現の節で「以上よりDBoxでの表現は[0.327, 0.629, 0.416, 0.424]となる」とありましたが、これを「[cx, cy, h, w]での表現では...」に変えました。BBoxでの表現を説明しているのに、DBoxと混在してしまっていました(BBoxを求める時はいったん[cx, cy, h, w]にした後に[x_min, y_min, x_max, x_min]の形にします...(2025 12/19)
* 式(6)の後の説明を修正しました。こちらもDBoxとBBoxが混在していたためです。
* また、オフセットの導出式(式(5),(6))を修正しました...(2025 12/19)
# 参考文献
* 新納浩幸『PyTorchによる物体検出』オーム社, 2020年
* Wei Liu, et al. "SSD: Single Shot MultiBox Detector", ECCV, pp. 21-37, 2016.
###### SSDの原論文 
https://arxiv.org/pdf/1512.02325
# SSDでの物体検出
* 画像から予め設定したラベルを持つ物体部分を見つけだして、その物体を囲むバウンディングボックス(BBox)という枠を付ける処理
* また物体のクラス識別も同時に行う
* 例はすぐ下の画像
* 同じ画像に複数の物体があることもあることにも対応
* 同じ画像に同じクラスの物体が複数あることにも対応

# ボックスの形式
* 物体に対する出力の形式はBBox(バウンディングボックス)、物体のラベル、推定の信頼度の3つ
* 下の画像の青い枠がBBox
* 0.95が信頼度(softmaxの出力で確率)

![スクリーンショット 2024-11-19 170749.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3897045/ad64c0b8-d497-b419-29ef-32a76f4acf45.png)


* BBoxの表現をどうするのかを決めておく必要がある
* まず、画像内部を次のようにx座標、y座標がそれぞれ[0, 1]の範囲で表現する
* BBoxをBBoxの中心座標(cx, cy), 幅w、 高さhの4つで表現 : [cx, cy, w, h]
* もう一つの表現としてはBBoxを前述した座標で表現 : [x_min, y_min, x_max, y_max]
 具体的には下の例の通り (座標の値の縮尺は参考文献のままです!)
 * 下の画像では[x_min, y_min, x_max, y_max]=[0.119, 0.417, 0.535, 0.841]の表現であるが、[cx, cy, w, h]の表現で書くと次のようになる
 ```math
 cx = \frac{(0.535 + 0.119)}{2} = 0.327
 
```
```math
 cy = \frac{(0.841 + 0.417)}{2} = 0.629
 ```
 ```math
 w = (0.535 - 0.119) = 0.416
 ```
 ```math
 h = (0.841 - 0.417) = 0.424
 ```
* 以上より[cx, cy, h, w]での表現は[0.327, 0.629, 0.416, 0.424]となる
![S__2973708.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3897045/5cee9ff9-150a-11e4-1828-57d87f0c0f0b.png)
# DBox(デフォルトボックス)とオフセット
* SSDはBBoxの検出にDBoxとそのオフセットという考えかたを導入(モデルの出力の1つとして予測オフセットがある)
* DBoxは予め決められている画像中のに定数のように定められたもの
* 畳み込みニューラルネットワークを適用した後の出力のセルに対応する形で各セルに4つor6つある(この後にも説明)
* 検出すべきBBoxとDBoxとの差分がオフセット(厳密にはただ引き算した訳ではない)
* DBoxとオフセットによって検出結果であるBBoxを表現
# 
* DBox(cx, cy, w, h)のオフセットが(Δx, Δy, Δw, Δh)となっていたとする
* 検出結果(cx', cy', w', h')は以下のようになる
```math
cx'= cx + 0.1\Delta x　　...(1)
```
```math
    cy' = cy+0.1\Delta y　　....(2)
```
```math
w' = w×exp(0.2\Delta w)　　...(3)
```
```math
h' = h×exp(0.2 \Delta h)　　...(4)
```
* いきなり出てきた0.1や0.2のイメージを掴む目的も踏まえ、オフセット(x, yとh,wで説明を分けて)の導出を以下で説明
# オフセット(x, y)
* 検出すべきBBoxとDBoxとの差分がオフセット(厳密にはただ引き算した訳ではない)
* 0.1や0.2はハイパーパラメータで、画像の解像度におけるlossのスケールを揃えるための値
* cx'とcy'で同じ値、w'とh'で同じ値を使用
* cx_bboxが予測したBBoxの中心座標、cx_dboxをDBox中心座標w_dboxをDBoxの幅とするとオフセットはこのように定義される
```math
\Delta x = \frac{(cx_\text{bbox} - cx_{dbox})}{0.1w_{\text{dbox}}}　　...(5)
```
* w_dboxで割ることで、異なるBBoxでも誤差のスケールを揃えられる(スケールが異なると学習が安定しない)
* 幅だけで正規化するとまだ不安定になる可能性があるため、0.1を掛けてスケールをさらに調整するイメージ
* Δyも同様
# オフセット(w, h)
* w_bboxを予測が予測したBBoxの幅、w_doxをDBoxの幅とするとオフセットはこのように定義される
```math
\Delta y = \frac{log(\frac{w_\text{bbox}}{w_\text{dbox}})}{0.2}　　...(6)
```
* (4)は(1)から(5)は(4)から導出できる
* 幅や高さのオフセットでは「BBoxの幅(高さ)はDBoxの幅の何倍か」を計算して、その値の対数スケールを求め正規化、0.2で割ってさらに正規化するイメージ

# 特徴マップを用いたクラス識別
* SSDでは複数の解像度の特徴マップが生成 
* [batch_size, channel, hight, width]の出力が途中でたくさん生成されるということ
* 1つの特徴量マップのセルに対して異なるサイズやアスペクト比(縦:横の比)のDBoxが複数生成
* 例としてあるサイズの特徴マップでは1セルで4つ、別のサイズの特徴マップでは1セルで6つなど
* このDBoxを用いて計算される予測オフセットを重みやバイアスなどを更新して精度を上げるイメージ
* その領域は特徴量マップから設定されたものであるので特徴マップを使えばクラス識別が可能
=> BBoxを用いた物体検出とクラス識別の両方を実現
# SSDの処理概要
* 処理の流れは次の通り
* 出力特徴マップの各セルに対応した4 or 6個のDBoxをアスペクト比を用いることで作成(畳み込み演算の前に出力の各セルに対応する形で作成される)
![スクリーンショット 2024-11-21 162752.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3897045/11fc6fa1-87f2-52ff-4d04-f7ac14402bc4.png)
↑上の写真のように1セルに4つのDBoxが作成(上の写真は6×6だが、実際は別のサイズ)サイズによっては6個作成される.作成されるDBoxの詳細は下のアスペクト比のところで。
* 畳み込み演算
* 畳み込みで得られる特徴マップを複数出力(計6個)
* この6個の出力を用いて、オフセットとクラスの信頼度を計算
* 最終的な出力はDBox (shape : [batch_size, channel, hight, width])、クラスの信頼度、厳密にはsoftmax適用前のlogits値で(shape [batch size, DBoxの数, num_classes])、オフセットの予測値(shape [batch size, DBoxの数, 4(Δx, Δy, Δw, Δh)])
* 推論時はまた異なるので注意(先のQiitaの更新で説明)


# アスペクト比
* 縦 : 横の比率
* DBoxは途中で出力される特徴マップの各セルに対応する形で生成される(厳密にはモデルのコンストラクタで生成される)
* 4つのDBoxを作る場合は以下の4つのDBoxが特徴マップの各セルに対応する形で作成
* 小さい正方形
* 大きい正方形
* 1:2の比率の長方形
* 2:1の比率の長方形
#
* 6つのDBoxを作る場合は以下の6つのDBoxが特徴マップの各セルに対応する形で作成
* 4つの場合と同じもの
* 1:3の比率の長方形
* 3:1の比率の長方形
#
なお、画像の端をはみだしたDBoxは、はみだした部分は削れる

# 次回
* SSDのネットワークモデル
* VGG
* L2Normalization