CNN神经网络之一维卷积、二维卷积详解

做者:凌逆战html

地址:https://www.cnblogs.com/LXP-Never/p/10763804.htmlpython


 

在看这两个函数以前,咱们须要先了解一维卷积(conv1d)二维卷积(conv2d),二维卷积是将一个特征图在width和height两个方向进行滑动窗口操做,对应位置进行相乘求和;而一维卷积则只是在width或者height方向上进行滑动窗口并相乘求和。api

一维卷积:tf.layers.conv1d()

一维卷积经常使用于序列数据,如天然语言处理领域。数组

tf.layers.conv1d( inputs, filters, kernel_size, strides=1, padding='valid', data_format='channels_last', dilation_rate=1, activation=None, use_bias=True, kernel_initializer=None, bias_initializer=tf.zeros_initializer(), kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, trainable=True, name=None, reuse=None )

参数:[1]网络

  • inputs:张量数据输入,通常是[batch, width, length]
  • filters:整数,输出空间的维度,能够理解为卷积核(滤波器)的个数
  • kernel_size:单个整数或元组/列表,指定1D(一维,一行或者一列)卷积窗口的长度。
  • strides:单个整数或元组/列表,指定卷积的步长,默认为1
  • padding:"SAME" or "VALID" (不区分大小写)是否用0填充,
      • SAME用0填充;
      • VALID不使用0填充,舍去不匹配的多余项。
  • activation:激活函数
  • ues_bias:该层是否使用误差
  • kernel_initializer:卷积核的初始化
  • bias_initializer:偏置向量的初始化器
  • kernel_regularizer:卷积核的正则化项
  • bias_regularizer:偏置的正则化项
  • activity_regularizer:输出的正则化函数
  • reuse:Boolean,是否使用相同名称重用前一层的权重
  • trainable:Boolean,若是True,将变量添加到图collection中
  • data_format:一个字符串,一个channels_last(默认)或channels_first。输入中维度的排序。
      • channels_last:对应于形状的输入(batch, length, channels)
      • channels_first:对应于形状输入(batch, channels, length)
  • name = 取一个名字

返回值dom

  一维卷积后的张量,ide

例子

import tensorflow as tf x = tf.get_variable(name="x", shape=[32, 512, 1024], initializer=tf.zeros_initializer) x = tf.layers.conv1d( x, filters=1,                    # 输出的第三个通道是1
    kernel_size=512,            # 不用管它是多大,都不影响输出的shape
    strides=1, padding='same', data_format='channels_last', dilation_rate=1, use_bias=True, bias_initializer=tf.zeros_initializer()) print(x)            # Tensor("conv1d/BiasAdd:0", shape=(32, 512, 1), dtype=float32)

解析函数

  1. 输入数据的维度为[batch, data_length, data_width]=[32, 512, 1024],通常输入数据input第一维为batch_size,此处为32,意味着有32个样本,第二维度和第三维度分别表示输入的长和宽(512,1024)
  2. 一维卷积核是二维的,也有长和宽,长为卷积核的数量kernel_size=512,由于卷积核的数量只有一个,因此宽为输入数据的宽度data_width=1024,因此一维卷积核的shape为[512,1024]
  3. filteres是卷积核的个数,即输出数据的第三维度。filteres=1,第三维度为1
  4. 因此卷积后的输出数据大小为[32, 512, 1]

二维卷积:tf.layers.conv2d()

二维卷积经常使用于计算机视觉、图像处理领域google

tf.layers.conv2d( inputs, filters, kernel_size, strides=(1, 1), padding='valid', data_format='channels_last', dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer=None, bias_initializer=tf.zeros_initializer(), kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, trainable=True, name=None, reuse=None )

参数:[4]

  • inputs:张量输入。通常是[batch, width, length,channel]
  • filters:整数,输出空间的维度,能够理解为卷积核(滤波器)的个数
  • kernel_size:2个整数或元组/列表,指定2D卷积窗口的高度和宽度。能够是单个整数,以指定全部空间维度的相同值。
  • strides:2个整数或元组/列表,指定卷积沿高度和宽度方向的步幅。能够是单个整数,以指定全部空间维度的相同值。
  • padding:"SAME" or "VALID" (不区分大小写)是否用0填充,
      • SAME用0填充;
      • VALID不使用0填充,舍去不匹配的多余项。
  • data_format:字符串,"channels_last"(默认)或"channels_first"。输入中维度的排序。
      • channels_last:对应于具备形状的输入,(batch, height, width, channels)
      • channels_first:对应于具备形状的输入(batch, channels, height, width)
  • activation:激活函数
  • use_bias:Boolean, 该层是否使用误差项
  • kernel_initializer:卷积核的初始化
  • bias_initializer:  偏置向量的初始化。若是为None,将使用默认初始值设定项
  • kernel_regularizer:卷积核的正则化项
  • bias_regularizer:  偏置矢量的正则化项
  • activity_regularizer:输出的正则化函数
  • trainable:Boolean,若是True,将变量添加到图collection中
  • name:图层的name
  • reuse:Boolean,是否使用相同名称重用前一层的权重

返回:

  二维卷积后的张量spa

例子:

import tensorflow as tf x = tf.get_variable(name="x", shape=[1, 3, 3, 5], initializer=tf.zeros_initializer) x = tf.layers.conv2d( x, filters=1,                    # 结果的第三个通道是1
    kernel_size=[1, 1],            # 不用管它是多大,都不影响输出的shape
    strides=[1, 1], padding='same', data_format='channels_last', use_bias=True, bias_initializer=tf.zeros_initializer()) print(x)            # shape=(1, 3, 3, 1)

解析:

  1. input输入是1张 3*3 大小的图片,图像通道数是5,输入shape=(batch, data_length, data_width, data_channel)
  2. kernel_size卷积核shape是 1*1,数量filters是1strides步长是[1,1],第一维和第二维分别为长度方向和宽度方向的步长 = 1。
  3. 最后输出的shape为[1,3,3,1] 的张量,即获得一个3*3的feature map(batch,长,宽,输出通道数)
  4. 长和宽只和strides有关,最后一个维度 = filters。

卷积层中的输出大小计算

  设输入图片大小W,Filter大小F*F,步长为S,padding为P,输出图片的大小为N:

$$N=\frac{W-F+2P}{S}+1$$

  向下取整后再加1。

在Tensoflow中,Padding有2个选型,'SAME'和'VALID' ,下面举例说明差异:

若是 Padding='SAME',输出尺寸为: W / S(向上取整)

import tensorflow as tf input_image = tf.get_variable(shape=[64, 32, 32, 3], dtype=tf.float32, name="input", initializer=tf.zeros_initializer) conv0 = tf.layers.conv2d(input_image, 64, kernel_size=[3, 3], strides=[2, 2], padding='same')  # 32/2=16
conv1 = tf.layers.conv2d(input_image, 64, kernel_size=[5, 5], strides=[2, 2], padding='same') # kernel_szie不影响输出尺寸
print(conv0)      # shape=(64, 16, 16, 64)
print(conv1)      # shape=(64, 16, 16, 64)

若是 Padding='VALID',输出尺寸为:(W - F + 1) / S

import tensorflow as tf input_image = tf.get_variable(shape=[64, 32, 32, 3], dtype=tf.float32, name="input", initializer=tf.zeros_initializer) conv0 = tf.layers.conv2d(input_image, 64, kernel_size=[3, 3], strides=[2, 2], padding='valid')  # (32-3+1)/2=15
conv1 = tf.layers.conv2d(input_image, 64, kernel_size=[5, 5], strides=[2, 2], padding='valid')  # (32-5+1)/2=14
print(conv0)      # shape=(64, 15, 15, 64)
print(conv1)      # shape=(64, 14, 14, 64)

 1x1卷积核的做用,加深一层网络,提取更深特征,数据变维,

有效卷积(valid)、同维卷积(same)、彻底卷积(full)

a = [1 2 3 4 5]   原数组
b = [8 7 6]    卷积核数组 kernel

使用b做为卷积核对a数组作一维卷积运算的过程以下:

原数组:   0  0  1  2  3  4  5 0 0 卷积数组: 6  7  8
            6  7  8
               6  7  8
                  6  7  8
                     6  7  8
                        6  7  8
                           6  7  8
-------------------------------------
结果:        44 65  86 有效卷积 (valid) 23 44 65  86 59 同维卷积 (same) 8   23 44 65  86 59 30   彻底卷积 (full)

 

参考文献:

[1] tensorflow官方API tf.layers.conv1d

[2] tf.layers.conv1d函数解析(一维卷积)

[3] tf.layer.conv1d、conv2d、conv3d

[4] tensorflow官方API tf.layers.conv2d

import tensorflow as tf # case 2
input = tf.Variable(tf.random_normal([1, 3, 3, 5])) filter = tf.Variable(tf.random_normal([1, 1, 5, 1])) op2 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')  # (1, 3, 3, 1) # case 3
input = tf.Variable(tf.random_normal([1, 3, 3, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 1])) op3 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')  # (1, 1, 1, 1) # case 4
input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 1])) op4 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='VALID')  # (1, 3, 3, 1) # case 5
input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 1])) op5 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME')  # (1, 5, 5, 1) # case 6
input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 7])) op6 = tf.nn.conv2d(input, filter, strides=[1, 1, 1, 1], padding='SAME')  # (1, 5, 5, 7) # case 7
input = tf.Variable(tf.random_normal([1, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 7])) op7 = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')  # (1, 3, 3, 7) # case 8
input = tf.Variable(tf.random_normal([10, 5, 5, 5])) filter = tf.Variable(tf.random_normal([3, 3, 5, 7])) op8 = tf.nn.conv2d(input, filter, strides=[1, 2, 2, 1], padding='SAME')  # (10, 3, 3, 7)
 init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) print("case 2") print(sess.run(op2).shape)  # (1, 3, 3, 1)
    print("case 3") print(sess.run(op3).shape)  # (1, 1, 1, 1)
    print("case 4") print(sess.run(op4).shape)  # (1, 3, 3, 1)
    print("case 5") print(sess.run(op5).shape)  # (1, 5, 5, 1)
    print("case 6") print(sess.run(op6).shape)  # (1, 5, 5, 7)
    print("case 7") print(sess.run(op7).shape)  # (1, 3, 3, 7)
    print("case 8") print(sess.run(op8).shape)  # (10, 3, 3, 7)
View Code

 

原文出处:https://www.cnblogs.com/LXP-Never/p/10763804.html

相关文章
相关标签/搜索