1 问题描述
实验室有位同学做的风机故障诊断,是通过该时刻的26个特征对风机叶片的运行状态进行二分类,使用的模型是CNN+BiGRU,训练数据shape为(1221,512,26),即传感器每7秒进行一次采样作为一个样本,每小时取512个样本,一共有1221个小时。CNN对时间维度进行一维卷积,且保持该维度的大小不变。实现起来很简单,只需要将padding = ‘SAME’就可以实现,那么具体原理是怎样呢?
2 三种零填充设定
我们先来看看零填充的三种方式:
- 第一种被称为有效(valid)卷积,这是一种无论怎样都不使用零填充的极端情况,并且卷积核只允许访问图像中能够完全包含整个核的位置。在这种情况下,输出的所有像素都是输入中相同数量像素的函数,这样输出的大小在每一层都会缩减。如果输入图像的宽度是m,核的宽度是k,那么输出的宽度为m - k + 1。这种情况网络的空间维度会一直缩小,当缩小到1 * 1时,在进行卷积就没有意义了,所以会限制卷积层的层数。
- 第二种是全(full)卷积,这也是一种极端的情况。因为在第一种卷积情况中,输入像素中靠近边界的部分相比于中间部分对输出像素的影响更小,这会导致边界像素欠表示,所以全卷积进行了足够多的零填充,使每个像素在每个方向上恰好被访问k次,最终输出图像的宽度为m + k -1。
- 第三种就是我们今天所说的相同(same)卷积,在这种情况下,卷积运算不改变下一层的结构,因此只要硬件支持,网络就能包含任意多的卷积层。这种情况零填充的数量位于以上两者之间,通常,该情况也会使得边界像素存在一定程度的欠表示。
一般情况下,零填充的最优数量(对于测试集的分类正确率)处于“有效卷积”和“相同卷积”之间的某个位置。
3 相同(same)卷积的具体实现
如果要减少边界数据的欠表示程度并且保证卷积层的输出和输入保持相同的shape,我们会选择在数据的外围进行零填充。对于一维数据来说,会在首行前和尾行后补上N行零,那么N的数量该如何确定呢?
其实根据公式
W
n
+
1
=
(
W
n
+
2
∗
P
−
K
)
/
S
+
1
W_{n+1} = (W_n + 2 * P - K) / S + 1
Wn+1=(Wn+2∗P−K)/S+1
其中,
W
n
Wn
Wn为输入的size,
W
n
+
1
W_{n+1}
Wn+1为输出的size,
K
K
K为filter的size,
S
S
S为步长,
P
P
P是两边各填充的行数。
我们不难反推:
P
=
(
W
n
+
1
−
1
)
∗
S
+
K
−
W
n
2
P = \frac{(W_{n + 1} - 1) * S + K - W_n}{2}
P=2(Wn+1−1)∗S+K−Wn
例如:数据长度为4,卷积核为3,步长为1,若使卷积后shape不变,则令
W
n
+
1
=
W
n
=
4
W_{n+1} = W_n = 4
Wn+1=Wn=4可得P = 1。也就是数据两边各填充一行。
填充后卷积的过程如下:
可以发现按照上述过程进行卷积填充,可以做到相同卷积。那么问题来了,当K为偶数时该当如何呢?
例如把上例中把卷积核的大小改为2或者改为4时,分别需要填充1行或者3行,应该怎么分配呢?
通常情况下,后面会比前面多一行。
需要注意的是,在TensorFlow的具体实现中,对于VALID,输出的形状计算如下:
W
n
+
1
=
⌈
W
–
K
+
1
S
⌉
W_{n+1}=⌈\frac{W–K+1}{S}⌉
Wn+1=⌈SW–K+1⌉
对于SAME,输出的形状计算如下:
W
n
+
1
=
⌈
W
S
⌉
W_{n+1}=⌈\frac{W}{S}⌉
Wn+1=⌈SW⌉⌈⌉为向上取整符号。
这样只需设置strides = 1, padding = ‘SAME’,就能实现维度大小不变的卷积。