TensorFlow对cnn的支持

TensorFlow对cnn的支持

对卷积的支持

卷积层最重要的部分是卷积核,也被称为过滤器。
卷积核的概念这里就不赘述了。简单说一下在做卷积运算时需要指明的几个参数:

  1. 卷积核的尺寸。卷积核尺寸即卷积核的宽高,再说的不规范一点,就是二维矩阵的行数和列数。常用卷积核的尺寸(H*W)有2*23*35*5的。
  2. 卷积核的通道数。这个不是随心所欲可以设置的,需要看输入特征图的通道数,卷积核的通道数应该和输入特征图的通道数保持一致。如果输入图是单通道灰白色图那么通道数应该是1,如果是三通道RGB色,那么通道数应该是3(C)。加上前面卷积核的尺寸,现在的卷积核应该是一个立体的小方块,大小是C*H*W
  3. 卷积核的个数。这个值就可以根据经验自己设置了,多个卷积核可以对输入特征图提取不同的特征。除此之外,该值其实就是输出特征图的通道数。

那么考虑这三个数据,假设我们有个batch的输入特征图(B*C*H*W)前馈到某一卷积层(C*FH*FW*N),则应该得出输出特征图(B*N*OH*OW)。其中B为batch的大小,C是输入特征图和卷积层的通道数,HW是输入特征图的尺寸,FHFW卷积核的尺寸,N是卷积核的个数,OHOW是输出特征图的尺寸。

由于卷积核的使用方法是,在前向传播过程中,将卷积核从神经网络当前层的左上角移动到右下角,并且在移动过程中计算每一个对应的单位矩阵(卷积核和扫描到的相同尺寸的矩阵做对应位置乘法并求和)。
很容易理解这样的乘法执行完后,矩阵的尺寸是会缩小的(如果不理解可以模拟下),为了避免尺寸的变化,可以在当前层矩阵的边界上加入全0填充。这样可以使卷积层前向传播结果矩阵的大小和当前层保持一致。
除了使用全0填充,还可以通过设置卷积核移动的步长来调整结果矩阵的大小。

import tensorflow as tf

# 通过tf.get_variable的方式创建卷积核的权重和偏置项变量。
# 卷积核的参数个数与过滤器的尺寸、通道数和个数有关,
# 所以这里声明变量的参数变量是一个四维矩阵,
# 前面两个维度代表了过滤器的尺寸,第三个维度表示当前层的通道数,第四个维度表示过滤器的个数
filter_weight = tf.get_variable('weights', [5, 5, 3, 16],
        initializer = tf.truncated_normal_initializer(stddev=0.1))

# 和卷积层的权值类似,当前层矩阵上不同位置的偏置项也是共享的,
# 有多少个卷积核就有多少个偏置项。
biases = tf.get_variable('biases', [16], 
        initializer = tf.constant_initializer(0.1))

# tf.nn.conv2d提供了一个非常方便的函数来实现卷积层前向传播的算法。
# 这个函数的第一个输入为当前层的节点矩阵,注意这是一个四维矩阵
# 后面三个维度对应一个节点矩阵,第一维对应一个输入batch
# 如在输入层,input[0,:,:,:]表示第一张图片, input[1,:,:,:]代表第二张图片
# tf.nn.conv2d第二个参数提供了卷积层的权值(也就是卷积核或过滤器)
# 第三个参数为不同维度上的步长。虽然这个参数提供的是一个长度为4的数组
# 但第一维和最后一维的数字要求一定是1。因为卷积层的步长只对矩阵的长和宽有效
# 而第一维是输入batch,最后一维是图片的高(颜色,色彩通道)
# 最后一个参数是填充(padding)的方法。
# TensorFlow提供SAME和VALID两种选择,
# 其中SAME表示用0填充,VALID表示不填充
conv = tf.nn.conv2d(input, filter_weight, strides = [1, 1, 1, 1],
        padding = 'SAME')

# tf.nn.bias_add提供了一个方便的函数给每个节点加上偏置项。
# 注意这里不能使用简单的加法,因为矩阵不同位置上的节点都需要加上同样的偏置项
bias = tf.nn.bias_add(conv, biases)

# 将计算结果通过ReLU激活函数完成去线性化
actived_conv = tf.nn.relu(bias)

对池化的支持

池化层可以非常有效的缩小矩阵的尺寸,从而减少最后全连接层中的参数。
使用池化层既可以加快计算速度,也有效防止过拟合的作用。

池化层前向传播的过程也是通过一个类似过滤器的结构完成的。不过池化层过滤器中的计算不是节点的加权和,而是采用更加简单的最大值或平均值运算。
使用最大值操作的池化层称为最大池化层,这是被用的最多的池化层结构。
使用平均值操作的池化层称为平均池化层。
其它还有些实践中使用的较少的池化层。

与卷积层的过滤器类似,池化层的过滤器也需要人工设定过滤器的尺寸,是否使用全0填充以及过滤器移动的步长。意义也是类似的。不过这里有个需要注意的点就是,卷积层和池化层中过滤器的移动方式是类似的,但卷积层使用的过滤器是横跨整个深度的,而池化层使用的过滤器只影响一个深度上的节点。所以池化层的过滤器除了在长和宽两个维度上移动之外,它还需要在深度这个维度上进行移动。

import tensorflow as tf

# tf.nn.max_pool实现了最大池化层的前向传播过程,
# 它的参数和tf.nn.conv2d函数类似。
# ksize提供了过滤器的尺寸,strides提供了步长信息,padding提供了是否使用全0填充
# 这里过滤器的尺寸最后一数仍必须为1,虽然在深度上有移动
# 但池化层的过滤器不可以跨节点矩阵深度。
pool = tf.nn.max_pool(actived_conv, ksize = [1, 3, 3, 1],
        strides = [1, 2, 2, 1], padding = 'SAME')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值