1 简介
在TensorFlow的UG中,他们强烈的建议在写Tensorflow程序时使用estimator的API,使用后发现的确好用!在github上一些开源程序也已经开始使用estimator,比如DeeplabV3+,关于DeeplabV3+的代码注释可以参考我的另一篇博客。
官方原话:
We strongly recommend writing TensorFlow programs with the following APIs:
· Estimators, which represent a complete model. The Estimator API provides methods to train the model, to judge the model’s accuracy, and to generate predictions.
· Datasets for Estimators, which build a data input pipeline. The Dataset API has methods to load and manipulate data, and feed it into your model. The Dataset API meshes well with the Estimators API.
TensorFlow官方文档对Estimator的定义是:High level tools for working with models.
它已经包含了一些内建的机器学习或者深度学习算法模型(Premade Estimators),比如:
BaselineClassifier
BaselineRegressor
BestExporter
BoostedTreesClassifier
BoostedTreesRegressor
DNNClassifier
DNNLinearCombinedClassifier
DNNLinearCombinedRegressor
DNNRegressor
我们可以直接使用上面的模型进行深度学习算法的验证和实现。
2 自定义Estimator与pre-made Estimator
pre-made Estimator是别人写好的模型(model_fn);自定义estimator需要自己设计模型
首先我们要对pre-made Estimator和custom Estimator的关系有一个清晰的理解:
3 使用Pre-made Estimator
我很少会用到pre-made Estimator,这里就不做介绍了,感兴趣可以参考官方UG
4 入门 Custom Estimator
我的另一篇博客中介绍了DeeplabV3+,源码中就是使用了Custom Estimator,这份源码是一个不错的实例。
此处我们首先另起炉灶,举一个更加简单的例子。之后再谈论DeeplabV3+这个程序。
4.1 Write an Input function
def train_input_fn(features, labels, batch_size):
"""An input function for training"""
# Convert the inputs to a Dataset.
dataset = tf.data.Dataset.from_tensor_slices((dict(features), labels))
# Shuffle, repeat, and batch the examples.
dataset = dataset.shuffle(1000).repeat().batch(batch_size)
# Return the read end of the pipeline.
return dataset.make_one_shot_iterator().get_next()
这个输入函数建立了一个input pipline,每次提取batch大小的(features, labels)
4.2 Create feature columns
我们必须定义模型的feature columns来明确我们的模型应该如何使用各个feature
# Feature columns describe how to use the input.
my_feature_columns = []
for key in train_x.keys():
my_feature_columns.append(tf.feature_column.numeric_column(key=key))
4.3 Write a model function
Custom Estimator应该和DNNClassifier等Pre-made Estimator具有相同的接口:
tf.estimator.Estimator(
model_fn, #模型函数
model_dir=None, #存储目录,训练和验证产生的文件都会存储在这个目录下
config=None, #设置参数对象,主要针对运行环境的一些设置
params=None, #超参数,将传递给model_fn使用
warm_start_from=None #热启动目录路径
)
其中最重要的就是model_fn了,它应该具有以下形式:
my_model(
features, #This is batch_features from input_fn
labels, #This is batch_labels from input_fn
mode, #An instance of tf.estimator.ModeKeys, train、evaluate或predict
params #超参数,对应上面Estimator传来的参数
)
4.3.1 Define the model
上面的4.3只是写了一个函数接口,我们还要进一步详细的定义模型。
- An input layer
- One or more hidden layers
- An output layer
4.3.1.1 Define the input layer
model_fn的第一行就应该调用 tf.feature_column.input_layer ,把feature dictionary和feature_columes导入模型中:
# Use `input_layer` to apply the feature columns.
net = tf.feature_column.input_layer(features, params['feature_columns'])
这句话建立了模型input layer并完成了feature columns中定义的转换
4.3.1.2 Hidden Layers
hidden layers不用多说,建立之后网络呈现如下结构
4.3.1.3 Output Layer
注意,activation=None;
units = params[‘n_classes’],这个实在构造estimator时就已经设定好了
我们把outlayer中的logits传入softmax,就可以输出概率分布。
# Compute logits (1 per class).
logits = tf.layers.dense(net, params['n_classes'], activation=None)
4.3.2 Implement training, evaluation, and prediction
到此为止,模型已经定义好了,我们要着手实现模型的training,evaluation,prediction等功能。
4.3.2.1 Predict
# Compute predictions.
predicted_classes = tf.argmax(logits, 1)
if mode == tf.estimator.ModeKeys.PREDICT:
predictions = {
'class_ids': predicted_classes[:, tf.newaxis],
'probabilities': tf.nn.softmax(logits),
'logits': logits,
}
return tf.estimator.EstimatorSpec(mode, predictions=predictions)
4.3.2.2 Calculate the loss
this is the object that will be optimized !!!
train和evaluate都需要使用它
# Compute loss.
loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
4.3.2.3 Evaluate
tensorflow提供API去评价一个model的性能,比如tf.metrics
# Compute evaluation metrics.
accuracy = tf.metrics.accuracy(labels=labels,
predictions=predicted_classes,
name='acc_op')
如果我们还需要看其他的评价指标,比如roi等,可以把roi加入metrics字典中去。以下为完整写法。
metrics = {'accuracy': accuracy}
tf.summary.scalar('accuracy', accuracy[1])
if mode == tf.estimator.ModeKeys.EVAL:
return tf.estimator.EstimatorSpec(
mode, loss=loss, eval_metric_ops=metrics)
4.3.2.4 Train
- 首先制定优化器
optimizer = tf.train.AdagradOptimizer(learning_rate=0.1)
- 然后确定train_op
train_op = optimizer.minimize(loss, global_step=tf.train.get_global_step())
- 最后返回
return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
5 实战 Custom Estimator
待续…