卷积神经网络
7.1 卷积操作 图片卷积 图像卷积就是卷积核在图像上按行滑动遍历像素时不断地相乘求和的过程。 原图 Image:
步长
步长就是卷积核在图像上移动的步幅。在上一个例子中,卷积核每次移动一个像素步长的结果,如果将这个步长修改为2个像素,结果又不一样。 为了充分扫描图片,步长一般设置为1。
padding
从上面的例子中我们发现,卷积之后图片的长宽会变小。如果要保持图片大小不变,我们需要在图片周围填充0,padding指的就是填充的0的圈数。
我们可以通过公式计算出需要填充的0的圈数:
例题: 现给定一张28x28的图片,卷积核大小为5x5,步长为1,padding为0,计算一次卷积后得到的图片大小? 解:
∴ 一次卷积后得到的图片大小为 24x24
综上:
- 3x3的卷积核若没有padding,则一次卷积后的图片宽高均 -2
- 5x5的卷积核若没有padding,则一次卷积后的图片宽高均 -4
- 7x7的卷积核若没有padding,则一次卷积后的图片宽高均 -6
如果要保持卷积之后图片大小不变,可以得出等式:
(N 2∗P−F 1)=N
从而可以推导出:
P={F-1 over 2}
综上:
- 3x3的卷积核需要补1圈0
- 5x5的卷积核需要补2圈0
- 7x7的卷积核需要补3圈0
卷积核的大小
图片卷积中,卷积核一般为奇数,比如 3x3 5x5 7x7 为什么选用奇数卷积核,需要从以下两个方面进行考虑:
- 根据上述padding的计算公式,如果要保持图片大小不变,采用偶数卷积核的话会出现填充1.5层零圈的情况。
- 奇数维度的过滤器有中心点,便于指出过滤器的位置,即OpenCV卷积中的锚点。
卷积案例
- filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])
- ddepth:卷积之后图片的位深,即卷积之后图片的数据类型,一般为-1,表示核原图类型保持一致;
- kernel:卷积核大小,用元组或ndarray表示,要求数据类型必须是float类型;
- anchor:锚点,即卷积核的中心点,是可选参数,默认为(-1, -1);
- delta:可选参数,表示卷积之后额外加的一个值,相当于线性方程中的偏差,默认为0;
- borderType:边界类型,一般不设置;
# OpenCV图像卷积操作
import cv2
import numpy as np
img = cv2.imread('./dog.jpg')
# kernel必须是float类型
# 相当于原始图片中的每个点都被平均了一次,所以图片变模糊了
kernel = np.ones((5, 5), np.float32) / 25
# 2D卷积
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('2Dfilter', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()
使用不同的卷积核提取不同的特征:
- 轮廓卷积
# 轮廓卷积
import cv2
import numpy as np
img = cv2.imread('./dog.jpg')
kernel = np.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('2Dfilter', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()
- 浮雕卷积
# 浮雕卷积
import cv2
import numpy as np
img = cv2.imread('./dog.jpg')
kernel = np.array([[-2,1,0],[-1,1,1],[0,1,2]])
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('2Dfilter', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()
- 锐化卷积
# 锐化卷积
import cv2
import numpy as np
img = cv2.imread('./dog.jpg')
kernel = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])
dst = cv2.filter2D(img, -1, kernel)
cv2.imshow('2Dfilter', np.hstack((img, dst)))
cv2.waitKey(0)
cv2.destroyAllWindows()