TF Esitmator

2019-02-01  本文已影响0人  one_game

简介

tf.estimator属于tensorflow中的高级抽象封装,目的是为了提供开发着的开发速度,但是同时也会在一定程度上限制灵活性。

tensorflow编程栈

Estimator封装了训练、评估、预测及导出等操作

如何定义一个Estimator

Tensorflow为我们预定义好了一些Estimator(如下图),我们也可根据自己的网络结构去自定义Estimator。


estimator_types.png

通常来说我们去实例化一个Estimator并且进行训练只需要两步:

estimator = tf.estimator.Estimator(..) #实例化
esitmator.train(..) #训练
estimator.evaluate(..) #评估
estimator.predict(..) #预测
estimator.save(..) #保存、导出
estimator.load(..) #加载

所以接下来我们分别看一下每一步中都需要我们准备什么。


实例化Estimator

#tf.estimator.Estimator的构造函数
__init__(
    model_fn,
    model_dir=None,
    config=None,
    params=None,
    warm_start_from=None
)

其中:

def my_model_fn(
   features, # This is batch_features from input_fn, passed by estimator
   labels,   # This is batch_labels from input_fn, passed by estimator
   mode,     # An instance of tf.estimator.ModeKeys,e.g. train、eval or predict
   params):  # Additional configuration

featureslabels 是在模型训练(或者评估和预测)过程中通过input_fn的返回传入的
mode是指定模型的运行模型,如训练、评估和预测
params是其他参数用于模型的构建和超参的调优
注: 该函数必须返回一个tf.estimator.EstimatorSpec的实例

@staticmethod
__new__(
  cls,
  mode,
  predictions=None,
  loss=None,
  train_op=None,
  eval_metric_ops=None,
  export_outputs=None,
  training_chief_hooks=None,
  training_hooks=None,
  scaffold=None,
  evaluation_hooks=None,
  prediction_hooks=None
)

训练模型
接下来我们看一下estimitor的训练都需要什么,函数的原型定义如果下:

train(
    input_fn,
    hooks=None,
    steps=None,
    max_steps=None,
    saving_listeners=None
)
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 dataset.
    return dataset

评估模型


预测


保存、导出模型


模型的加载


综上,当我们使用Estimator进行建模训练的步骤如下:

1、定义网络结构

如果使用tensorflow为我们预定义好的网络则可略过此步,否则需要定义在estimator构造阶段提到的model_fn方法,在该方法中我们要实现的是:

Estimator 方法 Estimator 模式(mode) tf.estimator.EstimatorSpec必须参数
train() ModeKeys.TRAIN loss和train_op
predict() ModeKeys.PREDICT loss
eval() ModeKeys.EVAL predictions

如下是一个简单的例子:

def my_model_fn(features, labels, mode):
  if (mode == tf.estimator.ModeKeys.TRAIN or
      mode == tf.estimator.ModeKeys.EVAL):
    loss = ...
  else:
    loss = None
  if mode == tf.estimator.ModeKeys.TRAIN:
    train_op = ...
  else:
    train_op = None
  if mode == tf.estimator.ModeKeys.PREDICT:
    predictions = ...
  else:
    predictions = None

  return tf.estimator.EstimatorSpec(
      mode=mode,
      predictions=predictions,
      loss=loss,
      train_op=train_op)
2、 编写一个或多个数据集导入函数
def input_fn(dataset):
   ...  # manipulate dataset, extracting the feature dict and the label
   return feature_dict, label
3、定义特征列

对特征的定义主要由 tf.feature_column实现,它标识了特征名称、特征类型和任何输入预处理操作。

# Define three numeric feature columns.
population = tf.feature_column.numeric_column('population')
crime_rate = tf.feature_column.numeric_column('crime_rate')
median_education = tf.feature_column.numeric_column('median_education',
                    normalizer_fn=lambda x: x - global_education_mean)
inputs_to_model_bridge.jpg
tf.feature_column在dataset和estimator之间起到了桥接作用,将dataset中的原始特征转换成模型可以使用的特征形式。

根据不同的特征类型,tf.feature_column又包含如下9个不同的函数用来处理不同的数据类型:


feature_columns类型

总体上特征可以分为Dense特征(Dense Column)和Sparse特征(Categorical Column),最终所有的特征列转换为Dense Column作为网络的输入。

对于Dense Column:

tf.feature_column.numeric_column(
    key,
    shape=(1,),
    default_value=None,
    dtype=tf.float32,
    normalizer_fn=None
)
tf.feature_column.indicator_column(categorical_column)
categorical_column = ... # Create any categorical column

# Represent the categorical column as an embedding column.
# This means creating an embedding vector lookup table with one element for each category.
# dimension选择经验公式
# embedding_dimensions =  number_of_categories**0.25
embedding_column = tf.feature_column.embedding_column(
    categorical_column=categorical_column,
    dimension=embedding_dimensions)

对于Categorical Column:

tf.feature_column.categorical_column_with_identity(
    key,
    num_buckets,
    default_value=None
)

所有的输入都必须在[0, num_buckets)内,如果超出范围,则会使用default_value,如果default_value没有定义则会抛异常。

tf.feature_column.categorical_column_with_vocabulary_list(
    key,
    vocabulary_list,
    dtype=None,
    default_value=-1,
    num_oov_buckets=0
)
tf.feature_column.categorical_column_with_hash_bucket(
    key,
    hash_bucket_size,
    dtype=tf.string
)
hashed_column.jpg
tf.feature_column.crossed_column(
    keys,
    hash_bucket_size,
    hash_key=None
)
#e.g
# Bucketize the latitude and longitude using the `edges`
latitude_bucket_fc = tf.feature_column.bucketized_column(
    tf.feature_column.numeric_column('latitude'),
    list(atlanta.latitude.edges))

longitude_bucket_fc = tf.feature_column.bucketized_column(
    tf.feature_column.numeric_column('longitude'),
    list(atlanta.longitude.edges))

# Cross the bucketized columns, using 5000 hash bins.
crossed_lat_lon_fc = tf.feature_column.crossed_column(
    [latitude_bucket_fc, longitude_bucket_fc], 5000)

其他

 tf.feature_column.bucketized_column(
    source_column,
    boundaries
)
# First, convert the raw input to a numeric column.
numeric_feature_column = tf.feature_column.numeric_column("Year")

# Then, bucketize the numeric column on the years 1960, 1980, and 2000.
bucketized_feature_column = tf.feature_column.bucketized_column(
    source_column = numeric_feature_column,
    boundaries = [1960, 1980, 2000])
4、实例化相关的预创建的 Estimator
# Instantiate an estimator, passing the feature columns.
estimator = tf.estimator.LinearClassifier(
    feature_columns=[population, crime_rate, median_education],
    )
5、调用训练、评估或推理方法
# my_training_set is the function created in Step 1
estimator.train(input_fn=my_training_set, steps=2000)
上一篇下一篇

猜你喜欢

热点阅读