1. 程式人生 > 其它 >[論文理解] Temporal Shift Module for Efficient Video Understanding

[論文理解] Temporal Shift Module for Efficient Video Understanding

Temporal Shift Module for Efficient Video Understanding

Intro

文章是提出了一種頗為有效的跨幀處理模組,能夠提升2DCNN對於視訊資料的特徵提取能力,大大提升視訊分類的準確率,同時,該模組還是0引數量的模組,即插即用。

Intution

本文的Intution其實很明顯,是想要借鑑一維卷積的移位、乘加操作的分解,將其利用到視訊處理中,而恰巧2D卷積本質上是對通道維度的乘加,恰巧滿足卷積的第二個操作,那麼只要實現了卷積的移位操作,就可以將視訊序列在時間維度上當成一維序列進行卷積化處理了。

首先我們先回顧一下一維卷積的過程:

對於序列\(X\)

,假定我們需要使用大小為3的卷積對其進行處理,卷積核權重為 \(W =(w_1, w_2, w_3)\),

那麼首先需要對輸入序列\(X\)進行移位處理:

\[X_{i}^{-1}=X_{i-1}, \quad X_{i}^{0}=X_{i}, \quad X_{i}^{+1}=X_{i+1} \]

然後進行乘加處理:

\[Y=w_{1} X^{-1}+w_{2} X^{0}+w_{3} X^{+1} \]

基於此,作者想到,如果想要對時序維度進行資訊利用,其實並不一定需要引數量更大的3D卷積網路,而是可以利用卷積對通道維度的乘加處理,再單獨加上時間維度的移位操作,這樣就可以實現在時間維度上的1D卷積了。

Method

文章對TSM進行了這樣一張圖的解釋:

怎奈右邊部分怎麼也看不懂。。然後就去看了程式碼,其實還是不太懂。
研究了下我畫了個更好理解的圖:

以通道為3的特徵層為例,每組3個通道為一張圖對應的特徵層,因此從上往下是對應不同幀的特徵層。對這個圖進行解釋,shift操作對所有特徵層的第一層向下進行平移,於是可以看到shift之後第一列對應shift之前第一列是向下平移的了,其中白色的層表示0填充,第二層不動,第三層向上平移,那麼第一層第二層第三層的序列就可以表示成X(i-1)、X(i)和X(i+1)的三個序列了,由於卷積本身是對所有通道的一個加權,因此2D卷積處理後就把三個特徵層加權求和變成了一個特徵層,從而實現了1D卷積的乘加操作(kernel size = 3)。

需要說明的是,原文是對很多相鄰的通道同時進行平移,而我的例子只是平移了一個通道,顯然對於kernel size為3的1D卷積,如果channel數量大於3,只能是同時對channel size / 3數量的channel進行平移,這樣做就是將相鄰多個通道看成一個通道進行處理,當然也是可以這麼做的;但是原文中是四分之一的通道上移,四分之一的通道下移,二分之一的通道不移動(移動先後順序無關,因為最後是求和),我畫的圖是三個通道的例子;為什麼原文那樣做比較好,後面作者簡單做了個實驗:

每個shift佔比四分之一可能是個比較合適的值,但其實這裡的實驗明顯是不夠的,感覺不能充分說明四分之一的超參足夠優秀。。。

Training

訓練的話其實是參考TSN的,TSN的訓練是下面幾個過程:

  1. 將視訊劃分為若干clip
  2. 每個clip的影象被按當成batch處理,使用2d卷積
  3. 所有clip處理完之後進行fuse
  4. fuse之後對整個視訊分類。

基本也就是把一些卷積結構換成TSM,不再贅述。

Code

out = torch.zeros_like(x)
fold = c // fold_div
out[:, :-1, :fold] = x[:, 1:, :fold]  # shift left
out[:, 1:, fold: 2 * fold] = x[:, :-1, fold: 2 * fold]  # shift right
out[:, :, 2 * fold:] = x[:, :, 2 * fold:]  # not shift
return out