【问题标题】:Tensorflow high-level Estimator with input_fn from external file reader带有来自外部文件阅读器的 input_fn 的 Tensorflow 高级估计器
【发布时间】:2017-05-15 13:52:11
【问题描述】:

[简短总结:如何通过外部文件阅读器在 Python 上使用 TF 高级 Estimator?还是使用 feed_dict?]

为此苦苦挣扎了几天,在网上找不到任何解决方案...

我正在使用 TF 高级模块(tf1.0 上的 tf.contrib.learn.Estimator 或 tf1.1 上的 tf.estimator.Estimator), 通过 input_fn 输入的特征和目标 (x/y),以及基于 model_fn 构建的图。

已经使用 slice_input_producer 等在“小型”数据集上训练了一个神经网络,其中整个输入是图形的一部分。(如果它在这里为 ppl 服务,我可以将一个示例推送到 github)。

我尝试在“较重”数据集(10s-100s GB)上训练更大的 nn。 我有一个外部 Python 阅读器,它读取一些讨厌的二进制文件,我真的不想进入。 这个阅读器有自己的 queue.Queue 和 m1 个样本。当我使用它来提取 m1 {features} 和 {targets} 时,网络只是将所有这些样本保存为 const。在图表的第一层......完全不受欢迎。

我尝试要么 -

  1. 将外部文件阅读器的输出作为输入提供给我的图表。
  2. 定义一个适当的 tf 队列对象,该对象将不断更新队列(每次一个样本出队时,我都希望另一个样本完全入队)。

提醒我使用“高级”,例如

self.Estimator = tf.contrib.learn.Estimator(
    model_fn=self.model_fn,
    model_dir=self.config['model_dir'],
    config=tf.contrib.learn.RunConfig( ... ) )

def input_fn(self, mode):
    batch_data = self.data[mode].next() # pops out a batch of samples, as numpy 4D matrices 
    ... # some processing of batch data 
    features_dict = dict(data=batch_data.pop('data'))
    targets_dict = batch_data
    return features_dict, targets_dict

self.Estimator.fit(input_fn=lambda: self.input_fn(modekeys.TRAIN))

【问题讨论】:

  • 我在下午收到以下提示,但无法解决,也许我错过了一些必需的 Python 技能;建议? 你必须自己做——使用 py_func 来封装你的 python 阅读器,并查看tensorflow.org/programmers_guide/reading_data 了解更多详细信息。 input_fn 简单必须返回两个字典:一个带有特征张量,一个带有标签。 contrib 中有很多工具可以让这更容易,特别是在 tf.contrib.training 和 tf.contrib.learn.FeatureColumn 中。

标签: python-2.7 tensorflow


【解决方案1】:

附件是将外部阅读器集成到高级 TF api (tf.contrib.learn.Estimator / tf.estimator.Estimator) 的最终解决方案。

请注意:

  • 架构和“逻辑”并不重要。这是一个愚蠢的简单网络。
  • 外部阅读器输出一个 numpy 矩阵字典。
  • input_fn 正在使用此阅读器。
  • 为了验证读者“拉新值”,我都
    • 将最近的值保存到self.status(应该> 1.0)
    • 保存摘要,以便在 tensorboard 中查看。

代码示例为in gist,及以下。

import tensorflow as tf
import numpy as np
modekeys = tf.contrib.learn.ModeKeys
tf.logging.set_verbosity(tf.logging.DEBUG)
# Tested on python 2.7.9, tf 1.1.0

class inputExample:
    def __init__(self):
        self.status = 0.0 # tracing which value was recently 'pushed' to the net
        self.model_dir = 'temp_dir'
        self.get_estimator()

    def input_fn(self):
        # returns features and labels dictionaries as expected by tf Estimator's model_fn
        data, labels = tf.py_func(func=self.input_fn_np, inp=[], Tout=[tf.float32, tf.float32], stateful=True)
        data.set_shape([1,3,3,1]) # shapes are unknown and need to be set for integrating into the network
        labels.set_shape([1,1,1,1])
        return dict(data=data), dict(labels=labels)

    def input_fn_np(self):
        # returns a dictionary of numpy matrices
        batch_data = self.reader()
        return batch_data['data'], batch_data['labels']

    def model_fn(self, features, labels, mode):
        # using tf 2017 convention of dictionaries of features/labels as inputs
        features_in = features['data']
        labels_in = labels['labels']
        pred_layer = tf.layers.conv2d(name='pred', inputs=features_in, filters=1, kernel_size=3)
        tf.summary.scalar(name='label', tensor=tf.squeeze(labels_in))
        tf.summary.scalar(name='pred', tensor=tf.squeeze(pred_layer))
        loss = None
        if mode != modekeys.INFER:
            loss = tf.losses.mean_squared_error(labels=labels_in, predictions=pred_layer)
        train_op = None
        if mode == modekeys.TRAIN:
            train_op = tf.contrib.layers.optimize_loss(
                loss=loss,
                learning_rate = 0.01,
                optimizer = 'SGD',
                global_step = tf.contrib.framework.get_global_step()
            )
        predictions = {'estim_exp': pred_layer}
        return tf.contrib.learn.ModelFnOps(mode=mode, predictions=predictions, loss=loss, train_op=train_op)

    def reader(self):
        self.status += 1
        if self.status > 1000.0:
            self.status = 1.0
        return dict(
            data = np.random.randn(1,3,3,1).astype(dtype=np.float32),
            labels = np.sin(np.ones([1,1,1,1], dtype=np.float32)*self.status)
        )
    def get_estimator(self):
        self.Estimator = tf.contrib.learn.Estimator(
            model_fn = self.model_fn,
            model_dir = self.model_dir,
            config = tf.contrib.learn.RunConfig(
                save_checkpoints_steps = 10,
                save_summary_steps = 10,
                save_checkpoints_secs = None
            )
        )

if __name__ == '__main__':
    ex = inputExample()
    ex.Estimator.fit(input_fn=ex.input_fn)

【讨论】:

  • 使用 tf.py_func 的好例子,它没有很好地记录,可以作为 POC 使用 tf.constant(在图中加载整个数据集)并具有预先将数据集序列化为 tfrecords 的处理步骤(推荐,但速度快但麻烦)。
  • 顺便说一句,你的代码看起来有点奇怪,无论是在布局(使用小写的类和大写的属性)和结构(类用于保存全局变量和一堆不相关的方法,还不如只使用带有“平面”方法和状态全局变量的简单模块。
  • 谢谢@Guillaume,我的 Python 写作技能需要更多的工作,我会使用你的编码反馈:所以我从你那里了解到 - * Python 约定是 CLASS_NAME 大写,单词之间有 _ ? * 我会尝试在不使用类的情况下重写上面的内容。
【解决方案2】:

如果训练数据已经在 python 内存中,您可以使用tf.constant,如鲍鱼 TF 示例所示:https://github.com/tensorflow/tensorflow/blob/r1.1/tensorflow/examples/tutorials/estimators/abalone.py#L138-L141

注意:将数据从磁盘复制到 Python 到 TensorFlow 的效率通常低于在 TensorFlow 中构建输入管道(即将数据从磁盘直接加载到 TensorFlow 张量),例如使用tf.contrib.learn.datasets.base.load_csv_without_header

【讨论】:

    猜你喜欢
    • 2018-06-03
    • 2018-05-03
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多