在图像物体边缘检测应用中,我们构造卷积核从而精确地找到了像素变化的位置。设任意二维数组X
的i
行j
列的元素为X[i, j]
。如果我们构造的卷积核输出Y[i, j]=1
,那么说明输入中X[i, j]
和X[i, j+1]
数值不一样。这可能意味着物体边缘通过这两个元素之间。
X:
tensor([[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.]])
卷积核:
然后我们构造一个高和宽分别为1和2的卷积核`K`。当它与输入做互相关运算时,如果横向相邻元素相同,输出为0;否则输出为非0。
``` python
K = torch.tensor([[1, -1]])
Y:
tensor([[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.]])
输出中Y[0,1] = 1,那么说明X[0,1] and X[0, 2]值是不同的,Y[2, 5] = -1, 说明X[2, 5] 与 X[2, 6]是不同的,使用X中的元素进行验证,果然是这样。
在实际的图像里,我们感兴趣的物体,不会总出现在固定位置:即使我们连续拍摄同一个物体也既有可能出现像素位置上的偏移。这会导致同一个边缘对应的输出可能出现在卷积输出Y中的不同位置,进而对后面的模式识别造成不便。
让我们再次回到本节开始提到的物体边缘检测的例子。现在我们将卷积层的输出作为2×2最大池化的输入。设该卷积层输入是X
、池化层输出为Z。
则Z=
tensor([[ 1., 1., 0., 0., 0., 0.],
[ 1., 1., 0., 0., 0. 0.],
[ 1., 1., 0., 0., 0., 0.],
[ 1., 1., 0., 0., 0., 0.],
[ 1., 1., 0., 0., 0., 0.],
[ 1., 1., 0., 0., 0., 0.]])
无论是X[i, j]
和X[i, j+1]
值不同,还是X[i, j+1]
和X[i, j+2]
不同,池化层输出均有z[i, j]=1
。也就是说,使用2×2最大池化层时,只要卷积层识别的模式在高和宽上移动不超过一个元素,我们依然可以将它检测出来。
这样的话卷积运算,只有X[i, j]
和X[i, j+1]不同,能检测出来边缘,加入池化之后,X[i, j]
和X[i, j+1]不同,或者X[i, j+1]
和X[i, j+2]
不同都可以检测出边缘来,对于检测边缘这个模式来说,加入池化之后,扩大了检测像素的范围(池化层要求1和2,或者2和3不同,都可以检测出边缘,而卷积层要检测出边缘必须有1和2不同才可以),因此对像素位置的敏感性降低了。