膨脹卷積,也叫空洞卷積,Dilated Convolution,也有叫 擴張卷積;
空洞卷積 是 2016在ICLR(International Conference on Learning Representation)上被提出的,本身用在圖像分割領域,被deepmind拿來應用到語音(WaveNet)和NLP領域,它在物體檢測也發揮了重要的作用,對於小物體的檢測十分重要
普通卷積
先來看看 普通卷積
卷積后需進行池化 pooling,池化除了 降維、提升局部位移魯棒性 等作用外,還有 增大感受野 的作用,
但是在 pooling 時,會丟失一部分信息,特別是一些 細節信息 和 小目標信息,對任務造成一定的影響:
1.在圖像識別任務中,丟失細節可能降低准確率
2.在目標檢測任務中,小目標檢測 受影響較大
3.在語義分割任務中,下采樣后的上采樣無法還原這些信息
如果沒有 pooling,感受野 太小,
不利於 在圖像需要全局信息、語音文本需要較長的 sequence 信息依賴 等問題
感受野
卷積模塊 輸出結果中 一個元素 對應 輸入層的 區域大小,代表 卷積核 在 圖像上看到的區域大小,感受野 越大,包含的 上下文關系 越多,【通俗理解就是 視野更廣闊了,看問題更全面了 等等】
空洞卷積
為了避免 pooling 的影響,提出了 空洞卷積
VS 普通卷積
空洞卷積其實 就是在 普通卷積核中間 插 0,看起來像中間有洞,故稱空洞;
空洞卷積與 普通卷積 參數量 相同;
空洞卷積與 普通卷積 輸出的 feature map 大小相同;
膨脹率
空洞卷積中引入 膨脹率 dilation_rate 的概念,也叫 擴張率,空洞數,
膨脹率 代表 將 原來的一個 元素 擴展到 多少倍,擴展后的 卷積核尺寸 dilation_rate*(kernel_size - 1)+1,
如下圖
a為 普通卷積核為 3x3,感受野 9;
b 膨脹率為 2,原先1個元素變成2個,5x5,感受野 25;
c 膨脹率為 3,原先1個元素變成3個,7x7,感受野 49;
保持數據結構不變
pooling 操作一般會改變 數據尺寸,在 圖像分割 領域,下采樣后需上采樣,數據尺寸會發生變化,而空洞卷積只有卷積,沒有池化,可以保持數據結構不變
空洞卷積的問題與優化
柵格效應 Gridding Effect
這張圖代表了3層空洞卷積,每層在 原始輸入 上 參與計算的 像素個數,可忽略,直接看下面的圖
多個相同膨脹率的空洞卷積堆疊
左側從下往上看,相當於一個卷積網絡,每次卷積采用 膨脹率為 2 的空洞卷積,
右側是卷積后的統計分析,整個圖代表 原始輸入,每個格子代表一個像素,格子里的值代表 3次卷積后,該像素被 計算的次數,
可以看到有些 像素 是沒有參與計算的,造成了大量的信息丟失,影響最終效果,
論文中稱 卷積核 不連續;
多個不同膨脹率的空洞卷積堆疊
左側膨脹率分別為 1 2 3,右側所有像素都參與計算了,信息利用率大大增強,
同時感受野 等於 上個圖,大於 下個圖(普通卷積)
多個普通卷積堆疊
感受野明顯小很多
Hybrid Dilated Convolution(HDC)
混合膨脹卷積,
空洞卷積會產生 柵格效應,需要 設計 膨脹率 使得卷積核能夠覆蓋所有像素,HDC 用於解決這一問題。
HDC 要求 膨脹率 滿足如下要求
1.滿足公式和約束
Mi 表示 第 i 層 最大 可使用 的 膨脹率,ri 表示 第 i 層的膨脹率, n 表示 膨脹卷積核 的 個數,
下面分別表示 膨脹系數 為 [1 2 5] 和 [1 2 9]
2.鋸齒結構
dilated rate設計成了鋸齒狀結構,例如[1, 2, 5, 1, 2, 5]這樣的循環結構
鋸齒狀本身的性質就比較好的來同時滿足小物體大物體的分割要求(小 dilation rate 來關心近距離信息,大 dilation rate 來關心遠距離信息)。
這樣卷積依然是連續的,依然能滿足VGG組觀察的結論,大卷積是由小卷積的 regularisation 的 疊加。
3.公約數不能大於 1
疊加的膨脹卷積的膨脹率dilated rate不能有大於1的公約數(比如[2, 4, 8]),不然會產生柵格效應
下面代碼用於 畫 上面的圖
import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap def dilated_conv_one_pixel(center: (int, int), feature_map: np.ndarray, k: int = 3, r: int = 1, v: int = 1): """ 膨脹卷積核中心在指定坐標center處時,統計哪些像素被利用到, 並在利用到的像素位置處加上增量v Args: center: 膨脹卷積核中心的坐標 feature_map: 記錄每個像素使用次數的特征圖 k: 膨脹卷積核的kernel大小 r: 膨脹卷積的dilation rate v: 使用次數增量 """ assert divmod(3, 2)[1] == 1 # left-top: (x, y) left_top = (center[0] - ((k - 1) // 2) * r, center[1] - ((k - 1) // 2) * r) for i in range(k): for j in range(k): feature_map[left_top[1] + i * r][left_top[0] + j * r] += v def dilated_conv_all_map(dilated_map: np.ndarray, k: int = 3, r: int = 1): """ 根據輸出特征矩陣中哪些像素被使用以及使用次數, 配合膨脹卷積k和r計算輸入特征矩陣哪些像素被使用以及使用次數 Args: dilated_map: 記錄輸出特征矩陣中每個像素被使用次數的特征圖 k: 膨脹卷積核的kernel大小 r: 膨脹卷積的dilation rate """ new_map = np.zeros_like(dilated_map) for i in range(dilated_map.shape[0]): for j in range(dilated_map.shape[1]): if dilated_map[i][j] > 0: dilated_conv_one_pixel((j, i), new_map, k=k, r=r, v=dilated_map[i][j]) return new_map def plot_map(matrix: np.ndarray): plt.figure() c_list = ['white', 'blue', 'red'] new_cmp = LinearSegmentedColormap.from_list('chaos', c_list) plt.imshow(matrix, cmap=new_cmp) ax = plt.gca() ax.set_xticks(np.arange(-0.5, matrix.shape[1], 1), minor=True) ax.set_yticks(np.arange(-0.5, matrix.shape[0], 1), minor=True) # 顯示color bar plt.colorbar() # 在圖中標注數量 thresh = 5 for x in range(matrix.shape[1]): for y in range(matrix.shape[0]): # 注意這里的matrix[y, x]不是matrix[x, y] info = int(matrix[y, x]) ax.text(x, y, info, verticalalignment='center', horizontalalignment='center', color="white" if info > thresh else "black") ax.grid(which='minor', color='black', linestyle='-', linewidth=1.5) plt.show() plt.close() def main(): # bottom to top dilated_rates = [1, 2, 3] # init feature map size = 31 m = np.zeros(shape=(size, size), dtype=np.int32) center = size // 2 m[center][center] = 1 # print(m) # plot_map(m) for index, dilated_r in enumerate(dilated_rates[::-1]): new_map = dilated_conv_all_map(m, r=dilated_r) m = new_map print(m) plot_map(m) if __name__ == '__main__': main()
參考資料:
https://www.cnblogs.com/pinking/p/9192546.html 膨脹卷積與IDCNN 言簡意賅,有圖 有代碼,適合入門
https://www.bilibili.com/video/BV1Bf4y1g7j8?spm_id_from=333.337.search-card.all.click b站視頻,講得很清楚,特別是 gridding effect 問題 及 HDC 策略
https://blog.51cto.com/u_15072927/4308099 基本和 上個視頻對應,建議先看視頻再看該文章
https://blog.csdn.net/qq_27586341/article/details/103131674 膨脹卷積(Dilated convolution)
https://blog.csdn.net/qq_35495233/article/details/86638098 NLP進階之(七)膨脹卷積神經網絡
https://zhuanlan.zhihu.com/p/113285797 吃透空洞卷積(Dilated Convolutions)
https://www.zhihu.com/question/54149221/answer/1683243773 如何理解空洞卷積(dilated convolution)?
https://zhuanlan.zhihu.com/p/89425228 空洞(擴張)卷積(Dilated/Atrous Convolution)