1. 程式人生 > >點雲深度學習

點雲深度學習

目前二維深度學習取得了很大的進步並且應用範圍越來越廣,隨著三維裝置的發展,三維深度學習得到了很大的關注。

最近接觸了三維深度學習方面的研究,從pointnet入手,對此有了一點點了解希望記錄下來並分享,若有誤希望指正~持續更新

以下所有的解讀基於點雲分類。

一、三維深度學習簡介

二、點雲存在的問題

三、pointnet網路結構詳解

四、pointnet程式碼詳解

一、三維深度學習簡介

  1. 多視角(multi-view):通過多視角二維圖片組合為三維物體,此方法將傳統CNN應用於多張二維視角的圖片,特徵被view pooling procedure聚合起來形成三維物體;
  2. 體素(volumetric):通過將物體表現為空間中的
    體素
    進行類似於二維的三維卷積(例如,卷積核大小為5x5x5),是規律化的並且易於類比二維的,但同時因為多了一個維度出來,時間和空間複雜度都非常高,目前已經不是主流的方法了;
  3. 點雲(point clouds):直接將三維點雲拋入網路進行訓練,資料量小。主要任務有分類、分割以及大場景下語義分割;
  4. 非歐式(manifold,graph):在流形或圖的結構上進行卷積,三維點雲可以表現為mesh結構,可以通過點對之間臨接關係表現為圖的結構。流形表達比較抽象,用到拉普拉斯特徵什麼的,我也不太懂……

二、點雲存在的問題

  1. 無序性:點雲本質上是一長串點(nx3矩陣,其中n是點數)。在幾何上,點的順序不影響它在空間中對整體形狀的表示,例如,相同的點雲可以由兩個完全不同的矩陣表示。 如下圖左邊所示:
 我們希望得到的效果如下圖右邊:N代表點雲個數,D代表每個點的特徵維度。不論點雲順序怎樣,希望得到相同的特徵提取結果。

    

我們知道,網路的一般結構是:提特徵-特徵對映-特徵圖壓縮(降維)-全連線。

  下圖中x代表點雲中某個點,h代表特徵提取層,g叫做對稱方法,r代表更高維特徵提取,最後接一個softmax分類。g可以是maxpooling或sumpooling,也就是說,最後的D維特徵對每一維都選取N個點中對應的最大特徵值或特徵值總和,這樣就可以通過g來解決無序性問題。pointnet採用了max-pooling策略。

 2.旋轉性:相同的點雲在空間中經過一定的剛性變化(旋轉或平移),座標發生變化,如下圖所示:

我們希望不論點雲在怎樣的座標系下呈現,網路都能正確的識別出。這個問題可以通過STN(spacial transform netw)來解決。二維的變換方法可以參考這裡,三維不太一樣的是點雲是一個不規則的結構(無序,無網格),不需要重取樣的過程。pointnet通過學習一個矩陣來達到對目標最有效的變換。

三、pointnet網路結構詳解

先來看網路的兩個亮點:

  1. 空間變換網路解決旋轉問題:三維的STN可以通過學習點雲本身的位姿資訊學習到一個最有利於網路進行分類或分割的DxD旋轉矩陣(D代表特徵維度,pointnet中D採用3和64)。至於其中的原理,我的理解是,通過控制最後的loss來對變換矩陣進行調整,pointnet並不關心最後真正做了什麼變換,只要有利於最後的結果都可以。pointnet採用了兩次STN,第一次input transform是對空間中點雲進行調整,直觀上理解是旋轉出一個更有利於分類或分割的角度,比如把物體轉到正面;第二次feature transform是對提取出的64維特徵進行對齊,即在特徵層面對點雲進行變換。
  2. maxpooling解決無序性問題:網路對每個點進行了一定程度的特徵提取之後,maxpooling可以對點雲的整體提取出global feature。

再來看網路結構:

 其中,mlp是通過共享權重的卷積實現的,第一層卷積核大小是1x3(因為每個點的維度是xyz),之後的每一層卷積核大小都是1x1。即特徵提取層只是把每個點連線起來而已。經過兩個空間變換網路和兩個mlp之後,對每一個點提取1024維特徵,經過maxpool變成1x1024的全域性特徵。再經過一個mlp(程式碼中運用全連線)得到k個score。分類網路最後接的loss是softmax。

四、pointnet程式碼詳解

好像也沒有特別需要講的……重點我都框出來了

網路模型部分

變換矩陣部分,以第一個STN為例

以上主要引入了三維深度學習相關的一些背景知識,並介紹了pointnet整體思想和框架,那這一篇來介紹出自同一團隊的基於pointnet改進的pointnet++。同樣,以下所有的解讀基於點雲分類

一、pointnet存在的問題

二、pointnet++網路結構詳解

三、pointnet++程式碼詳解

一、pointnet存在的問題

pointnet只是簡單的將所有點連線起來,只考慮了全域性特徵,但丟失了每個點的區域性資訊,如下圖(以點雲分割為例):

所以繼pointnet之後,很多人的著重點都在提取區域性區域特徵方面。為了解決這個問題,pointnet++的整體思想就是:首先選取一些比較重要的點作為每一個區域性區域的中心點,然後在這些中心點的周圍選取k個近鄰點(歐式距離的近鄰)。再將k個近鄰點作為一個區域性點雲採用pointnet網路來提取特徵。

二、pointnet++網路結構詳解

網路的兩個亮點:

    1.改進特徵提取方法:pointnet++使用了分層抽取特徵的思想,把每一次叫做set abstraction。分為三部分:取樣層、分組層、特徵提取層。首先來看取樣層,為了從稠密的點雲中抽取出一些相對較為重要的中心點,採用FPS(farthest point sampling)最遠點取樣法,這些點並不一定具有語義資訊。當然也可以隨機取樣;然後是分組層,在上一層提取出的中心點的某個範圍內尋找最近個k近鄰點組成patch;特徵提取層是將這k個點通過小型pointnet網路進行卷積和pooling得到的特徵作為此中心點的特徵,再送入下一個分層繼續。這樣每一層得到的中心點都是上一層中心點的子集,並且隨著層數加深,中心點的個數越來越少,但是每一箇中心點包含的資訊越來越多。

    2.解決點雲密度不同問題:由於採集時會出現取樣密度不均的問題,所以通過固定範圍選取的固定個數的近鄰點是不合適的。pointnet++提出了兩個解決方案。

    方案一:多尺度分組

        如上圖左所示,比較直觀的思想是,在每一個分組層都通過多個尺度來確定每一箇中心點的鄰域範圍,並經過pointnet提取特徵之後將多個特徵聯合起來,得到一個多尺度的新特徵。

    方案二:多解析度分組

        很明顯,通過上述做法,對於每一箇中心點都需要多個patch的選取與卷積,計算開銷很大,所以pointnet++提出了多解析度分組法解決這個問題。如上圖右所示,類似的,新特徵通過兩部分連線起來。左邊特徵向量是通過一個set abstraction後得到的,右邊特徵向量是直接對當前patch中所有點進行pointnet卷積得到。並且,當點雲密度不均時,可以通過判斷當前patch的密度對左右兩個特徵向量給予不同權重。例如,當patch中密度很小,左邊向量得到的資訊就沒有對所有patch中點提取的特徵可信度更高,於是將右特徵向量的權重提高。以此達到減少計算量的同時解決密度問題。

三、pointnet++程式碼詳解

FPS和鄰域點確定的方法都是c語言程式設計的並混編成.so檔案的,下面以pointnet2_cls_ssg模型為例解釋程式碼。

整體網路結構:

特徵提取pointnet_sa_module: