将 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 的几个常用的参数。