卷积神经网络(CNN)在最近今年持续得到关注,因为这是深度学习的一种特别有前途的形式,在图像和语音识别领域有着出色的表现。

卷积

卷积可以看作通过两个函数 fg 生成第三个函数的一种数学算子,表征函数 f 经过翻转和平移的 g 的乘积函数所围成的曲边梯形。

简单的说就是 某个时刻的输出结果是多个输入共同的运算结果。

卷积
卷积

在 tensorflow 中定义了卷积神经网络的函数 tf.nn.conv2d(input,filter,strides,padding)

其中 input 为数据或者是前一层卷积后的特征图( feature_map 表示卷积层的输出)。而 filter 为卷积滤波器也叫卷积核。inputfilter 都是 tensor 类型,同时也都是一个四维数组。

input

input 要求为 [batch, in_height, in_width, in_channels],分别为图像数量未知可以用 None,图像的高度,宽度,和图像通道。

fliter

同样卷积过滤器要求以下参数 [filter_height, filter_width, in_channels, out_channels] 。过滤器的高度和宽度,图像通道和卷积核数。

strides

该参数定义了滤波器 filterinput 上的空间移动。

padding

padding 有一个参数,可以为 SAME 或者 VALID

  • SAME 意味着input的边界会被填充,使得操作处理过的结果的大小和input大小一致。

激活函数

使用线性整流(Rectified Linear Units, ReLU) $f\left( x \right) = max\left( 0,x \right)$ ,作为这一层神经激励函数,它可以增强判定函数和整个神经网络的非线性特性,而本身并不会改变卷积层。也可以应用其他线性激活函数,比如$f\left ( x \right ) = tanh\left ( h \right )$、$f\left( x \right) = \left|tanh \left( x \right) \right|$

相较于其他函数来说,ReLU 更加受人喜欢。

修正线性单元 ReLU
修正线性单元 ReLU

池化

池化表示使用某个局部聚合函数来降低数据的大小,一般针对每个特征图进行池化。通常使用最大池化(max pool)方法。

如图,我们将特征图上的 2×2 块上应用最大池化,每个区块上选取最大数,这样会减少 75% 的数据。

通过 tf.nn.max_pool(value, ksize, strides, padding, name=None)

value 通常是输入 feature_map , shape 如上文说有。

ksize 是控制池化大小。

x = tf.constant(
    [
        [1.0, 0.0, 2.0, 3.0],
        [4.0, 6.0, 6.0, 8.0],
        [3.0, 1.0, 1.0, 0.0],
        [1.0, 2.0, 2.0, 4.0]
    ]
)
x = tf.reshape(x, [1, 4, 4, 1])
pooling = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')

with tf.Session() as sess:
    x_ = sess.run(x)
    print(x_)
    print("\n pool -> \n")
    p = sess.run(pooling)
    print(p)

输出结果:

[[[[1.]
   [0.]
   [2.]
   [3.]]

  [[4.]
   [6.]
   [6.]
   [8.]]

  [[3.]
   [1.]
   [1.]
   [0.]]

  [[1.]
   [2.]
   [2.]
   [4.]]]]

 pool -> 

[[[[6.]
   [8.]]

  [[3.]
   [4.]]]]  

随机丢弃

随即丢弃是将层中随机预设的一部分单元暂时性,测试时我们会将此值设为1.0,训练时候我们会将此值设置为 0.5。

tensorflow 给出了该 API tf.nn.dropout(x, keep_prob=None, noise_shape=None, seed=None, name=None, rate=None)

参考资料