深度学习之四:卷积神经网络基础
Posted zzulp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深度学习之四:卷积神经网络基础相关的知识,希望对你有一定的参考价值。
计算机视觉在深度学习的帮助下取得了令人惊叹的进展,其中发挥重要作用的是卷积神经网络。本节总结了卷积神经的原理与实现方法。
1 卷积神经网络
1.1 计算机视觉与深度学习
计算机视觉要解决的问题是如何让机器理解现实世界的现象。目前主要处理的问题如图像分类,目标检测,风格变换等。
对于小型图片,如MNIST的图片处理,图像大小为64*64,使用全连接神经网络还可以处理。如果图像较大,如1000*1000*3时,单个输入层就需要3M的节点,全连接情况下,单层的权重就可能多达数十亿的待训练参数。这将导致神经网络无法进行有效训练。因此业界提出卷积神经网络解决参数过多的问题。
先看一个卷积神经网络的结构,在卷积神经网络中包括三种类型的层:卷积层,池化层和全连接层。下面几节介绍卷积神经网络的基本概念。
1.2 过滤器
在卷积神经网络中,过滤器也称为卷积核,通常是3*3或5*5的小型矩阵(先忽略每个点可能有多个通道)。过滤器的作用是和输入图像的各个区域逐次进行卷积。
所谓卷积运算是计算两个矩阵的对应元素(Element-wise)乘积的和。卷积本质是两个向量的内积,体现了两个向量的距离。
下图展示了过滤器在输入图像上的卷积计算的过程:
因此过滤器可以捕获图像中与之类似模式的图像区域。例如下图展示了一个过滤器的数值矩阵与图形。
当使用这个过滤器在图像上移动并计算卷积时,不同的区域会有不同的卷积结果。
在类似于的模式下过滤器与图像区域的卷积会产生较大的值。
不相似的区域则产生较小的值。
此外在一层上捕获的模式可以组合为更复杂的模式并输入到下一层,从而使得下一层能识别更复杂的图像模式。
训练CNN在一定意义上是在训练每个卷积层的过滤器,让其组合对特定的模式有高的激活,以达到CNN网络的分类/检测等目的。
1.3 Padding
对于一个shape为 [n,n] [ n , n ] 的图像,若过滤器的 shape为 [f,f] [ f , f ] ,在卷积时每次移动1步,则生成的矩阵shape为 [n−f+1,n−f+1] [ n − f + 1 , n − f + 1 ] 。这样如果经过多层的卷积后,输出会越来越小。另一方面图像边界的点的特征不能被过滤器充分捕获。
通过对原始图像四个边界进行padding,解决上面提到的两个问题。术语Same填充,会保证输出矩阵与输入矩阵大小相同,因此其需要对输入图像边界填充 f−12 f − 1 2 个象素。另一个术语Valid填充表示不填充。
通过下图体会Padding对输出的影响
下面的代码展示了使用0填充,向X边界填充pad个像素的方法
def zero_pad(X, pad):
X_pad = np.pad(X, ((0, 0), (pad, pad), (pad, pad), (0, 0)), 'constant', constant_values=0)
return X_pad
1.4 卷积步长
另一个影响输出大小的因素是卷积步长(Stride)。
对于一个shape为
[n,n]
[
n
,
n
]
的图像,若过滤器的 shape为
[f,f]
[
f
,
f
]
,卷积步长为s,边界填充p个象素,则生成的矩阵shape为
[n+2p−fs+1,n+2p−fs+1]
[
n
+
2
p
−
f
s
+
1
,
n
+
2
p
−
f
s
+
1
]
。
1.5 卷积层记法说明
对于第 l l 层的卷积层,为该层的卷积核数,其输入矩阵的维度为
[n[l−1]H,n[l−1]W,n[l−1]c] [ n H [ l − 1 ] , n W [ l − 1 ] , n c [ l − 1 ] ]输出矩阵的维度以channel-last展示为
[n[l]H,n[l]W,n[l]c]
[
n
H
[
l
]
,
n
W
[
l
]
,
n
c
[
l
]
]
,各维度值如下:
n[l]H=n[l−1]H+2p[l]−f[l]s[l]+1
n
H
[
l
]
=
n
H
[
l
−
1
]
+
2
p
[
l
]
−
f
[
l
]
s
[
l
]
+
1
n[l]W=n[l−1]W+2p[l]−f[l]s[l]+1
n
W
[
l
]
=
n
W
[
l
−
1
]
+
2
p
[
l
]
−
f
[
l
]
s
[
l
]
+
1
下面的代码展示了图像卷积计算的方法
def conv_single_step(a_slice_prev, W, b):
"""
Apply one filter defined by parameters W on a single slice (a_slice_prev) of the output activation
of the previous layer.
Arguments:
a_slice_prev -- slice of input data of shape (f, f, n_C_prev)
W -- Weight parameters contained in a window - matrix of shape (f, f, n_C_prev)
b -- Bias parameters contained in a window - matrix of shape (1, 1, 1)
Returns:
Z -- a scalar value, result of convolving the sliding window (W, b) on a slice x of the input data
"""
s = np.multiply(a_slice_prev, W) + b
Z = np.sum(s)
return Z
def conv_forward(A_prev, W, b, hparameters):
"""
Implements the forward propagation for a convolution function
Arguments:
A_prev -- output activations of the previous layer, numpy array of shape (m, n_H_prev, n_W_prev, n_C_prev)
W -- Weights, numpy array of shape (f, f, n_C_prev, n_C)
b -- Biases, numpy array of shape (1, 1, 1, n_C)
hparameters -- python dictionary containing "stride" and "pad"
Returns:
Z -- conv output, numpy array of shape (m, n_H, n_W, n_C)
cache -- cache of values needed for the conv_backward() function
"""
(m, n_H_prev, n_W_prev, n_C_prev) = A_prev.shape
(f, f, n_C_prev, n_C) = W.shape
stride = hparameters['stride']
pad = hparameters['pad']
n_H = int((n_H_prev - f + 2 * pad) / stride) + 1
n_W = int((n_W_prev - f + 2 * pad) / stride) + 1
# Initialize the output volume Z with zeros.
Z = np.zeros((m, n_H, n_W, n_C))
# Create A_prev_pad by padding A_prev
A_prev_pad = zero_pad(A_prev, pad)
for i in range(m): # loop over the batch of training examples
a_prev_pad = A_prev_pad[i] # Select ith training example's padded activation
for h in range(n_H):
for w in range(n_W):
for c in range(n_C): # loop over channels (= #filters) of the output volume
# Find the corners of the current "slice"
vert_start = h * stride
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
# Use the corners to define the (3D) slice of a_prev_pad (See Hint above the cell).
a_slice_prev = a_prev_pad[vert_start:vert_end, horiz_start:horiz_end, :]
# Convolve the (3D) slice with the correct filter W and bias b, to get back one output neuron.
Z[i, h, w, c] = conv_single_step(a_slice_prev, W[..., c], b[..., c])
assert (Z.shape == (m, n_H, n_W, n_C))
cache = (A_prev, W, b, hparameters)
return Z, cache
1.6 池化层
有两种类型的池化层,一种是最大值池化,一种是均值池化。
下图体现了最大池化的作用,其过滤器大小为2,步幅为2:
均值池化与最大池化不同的是计算相应区域的均值,而不是取最大值。
对池化层各维度值如下:
深度学习之 TensorFlow:卷积神经网络