扩张卷积
先决条件:卷积神经网络
扩张卷积:这是一种通过在其连续元素之间插入孔来扩展内核(输入)的技术。简单来说,它与卷积相同,但它涉及像素跳跃,以覆盖更大的输入区域。
一个额外的参数l (扩张因子)表明输入被扩张了多少。换句话说,根据这个参数的值,在核中跳过(l-1)个像素。图 1描绘了正常卷积与扩张卷积之间的差异。本质上,普通卷积只是1-dilated convolution 。
直觉:
扩张卷积有助于扩大输入图像覆盖的区域而无需池化。目标是从每次卷积操作获得的输出中覆盖更多信息。这种方法以相同的计算成本提供了更广阔的视野。我们通过查看每个卷积在不同l值上获得多少信息来确定扩张因子( l)的值。
通过使用这种方法,我们能够在不增加内核参数数量的情况下获得更多信息。在图 1中,左边的图像描绘了扩张卷积。在保持l = 2 的值时,我们在将过滤器映射到输入时跳过 1 个像素( l – 1 个像素),从而在每一步中覆盖更多信息。
涉及公式:
where,
F(s) = Input
k(t) = Applied Filter
*l = l-dilated convolution
(F*lk)(p) = Output
扩张卷积的优点:
使用这种方法而不是普通卷积更好,因为:
- 更大的感受野(即没有覆盖范围的损失)
- 计算效率高(因为它在相同的计算成本下提供了更大的覆盖范围)
- 更少的内存消耗(因为它跳过池化步骤)实现
- 输出图像的分辨率没有损失(因为我们扩张而不是执行池化)
- 这种卷积的结构有助于保持数据的顺序。
代码实现:
Python3
import numpy as np
import tensorflow as tf
import sys
from scipy.signal import convolve2d
np.random.seed(678)
tf.random.set_seed(6789)
sess = tf.compat.v1.Session()
# Initializing a 9x9 matrix of zeros.
mat_size = 9
matrix = np.zeros((mat_size,mat_size)).astype(np.float32)
# Assigning 1's in the middle of matrix
# to create a random input matrix
for x in range(4,7):
for y in range(3,6):
matrix[y,x] = 1
# Creating a random kernal for test
kernel = np.array([
[1,2,3],
[4,5,6],
[7,8,9]
]).astype(np.float32)
print("Original Matrix Shape : ",matrix.shape)
print(matrix)
print('\n')
print("Original kernel Shape : ",kernel.shape)
print(kernel)
# self-initializing a dilated kernal.
# ======[dilation factor = 3]======
dilated_kernel = np.array([
[1,0,0,2,0,0,3],
[0,0,0,0,0,0,0],
[0,0,0,0,0,0,0],
[4,0,0,5,0,0,6],
[0,0,0,0,0,0,0],
[0,0,0,0,0,0,0],
[7,0,0,8,0,0,9]
])
print('\n')
print("Dilated kernel Shape : ",dilated_kernel.shape)
print(dilated_kernel)
print('\n')
print("DILATED CONVOLUTION RESULTS [Dilation Factor = 3]")
output = convolve2d(matrix,dilated_kernel,mode='valid')
print("Numpy Results Shape: ",output.shape)
print(output)
输出
以下输出是从上面的代码中获得的。
获得的输出是针对膨胀因子为 3 的。 如需更多实验,您可以使用不同的扩张因子值初始化 dilated_kernel 并观察获得的输出的变化。