Tensorflow预制估算器比自定义慢得多?

时间:2019-03-06 15:17:21

标签: python tensorflow sparse-matrix tensorflow-estimator sparse-file

我正在对常规TF操作进行基准测试,因此,为了建立基线,我试图弄清楚用训练数据的单次通过来训练简单的逻辑回归的速度。我的输入是一个TFRecord文件,其中包含860,000个稀疏行,并具有164,000个一键编码功能。底部的数据处理。

像这样配置的预制tf.estimator.Estimator可以在 932秒中容纳一次数据传递:

feature_columns = [tf.feature_column.numeric_column(key='features',shape=164000)]

custom_config = tf.estimator.RunConfig(save_summary_steps=None,
                                       save_checkpoints_steps=None)

estimator = tf.estimator.LinearClassifier(
    feature_columns = feature_columns,
    model_dir = os.path.join(MODELDIR,f'PremadeLinearClassifier_{currtime()}'),
    config = custom_config
)

如果我将数据读入numpy数组并从from_tensor_slices()创建数据集,我可以将其缩短至 467秒

如果我构建自己的训练功能,则可以在 66.6 秒内从磁盘读取一次数据。

class LogisticModel(object):
    def __init__(self):

        self.W = tf.Variable(tf.random_normal([164000,1],mean=0, stddev=0.1))
        self.B = tf.Variable(tf.random_normal([],mean=0.0,stddev=0.1))

    def __call__(self, x):

        return tf.sparse_tensor_dense_matmul(x,self.W) + self.B


def grad_fn(model, inputs, targets):

    with tf.GradientTape() as t:
        loss_val = loss_fn(model, inputs, targets)

    return t.gradient(loss_val, [model.W, model.B])


def loss_fn(model, inputs, targets):

    target_size = targets.shape.as_list()[0]
    return (tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels = tf.reshape(targets,[target_size,1]),
                                                                   logits = model(inputs))) 
           )

def perform_train(model, optim, dataset):

    step = 0
    for x, y in dataset:
        grads = grad_fn(lm, x, y)
        optimizer.apply_gradients(zip(grads, [lm.W, lm.B]),
                                 global_step = tf.train.get_or_create_global_step())

        if step % 20 == 0:
            print(f"Step {step}: {loss_fn(lm,x,y)}")
        step += 1

1)造成这种巨大速度差异的原因是什么?估算器中的开销重大吗? 2)如果不读入内存,是否可以进一步改进自定义功能?内部基于C ++的库仍然快一个数量级。

数据生成

def ex_to_tensors(ex, tensor_size):

    feature_spec = {'sparse': tf.SparseFeature(index_key='indices',
                                           value_key='values',
                                           dtype=tf.int64,
                                           size=tensor_size),
                'label': tf.FixedLenFeature([], tf.int64, default_value=0)
                }

    parsed_dict = tf.parse_single_example(ex, feature_spec)

    return tf.cast(parsed_dict['sparse'],tf.float32), tf.cast(parsed_dict['label'],tf.float32)


def ex_input_fn(*filenames,batch_size=1000, feature_size=int(1e6)):

    def parseTensors(x):
        return ex_to_tensors(x,feature_size)

    dataset = (tf.data.TFRecordDataset(filenames)

               .map(parseTensors)
               .batch(batch_size)
              )

    return dataset

0 个答案:

没有答案