TensorFlow图层模块用法

TensorFlow中的图层模块提供用于深度学习的更高层次封装的API,利用它我们可以轻松地构建模型,这一节我们就来看这个模块的API的具体用法。

概览

层模块的路径写法为tf.layers,这个模块定义在tensorflow / python / layers / layers.py,其官方文档地址为:
版本为1.5。

这里面提供了多个类和方法以供使用,下面我们分别予以介绍。

方法

tf.layers模块提供的方法有:

  • Input(...):用于实例化一个输入张量,作为神经网络的输入。
  • average_pooling1d(...):一维平均池化层
  • average_pooling2d(...):二维平均池化层
  • average_pooling3d(...):三维平均池化层
  • batch_normalization(...):批量标准化层
  • conv1d(...):一维卷积层
  • conv2d(...):二维卷积层
  • conv2d_transpose(...):二维反卷积层
  • conv3d(...):三维卷积层
  • conv3d_transpose(...):三维反卷积层
  • 密集(...):全连接层
  • 辍学(...):辍学层
  • flatten(...):Flatten层,即把一个张量展平
  • max_pooling1d(...):一维最大池化层
  • max_pooling2d(...):二维最大池化层
  • max_pooling3d(...):三维最大池化层
  • separable_conv2d(...):二维深度可分离卷积层

输入

tf.layers.Input()这个方法是用于输入数据的方法,其实类似于tf.placeholder,相当于一个占位符的作用,当然也可以通过传入张量参数来进行赋值。

12345678Input(    shape=None,    batch_size=None,    name=None,    dtype=tf.float32,    sparse=False,    tensor=None)复制代码

参数说明如下:

  • 形状:可选,默认无,是一个数字组成的组或列表,但是这个形状比较特殊,它不包含batch_size,比如传入的形为[32],那么它会将形状转化为[?,32 ],这里一定需要注意。
  • batch_size:任选,默认无,代表输入数据的批量大小,可以是数字或者无。
  • 名称:可选,默认无,输入层的名称。
  • dtype:可选,默认tf.float32,元素的类型。
  • 稀疏:可选,默认False,指定是否以稀疏矩阵的形式来创建占位符。
  • 张量:任选,默认无,如果指定,那么创建的内容便不再是一个占位符,会用此张量初始化。

返回值:返回一个包含历史元数据的张量。

我们用一个实例来感受一下:

1234x = tf.layers.Input(shape=[32])print(x)y = tf.layers.dense(x, 16, activation=tf.nn.softmax)print(y)复制代码

首先我们用Input()方法初始化了一个占位符,这时我们没有传入张量参数,然后调用了dense()方法构建了一个全连接网络,激活函数使用softmax,然后将二者输出,结果如下:
12Tensor("input_layer_1:0", shape=(?, 32), dtype=float32)Tensor("dense/Softmax:0", shape=(?, 16), dtype=float32)复制代码

这时我们发现,shape它给我们做了转化,本来是[32],结果它给转化成了[?,32],即第一维代表batch_size,所以我们需要注意,在调用此方法的时候不需要去关心batch_size这一维。

如果我们在初始化的时候传入一个已有张量,例如:

123data = tf.constant([1, 2, 3])x = tf.layers.Input(tensor=data)print(x)复制代码

结果如下:

1Tensor("Const:0", shape=(3,), dtype=int32)复制代码

可以看到它可以自动计算出其形状和dtype。

batch_normalization

此方法是批量标准化的方法,经过处理之后可以加速训练速度,其定义在tensorflow / python / layers / normalization.py,论文可以参考:
http://arxiv.org/abs/1502.03167
“批量标准化:加速深度通过减少内部协变量来进行网络培训“。

1234567891011121314151617181920212223242526batch_normalization(    inputs,    axis=-1,    momentum=0.99,    epsilon=0.001,    center=True,    scale=True,    beta_initializer=tf.zeros_initializer(),    gamma_initializer=tf.ones_initializer(),    moving_mean_initializer=tf.zeros_initializer(),    moving_variance_initializer=tf.ones_initializer(),    beta_regularizer=None,    gamma_regularizer=None,    beta_constraint=None,    gamma_constraint=None,    training=False,    trainable=True,    name=None,    reuse=None,    renorm=False,    renorm_clipping=None,    renorm_momentum=0.99,    fused=None,    virtual_batch_size=None,    adjustment=None)复制代码

参数说明如下:

  • 输入:必需,即输入数据。
  • axis:任选,默认-1,即进行标注化操作时操作数据的哪个维度。
  • 动力:可选,默认0.99,即动态均值的动量。
  • epsilon:可选,默认0.01,大于0的小浮点数,用于防止除0错误。
  • center:可选,默认True,若设为True,将会beta作为偏置加上去,否则忽略参数beta
  • scale:任意,默认True,若设为True,则会乘以gamma,否则不使用gamma。当下一层是线性的时,可以设False,因为scaling的操作将被下一层执行。
  • beta_initializer:任选,默认zeros_initializer,即beta权重的初始方法。
  • gamma_initializer:可选,默认ones_initializer,即gamma的初始化方法。
  • moving_mean_initializer:任选,默认zeros_initializer,即动态均值的初始化方法。
  • moving_variance_initializer:可选,默认ones_initializer,即动态方差的初始化方法。
  • beta_regularizer:可选,默认无,beta的正则化方法。
  • gamma_regularizer:可选,默认无,gamma的正则化方法。
  • beta_constraint:可选,默认无,加在beta上的约束项。
  • gamma_constraint:可选,默认无,加在gamma上的约束项。
  • 训练:可选,默认False,返回结果是训练模式。
  • 可训练:可选,默认为True,布尔类型,如果为True,则要变量添加GraphKeys.TRAINABLE_VARIABLES中。
  • 名称:任选,默认无,层名称。
  • 重用:可选,默认无,根据层名判断是否重复利用。
  • renorm:任选,默认False,是否要用Batch Renormalization(
  • renorm_clipping:可选,默认无,是否要使用rmax,rmin,dmax来标量张量。
  • renorm_momentum,可选,默认0.99,用来更新动态均值和标准差的Momentum值。
  • 融合,可选,默认无,是否使用一个更快的,融合的实现方法。
  • virtual_batch_size,可选,默认无,是一个int数字,指定一个虚拟批量大小。
  • 调整,任选,默认无,对标准化后的结果进行适当调整的方法。

最后的一些参数说明不够详尽,更详细的用法参考:
https

其用法很简单,在输入数据后面加一层batch_normalization()即可:
123x = tf.layers.Input(shape=[32])x = tf.layers.batch_normalization(x)y = tf.layers.dense(x, 20)复制代码

稠密

密集,即全连接网络,层模块提供了一个dense()方法来实现此操作,定义在tensorflow / python / layers / core.py中,下面我们来说明一下它的用法。
12345678910111213141516dense(    inputs,    units,    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)复制代码

参数说明如下:

  • 输入:必需,即需要进行操作的输入数据。
  • 单位:必须,即神经元的数量。
  • activation:可选,默认为None,如果为None则是线性激活。
  • use_bias:可选,默认为True,是否使用偏置。
  • kernel_initializer:可选,默认为None,即权重的初始化方法,如果为None,则使用默认的Xavier初始化方法。
  • bias_initializer:可选,默认为零值初始化,即偏置的初始化方法。
  • kernel_regularizer:可选,默认为None,施加在权重上的正则项。
  • bias_regularizer:可选,默认为None,施加在偏置上的正则项。
  • activity_regularizer:可选,默认为None,施加在输出上的正则项。
  • kernel_constraint,可选,默认为None,施加在权重上的约束项。
  • bias_constraint,可选,默认为None,施加在偏置上的约束项。
  • 可训练:可选,默认为True,布尔类型,如果为True,则会将变量添加到GraphKeys.TRAINABLE_VARIABLES中。
  • name:可选,默认为None,卷积层的名称。
  • 重用:可选,默认为无,布尔类型,如果为True,那么如果名称相同时,会重复利用。

返回值:全连接网络处理后的张量。

下面我们用一个实例来感受一下它的用法:

1
2
3
4
5
6
x = tf.layers.Input(shape=[32])
print(x)
y1 = tf.layers.dense(x, 16, activation=tf.nn.relu)
print(y1)
y2 = tf.layers.dense(y1, 5, activation=tf.nn.sigmoid)
print(y2)

首先我们用Input定义了[?,32]的输入数据,然后经过第一层全连接网络,此时指定了神经元个数为16,激活函数为relu,接着输出结果经过第二层全连接网络,此时指定了神经元个数为5,激活函数为sigmoid,最后输出,结果如下:

1
2
3
Tensor("input_layer_1:0", shape=(?, 32), dtype=float32)
Tensor("dense/Relu:0", shape=(?, 16), dtype=float32)
Tensor("dense_2/Sigmoid:0", shape=(?, 5), dtype=float32)

可以看到输出结果的最后一维度就等于神经元的个数,这是非常容易理解的。

卷积

(),conv2d(),conv3d(),分别代表一维,二维,三维卷积,另外还有conv2d_transpose(),conv3d_transpose(),这个提供了多卷积方法, ,分别代表二维和三维反卷积,还有separable_conv2d()方法代表二维深度可分离卷积。它们定义在tensorflow / python / layers / convolutional.py中,其用法都是类似的,在这里conv2d()方法为例进行说明。

123456789101112131415161718192021conv2d(    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)复制代码

参数说明如下:

  • 输入:必需,即需要进行操作的输入数据。
  • filters:必需,是一个数字,代表了输出通道的个数,即output_channels。
  • kernel_size:必需,卷积核大小,必须是一个数字(高和宽都是此数字)或者长度为2的列表(分别代表高,宽)。
  • strides:可选,默认为(1,1),卷积步长,必须是一个数字(高和宽都是此数字)或者长度为2的列表(分别代表高,宽)。
  • padding:可选,默认为valid,padding的模式,有效和same两种,大小写不区分。
  • data_format:可选,默认channels_last,分为channels_last和channels_first两种模式,代表了怎么输入数据的维度类型,如果是channels_last,那么输入数据的形状为(batch,height,width,channels),如果是channels_first,那么输入数据的形状为(批次,通道,高度,宽度)。
  • dilation_rate:任选,默认为(1,1),卷积的扩张率,如当扩张率为2时,卷积核内部就会有边距,3×3的卷积核就会变成5× 5。
  • activation:可选,默认为None,如果为None则是线性激活。
  • use_bias:可选,默认为True,是否使用偏置。
  • kernel_initializer:可选,默认为None,即权重的初始化方法,如果为None,则使用默认的Xavier初始化方法。
  • bias_initializer:可选,默认为零值初始化,即偏置的初始化方法。
  • kernel_regularizer:可选,默认为None,施加在权重上的正则项。
  • bias_regularizer:可选,默认为None,施加在偏置上的正则项。
  • activity_regularizer:可选,默认为None,施加在输出上的正则项。
  • kernel_constraint,可选,默认为None,施加在权重上的约束项。
  • bias_constraint,可选,默认为None,施加在偏置上的约束项。
  • 可训练:可选,默认为True,布尔类型,如果为True,则会将变量添加到GraphKeys.TRAINABLE_VARIABLES中。
  • name:可选,默认为None,卷积层的名称。
  • 重用:可选,默认为无,布尔类型,如果为True,那么如果名称相同时,会重复利用。

返回值:卷积后的张量。

下面我们用实例感受一下它的用法:

123x = tf.layers.Input(shape=[20, 20, 3])y = tf.layers.conv2d(x, filters=6, kernel_size=2, padding='same')print(y)复制代码

这里我们首先声明了一个[?,20,20,3]的输入x,然后将其传给conv2d()方法,filters设定为6,即输出通道为6,kernel_size为2,即卷积核大小为2 x 2,padding方式设置为same,那么输出结果的宽高和原来一定是相同的,但是输出通道就变成了6,结果如下:
1Tensor("conv2d/BiasAdd:0", shape=(?, 20, 20, 6), dtype=float32)复制代码

但如果我们将padding方式不传入,使用默认的有效模式,代码改写如下:

1
2
3
x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=2)
print(y)

结果如下:

1
Tensor("conv2d/BiasAdd:0", shape=(?, 19, 19, 6), dtype=float32)

结果就变成了[?,19,19,6],这是因为步长默认为1,卷积核大小为2 x 2,所以得到的结果的高宽即为(20 - (2 - 1) )×(20-(2-1))= 19×19。

当然卷积核我们也可以变换大小,传入一个列表形式:

1
2
3
x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=[2, 3])
print(y)

这时我们的卷积核大小变成了2 x 3,即高为2,宽为3,结果就变成了[?,19,18,6],这是因为步长默认为1,核大小为2 x 2,所以得到的结果的高宽即为(20 - (2 - 1))x(20 - (3 - 1))= 19 x 18。

如果我们将步长也设置一下,也传入列表形式:

1
2
3
x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=[2, 3], strides=[2, 2])
print(y)

这个卷积核大小变成了2 x 3,步长变成了2 x 2,所以结果的高宽为ceil(20 - (2 1))/ 2 x ceil(20 - (3 - 1) )/ 2 = 10 x 9,得到的结果即为[?,10,9,6]。

运行结果如下:

1
Tensor("conv2d_4/BiasAdd:0", shape=(?, 10, 9, 6), dtype=float32)

另外我们还可以传入激活函数,或者用于偏置等操作,实例如下:

1
2
3
x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d(x, filters=6, kernel_size=2, activation=tf.nn.relu, use_bias=False)
print(y)

这样我们就将激活函数改成了relu,同时禁用了bias,运行结果如下:

1
Tensor("conv2d_5/Relu:0", shape=(?, 19, 19, 6), dtype=float32)

另外还有反卷积操作,反卷积顾名思义即卷积的反向操作,即输入卷积的结果,得到卷积前的结果,其参数用法是完全一样的,例如:

1
2
3
x = tf.layers.Input(shape=[20, 20, 3])
y = tf.layers.conv2d_transpose(x, filters=6, kernel_size=2, strides=2)
print(y)

例如此处输入的图像高宽为20 x 20,经过卷积核为2,步长为2的反卷积处理,得到的结果高宽就变为了40 x 40,结果如下:

1
Tensor("conv2d_transpose/BiasAdd:0", shape=(?, 40, 40, 6), dtype=float32)

pooling,即池化,layers模块提供了多个池化方法,这几个池化方法都是类似的,包括max_pooling1d(),max_pooling2d(),max_pooling3d(),average_pooling1d(),average_pooling2d(),average_pooling3d ),分别代表一维二维三维最大和平均池化方法,它们都定义在tensorflow / python / layers / pooling.py中,这里以max_pooling2d()方法为例进行介绍。
12345678max_pooling2d(    inputs,    pool_size,    strides,    padding='valid',    data_format='channels_last',    name=None)复制代码

参数说明如下:

  • 输入:必需,即需要池化的输入对象,必须是4维的。
  • pool_size:必需,池化窗口大小,必须是一个数字(高和宽都是此数字)或者长度为2的列表(分别代表高,宽)。
  • strides:必需,池化步长,必须是一个数字(高和宽都是此数字)或者长度为2的列表(分别代表高,宽)。
  • padding:可选,默认valid,padding的方法,有效或者相同,大小写不区分。
  • data_format:可选,默认channels_last,分为channels_last和channels_first两种模式,代表了怎么输入数据的维度类型,如果是channels_last,那么输入数据的形状为(batch,height,width,channels),如果是channels_first,那么输入数据的形状为(批次,通道,高度,宽度)。
  • 名称:可选,默认无,池化层的名称。

返回值:经过池化处理后的张量。

下面我们用一个实例来感受一下:

1
2
3
4
5
6
x = tf.layers.Input(shape=[20, 20, 3])
print(x)
y = tf.layers.conv2d(x, filters=6, kernel_size=3, padding='same')
print(y)
p = tf.layers.max_pooling2d(y, pool_size=2, strides=2)
print(p)

在这里我们首先指定了输入x,形为[20,20,3],然后对其进行了卷积计算,然后池化,最后得到池化后的结果。结果如下:

1
2
3
Tensor("input_layer_1:0", shape=(?, 20, 20, 3), dtype=float32)
Tensor("conv2d/BiasAdd:0", shape=(?, 20, 20, 6), dtype=float32)
Tensor("max_pooling2d/MaxPool:0", shape=(?, 10, 10, 6), dtype=float32)

可以看到这里池化窗口用的是2,步长也是2,所以原本卷积后形为[?,20,20,6]的结果就变成了[?,10,10,6]。

退出

dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃,可以用来防止过拟合,层模块中提供了dropout()方法来实现这一操作,定义在tensorflow / python / layers / core.py。下面我们来说明一下它的用法。
12345678dropout(    inputs,    rate=0.5,    noise_shape=None,    seed=None,    training=False,    name=None)复制代码

参数说明如下:

  • 输入:必须,即输入数据。
  • rate:任选,默认为0.5,即丢失率,如设置为0.1,则意味着会丢弃10%的神经元。
  • noise_shape:可选,默认为None,int32类型的一维Tensor,它代表了丢弃mask的形状,dropout mask会与输入相乘对输入做转换,例如输入的形状为(batch_size,timesteps,features),但我们想要droput mask在所有timeteps都是相同的,我们可以设置noise_shape = [batch_size,1,features]。
  • seed:任选,默认为None,即产生随机熟的种子值。
  • 训练:可选,默认为False,布尔类型,即代表了是否标志位训练模式。
  • name:可选,默认为None,dropout层的名称。

返回:经过dropout层之后的张量。

我们用一个实例来感受一下:

1
2
3
4
5
6
x = tf.layers.Input(shape=[32])
print(x)
y = tf.layers.dense(x, 16, activation=tf.nn.softmax)
print(y)
d = tf.layers.dropout(y, rate=0.2)
print(d)

运行结果:

1
2
3
Tensor("input_layer_1:0", shape=(?, 32), dtype=float32)
Tensor("dense/Softmax:0", shape=(?, 16), dtype=float32)
Tensor("dropout/Identity:0", shape=(?, 16), dtype=float32)

在这里我们使用dropout()方法实现了droput操作,并制定dropout rate为0.2,最后输出结果的shape和原来是一致的。

弄平

flatten()方法可以对张量进行展平操作,定义在tensorflow / python / layers / core.py中。
1234flatten(    inputs,    name=None)复制代码

弄平

flatten()方法可以对张量进行展平操作,定义在tensorflow / python / layers / core.py中。

1
2
3
4
flatten(
inputs,
name=None
)

参数说明如下:

  • 输入:必需,即输入数据。
  • 名称:可选,默认为无,即该层的名称。

返回结果:展平后的张量。

下面我们用一个实例来感受一下:

1
2
3
4
x = tf.layers.Input(shape=[5, 6])
print(x)
y = tf.layers.flatten(x)
print(y)

运行结果:

1
2
Tensor("input_layer_1:0", shape=(?, 5, 6), dtype=float32)
Tensor("flatten/Reshape:0", shape=(?, 30), dtype=float32)

这里输入数据的形状为[?,5,6],经过flatten层之后,就会变成[?,30],即将除了第一维的数据维度相乘,对原Tensor进行展平。

假如第一维是一个已知的数的话,它依然还是同样的处理,示例如下:

1
2
3
4
x = tf.placeholder(shape=[5, 6, 2], dtype=tf.float32)
print(x)
y = tf.layers.flatten(x)
print(y)

结果如下:

1
2
Tensor("Placeholder:0", shape=(5, 6, 2), dtype=float32)
Tensor("flatten_2/Reshape:0", shape=(5, 12), dtype=float32)

除了如上的方法,其实我们还可以直接使用类来进行操作,实际上看方法的实现就是实例化了其对应的类,下面我们首先说明一下有哪些类可以使用:

  • class AveragePooling1D:一维平均池化层类
  • 班级AveragePooling2D:二维平均池化层类
  • 班级AveragePooling3D:三维平均池化层类
  • BatchNormalization:批量标准化层类
  • class Conv1D:一维卷积层类
  • class Conv2D:二维卷积层类
  • class Conv2DTranspose:二维反卷积层类
  • class Conv3D:三维卷积层类
  • class Conv3DTranspose:三维反卷积层类
  • class Dense:全连接层类
  • class Dropout:Dropout层类
  • class Flatten:拼合层类
  • 类InputSpec:输入层类
  • 类层:基类,父类
  • class MaxPooling1D:一维最大池化层类
  • class MaxPooling2D:二维最大池化层类
  • class MaxPooling3D:三维最大池化层类
  • class SeparableConv2D:二维深度可分离卷积层类

其实类这些类都和上文介绍的方法是一一对应的,关于它的用法我们可以在方法的源码实现里面找到,下面我们以密类的用法为例来说明一下这些类的具体调用方法:

1
2
3
4
x = tf.layers.Input(shape=[32])
dense = tf.layers.Dense(16, activation=tf.nn.relu)
y = dense.apply(x)
print(y)

这里我们初始化了一个Dense类,它只接受一个必须参数,那就是units,相比dense()方法来说它没有了inputs,因此这个实例化的类和inputs是无关的,这样就相当于创建了一个16个神经元的全连接层。

但创建了不调用是没有用的,我们要将这个层构建到网络之中,需要调用它的apply()方法,而apply()方法就接收输入这个参数,返回计算结果,运行结果如下:

1
Tensor("dense/Relu:0", shape=(?, 16), dtype=float32)

因此我们可以发现,这些类在初始化的时候实际上是比其对应的方法少了输入参数,其他的参数都是完全一致的,另外需要调用apply()方法才可以应用该层并将其构建到模型中。

所有其他类的用法在此就不一一赘述了,初始化的参数可以类比其对应的方法,实例化类之后,调用apply()方法,可以达到同样的构建模型的效果。

结语

以上便是TensorFlow layers模块的详细用法说明,更加详细的用法可以参考官方文档:

本节代码地址:


本资源首发于崔庆才的个人博客静觅: Python3网络爬虫开发实战教程 | 静觅

如想了解更多爬虫资讯,请关注我的个人微信公众号:进击的Coder

weixin.qq.com/r/5zsjOyvEZ… (二维码自动识别)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值