将 Keras 模型转化为 Estimator 模型

在上一节课之中,我们学习了使用 Estimator 来进行模型训练的一系列步骤,同时也通过一个示例了解了如何使用内置的 Estimator 来进行模型的训练。

而在实际的应用过程之中,我们难免会遇到要使用自定义模型进行训练的情况,而在之前的学习之中我们曾经学习过如何使用 Keras 来自定义模型,那么这节课我们就来学习一下如何使用自定义的 Keras 模型转化为 Estimator 模型并进行训练

那么这节课我们便使用对 Fashion_Mnist 数据集进行分类的示例来学习如何 Keras 模型转化为 Estimator 模型。

1. 采用的方法

在 TensorFlow 之中,若要将一个 Keras 模型转化为一个 Estimator 模型,我们只需要调用一个步骤,那就是 tf.keras.estimator.model_to_estimator 接口

可以看出,该 API 是一个 keras 的 API ,而该接口会将一个 Keras 模型转化为一个估算器(Estimator)。

对于该接口的详细参数,我们会在具体实现的时候进行说明。

由于转化完成的接口仍然是一个 Estimator 模型,因此我们依然需要之前的四步骤:

  • 定义特征列,在这里可以省略,因为输入的特征我们可以在 Keras 模型之中处理
  • 定义输入函数;
  • 创建 Estimator 模型,在这里就是将Keras模型转化为 Estimator 模型
  • 进行训练与评估等操作。

2. 具体示例

首先我们需要获取数据集,和之前一样,为了方便,我们直接采用官方 API 进行数据集的获取:

import tensorflow as tf

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()

x_train, x_test = x_train / 255.0, x_test / 255.0

通过上面的代码,我们便得到了数据集,同时对图片数据进行了归一化处理,也就是所将他们的数值规范化到 [0, 1] 之间。

然后我们就需要定义我们的模型:

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(256, activation='relu'),
  tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(loss=tf.keras.losses.SparseCategoricalCrossentropy(), 
        optimizer='adam', metrics=['accuracy'])

在这里我们使用了一个和之前一样的模型:

  • 第一层为一个扁平化层,将二维数据一维化;
  • 第二层为一个隐含层,其中包括256个隐含节点;
  • 最后一层为输出层,包含十个节点,因为我们的分类一共有10个

然后我们对模型进行了编译,我们采用的是 adam 优化器,因为我们是多分类任务,因此我们采用了 SparseCategoricalCrossentropy 损失函数

然后我们需要进行非常重要的一步:定义输入函数,在这里我们要定义两个输入函数,第一个为训练时的输入函数,另一个为测试时的输入函数。

def train_input_fn(x_train, y_train):
  dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train))
  dataset = dataset.batch(16).repeat()
  return dataset

def test_input_fn(x_test, y_test):
  dataset = tf.data.Dataset.from_tensor_slices((x_test, y_test))
  dataset = dataset.batch(16)
  return dataset

在这里我们依然采用的是 tf.data.Dataset.from_tensor_slices 切片的方法来构建数据集,同时我们进行了分批处理,其中批次的大小为16,而对于训练集,我们进行了重复处理,因为我们的训练过程可能需要多次遍历数据集。

然后我们便将我们创建的Keras模型转化为Estimator模型:

keras_estimator = tf.keras.estimator.model_to_estimator(keras_model=model)

仅仅需要一行代码,我们的Keras模型就转化为了 Estimator 模型,在这里我们仅仅使用了一个参数,那就是 keras_model 参数,其实该函数还包括几个非常有用的参数:

  • keras_model_path:与 keras_model 互斥,也就是说不能与 keras_model 同时不为 None ,用来指定从磁盘上加载一个模型;
  • model_dir:用来保存各种日志、参数、图表的目录;
  • checkpoint_format:用来保存模型的格式。

最后我们进行模型的训练与测试:

keras_estimator.train(input_fn=lambda: train_input_fn(x_train, y_train), steps=5000)
eval_result = keras_estimator.evaluate(input_fn=lambda: test_input_fn(x_test, y_test), steps=len(x_test)//16)
print(eval_result)

在这里,我们在训练的时候采用了一个参数 steps ,这个参数指明要训练多少个 batch_size (在这里是16 );因为在测试的时候我们只需要进行一次数据遍历,因此我们的 steps 设置为 len(x_test)//16 。

举个例子,加入我们数据一共有 10 条,我们想要训练 20 个 epoch ,那么我们就需要设置 steps 为10*20=200 。而如果 steps 为 300 ,那我们的 epoch 就是 300 // 10 = 30 。

而最后我们得到的 eval_result 是一个字典类型的对象,其中包含了 loss、step 以及我们定义的 metrics 等字段。

最后在测试结束后我们可以得到结果为:

INFO:tensorflow:Saving dict for global step 5000: accuracy = 0.8086, global_step = 5000, loss = 1.652609
INFO:tensorflow:Saving 'checkpoint_path' summary for global step 5000: /tmp/tmptu8apzc8/model.ckpt-5000
{'accuracy': 0.8086, 'loss': 1.652609, 'global_step': 5000}

可以看到我们的模型最终达到了 0.8 的准确率,如果提升 steps ,我们便可以在一定程度上进一步提升准确率。

3. 小结

在这节课之中,我们学习了如何将 Keras 转化为 Estimator 模型,总而言之,我们依然需要使用训练 Estimator 模型的一贯步骤。同时我们也了解了 tf.keras.estimator.model_to_estimator 的几个常用的参数。

图片描述