# Person Re-Identification - RMNet > [name=謝朋諺(Adam Hsieh)] > [time=Thu, Jul 4, 2019 10:46 AM] ###### tags: `paper`,`IVA`,`PR` --- ## Reference > [基于GRU和am-softmax的句子相似度模型](https://kexue.fm/archives/5743) --- # Fast and Accurate Person Re-Identification with RMNet [論文連結](https://arxiv.org/pdf/1812.02465.pdf) {%pdf https://arxiv.org/pdf/1812.02465.pdf %} ## 摘要重點 * RMNet 的骨幹是參考 ResNet 跟 MobileNet。 * 期望建立一個可以用在 mobile 的有限計算裝置上。 * 全新的輕量權重的網路接頭結合了低 loss 與高 loss 的優點,而且還不會增加參數量。 ![](https://i.imgur.com/cF3qICb.png) :::info :bulb: 上圖是作者在思考他們如何建造輕量版權重網路的思考流程 ::: ## BackBone Design * 本文遵循 "top-down" 的原則架設網路架構。 * 在 Deep 與 Shallow 中選擇了 Deep 的架構。原因是在 Bottlenet 的 Residual 架構可以被解釋為是在為同個 Level 的特徵做迭代增強,所以越深的 Level 才能看得越多,在 ResNet-18 或 ResNet-50 都太過淺,不能滿足我們的需求。e * 因此本文的網路參考了幾個架構特點: * 有著 100 多層的深層網路。 * 與 ResNet 相似的架構。 * Residual blocks 使用三層的 CNN ($1\times1 \rightarrow 3\times3 \rightarrow 1\times1$)以及非線形函數,用此方式比起兩層的 CNN ($3\times3$)可以減少許多參數量。 * RMNet Backbone: * Residual blocks 第一個 ($1\times1$)CNN 負責縮減通道數,第二個 ($3\times3$)CNN 負責空間混合,最後一層 ($1\times1$)CNN 負責將它還原到最初的輸入大小。 * 在內部卷積之後保留了非線性函數,外面的卷積也進行了 Max-Pooling 與 CNN 降到只剩 1/4 的強因子去相加。 ![](https://i.imgur.com/5jAfb8N.png) * 使用 ELU 替代常用的 ReLU 會有顯著的改善。 * 正交權重初始化(不適用於所有 Filter)。 * 使用巨大的通用數據集進行預訓練。 * 在每個 Bottleneck 結束前使用 Dropout 正規化。 ![](https://i.imgur.com/UkkTGxQ.png) ## ReID Network ### Losses * 本文定義了兩種 Loss: **Global and Local structure losses** * **Global Loss**: 定義映射函數的 Global Rule,希望能夠讓相同類別的元素越近不同類別的越遠。 * 對具有 Cross-Entropy Loss 的 Softmax 進行修改(下方第一個公式),變為關注在類之間具有較大 margin 的變數,也就是 **AM-Softmax loss**,公式如下第二個: ![](https://i.imgur.com/Cu5U0D8.png) ![](https://i.imgur.com/UOdaBm2.png) :::info :fire: **AM-Softmax** 假設原來的 softmax 是 $p=softmax(zW)$,設 $W=(c_1,c_2,...,c_n)$ 那麼 softmax 可以重新寫為 $p=softmax(<z,c_1>,<z,c_2>,...,<z,c_n>)$ 然後 loss 取交叉熵,也就是:$-log \space p_t=-log \dfrac{e^{<z,c_t>}}{\sum_{i=1}^{n}e^{<z,c_i>}}$ $t$ 為目標標籤,而 AM-Softmax 做了兩件事: :::warning 1. 將 $z$ 和 $c$ 都做 l2 Normalization,也就是說內積變成 cosine 值。 2. 對目標 cosine 值減去一個正整數 $m$,然後做比例縮放 $s$。 ::: :::info * Loss 最終就會變成 * $-log \space p_t=-log \dfrac{e^{s\cdot(cos \theta _t -m)}}{e^{s\cdot(cos \theta _t-m)}+\sum_{i\neq t}e^{s\cdot cos\theta_t}}$ * 其中 $\theta_t$代表$z,c_i$的夾角。在 **AM-Softmax** 原論文中 $s=30, m=0.35$ * $s$ 的存在是必要的,因為要讓 cosine 的範圍是 $[1,-1]$,需要做好比例縮放,才允許 $p_t$ 能夠逐漸接近 $1$。 * 但整體核心是原來的 $cos\space\theta_t$ 換成了 $cos\space\theta_t-m$ ::: 以下是用基本方式實作 **AM-Softmax** Loss 的範例程式碼: ```python= from keras.models import Model from keras.layers import * import keras.backend as K from keras.constraints import unit_norm x_in = Input(shape=(maxlen,)) x_embedded = Embedding(len(chars)+2, word_size)(x_in) x = CuDNNGRU(word_size)(x_embedded) x = Lambda(lambda x: K.l2_normalize(x, 1))(x) pred = Dense(num_train, use_bias=False, kernel_constraint=unit_norm())(x) encoder = Model(x_in, x) # 最终的目的是要得到一个编码器 model = Model(x_in, pred) # 用分类问题做训练 def amsoftmax_loss(y_true, y_pred, scale=30, margin=0.35): y_pred = y_true * (y_pred - margin) + (1 - y_true) * y_pred y_pred *= scale return K.categorical_crossentropy(y_true, y_pred, from_logits=True) model.compile(loss=amsoftmax_loss, optimizer='adam', metrics=['accuracy']) ``` * **Local Loss**: * 不使用單純的 Triplet Loss 原因是他的採樣方式將會顯著影響 model 的準確率,而且 Triplet 每次只比一個負樣本。 * 為了改善上述情況,本文將 Triplet Loss 變為: **Push and Pull Losses** * 這種 Loss 提出一種 $(N+1)$-Tuplet Loss 來同時優化一個正樣本和 $N-1$ 個負樣本,當 $N$ 為 $2$ 時等價於 Triplet。 * 當 $N$ 很大時也會承擔很大的計算負擔,因此為了解決這問題,有一種高效的 **Batch Construction** 策略可以解決,僅僅使用 $2N$ 個樣本而不是 $N(N+1)$ 個樣本就能完成 $N$ 類的優化。 * 通過 "smart" 變數 $m$ 來設定邊距。 * 最後變為三個 Losses 的架構: ![](https://i.imgur.com/jKsmNbh.png) * 最後整體 Loss 就是將 global 與 local 的 loss 相加($w_i$ 是指預估每個 loss 在總和中的影響): ![](https://i.imgur.com/gKvZksp.png) ## Re-identification Head * 網路的最後一層 re-identification head 負責把骨幹中的輸出結果映射到 embedding,並且可以利用此 embedding 去計算 **cosine similarity** 或**歐式距離**。 * 一般我們都會使用 **Fully Connected** 去當最後一層輸出,但它卻會==浪費太多運算資源==,不便於移動裝置。 * 另外有些人會使用 global-pooling 當作輸出層,像是 max-pooling 或是 average-pooling,如下圖所示: ![](https://i.imgur.com/8tFtRSD.png) * 本文的 Re-identification 有兩個關鍵元件: * 第一個是在 GMP 之後的 inverted bottleneck,裡面由 CNN ($1\times1$) 組成,將 channel 數由 256 變為 512 再壓回 256。 * 第二個是利用 **Global Loss** 和 **Local Loss**,只用 **Local Loss** 進行訓練,然後通過學習 **Global Loss** 來校準它。 * 對這兩種 Loss,本文皆使用 **L2 Normalization** 來遵循 **AM-Softmax** 提出的 embedding 限制(與 **Cosine Similarity** 兼容)。最後網絡輸出是最後一次校正 embedding。 ## Network Architecture * 這個網路主要由兩個元件組成:輕量級特徵提取器 (**RMNet-based Backcone**) 和單個 **Re-Identification Head**。 * 為了減少整體運算時間,本文遵循**完全卷積網路**(Fully Convolutional Network,FCN),沒有任何的全連接網路 (Fully Connected Network)。 * 最後透過 **$L_2$ Normalization** 擷取出的向量來當作此圖的 Embedding,並可拿來與其他圖片做 Cosine Similarity 計算距離。 ## Optimization * 本論文使用 Caffe 的框架。 * 使用有著 momentum 的 **SGD** Optimization,並以每 50k 迭代後將 Learning Rate 做 $10^{-1}$ 的 Decay,起始 Learning rate 設為 $10^{-2}$。 * 初始化方式使用混合策略: * 每個 Bottleneck 的 CNN($1\times1$) 被==正交初始化==,其餘權重使用 ==MSRA== 方法初始化。 * 本文還在 ==OpenImages== 上先做預訓練,預訓練的圖片是將擷取後的物件 crop 出大小為 $224\times224$,並且是在上面做分類的任務。 * 訓練輕量級網路有個重點,就是==盡量利用大部分的參數,避免修剪模型(Pruning model)== 而是使用 ==Dropout 去正規化 (Ratio: 10%)==。 * 但 Dropout 縮減了整體網路的容量,並且不適用於本文一開始說的小型架構,為了解決這問題,本文在==後期的迭代就禁用了 Dropout (當 Learning rate 夠小的時候)==,這種架構將會讓本模型早期除了不會過度擬合以外,而且可以再後期用盡所有的網路容量。 * 為了==解決資料不平衡==的問題,有了以下的做法 **(Hard Sample Mining,HSM)**: 1. 每個分類採樣 k 個增強的影像。 2. 估算每個樣本的 Loss 值:$w_1L_{glob}+w_2L_{center}+w_3L_{gpush}$ 3. 選擇最難的前 50% Loss。 4. 在最難的樣本上做小批次的訓練。 5. 最後增加難度的數量並開始訓練。 * 除了標準==水平翻轉== 以及==Random Crop== 外,最有用的方法是==Random Erasing==。 ## Ablation Study (控制變量法、對比實驗、參數敏感性分析) ### ReLU & ELU ![](https://i.imgur.com/vTg9hNf.png) * 上圖是利用 ReLU 跟 ELU 的比較,為了證明 ReLU 並不適用於這個問題,本文計算每個 CNN 中的濾波器權重絕對值之間的比例 $w_{max}/w_{min}$,高比例的值代表有不合理的濾波器在現今的 Level 上。 * 可以看出來在 ReLU 的網路架構上有超過一半以上的 Noisy Filter,而且這些濾波器往往都會變成被修剪掉以用來壓縮模型所使用。 * ELU 的結果就有顯著差別,基本上不太需要修剪 Filter,因此在不影響模型品質上本文選擇用 ELU 當作 Activation Function。 ### Ablation Study on Marlet-1501 Dataset ![](https://i.imgur.com/hkFVEvi.png) 第一項僅使用 AM-Softmax Loss 而且模型大小有限,因此如果要跟其他最先進的(SOTA)結果比較還有段距離。 1. 本文先解決資料不平衡的問題,而使用的方法就是利用 Hard Sample Mining (HSM),但未執行上面 HSM 的第 2 步驟。 2. 通過引入不同的局部結構 loss 來深入研究 manifold 學習方法:Center、Push、GlobPush,每個步驟都改善了我們的模型。 3. 尤其是在 Push 跟 GlobPush 使用了 Smart Margins 更是獲得了顯著的改進。 4. 本文一開始有說有使用 Dropout 可能導致模型的容量受限,因此在訓練後期禁用 Dropout 之後,也獲得了顯著的上升。 5. 最後一個增加效果的方法是將多個 Loss 混合到排名標準中來使 Sample Mining 過程更靈活(上面 HSM 的第二點,更聰明地考慮不同 Level Loss 的複雜度),主要改進了 mAP 的結果。 6. 為了跟效果最好的幾個 Paper 做比較,本文也做了不同解析度的輸入測試,本文主要用 $160\times64$ 的解析度當輸入,也測試了 $384\times128$ 可以看出效果的確也有上升,但速度會變慢。 ## Result ### OpenVINO on Intel Core i7-6700K CPU@2.90GHz ![](https://i.imgur.com/cGlwBtw.png) * 由上表可以看出本文的效果快上很多,這是由於本文不是用 ResNet-50 而是用 RMNet 的 Backbone。 * 本文提出的 Loss 跟訓練策略是使我們可以用這麼少參數還可以訓練這麼好的原因。 * 依照本文的做法 FPS 可以跑到 923,甚至可即時處理每個 Frame 約 30 人,目前沒有技術可以做到。 ## 實作後的模型 ![](https://i.imgur.com/n3qcohH.jpg)