FloatingPoint64 / research_pub

The Unlicense
0 stars 0 forks source link

StreamPETR手法調査 #1

Open FloatingPoint64 opened 5 months ago

FloatingPoint64 commented 5 months ago

関連手法と論文リンク

FloatingPoint64 commented 5 months ago

DETRは2D-2Dの物体検出手法。
DETR3D以降は、Multi 2D-3D物体検出手法。

FloatingPoint64 commented 5 months ago

DETR

推論フロー

image

  1. 画像をCNN(ResNet等)に入力する。
    • CNNで出力されたチャネル数(ex.2048)を1×1畳み込みでチャネル数をより小さい次元d(ex.256)に縮小する。
  2. 特徴マップが生成される(d個)
  3. Transformerにd個の特徴マップを入力する
  4. N個のオブジェクト情報(クラス、位置、サイズ)が出力される
    • N個が一括して推論されます。なお、Nは100個等入力画像に含まれるよりも十分に多い数を選びます

DETRアーキテクチャ

概要図

image

詳細図

image

DETRの時点で、Transformer encoderへの入力時にpositional encoding情報が使用されている。
(発展手法でこの部分が3D position情報が使用されている?)

object queryについて

画像内から「物体検出」と「分類」をするために学習される値。初期値は完全にランダムなベクトル数値。分類するクラスに対して十分に大きな値にします。(イメージ的には画像内に映っている物体の関連性をみながら対応付けていくと思われます) 図4は原論文に記載されているN=100のときの内20個のボックスの予測を可視化したものです。画像サイズごとにポイントは色分けされており、緑の色が小さい画像、赤は大きな横長のボックス、青は大きな縦長のボックスを示します。各Nそれぞれで見方の傾向に違いがあることが見て取れます。この違いが適切に物体検出と分類を行うことを可能にしています。 image

損失計算

損失を求める際には、正解データとの対応付けにハンガリアン法を使用。 コストとしては、IoUとBboxの位置・サイズのL1ロスを使用。

中間処理結果

Encoder最終層のAttentionマップ

image

この時点で、objectのインスタンスごとの分離は完了している。
通常のCNNとTransformerの組合せ。

Decoder最終層のAttentionマップ

image

鼻先や足などのオブジェクト境界に集中している。
境界線の判断が行われている。

FloatingPoint64 commented 5 months ago

TODO

import torch
from torch import nn
from torchvision.models import resnet50

class DETR(nn.Module):

    def __init__(self, num_classes, hidden_dim, nheads,
                 num_encoder_layers, num_decoder_layers):
        super().__init__()
        # We take only convolutional layers from ResNet-50 model
        self.backbone = nn.Sequential(*list(resnet50(pretrained=True).children())[:-2])
        self.conv = nn.Conv2d(2048, hidden_dim, 1)
        self.transformer = nn.Transformer(hidden_dim, nheads,
                                          num_encoder_layers, num_decoder_layers)
        self.linear_class = nn.Linear(hidden_dim, num_classes + 1)
        self.linear_bbox = nn.Linear(hidden_dim, 4)
        self.query_pos = nn.Parameter(torch.rand(100, hidden_dim))
        self.row_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))
        self.col_embed = nn.Parameter(torch.rand(50, hidden_dim // 2))

    def forward(self, inputs):
        x = self.backbone(inputs)
        h = self.conv(x)
        H, W = h.shape[-2:]
        pos = torch.cat([
            self.col_embed[:W].unsqueeze(0).repeat(H, 1, 1),
            self.row_embed[:H].unsqueeze(1).repeat(1, W, 1),
        ], dim=-1).flatten(0, 1).unsqueeze(1)
        h = self.transformer(pos + h.flatten(2).permute(2, 0, 1),
                             self.query_pos.unsqueeze(1))
        return self.linear_class(h), self.linear_bbox(h).sigmoid()

detr = DETR(num_classes=91, hidden_dim=256, nheads=8, num_encoder_layers=6, num_decoder_layers=6)
detr.eval()
inputs = torch.randn(1, 3, 800, 1200)
logits, bboxes = detr(inputs)

Prediction feed-forward networks (FFNs). The final prediction is computed by a 3-layer perceptron with ReLU activation function and hidden dimension d, and a linear projection layer. The FFN predicts the normalized center coordinates, height and width of the box w.r.t. the input image, and the linear layer predicts the class label using a softmax function. Since we predict a fixed-size set of N bounding boxes, where N is usually much larger than the actual number of objects of interest in an image, an additional special class label ∅ is used to represent that no object is detected within a slot. This class plays a similar role to the “background” class in the standard object detection approaches.

Feed-forward network (FFN) layers: The original transformer alternates multi-head attention and so-called FFN layers [47], which are effectively multilayer 1x1 convolutions, which have M d input and output channels in our case. The FFN we consider is composed of two-layers of 1x1 convolutions with ReLU activations. There is also a residual connection/dropout/layernorm after the two layers, similarly to equation 6.

FloatingPoint64 commented 5 months ago

DETR3D

推論フロー

image

  1. ResNet + FPNから2D特徴量を抽出
  2. Object QueriesをTransformerに与え、3D上での参照位置を計算
  3. 3D参照位置をカメラパラメータを使用して2D上の位置に投影
  4. 投影された2D上の参照位置に対応する2D特徴量を収集
  5. 収集した特徴量から3D Bboxを推定

ネットワーク概要

特徴量抽出部

ResNetとFPNを使用してカメラごとに特徴Fを抽出。

入力画像:

I = \{im_1,...,im_K\} \subset {R^{H_{im} \times W_{im} \times 3}}

出力特徴量 (6カメラ分):

F_k = \{f_{k1},...,f_{k6}\} \subset {R^{H \times W \times C}} |_{k=4}

物体検出部

objest queries:

Q_l = \{q_{l1},...,q_{lM*}\} \subset R^C

画像上の特徴量取得位置:

c_{li} = \Phi^{ref}(q_{li})
c_{li}^* = c_{li} \oplus 1
c_{lmi} = T_m c_{li}^*

$\Phi^{ref}$はneural network、$T_m \subset R^{3 \times 4}$は各カメラのカメラ行列。
投影された座標と特徴量$F_k$からバイリニア保管によって特徴量を得る。

f_{lkmi} = f^{\textrm{bilinear}}(F_{km}, c_{lmi})

where $f_{kmi}$ is the feature for $i$-th point from $k$-th level of $m$-th camera at $l$-th layer.

カメラごとに、投影後の位置が画像画角外の対策として特徴量の有効無効を判定するマスクを定義しておく。このマスクを適用することで最終的な特徴量$f_{li}$を得る。

f_{li} = \frac{1}{\Sigma_{k} \Sigma_{m} \sigma_{lkmi} + \varepsilon} \Sigma_{k} \Sigma_{m} f_{lkmi} \sigma_{lkmi}

上記の特徴量をobject queryに加算していくことで、Transformerの出力値$q_{(l+1)i}$を得る。

q_{(l+1)i} =  f_{li}+ q_{li}

上記のTransfomerの出力値をネットワークに入力することで、3D Bbox$\hat{b}_{li}$とクラスラベル$\hat{c}_{li}$を得る。

\hat{b}_{li} = \Phi^{reg}_l(q_{li}) \qquad \textrm{and} \qquad \hat{c}_{li} = \Phi^{cls}_l(q_{li})

3D Bbox情報$b_j \subset R^9$は、中心位置、3D Bboxの大きさ、向き、BEV上の速度。

b_j = (x_j, y_j, z_j, W, L, H, \theta, \dot{x}, \dot{y})

損失関数

DETR同様にハンガリアン法を用いたマッチングを行い損失を計算する。
(ハンガリアン法のコスト関数も基本的にはDETRと同じだが、boxのコストをL1ロスとしている点が異なる)
3D Bbox位置はL1ロス、クラスはFocal Lossを使用する。

FloatingPoint64 commented 5 months ago

positional encoding(PE)がobject query(OQ)と一体化している印象。
DETRではPEが2D画像上であるのに対して、DETR3DではOQから2D画像上の参照点を導出しているように見える。
このため、DETR3DのOQは、3D空間上のPEとして機能しているように感じるのだと思う。
この点に関して論文中で確認しながら読み進める。

FloatingPoint64 commented 5 months ago

PETR

推論フロー

image

  1. N個のカメラ画像をBackboneに入力し2D Featuresを算出
  2. N個のカメラごとに3D 位置をCamera frustum spaceとカメラパラメータから導出
  3. 3D 位置をEncoderに入力後2D Featuresと混合して最終的な特徴量を得る
  4. 特徴量からDecoderネットワークを通して3D Bbox位置・クラスを推定

ネットワーク概要

2D Features

ResNetなどを用いてカメラごとに特徴量 $F^{2d}$ を抽出

F^{2d}=\{F^{2d}_i \in R^{C \times H_F \times W_F}, i=1, 2, ..., N \}

($N$ はカメラ画像数)

3D Features

3D Coordinates Generator

  1. カメラのフラスタム空間でメッシュ状に観測点 $p^m_j = (u_j \times d_j, v_j \times d_j, d_j, 1)^T$ を生成する。ここで、 $(u_j, v_j)$ はpixel座標系の位置。
  2. これをカメラパラメータ $Ki \in R^{4 \times 4}$ を用いて3D位置 $p{i, j}^{3d} = (x{i, j}, y{i, j}, z_{i, j}, 1)^T$ に変換する。
p^{3d}_{i, j}=K^{-1}_{i}p^m_j
p^{3d}_{i, j} = {P_i^{3d} \in R^{(D \times 4|_{len(x, y, z, 1)}) \times H_F \times W_F}}

3D位置は3D空間の設定範囲(RoI)を用いて正規化する。

\begin{equation*}
    \begin{cases}
      x_{i, j} = (x_{i, j} - x_{min})/(x_{max} - x_{min}) \\
      y_{i, j} = (y_{i, j} - y_{min})/(y_{max} - y_{min}) \\
      z_{i, j} = (z_{i, j} - z_{min})/(z_{max} - z_{min}) \\
    \end{cases}
\end{equation*}

RoIはハイパーパラメータ: $[x{min}, y{min}, z{min}, x{max}, y{max}, z{max}]$ 。
4.4 Ablation Studyにて、データセット中で最適な設定範囲を探索的に求めている。
著者らの設定値は下記の通り。

For 3D coordinates generation, we sample 64 points along the depth axis following the linear-increasing discretization (LID) in CaDDN [38]. We set the region to [−61.2m, 61.2m] for the X and Y axis, and [−10m, 10m] for Z axis.

3D Position Encoder

3D Position Encoderの概念図は下記の通り。

image

画像のエンコーダはバックエンドネットワークから算出した特徴量 $F^{2d}$ を1x1のCNNに入力する。
3D位置のエンコーダは、 $p^{3d}$ を入力としたMLP(FC-ReLU-FC)を通す。
これらの1x1のCNNの出力とMLPの出力を加算して3D Position-aware Featuresを得る。

1x1 CNN出力とMLPの混合のさせ方については、4.4 Ablation StudyにてAdd, Concat, Multiplyの3種類で比較検討している。総合的には加算が良い成績。

Query Generator

Anchor-DETRと似たような形で、3D空間上で一様に分布するように学習可能なアンカーポイントを配置している。
DETRやBEV上でアンカーポイントを配置した場合と比べて検出性能が高かったらしい。

Decoder, Head, Loss

DETRと同様の仕組みを使用。

処理時間

NVIDIA Tesla V100 1台を使用して推論時間を計測している。
比較対象として、DETR3Dが出てくるがこちらの処理時間は、Graph-DETR3Dの論文に推論時間の記載がある。
(こちらでもNVIDIA Tesla V100 1台を使用して推論時間を計測)

Fig. 5(b)より、最も小さい構成(ResNet50、入力解像度384x1056)で10.7FPS。
最も大きな構成(ResNet101、入力解像度900x1600)で1.7FPS。
対して、DETR3DではResNet101、入力解像度不明で3.1FPS (Graph-DETR3Dの論文のv2に記載あり、最新版のv3では記載が削られているので信頼性は低い)。

FloatingPoint64 commented 5 months ago

PETRv2

ネットワーク概要

image

PETRからの改善点

  1. 時系列情報として画像特徴量を取り込み
    • 3D Coordinates Alignment
  2. Position Encoderに画像特徴量を考慮
    • Feature-guided Position Encoder
  3. マルチタスク
    • 3D Object Detection, BEV Segmentation, 3D Lane Detection

1. 時系列情報として画像特徴量を取り込み

画像特徴量については、Concatenationオペレータで結合する。
Positon Encoderでは、自車両の運動量を用いて前時刻の画像特徴量を現在時刻に投影後、Concatenationオペレータで結合する。

2. Position Encoderに画像特徴量を考慮

image

a1. 画像特徴量は1x1のCNNを適用 a2. MLPとSigmoid関数を適用 b1. 3D座標側は、MLPを適用 b2. "b1."と"a2."を乗算して3D PEを得る b3. PETRと同様にして、3D PEと"a1."を加算する

Robustness analysis

Extrinsics noises

PETRと比較すると、PETR + FPEPETRv2が同等のスコア。
FPEによって外部パラメータのノイズを吸収できる。一方で、2度のずれで約1%性能が低下するので、影響をゼロにはできない。
image

Camera time delay

T=83msの時刻ずれによって約3%性能が低下する。
(30FPSのカメラだと2フレームずれ。1フレーム分相当の0.5Tだと1.5%程度の性能低下?)
image

FloatingPoint64 commented 5 months ago

Stream-PETR

ネットワーク概要

image
(Queueの概念図)
image
(Propagation Transfomerの概念図)

image
(この図は、Query部のV、K、QについてPETRの用語との対応付け確認のためFocal-PETRより引用。
Focal-PETRは同一著者による2022年公開の論文。)

image
(PETRから引用: V, K, Attention部分の参照用。)

image
(V, K, Attention部分を強調)

処理フロー

image

12~18行の処理がPETR等のTransformer Decoderに該当。

image

PETRからの改善点

※PETRv2の改善点は反映されていないので注意

動かしてみないと分からない点

FloatingPoint64 commented 5 months ago

疑問点

FloatingPoint64 commented 5 months ago

ネットワーク概念図を見ていると、PETRv2のEncoder部分の改善要素をStreamPETRに取り込むことはできそう。
(その分処理速度は落ちるが)

FloatingPoint64 commented 5 months ago

次に読みたい論文 (いずれもマルチカメラ入力の分野)