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

最根本的問題是研究人員通常不共享他們的原始碼。

可驗證的知識是科學的基礎,它事關理解。隨著人工智慧領域的發展,打破不可復現性將是必要的。為此,

PaperWeekly 聯手百度 PaddlePaddle 共同發起了本次論文有獎復現

,我們希望和來自學界、工業界的研究者一起接力,為 AI 行業帶來良性迴圈。

作者丨Dicint

學校丨北京資訊科技大學

研究方向丨分割、推薦

Learning Feature Pyramids for Human Pose Estimation 是發表在 ICCV 2017 的工作,論文提出了一個新的特徵金字塔模組,在卷積網路中學習特徵金字塔,並修正了現有的網路引數初始化方法,在人體姿態估計和影象分類中都取得了很好的效果。

手把手帶你復現ICCV 2017經典論文—PyraNet

論文復現程式碼:

http://

aistudio。baidu。com/?

_=1540892031956#/projectdetail/29380

LSP資料集簡介

LSP && LSP_extended

這個資料集是由 Flickr 上‘Volleyball’, ‘Badminton’, ‘Athletics’, ‘Baseball’, ‘Gymnastics’, ‘Parkour’, ‘Soccer’, ‘Tennis’(原資料集), ‘parkour’, ‘gymnastics’, and ‘athletics’ (擴充套件集)等標籤所構成。

每個圖片都由 Amazon Mechanical Turk 和類似的途徑標註而來,並不高度準確。這些圖片被縮放至每個人大約 150 px 長度進行標註,包含了 14 個節點。

LSP 地址:

http://

sam。johnson。io/research

/lsp_dataset。zip

LSP 樣本數:

2000 個(全身,單人)

LSP_extended 地址:

http://

sam。johnson。io/research

/lspet_dataset。zip

LSP_extended 樣本數:

10000 個(全身,單人)

LSP && LSP_extended 共 12000 個標註,節點是以下 14 個:

{1。 Right ankle 2。 Right knee 3。 Right hip 4。 Left hip 5。 Left knee 6。Left ankle 7。Right wrist 8。 Right elbow 9。 Right shoulder 10。 Left shoulder 11。 Left elbow 12。 Left wrist 13。 Neck 14。 Head top}

由於是單人資料集,該資料集的訓練難度比多人資料集更簡單。

MPII資料集簡介

MPII 人體姿勢資料集是人體姿勢預估的一個 benchmark,資料集包括了超過 40k 人的 25000 張帶標註圖片,這些圖片是從 YouTube video 中抽取出來的。在測試集中還收錄了身體部位遮擋、3D 軀幹、頭部方向的標註。

MPII 地址:

http://

human-pose。mpi-inf。mpg。de

/#overview

MPII 樣本數:

25000 個(單人、多人)

包括以下 16 類標註:

{Head – 0, Neck – 1, Right Shoulder – 2, Right Elbow – 3, Right Wrist – 4, Left Shoulder – 5, Left Elbow – 6, Left Wrist – 7, Right Hip – 8, Right Knee – 9, Right Ankle – 10, Left Hip – 11, Left Knee – 12, Left Ankle – 13, Chest – 14, Background – 15}

資料集處理

MATLAB格式讀入

檔案 joints。mat 是 MATLAB 資料格式,包含了一個以 x 座標、y 座標和一個表示關節可見性的二進位制數字所構成的 3 x 14 x 10000 的矩陣。使用模組

http://

scipy。io

的函式 loadmat 和 savemat 可以實現對 mat 資料的讀寫。讀入後對原始標註進行轉置,轉置目的是分離每個圖片的標註。

import

scipy。io

as

sio

import

numpy

as

np

data

=

sio

loadmat

self

lsp_anno_path

count

])

joints

=

data

‘joints’

joints

=

np

transpose

joints

2

1

0

))

JSON格式讀入

MPII 資料集是以 JSON 格式進行的標註,可以透過 JSON 庫進行讀入。

import

json

anno

=

json

load

self

mpii_anno_pah

將每個圖片打包成(圖片,標註,bounding box)的形式,bounding box 即圖片大小,其目的是將大小不一的圖片處理成 256 x 256 的大小。

from

PIL

import

Image

for

idd

joint_idd

in

enumerate

joints

):

image_name

=

“im

%s

。jpg”

%

str

idd

+

1

zfill

5

if

count

else

“im

%s

。jpg”

%

str

idd

+

1

zfill

4

joint_id

=

idd

+

len

joints

if

count

else

idd

im_path

=

os

path

join

self

lsp_data_path

count

],

image_name

im

=

Image

open

im_path

im

=

np

asarray

im

shape

=

im

shape

bbox

=

0

0

shape

1

],

shape

0

]]

joint_dict

joint_id

=

{

‘imgpath’

im_path

‘joints’

joint_idd

‘bbox’

bbox

}

資料增強

作者用到了幾種資料增強的手段:

縮放 scale

旋轉 rotate

翻轉 flip

新增顏色噪聲 add color noise

縮放

讀入資料後,需要先把大小不一的標註圖片統一轉換成 256 x 256。

對於 LSP 測試集,作者使用的是影象的中心作為身體的位置,並直接以影象大小來衡量身體大小。資料集裡的原圖片是大小不一的(原圖尺寸存在 bbox 裡),一般採取 crop 的方法有好幾種,比如直接進行 crop,然後放大,這樣做很明顯會有丟失關節點的可能性。也可以先把圖片放在中間,然後將圖片縮放到目標尺寸範圍內原尺寸的可縮放的大小,然後四條邊還需要填充的距離,最後 resize 到應有大小。

這裡採用的是先擴充套件邊緣,然後放大圖片,再進行 crop,這樣做能夠保證圖片中心處理後依然在中心位置,且沒有關節因為 crop 而丟失。注意在處理圖片的同時需要對標註也進行處理。

要注意 OpenCV 和 PIL 讀入的 RGB 順序是不一樣的,在使用不同庫進行處理時要轉換通道。

import

cv2

big_img

=

cv2

copyMakeBorder

img

add

add

add

add

borderType

=

cv2

BORDER_CONSTANT

value

=

self

pixel_means

reshape

-

1

))

#self。show(bimg)

bbox

=

np

array

dic

‘bbox’

])

reshape

4

astype

np

float32

bbox

[:

2

+=

add

if

‘joints’

in

dic

process

joints_anno

objcenter

=

np

array

([

bbox

0

+

bbox

2

/

2。

bbox

1

+

bbox

3

/

2。

])

minx

miny

maxx

maxy

=

compute

extend_border

objcenter

in_size

out_size

img

=

cv2

resize

big_img

min_y

max_y

min_x

max_x

,:],

width

height

))

示例圖:

手把手帶你復現ICCV 2017經典論文—PyraNet

▲ 左:原圖,右:縮放後

示例圖的十四個標註點:

(88。995834, 187。24898);(107。715065, 160。57408);(119。648575, 124。30561) (135。3259, 124。53958);(145。38748, 155。4263);(133。68799, 165。95587) (118。47862, 109。330215);(108。41703, 104。65042);(120。81852, 84。05927) (151。70525, 86。63316);(162。93677, 101。14057);(161。29883, 124。773575) (136。0279, 85。93119);(138。13379, 66。509995)

旋轉

旋轉後點的座標需要透過一個旋轉矩陣來確定,在網上的開原始碼中,作者使用了以下矩陣的變換矩陣圍繞著 (x,y) 進行任意角度的變換。

手把手帶你復現ICCV 2017經典論文—PyraNet

在 OpenCV 中可以使用:

cv2

getRotationMatrix2D

((

center_x

center_y

angle

1。0

newimg

=

cv2

warpAffine

img

rotMat

width

height

))

得到轉換矩陣,並透過仿射變換得到旋轉後的影象。而標註點可以直接透過旋轉矩陣獲得對應點。

rot

=

rotMat

[:,

2

add

=

np

array

([

rotMat

0

][

2

],

rotMat

1

][

2

]])

coor

=

np

dot

rot

coor

+

w

該部分程式碼:

def

rotate

self

img

cord

anno

center

):

angle

=

random

uniform

45

135

rotMat

=

cv2

getRotationMatrix2D

((

center

0

],

center

1

])

angle

1。0

newimg

=

cv2

warpAffine

img

rotMat

width

height

))

for

i

in

range

n

):

x

y

=

anno

i

][

0

],

anno

i

][

1

coor

=

np

array

([

x

y

])

rot

=

rotMat

[:,

2

add

=

np

array

([

rotMat

0

][

2

],

rotMat

1

][

2

]])

coor

=

np

dot

rot

coor

+

add

label

append

((

coor

0

],

coor

1

]))

newimg

=

newimg

transpose

2

0

1

train_data

cnt

++

=

newimg

train_label

cnt

++

=

np

array

label

手把手帶你復現ICCV 2017經典論文—PyraNet

翻轉

使用 OpenCV 中的 flip 進行翻轉,並對標註點進行處理。在 OpenCV 中 flip 函式的引數有 1 水平翻轉、0 垂直翻轉、-1 水平垂直翻轉三種。

def

flip

self

img

cod

anno_valid

symmetry

):

‘’‘對圖片進行翻轉’‘’

newimg

=

cv2

flip

img

1

train_data

counter

=

newimg

transpose

2

0

1

‘’‘處理標註點,symmetry是flip後所對應的標註,具體需要自己根據實際情況確定’‘’

for

l

r

in

symmetry

cod

l

],

cod

r

=

cod

l

],

cod

r

for

i

in

range

n

):

label

append

((

cod

i

][

0

],

cod

i

][

1

]))

train_label

cnt

++

=

np

array

label

手把手帶你復現ICCV 2017經典論文—PyraNet

新增顏色噪聲

我所採用的方法是直接新增 10% 高斯分佈的顏色點作為噪聲。人為地損失部分通道資訊也可以達到新增彩色噪聲的效果。

def

add_color_noise

self

image

percentage

=

0。1

):

noise_img

=

image

‘’‘產生影象大小10%的隨機點’‘’

num

=

int

percentage

*

image

shape

0

*

image

shape

1

])

‘’‘新增噪聲’‘’

for

i

in

range

num

):

x

=

np

random

randint

0

image

shape

0

])

y

=

np

random

randint

0

image

shape

1

])

for

j

in

range

3

):

noise_img

x

y

i

=

noise_img

x

y

i

+

random

gauss

2

4

noise_img

x

y

i

=

255

if

noise_img

x

y

ch

>

255

else

0

return

noise_img

手把手帶你復現ICCV 2017經典論文—PyraNet

除此之外,以下資料增強的方法也很常見:

1。 從顏色上考慮,還可以做影象亮度、飽和度、對比度變化、PCA Jittering(按照 RGB 三個顏色通道計算均值和標準差後在整個訓練集上計算協方差矩陣,進行特徵分解,得到特徵向量和特徵值);

2。 從影象空間性質上考慮,還可以使用隨機裁剪、平移;

3。 從噪聲角度,高斯噪聲、椒鹽噪聲、模糊處理;

4。 從類別分佈的角度,可以採用 label shuffle、Supervised Data Augmentation(海康威視 ILSVRC 2016 的 report)。

在這個具體例子中,進行資料增強的時候要考慮的是:1)形變會不會影響結果;2)會不會丟掉部分節點。

製作Paddle資料

使用 paddle。batch 批次讀入資料,並製作成 Paddle 的資料格式。

reader

=

paddle

batch

self

read_record

test_list

joint_dict

mode

=

‘train’

),

batch_size

=

1

fluid

recordio_writer

convert_reader_to_recordio_file

“。/work/test_”

+

str

i

+

“_test。recordio”

feeder

=

feeder

reader_creator

=

reader

其他資料相關內容

論文的評價標準

PCK:

檢測的關鍵點與其對應的 groundtruth 之間的歸一化距離小於設定閾值的比例。在本篇論文中,作者將圖片中心作為身體的位置,並以圖片大小作為衡量身體尺寸的標準。

[email protected] on LSP && LSP-extended:

以驅幹直徑為歸一化標準。

[email protected] on MPII:

以頭部為歸一化標準。

關於訓練的過擬合搶救

對於容易過擬合的資料,資料增強是比較重要的,訓練的時候學習率需要不能太大,當一次訓練過擬合後,可以從 loss 曲線波動的地方回溯到較為平穩的點,並以平穩點的學習率為起點,以更低的學習率接上上次學習。

關於PaddlePaddle

查了一下資料,PaddlePaddle 最早在 16 年就已經對外開放,然而可能因為本人入門做機器學習時間較晚有關,在復現活動之前,我只是聽過有一個開源深度學習平臺而不知道其名字。

從官方開源的一些 demo 專案來講,對推薦和文字處理方面的應用比較友好,搜尋相關關鍵字也能獲得很多入門的部落格、在不同環境的安裝指南,官方甚至還做了教學影片。

據說當前版本的 Fluid 在編寫邏輯上和過去的版本已經有了很大的區別,在使用上直觀的感受是和 TensorFlow 有一定的相似性。

但由於不熟悉這個框架,也會遇到一些問題:

一開始在 AI 開放平臺上找了半天沒找到文件入口,在搜尋引擎上才發現有另一個

http://

paddlepaddle。org

的入口;當一些運算元的名字和其他框架不太一樣的時候,不太容易從文件裡找到;不清楚不同版本之間的區別(能跑就行?);官網介紹對大規模計算友好、對視覺化的支援均沒有體驗;Notebook 非常容易崩等問題等等……

儘管如此,在使用一定時間後,我覺得還是覺得挺方便的。這個框架的使用群體目前並不多,對大公司來講大家都有內部各自對 TensorFlow 的封裝性最佳化平臺,對入門者而言往往又不是那麼首選。

從個人學習路徑來講,我覺得就 TensorFlow 和現在流行的 PyTorch 而言,前者是業界工程依賴程度高,後者是研究者使用方便,PaddlePaddle 需要有一個清晰的受眾定位和有效的推廣機制。

#投 稿 通 道#

如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢?

答案就是:你不認識的人。

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

PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是

最新論文解讀

,也可以是

學習心得

技術乾貨

。我們的目的只有一個,讓知識真正流動起來。

來稿標準:

• 稿件確係個人

原創作品

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

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

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

投稿方式:

• 方法一:在PaperWeekly知乎專欄頁面點選“投稿”,即可遞交文章

• 方法二:傳送郵件至:

hr@paperweekly。site

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

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

關於PaperWeekly

PaperWeekly 是一個推薦、解讀、討論、報道人工智慧前沿論文成果的學術平臺。如果你研究或從事 AI 領域,歡迎在公眾號後臺點選

「交流群」

,小助手將把你帶入 PaperWeekly 的交流群裡。

加入社群:

http://

paperweek。ly

微信公眾號:PaperWeekly

新浪微博:@PaperWeekly