18年是GNN開始初出茅廬也是大放異彩的一年, 這篇論文是李飛飛團隊的關於GNN在CV領域中的一個開拓性的應用.甚至作者陳鑫磊稱, 通過結合CNN和GNN, 本文發明了"下一代的視覺識別系統". 這個觀點是不是很讓人瑟瑟發抖? 好了, 下面開始分析論文結構和代碼組成.
0. 論文簡述
近年來, 由於卷積神經網絡的大放異彩, 我們在如圖像分類, 圖像分割等經典的CV任務中取得了很大的進展. 但是, 我們人類的視覺推理行爲中, 空間信息(spatial)和語義信息(semantic)對於識別效果非常關鍵. 而現有的視覺系統缺乏上下文推理(context reasoning), 即現有方案只是用卷積和大感受野來完成經典的CV任務.
本文正是爲了解決這個侷限, 提出了"吸收了空間信息和語義信息的下一代迭代視覺推理系統".
作者通過下圖舉例, 在實際的複雜場景情況中, 如果一個物體很小, 或者目標很模糊, 或者這個物體被遮住一部分, 那麼我們在做目標檢測時, 我們現在的算法會忽略這些目標. 但是人類可以通過周邊的事物以及物體的大致形狀推斷出這個目標的類型.
左上角的窗戶, 如果一排有3個都是窗戶, 則第4個也有很大的概率也爲窗戶(spatial reasoning); 右下角的公交車, 雖然被遮擋, 但是可以通過周邊的object來推斷出其是一個公交車(semantic reasoning).
因爲網上有很多博客對本文進行通篇翻譯了, 這裏簡單來說說這個下一代視覺推理系統的組成模塊:
- ① local module (負責像素級推理)
仍然屬於卷積推理模式.
- ② global module (負責基於圖結構的推理)
根據區域region和class建立圖(region和class都是圖中的兩種node, region-region, class-class, region-class是圖中的三種edge.)
- ③ 將兩個模塊輸出的結果進行cross-feed (進行spatial 和 semantic 特徵的融合)
這兩個模塊相互迭代, 把輸出相互喂.以便優化我們的估計: estimates.
- ④ 加入timestep維度 (可以參考Keras裏面的
ConvLSTM2D
)
下圖的, , , 對應第1個時間步的輸出. 同樣地, , , , 對應第n個時間步的輸出. 可以看出在推理框架最後的attention-based prediction中, 將每個時間步的都放到下面的attentions裏面, 進行combined; 同理對.
經分析代碼得知, 的shape的N x n_classes(在ADE數據集是1485個類別), 是經過softmax的結果, shape保持不變.
1. 局部模塊local module
局部模塊中:
-
① spatial memory()的概念是: 用將輸入的obj的區域按一定的規則放置在經過多層卷積後的特徵圖中對應的位置.S爲3維: x x (拋開batchsize這個維度), 爲設置的超參數深度(512)
其中, 和是輸入模型的原始圖像的高和寬. -
② 推理模塊卷積網絡, 它由三個3*3的卷積核, padding=same的卷積層和兩個hidden unit=4096的全連接層組成。
給定一個未更新的圖像區域,先通過特徵提取,然後使用bilinear插值將其調整爲大小7 x 7的區域 。因爲高層的特徵是覆蓋整個區域的向量,所以我們將這個向量附加到的所有位置,通過1 x 1的卷積核來提取特徵,並且輸出。記憶存儲器中的相同區域也提取出來,通過經過crop & resize, 變爲7 x 7,標記爲。這一步後,我們使用類似GRU的策略:
注意, 代碼的更新策略是 , 跟上式不同.
其中,是更新後的記憶,是更新門,是重置門,,和分別是卷積的權重和偏置,∘表示entry-wise矩陣內積(hadamard積),表示激活函數。更新後,通過提取特徵和尺寸調整重新放回.
下面說一下代碼裏面的memory 更新策略(代碼中的bsize都是1, ADE數據集的類別爲1485):
我看的是PyTorch版本:https://github.com/coderSkyChen/Iterative-Visual-Reasoning.pytorch
在第1次迭代的時候: mem是 bsize x 512 x sh x sw(值都是0)的Tensor.
- ① 因爲讓原始圖像通過resnet50的前4層, 得到了一個shape爲bsize x 1024 x sh x sw的base_feature_map(簡寫叫base_feat), 對其後面接上自定義的
CropAndResize
層後, 得到pool5/pool5_nb, 其shape爲N(region個數) x 1024 x 7 x 7
輸入到resnet50的最後1層, 最後接上一個用於分類的全連接層. 得到cls_score_conv
, 其shape爲N(region個數) x n_classes(1485). - ② 以第一次迭代進行說明memory 更新方式:
重要參數說明:
pool5_nb(Tensor) N x 1024 x 7 x 7.
cls_score(Tensor) N x 1485, 是self._mem_pred中的第1個返回值.
mem(Tensor) 1 x 512 x sh x sw(全是0).
rois(Tensor) N x 4
inv_rois(Tensor) N x 4 (跟rois一起產生, 維度一樣, 不過數值都很小)
iter(int) 0, 1, ...
處理流程說明:
① 與self._mem_pred生成mem_ct_pool5之前先卷積不同, pool5_mem是直接通過對mem進行CropAndResize得到的
N x 512 x 7 x 7的Tensor.
② self._input_module是由1個bottomup module和1個卷積層+ReLU的序貫模型組成的.
其中:
2.1) self._bottomtop按作者註釋的意思是: "讓特徵的描述能力更豐富" 也就是論文裏面提到的bottomtop機制在本推理框架中的使用.
它由2個part組成: self._bottomtop_fc和self._bottomtop_conv.
具體說明在放在這個函數體內部了.
2.2) self._input就是一個卷積層+ReLU, 接收的是_bottomtop的輸出.
得到N x 512 x 7 x 7的pool5_input.
③ 接着,把前面得到的pool5_input & pool5_mem傳入到self._mem_update函數中.
這個函數的作用是實現論文中的公式1的邏輯.
btw, 大致計算邏輯跟公式1一樣, 有差別, 差別記錄在self._mem_update函數的註釋中了.
通過這一步, 得到mem_update: N x 512 x 7 x 7的Tensor.
④ 最後, 通過self._inv_crops將mem_update變成 N x 512 x sh x sw的 tmp_mem, 按其depth求和,
得到mem_diff: N x sh x sw的Tensor.
一定要注意! 記憶mem(S)是要從N x 512 x 7 x 7 回到 1 x 512 x sh x sw的, 因爲mem的原始狀態就是 1 x 512 x sh x sw的.
因爲 self._count_matrix_eps爲 1 x sh x sw. 更新memory用到的 / 跟前面公式1中的 * 相似.
最終!!! 我們通過這一大堆的操作, 更新mem, 並返回!
2. 全局模塊global module
global module裏面有3組點–邊關係
-
a) (Region的節點) (Region的邊) 區域圖
-
b) 到的邊和: 在爲Region分配class的時候建立. 分配圖
-
c) (Class的節點) (Class的邊) 知識圖
類之間的關係有 “相似” “屬於” “一部分”
比如:
cake屬於food.
wheel is part of car.
puma與leopard相似.
上圖顯示瞭如何在擁有不同類型的邊(edge)的圖中直接傳遞信息.容易看出:
node之間的聯繫是單向的. 鄰近矩陣(adjacency matrix)中, 紅色表示有連線的邊.白色表示無連線的邊. 我們有3種edge類型,2種node類型.
如圖所示,四個節點之間通過不同的邊連接。每個節點表示一個輸入特徵向量。中間的表示連接矩陣,用來描述各邊之間的關係,我們通過訓練學習到一組權重。最後的輸出爲。
接着就是推理的過程。我們假設輸入是和(類別),讓它們分別走global module中兩條推理路徑(spatial path/ semantic path).
以region=2爲例, 圖像中的信息就是一個人騎車.對region node: 爲2x512. 人標識爲region1.車標識爲region2.對class node: 爲class(比如我們這個任務只有3個類:人,自行車, 樹, 那麼這個class應該爲3,跟region的個數無關)x512.
這裏, R = 2, C = 3, D = 512.
下面的r, c, d對應上面舉得例子中的R, C和D.
所以, 就像我們在CNN中堆疊卷積層一樣,我們同樣可以堆疊組建上面所說的結構.輸出可以作爲下一個圖形操作的輸入, 這允許本框架使用更深層次的特徵執行聯合空間-語義推理 (spatial-semantic reasoning).
3. 迭代推理Iterative Reasoning
推理過程中關鍵組成部分是迭代地(iteratively)構建估計(estimates).
但是,信息是如何從一次迭代傳導到下一次的呢?我們用explicit memory
來做這件事.explicit memory
存放了之前所有迭代的歷史信息.
在第i次迭代時, local module
中, 我們將輸入到卷積推理模塊來生成對每個region的新的預測結果. 同樣地, global module
, 有同樣地情況,從中產生新的預測結果.
雖然說使用者可以獨立使用local module
和global module
.
但是我們想發揮兩個模塊的合力(join force),所以提出了cross-feed connections
的策略:
“在每次迭代推理後, local/global的輸出將會concat, 通過類似GRU的策略來更新M_{i+1}.”
通過這樣, local module
中的空間記憶單元可以從
全局空間信息(global knowledge of spatial) 和 語義關係(semantic relationships) 中汲取信息; global module
中的圖也能更加理解局部區域的佈局(有助於圖結構的構建更加貼合實際情況.).
4. 試驗結果
通過在ADE數據集的試驗, 作者認爲通過這種新式結構獲得的準確率和精度的提升收益高於增加捲積網絡的深度。
圖中藍色的部分的兩個數字分別表示baseline的預測值和本方法的預測值.
顯然, 對機身(fuselage), baseline預測的結果是0.26, 0.01,0.10 而本文方法預測的結果大大優於baseline.
5. 參考資料
[1] Iterative Visual Reasoning Beyond Convolutions
[2] Iterative Visual Reasoning Beyond Convolutions論文筆記
[3] Iterative Visual Reasoning Beyond Convolutions 卷積推理網絡論文翻譯和閱讀