章节索引 :

Keras 中的 Masking 与 Padding

机器学习中的 Mask 与 Padding 是两个经常会使用到的概念,而之前我们也接触到一部分,那就是在我们进行文本分类的时候曾经接触过 Padding。而这节课我们就来详细了解一下 Masking 与 Padding 的概念以及基本的用法。

1. 基本概念

虽然 Mask(遮掩)和 Padding(填充)这两个概念看上去似乎很难理解,但是他他们的作用却很简单。简单来说,Mask与Padding的作用分别是:

  • Padding:将本来不相同的样本填充到相同的长度,以便于后面的处理,我们一般使用0做填充;
  • Mask:告诉网络层那些是真正的数据,哪些是填充的“0”,从而帮助网络层更好地计算。

简单举例,下面是我们的三个文本:

[
    ['Hello', 'Hi'],
    ['Who', 'are', 'you'],
    ['what', 'time', 'is', 'it', 'now']
]

假设我们将其编码之后得到的向量为:

[
    [1, 2],
    [3, 4, 5],
    [6, 7, 8, 9, 10]
]

于是我们将这三个张量填充到共同长度——5:

[
    [1, 2, 0, 0, 0],
    [3, 4, 5, 0, 0],
    [6, 7, 8, 9, 10]
]

经过填充之后我们得到了三个长度相同的向量,于是我们可以计算出mask来告诉网络哪些数据是填充的,哪些数据是真实的数据。于是我们得到了该向量的Mask:

[
    [True, True, False, False, False],
    [True, True, True,  False, False],
    [True, True, True,  True,  True ]
]

通过上面的例子相信大家可以清楚的了解到机器学习中Mask与Padding的概念。下面我们可以看一下在TesnorFlow之中如何使用这两者吧。

2. TensorFlow 中的 Padding

在TensorFlow之中,我们最常使用的方法是采用预处理的方式进行序列的Padding,就像我们在文本分类中所做的那样。

下面是一个简单的示例:

import tensorflow as tf

inputs = [
    [1, 2],
    [3, 4, 5],
    [6, 7, 8, 9, 10]
]

inputs = tf.keras.preprocessing.sequence.pad_sequences(
    raw_inputs, padding="post", value=0
)
print(inputs)

于是我们可以得到输出:

[[ 1  2  0  0  0]
 [ 3  4  5  0  0]
 [ 6  7  8  9 10]]

以上就是TensorFlow中进行填充最常用的方法。

3. TensorFlow 中的 Mask

在TensorFlow之中使用Mask也是比较简单的,主要有两种方法:

  • 添加一个tf.keras.layers.Embedding层并设置参数mask_zero=True;
  • 添加一个tf.keras.layers.Masking层。

这里我们使用之前的文本分类的模型作为例子来进行演示。值得注意的是,在很多情况之下,如果我们不使用Mask,那么模型依然会继续运行,但是采用Mask会让模型更加精确。

我们原来的网络为:

model = tf.keras.Sequential([
    tf.keras.layers.Embedding(10000, 32),
    tf.keras.layers.GlobalAveragePooling1D(),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])
model.summary()

我们可以查看到模型的结构为:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, None, 32)          320000    
_________________________________________________________________
global_average_pooling1d (Gl (None, 32)                0         
_________________________________________________________________
dense (Dense)                (None, 64)                2112      
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 65        
=================================================================
Total params: 322,177
Trainable params: 322,177
Non-trainable params: 0
_________________________________________________________________

1. 使用tf.keras.layers.Embedding层并设置mask_zero=True

因为我们已经使用了Embedding,因此我们只需要直接设置参数mask_zero=True即可:

model2 = tf.keras.Sequential([
    tf.keras.layers.Embedding(10000, 32, mask_zero=True),
    tf.keras.layers.GlobalAveragePooling1D(),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])
model2.summary()

于是我们可以看到网络的结构:

Model: "sequential_2"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_2 (Embedding)      (None, None, 32)          320000    
_________________________________________________________________
global_average_pooling1d_2 ( (None, 32)                0         
_________________________________________________________________
dense_4 (Dense)              (None, 64)                2112      
_________________________________________________________________
dense_5 (Dense)              (None, 1)                 65        
=================================================================
Total params: 322,177
Trainable params: 322,177
Non-trainable params: 0
_________________________________________________________________

我们可以发现网络的结构没有发生变化,为了验证该Mask已经生效,于是我们可以进行测试:

print(model(inputs))
print(model2(inputs))

我们可以通过输出看到,我们设置的遮掩(Mask)已经生效:

tf.Tensor(
[[0.5014145 ]
 [0.50220466]
 [0.5058755 ]], shape=(3, 1), dtype=float32)

tf.Tensor(
[[0.4913409 ]
 [0.49880138]
 [0.49782944]], shape=(3, 1), dtype=float32)

2. 使用tf.keras.layers.Masking层

我们依然以我们的文本分类模型为例,为了添加Masking层,我们将模型进行如下修改:

model3 = tf.keras.Sequential([
    tf.keras.layers.Masking(input_shape=(256,)),
    tf.keras.layers.Embedding(10000, 32),
    tf.keras.layers.GlobalAveragePooling1D(),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid')
])
model3.summary()

在该模型之中,因为Masking层是位于第一层,因此我们要设置参数input_shape,这里的参数(256,)表示的是我们的每条数据都是padding长度为256的序列。

于是我们可以得到输出:

Model: "sequential_10"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
masking_5 (Masking)          (None, 256)               0         
_________________________________________________________________
embedding_10 (Embedding)     (None, 256, 32)           320000    
_________________________________________________________________
global_average_pooling1d_10  (None, 32)                0         
_________________________________________________________________
dense_20 (Dense)             (None, 64)                2112      
_________________________________________________________________
dense_21 (Dense)             (None, 1)                 65        
=================================================================
Total params: 322,177
Trainable params: 322,177
Non-trainable params: 0
_________________________________________________________________

由此可以看到,虽然masking层没有参数,但是它确实作为一个网络层包含进了网络。

3. 小结

在这节课之中,我们学习了如何进行Padding,也学习到了如何设置Mask。这两种操作互相结合可以使得我们的处理序列的模型的精确度和准确率有很大的提升。

图片描述

TensorFlow 简介、安装与快速入门
TensorFlow 简介 TensorFlow 安装 - CPU TensorFlow 安装 - GPU TensorFlow 快速入门示例
TensorFlow 模型的简洁表示-Keras
Keras 简介 使用 tf.keras 进行图片分类 使用 Keras 进行文本分类 使用 Keras 进行回归 在 Keras 中保存与加载模型 在 Keras 中进行模型的评估 Keras 中的Masking 与 Padding
TensorFlow 中的数据格式
TensorFlow 中的数据核心 使用 TensorFlow 加载 CSV 数据 使用 TensorFlow 加载 Numpy 数据 使用 TF 加载 DateFrame 数据 使用图像数据来训练模型 在 TensorFlow 之中使用文本数据 TF 之中的 Unicode 数据格式的处理
TensorFlow模型的高级表示-Estimat
使用预设的 Estimator 模型 将Keras模型转化为Estimator模型 Estimator实现BoostingTree模型
TensorFlow 高级技巧
过拟合问题 TensorFlow 中的回调函数 文本数据嵌入 在 TensorFlow 之中使用卷积神经网络 在 TensorFlow 之中使用循环神经网络 在 TensorFlow 之中使用注意力模型 在 TensorFlow 之中进行迁移学习 在 TensorFlow 之中进行数据增强 在 TensorFlow 之中进行图像分割 如何进行多 GPU 的分布式训练? 使用 tf.function 提升效率 使用 TF HUB 进行模型复用
TensorFlow高级技巧-自定义
使用 TensorFlow 进行微分操作 在 TensorFlow 之中自定义网络层与模型 在 TensorFlow 之中自定义训练
TF 框架中的可视化工具-TensorBoard
TensorBoard 的简介与快速上手 使用 TensorBoard 记录训练中的各项指标 在 TensorBoard 之中查看模型结构图 在 TensorBoard 之中记录图片数据