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

經典論文復現 | 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)

分享創造快樂