DBNetの理論備忘録

# 目的
DBNetの理論を学習した際の備忘録。
OCRを行おうと思い、まず一般的なモデルについて確認したかったが、あまり説明記事が無かったのでまとめてみました。

# 参照
原論
Liao, M., Wan, Z., Yao, C., Chen, K., & Bai, X. (2019). Real-time Scene Text Detection with Differentiable Binarization. ArXiv. /abs/1911.08947

# DBNet(Differentiable Binarization)とは
2019年に発表されたOCRのためのモデル。
１番重要なのは、<b>positiveとnegativeを判断する閾値のマップを深層学習で作成して組み込んだ点。</b>

# モデル概要
　下図が一般的なOCRモデル(青線)とDBNet(赤線)のinputからoutputへの流れになっています。
　一般的な文字検出は青線のようにsegmentation(Unet等)により文字のある部分を検出します。そして検出されたエリアの中で文字認識を行います。
　DBNetは、図の赤線のプロセスを辿っています。segmentationの際に並列して、segmentationのアウトプットを二値化(1:文字エリア,0:それ以外)する際の閾値も特徴量マップで出力しています。<b>differentiable binarization(直訳: 微分可能な二値化)とは</b>、一般的にハイパラで設定する閾値も図のように<b>閾値用の特徴量マップ(threshold map)を作成して後のプロセスに繋げることで、微分可能(誤差逆伝播可能)にした点を指しています。</b>こうすることで、画像の場所毎に閾値を最適化することを目指しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3424989/dd4b7539-ea78-32bc-15d9-525f7fa1eddf.png)

　原論ではこの方法について利点を4つ挙げています。
- 精度向上
- 推論時間削減: 後処理を簡略化したため
- パラメータ数が少ないモデル(例: ResNet-18)を組み込んだ際に良いパフォーマンス。
　(サイズが大きい方が精度は良いが、小さいモデルでもあまり精度が落ちなかった)
- threshold mapは推論時には取り除けるため、メモリと時間を消費しない



　次にDBNetのより詳細なモデル図を示します。前半部分は一般的な物体検出モデルで用いられる特徴量ピラミッドが使われています。原論ではバックボーンにResNetが使用されてますが、<b>3,4,5層目の3*3の畳み込みは全てdeformable convolutionになっています</b>。これは文章のような縦横の比率が大きくことなる物体検出においては、deformableの方が通常よりも特徴量抽出に優れているためです。バックボーンの5層目と、upsamplingされたそれぞれの層における出力を結合(concat)して、予測値の特徴量マップ(probability map)と閾値の特徴量マップ(threshold map)を出力します。この二つのマップからapproximate binary mapを出力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3424989/401d77a9-b4d6-7ae3-031a-d5f48ef04573.png)


　approximate binary mapですが、<b>二値化の方法が通常と異なります</b>。通常は、特徴量マップをsigmoidで0~1に変換して、それを閾値(例えば0.5)と比較して二値化します。
DBNetでは以下の式が適用されます。
```math
\displaylines{
B_{i,j} = \frac{1}{1+e^{-k(P_{i,j}-T_{i,j})}} \\
B: ピクセル毎のbinary \ mapの値 \\
k: ハイパラ、原論では50に設定 \\
P: probability \ mapの値 \\
T: threshold \ mapの値 \\
}
```
　このようにすることで、0,1で二値化するよりも、関連するテキストを分割するのに役立ちます。また、この形による出力は効率的な学習を促進できる点も挙げられ、これを含めて損失関数について説明します。

# 損失関数

損失関数は以下の式で表せます。
```math
\displaylines{
L = L_{s} + \alpha *L_{b} + \beta *L_{t} \\
Ls: probability \ mapの損失 \\
L_{b}: binary\ mapの損失 \\
L_{t}: threshold\ mapの損失 \\
\alpha, \beta :ハイパラ。それぞれ1.0と10で設定。\\
}
```
　$ L_{s}, L_{b} $はBCEを適用しています。ただし、検出対象(positive)と背景(negative)のバランスを調整するため、誤差を学習するnegativeなセルの数はpositiveなセルの数に対し最大でも3:1になるように調整されます(hard negative mining)。

```math
\displaylines{
L_{s} = L_{b} = \sum_{i \in S_{i}}{y_{i}logx_{i}+(1-y_{i})log(1-x_{i})} \\
S_{l}: 最大3:1になるように調整された中で選ばれたサンプルセット \\
}
```
　ここで、先ほどの数式で二値化した出力にBCEを適用した際の損失と勾配について説明します。ピクセル毎の損失とそれを微分した値は以下のようになります。
```math
\displaylines{
l_{+} = -log( \frac{1}{1+e^{-kx}}) \\
l_{-} = -log(1- \frac{1}{1+e^{-kx}}) \\
l_{+},l_{-}: ポジティブ及びネガティブラベルに対する損失 \\
x: P_{i,j} -T_{i,j} \\
}
```
微分すると
```math
\displaylines{
\frac{\partial l_{+}}{\partial x}=-kf(x)e^{-kx} \\
\frac{\partial l_{-}}{\partial x}=kf(x) \\
f(x) : \frac{1}{1+e^{-kx}}
}
```
　損失に対する勾配がk倍されており、kで勾配の大きさがコントロールできるため学習効率をよくすることが出来ます。


　$ L_{t} $について、まず使用するラベルデータは他2つとは違います。ラベル作成用のアルゴリズム説明は割愛しますが、文字部分の周りを囲むようなラベルデータを作成します。この時囲まれた部分(境界線を含む)で予測値とラベルデータのL1距離を損失にしています。

```math
\displaylines{
L_{t} = \sum_{i \in R_{d}}|y_{i}^* - x_{i}^*| \\
R_{d}: 検出エリア内部のラベルの集合 \\
y_{i}^*:閾値マップ用のラベル
}
```

# 推論
　推論時にはprobability mapと approximate binary mapのどちらでも使用できます。原論ではどちらもほとんど同じ結果になったので、よりシンプルなprobability mapのみを使用した方法で推論しています。probability mapに対して閾値は0.2で二値化して、検出部分をVatti clipping algorithm(割愛したけどラベル作成にも使用されているアルゴリズム)に従って拡張します。