【问题标题】:How to combine feature_columns, model_to_estimator and dataset API in Tensorflow如何在 Tensorflow 中结合 feature_columns、model_to_estimator 和 dataset API
【发布时间】:2018-04-16 09:19:05
【问题描述】:

我在 tensorflow 中有一个使用高级 API 的玩具示例:tf.estimatortf.datatf.feature_column。我想使用tf.keras.estimator.model_to_estimator 将罐装估计器与 keras 模型交换。我可以从 keras 模型生成一个估计器,但是我得到一个关于输入的名称和形状的错误。我认为 keras 模型的输入形状是错误的,因为 input_fn 传递了所有数据,而不是特征列。换句话说,我不确定如何将特征列连接到 keras 模型

以下是有效的代码的相关部分:

...
col1 = categorical_column_with_vocabulary_list('col1', [1, 2, 3])
col1_ind = C.indicator_column(col1)

col2 = numeric_column('col2')

...

estimator = E.DNNClassifier(
    feature_columns=[col1_ind, col2],
    hidden_units=[10])

...

def input_fn(features, labels, batch_size):
    dataset = D.Dataset.from_tensor_slices((dict(features),
                                            labels))
    dataset = dataset.shuffle(1000).repeat().batch(batch_size)
return dataset

...

train_and_evaluate(estimator, train_spec, eval_spec)

如果我尝试将DNNClassifier 替换为以下内容,我会遇到问题:

model = tf.keras.models.Sequential()
model.add(L.Dense(10, activation='relu', input_dim=9))
....

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

estimator = model_to_estimator(keras_model=model)

在这种情况下,我收到以下错误消息:

INFO:tensorflow:Running training and evaluation locally (non-distributed).
INFO:tensorflow:Start train and evaluate loop. The evaluate will happen after 600 secs (eval_spec.throttle_secs) or training is finished.
INFO:tensorflow:Calling model_fn.
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-82-0242f6f379fc> in <module>()
----> 1 E.train_and_evaluate(estimator, train_spec, eval_spec)

~/.local/lib/python3.5/site-packages/tensorflow/python/estimator/training.py in train_and_evaluate(estimator, train_spec, eval_spec)
    437         '(with task id 0).  Given task id {}'.format(config.task_id))
    438 
--> 439   executor.run()
    440 
    441 

~/.local/lib/python3.5/site-packages/tensorflow/python/estimator/training.py in run(self)
    516         config.task_type != run_config_lib.TaskType.EVALUATOR):
    517       logging.info('Running training and evaluation locally (non-distributed).')
--> 518       self.run_local()
    519       return
    520 

~/.local/lib/python3.5/site-packages/tensorflow/python/estimator/training.py in run_local(self)
    648           input_fn=self._train_spec.input_fn,
    649           max_steps=self._train_spec.max_steps,
--> 650           hooks=train_hooks)
    651 
    652       # Final export signal: For any eval result with global_step >= train

~/.local/lib/python3.5/site-packages/tensorflow/python/estimator/estimator.py in train(self, input_fn, hooks, steps, max_steps, saving_listeners)
    353 
    354     saving_listeners = _check_listeners_type(saving_listeners)
--> 355     loss = self._train_model(input_fn, hooks, saving_listeners)
    356     logging.info('Loss for final step: %s.', loss)
    357     return self

~/.local/lib/python3.5/site-packages/tensorflow/python/estimator/estimator.py in _train_model(self, input_fn, hooks, saving_listeners)
    822       worker_hooks.extend(input_hooks)
    823       estimator_spec = self._call_model_fn(
--> 824           features, labels, model_fn_lib.ModeKeys.TRAIN, self.config)
    825 
    826       if self._warm_start_settings:

~/.local/lib/python3.5/site-packages/tensorflow/python/estimator/estimator.py in _call_model_fn(self, features, labels, mode, config)
    803 
    804     logging.info('Calling model_fn.')
--> 805     model_fn_results = self._model_fn(features=features, **kwargs)
    806     logging.info('Done calling model_fn.')
    807 

~/.local/lib/python3.5/site-packages/tensorflow/python/keras/_impl/keras/estimator.py in model_fn(features, labels, mode)
    317     """model_fn for keras Estimator."""
    318     model = _clone_and_build_model(mode, keras_model, custom_objects, features,
--> 319                                    labels)
    320     # Get inputs to EstimatorSpec
    321     predictions = dict(zip(model.output_names, model.outputs))

~/.local/lib/python3.5/site-packages/tensorflow/python/keras/_impl/keras/estimator.py in _clone_and_build_model(mode, keras_model, custom_objects, features, labels)
    251     input_tensors = _create_ordered_io(keras_model,
    252                                        estimator_io=features,
--> 253                                        is_input=True)
    254   # Get list of outputs.
    255   if labels is None:

~/.local/lib/python3.5/site-packages/tensorflow/python/keras/_impl/keras/estimator.py in _create_ordered_io(keras_model, estimator_io, is_input)
     94             'It needs to match one '
     95             'of the following: %s' % ('input' if is_input else 'output', key,
---> 96                                       ', '.join(keras_io_names)))
     97       tensors = [_cast_tensor_to_floatx(estimator_io[io_name])
     98                  for io_name in keras_io_names]

ValueError: Cannot find input with name "col1" in Keras Model. It needs to match one of the following: dense_1_input

【问题讨论】:

    标签: python tensorflow keras tensorflow-datasets tensorflow-estimator


    【解决方案1】:

    要将feature_columns 与通过model_to_estimator(keras_model=model) 创建的估计器连接起来,您必须使feature_column 的名称与模型输入层的名称相匹配。

    例如,您的input_fn() 可能如下所示:

    def input_fn(features, labels, batch_size):
        dataset = D.Dataset.from_tensor_slices((dict(features), labels))
        dataset = dataset.shuffle(1000).repeat().batch(batch_size)
        iterator = dataset.make_initializable_iterator()
        tf.add_to_collection(
            tf.GraphKeys.TABLE_INITIALIZERS, iterator.initializer)
        features, labels = iterator.get_next()
        return {"dense_1_input": features}, labels
    

    因此,无论您的输入层有什么名称,keras 模型都需要该名称的特征列并添加 _input

    model = tf.keras.models.Sequential()
    model.add(L.Dense(10, activation='relu', input_dim=9, name="MY_NAME"))
    
    def input_fn(features, labels, batch_size):
        ...
        return {"MY_NAME_input": features}, labels
    

    【讨论】:

      【解决方案2】:

      一些示例代码:

      from tensorflow.python.feature_column import feature_column_v2 as fc
      
      feature_layer = fc.FeatureLayer(your_feature_columns)
      
      model = tf.keras.Sequential([
        feature_layer,
        tf.keras.layers.Dense(128, activation=tf.nn.relu),
        tf.keras.layers.Dense(64, activation=tf.nn.relu),
        tf.keras.layers.Dense(1, activation=tf.nn.sigmoid)
      ])
      

      请参考feature_cols_keras

      【讨论】:

        猜你喜欢
        • 2018-02-18
        • 2018-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-28
        • 1970-01-01
        • 1970-01-01
        • 2018-12-09
        相关资源
        最近更新 更多