歡迎光臨
每天分享高質量文章

經典論文復現 | PyraNet:基於特徵金字塔網路的人體姿態估計

過去幾年發表於各大 AI 頂會論文提出的 400 多種演演算法中,公開演演算法程式碼的僅佔 6%,其中三分之一的論文作者分享了測試資料,約 54% 的分享包含“偽程式碼”。這是今年 AAAI 會議上一個嚴峻的報告。 人工智慧這個蓬勃發展的領域正面臨著實驗重現的危機,就像實驗重現問題過去十年來一直困擾著心理學、醫學以及其他領域一樣。最根本的問題是研究人員通常不共享他們的原始碼。 


可驗證的知識是科學的基礎,它事關理解。隨著人工智慧領域的發展,打破不可復現性將是必要的。為此,PaperWeekly 聯手百度 PaddlePaddle 共同發起了本次論文有獎復現,我們希望和來自學界、工業界的研究者一起接力,為 AI 行業帶來良性迴圈。


作者丨黃澤宇

學校丨深圳大學

研究方向丨計算機圖形學、深度學習

Learning Feature Pyramids for Human Pose Estimation 是發表在 ICCV 2017 的一篇有關人體姿態估計的論文,提出利用特徵金字塔來進行人體姿勢預測。作者是 Wei Yang,香港中文大學博士生。


論文復現程式碼: 


http://aistudio.baidu.com/aistudio/#/projectdetail/24019

人體姿態估計介紹


人體姿態估計是計算機視覺領域一個較有挑戰性的任務,問題的輸入是一張圖片,輸出是圖片中的人體各個關節點的位置,如下圖所示。人體姿態任務可以是單人姿態估計,或者是多人姿態估計,而本文給出的方法是單姿態估計,即一張圖片只預測一個人的姿態。



在本文之前,在人體姿態估計效果較好的工作是 2016 年 Alejandro Newell 等人的 Stacked Hourglass Networks for Human Pose Estimation [1],而本文的網路結構是在此之上的改進, 因此 Hourglass Network 的相關設計對理解本文網路非常重要。


重要工作介紹

Stacked Hourglass Network


Stacked Hourglass Network 是一種堆疊沙漏型的全摺積網路,能夠很好地捕捉圖片的多尺度特徵,並由粗到細地預測關節點位置的熱力圖 Heatmap,即關節點出現在各個位置的機率。最終的關節點的位置預測結果取 Heatmap 中機率最大的索引。

網路的基本結構如下圖所示,可以看到網路後面都是由一個個沙漏型的結構堆疊而成的。



Hourglass Module 


沙漏模組則是一種編碼器-解碼器加短接層的設計,其動機是捕獲多尺度資訊。因為對於人體的各個不同部位的大小尺度是不一樣的,透過短接層將不同尺度下的特徵圖加入到解碼階段可以獲得更尺度的資訊,從而得到更精準的預測。



Hourglass 模組和 Networks 中的白色方塊表示的都是類似於 ResNet 中的殘差模組 [2],其作用是在保留原特徵資訊的同時進一步提取更深層次的特徵,同時也能使得網路變得更深又不至於梯度消失。


像堆疊殘差模組一樣堆疊沙漏模組就得到了堆疊沙漏網路。值得註意的是,沙漏模組的輸入和輸出大小可以是一樣的,也就是說在每個沙漏模組之後都可以進行最終結果的預測並計算損失,起到中間監督作用


另外,上層模組的預測結果也可以作為下層模組的輸入,從而更好的幫助下層模組進行預測,因此預測結果也可以透過 1*1 的摺積重新加入到原來的特徵中,進行由粗糙到細緻的估計



改進方向 


為了捕捉不同尺度的,除了使用短接層,還可以使用不同的摺積核同時進行摺積,再將得到的特徵進行疊加,比如 Inception 模組 [3]。Inception 模組透過使用不同大小的摺積核以及 1*1 的摺積使得網路能夠捕捉不同解析度的特徵,並減少引數數量。



而在減少引數數量方面,ResNeXt 又在 ResNet 更進一步 [4],將初始的輸入分裂成多條分支進行摺積,其中每條分支的摺積核大小都是一樣的。



另外,使用空洞摺積也可以獲得多尺度的特徵 [5],空洞摺積是透過使用具有間隔的摺積核在特徵圖上進行摺積從而避免對原特徵圖進行下取樣的步驟。


本文方法


Pyramid Residual Modules (PRMs)


可能是受到上述三種模組的啟示,本文作者設計出了四種特徵金字塔模組如下圖所示。


PRM-A 是在原先的殘差模組的分支基礎上,直接增加多個解析度的分支,其解析度的不同主要是透過下取樣實現的,而由於殘差模組的結果需要將不同分支的結果相加,因此下取樣後的特徵要透過上取樣恢複原來解析度。


PRM-B 則是將 PRM-A 中不同解析度的分支開始的 1*1 摺積進行引數共享,從而減少引數數量。


PRM-C 則是將 PRM-B 中多解析度特徵的相加改為了串聯,由於串聯後的特徵通道數與原來不同,因此可能需要再進行一個 1*1 的摺積對齊特徵通道後再與原特徵相加。


PRM-D 則是使用空洞摺積代,替下取樣和上取樣得到多尺度的特徵。


根據後面的實驗結果可以看到在準確率、引數數量和複雜度的權衡之下,PRM-B 模組是較好的選擇。



Output Variance Accumulation 


除了上述的改進,本文作者還提到原始的殘差模組有輸出方差積累的問題,當堆疊多個殘差塊時,將原始特徵直接與摺積後的特徵相加時會有較大的方差,透過對原始特徵新增一個 Bn-ReLu-Conv 操作可以較好的控制這個問題。



PyraNet 


本文網路框架使用 Stacked Hourglass Network 的基本框架,但將其中的殘差模組都替換成了上述特徵金字塔模組 PRMs,網路結構圖如下。



再談初始化 


網路引數的初始化對網路的訓練以及結果會有一定影響,為了使得網路更順利的開始訓練,有許多不同的初始化方案,其中較常見的即是 Xavier [6]


Xavier 


Xavier 的提出者指出,第 i 層的引數方差從正向和反向傳播的角度考慮,應分別滿足如下式子。其中的 n_i 和 n_(i+1) 分別是該層輸入的元素個數以及輸出的元素個數。



折衷考慮,Xavier 初始化的引數方差同時考慮輸入和輸出元素個數,即將上述兩式相加後得到的結果。



Initialization Multi-Branch Networks 


本文作者考慮到提出 Xavier 時的大部分網路並沒有多條分支,因此對多分支網路的初始化方案重新考量,得出瞭如下的更泛化的結果。其中 l 表示網路層數,C_i 和 C_o 分別表示輸入和輸出分支數,n_i 和 n_o 分別表示各輸入和輸出分支的元素個數,α 根據啟用函式有不同取值,ReLu 取 0.5。即從前向和反向傳播的角度考慮,各層引數初始化時的方差應與各輸入分支合併前的總元素個數、各輸出分支分離後的總元素個數有關。



折衷考慮,多分支引數初始化的方差在文中應為滿足如下式子。註意到 α 帶有平方,特殊情況下,若 α 取 0.5,輸入輸出均只有 1 條分支,結果與 Xavier 不一致,因此筆者認為 α 不應取平方,這樣在上述情況下仍能 Xavier 保持一致,作為 Xavier 的泛化。


實驗結果與分析


人體姿態估計準確性 


本文在 MPII 和 LSP、LSPEt 資料集上進行訓練,使用 PCK (Percentage of Correct Keypoints) 和 PCKh 進行評估,PCK 計算估計的關鍵點與真實值間的歸一化距離小於設定閾值的比例,PCKh 則以頭部長度為參考的歸一化。實驗結果如下,可以看到使用 PRM-B 的 PyraNet 在所有對比的方法中都取得了最好的準確率。


控制變數比較 


在網路結構的對比實驗中可以看到,相比於 Baseline 即普通的 Stacked Hourglass Network,PyraNet 使用的特徵金字塔和多分支引數初始化方案都有提高結果的準確性。


其他實驗 


本文作者使 PRM 替代相應網路的殘差模組在 CIFAR-10 上進行訓練,得到最低的 Top-1 測試誤差,但網路的大小和運算量稍有增加。



總結


本文的主題雖然是人體姿態估計,但提出的改進和創新較為普適,在其他任務上也可以進嘗試。主要思想有如下: 


1. 本提出了特徵金字塔殘差模組,增強了深度神經網路的尺度不變性;


2. 本文提出了多分支引數初始化方案,使得網路訓練更順利;


3. 本文提出了透過在短接層增加一次摺積來減少殘差模組輸出方差積累的問題。

PaddleFluid模型復現

註:程式碼中的 bn_relu_convn*n 是對依次使用 PaddleFluid 的 batch norm、relu 和摺積核為 n 的 conv2d 的封裝。 


1. 定義特徵金字塔模組:特徵金字塔首先將輸入進行不夠規模的下取樣,再進行特徵提取,然後將下取樣後提取的特徵上取樣回輸入大小。原文使用了 Fraction pool 進行下取樣,使得下取樣更加平滑,而 PaddleFluid 並沒有實現 Fraction pool,故只能使用簡單的二線性插值 Resize bilinear 進行代替。


def pyramid(input, out_ch, ngroup):
    output_res = input.shape[-1]
    scale_base = pow(2.01.0/ngroup)

    # extract features in different resolution
    features = []
    for i in range(1, ngroup+1):
        # subsample
        scale = round(1.0/pow(scale_base, i),4)
        feature = resize_bilinear(input, scale=scale)

        # extract the feature
        feature = bn_relu_conv3x3(feature,out_ch)

        # upsample
        feature = resize_bilinear(feature, out_shape=[output_res, output_res])

        features.append(feature)

    # sum up features
    output = features[0]
    for i in range(1, ngroup):
        output = elementwise_add(output, features[i])   
    return output


2. 定義 PRM 特徵金字塔殘差塊:在一般的 ResNet 殘差模組的基礎上進行擴充套件,在進行完 3*3 的摺積後再加入一個特徵金字塔,這裡實現了上述的 PRM-B,即所有特徵金字塔分支使同一個輸入。


def conv_block(input, out_ch, type='prm-b', base_width=6, cardinality=30):
    # 1*1 conv
    conv_out = bn_relu_conv1x1(input,out_ch//2)
    # 3*3 conv
    conv_out = bn_relu_conv3x3(conv_out,out_ch//2)

    if type == 'res':
        output = bn_relu_conv1x1(conv_out,out_ch) 
        return output
    elif type == 'prm-b':
        pyra_depth = out_ch//base_width
        ngroup = cardinality

        # extract feature pyramid
        # 1 branch in, ngroup branches out
        pyra_out = bn_relu_conv1x1(input, pyra_depth,in_branches=1,out_branches=ngroup)

        pyra_out = pyramid(pyra_out, pyra_depth, ngroup)

        # ngroup braches in, 1 branch out
        pyra_out = bn_relu_conv1x1(pyra_out, out_ch//2,in_branches=ngroup,out_branches=1)

        # 2 branches in, 1 branch out 
        output = elementwise_add(conv_out, pyra_out)
        output = bn_relu_conv1x1(output, out_ch,in_branches=2,out_branches=1)
        return output        
    TODO: PRM-A/PRM-C/PRM-D
    return output


3. 按照 Stacked Hourglass Network 的方式定義沙漏模組和堆疊沙漏模組(程式碼略)。值得註意的是 Hourglass 是一個遞迴的結構,因此可以使用遞迴函式來建立網路結構。


4. 定義初始化方案 Branch initializer,筆者使用 Xavier 進行泛化,加入了輸入輸出分支數。


def branch_initializer(in_units=1,out_units=1,in_branches=1,out_branches=1,act='relu',uniform=False,seed=0):
    # it might be alpha instead of alpha**2 in formula.15
    # in this case, when in_branches=out_branches=1, it degenrates to Xavier
    alphax2 = 0.5*2 if act=='relu' else 1.0*2
    fan_in = in_units*in_branches*alphax2
    fan_out = out_units*out_branches*alphax2
    return Xavier(uniform,fan_in,fan_out)


5. 網路訓練:實驗使用 PaddleFluid v0.14 環境,Titan Xp 單 GPU,在 MPII 資料集上進行訓練,訓練圖片 20k 張,測試圖片 2k 張,訓練時進行了資料增強。PyraNet 堆疊沙漏數 nstack=2,殘差模組使用 PRM-B 結構,特徵金字塔分支數 cardinality=4,通道基數 base_width=9,批大小 batch_size=8,訓練輪述 epoch=150,使用 Adam 最佳化器,學習率 2.5*10^-4 且每 10 輪衰減至 90%,初始化使用 Xavier 泛化後的多分支初始化。對照組除了殘差模組為普通 res 模組其他引數均相同。 


6. 實驗結果:本次復現結果使用 PRM-B 模組的 PyraNet 並沒有比使用 Res 模組的堆疊沙漏網路效果要好。準確率使用 PCKh@0.5 進行評估。


準確率曲線如下:使用 PRM-B 由於發生了過擬合,在 Epoch=110 處進行了早停,而使用 Res 則在 Epoch=110 時接近收斂。



7. 結果對比分析:復現結果本應是使用 PRM-B 模組的 PyraNet 要好於使用 Res 模組的堆疊沙漏網路,但結果卻相反。 


在訓練時發現一個問題,即 PyraNet 很容易過擬合,調整多次都沒有得到很好的結果,而普通的堆疊沙漏網路訓練則非常穩定。推測是由於加入了特徵金字塔結構,分支數太多,網路變得複雜,所以難以訓練。由於時間關係,也沒有將網路除錯到最好狀態。



8. 結果視覺化:下麵是幾個使用 Res 模組的堆疊沙漏網路實驗結果的視覺化,可以看到預測出了基本的人體姿勢。


關於PaddlePaddle

這是筆者第一次接觸並復現有關人體姿態預測的論文,也是首次嘗試使用 PaddlePaddle,並沒有取得很好的結果。


人體姿態檢測相比於簡單的圖片識別、生成,資料處理過程更複雜,計算量更大,網路結構一旦變得複雜,就會變得難以訓練。同時網路變得更大引數數量急劇增加,只能用很小的批大小進行訓練,也容易使得網路陷入區域性最小值。


而 PaddlePaddle 則是極具潛力的深度學習框架,很容易上手,目前還只是實現了最基本、最常見的一些操作,對於實現純摺積網路來說非常便利,期待未來版本有更強大的功能和更好的使用體驗。


參考文獻


[1]. Newell A, Yang K, Deng J. Stacked Hourglass Networks for Human Pose Estimation[J]. 2016:483-499. 

[2]. He K, Zhang X, Ren S, et al. Deep Residual Learning for Image Recognition[C]// IEEE Conference on Computer Vision and Pattern Recognition. IEEE Computer Society, 2016:770-778. 

[3]. Szegedy C, Liu W, Jia Y, et al. Going deeper with convolutions[J]. 2014:1-9. 

[4]. Xie S, Girshick R, Dollar P, et al. Aggregated Residual Transformations for Deep Neural Networks[J]. 2016:5987-5995. 

[5]. Chen L C, Papandreou G, Kokkinos I, et al. DeepLab: Semantic Image Segmentation with Deep Convolutional Nets, Atrous Convolution, and Fully Connected CRFs.[J]. IEEE Transactions on Pattern Analysis & Machine Intelligence, 2018, 40(4):834-848. 

[6]. Glorot X, Bengio Y. Understanding the difficulty of training deep feedforward neural networks[J]. Journal of Machine Learning Research, 2010, 9:249-256.


點選標題檢視更多論文解讀: 


#投 稿 通 道#

 讓你的論文被更多人看到 


如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢? 答案就是:你不認識的人。


總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋梁,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。 


PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學習心得技術乾貨。我們的目的只有一個,讓知識真正流動起來。

來稿標準:

• 稿件確系個人原創作品,來稿需註明作者個人資訊(姓名+學校/工作單位+學歷/職位+研究方向) 

• 如果文章並非首發,請在投稿時提醒並附上所有已釋出連結 

• PaperWeekly 預設每篇文章都是首發,均會新增“原創”標誌


? 投稿郵箱:

• 投稿郵箱:hr@paperweekly.site 

• 所有文章配圖,請單獨在附件中傳送 

• 請留下即時聯絡方式(微信或手機),以便我們在編輯釋出時和作者溝通



?


現在,在「知乎」也能找到我們了

進入知乎首頁搜尋「PaperWeekly」

點選「關註」訂閱我們的專欄吧



關於PaperWeekly


PaperWeekly 是一個推薦、解讀、討論、報道人工智慧前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號後臺點選「交流群」,小助手將把你帶入 PaperWeekly 的交流群裡。

▽ 點選 | 閱讀原文 | 收藏復現程式碼

贊(0)

分享創造快樂