non-local操作如公式1所示,表達的意思就是利用xi附近的xj的資訊來得到yi。
那麼公式1中的兩個函式具體要怎麼實現呢?
在實驗中為了簡單計算,g()預設採用下面的形式(**實現上通過卷積來實現):
而f()函式是文章研究的重點,文章中列舉了f()函式的4種形式:
我們把figure2中的這一部分截圖下來,這一部分實現的就是f()操作,可以看出前面介紹的embedded gaussian就是截圖的完整操作(因為softmax操作會有乙個分母,也就是c(x),因此截圖中的softmax操作就完成了f()函式的冪計算和除以c(x)計算);gaussian就是對應截圖中去掉θ和φ的結果;dot product對應截圖中將softmax換成1/n。
前面介紹的是f()函式的幾種形式,接下來作者通過公式6將前面介紹的non local包裝成乙個block,這個block就類似resnet網路中的block,這樣non local操作就可以很方便地插入到現有的網路結構中。這裡的yi就是前面公式1中的yi,w*y對應figure2中右上角的1*1*1卷積;+xi就是residual connection,也就是figure2中最上面的element-wise sum操作。
因此公式1+公式3+公式6就是figure2。換句話說figure2表示f()函式採取embedded gaussian且新增了residual connection的計算圖。資料流是這樣的:輸入x的維度是t*h*w*1024,然後分別用數量為512,尺寸為1*1*1的卷積核進行卷積得到3條支路的輸出,維度都是t*h*w*512,然後經過flat和trans操作得到thw*512、512*thw和thw*512的輸出,前兩條支路的兩個輸出進行矩陣乘法得到thw*thw的輸出,經過softmax處理後再和第三條支路的輸出做矩陣乘法得到thw*512維度的輸出,將該輸出reshape成t*h*w*512維度的輸出後經過卷積核數量為1024,尺寸為1*1*1的卷積層並和原來的t*h*w*1024做element-wise sum得到最後的輸出結果,這個element-wise sum就是resnet網路中的residual connection。
為了提高non local block的計算效率,作者還從兩個角度做了優化:1、θ、φ和g操作的卷積核數量設定為輸入feature map通道數的一半(figure2中512對1024)。2、對φ和g輸出採取pooling方式進行抽樣,這樣φ和g輸出的feature map的size就減小為原來的一半。這二者在**中都有體現。
從公布的**來看,non local並不是對網路的每個block都引入,思考下原因可能是:non local機制的設計初衷就是為了獲取全域性資訊,而原來的卷積操作是為了獲取區域性資訊,二者相輔相成才能有好的效果。
實驗結果:table3是在kinetics資料集上和其他演算法的對比,可以看出只採用rgb作為輸入的non-local i3d演算法效果還是很不錯的。
table5是non-local機制在coco資料集上的檢測和分割效果提公升情況,基本上都能提公升1個百分點。
global和nonlocal的用法
1 global關鍵字用來在函式或其他區域性作用域中使用全域性變數。但是如果不修改全域性變數也可以不使用global關鍵字,global適用於函式內部修改全域性變數的值 2 nonlocal關鍵字用來在函式或其他作用域中使用外層 非全域性 變數。nonlocal適用於巢狀函式中內部函式修改外部變數的...
global和nonlocal作用域
python中的變數引用順序為 當前作用域區域性變數 外層作用域變數 當前模組中的全域性變數 python內建變數 global關鍵字的作用就是用來在函式或者其他區域性作用域中使用全域性變數 例如 a 0 這裡報錯原因是因為剛開始在第一行就定義了乙個全域性變數a 而之後我們嘗試修改了這個a的值,此時...
python 非區域性變數nonlocal
非區域性語句可以讓所列的識別符號 identifier 指向 最近的巢狀作用域 enclosing scope 中已經繫結過的變數,全域性變數除外。具體參考這篇文章 def a i 0 def b i i 1 b a b 中並不會賦值,a 和b 中i重名,報錯local variable i ref...