Tensorflow:在op

时间:2016-08-29 09:32:51

标签: python tensorflow

我正在尝试使用tf.map_fn在Tensor中包含的时间戳上逐个元素地执行相关的计算。这需要转换为日期时间并返回与Tensorflow兼容的类型。

例如,让我们说我们想要从Tensor的时间戳中得到月份的数量:

from datetime import datetime

dates = [datetime(2016, 1, 1).timestamp(),
         datetime(2016, 2, 1).timestamp()]

def timestamp_to_month(timestamp):
    return datetime.fromtimestamp(timestamp).month

def month(x, name=None):
    with tf.op_scope([x], name, "Month") as scope:
        return tf.map_fn(timestamp_to_month, x, back_prop=False)

month(dates)

这不起作用,因为timestamp中的timestamp_to_month参数作为具有形状[]的张量传递而不是浮点数,并且必须进行评估。

一种解决方案是在使用实际值之前执行timestamp.eval(),但是我必须得到当前会话,可能还有一个额外的session参数,这样会很不方便。

此外,这个month op在图形构建阶段实际上失败了,而不是在执行期间发生的事件,这意味着在构建图形时调用映射的timestamp_to_month函数。因此,当我实际上只想构建它时,包含timestamp.eval()调用会触发图形的执行。

如何在仍然推迟执行图形的同时在op中包含这样的基本Python(或Numpy)步骤?

1 个答案:

答案 0 :(得分:0)

您不能像这样将任意Python代码插入TF图。虽然可以使用TF操作表示某些日期时间函数(主要是时间戳差异),但必须暂时在预处理中计算日期时间字段。

话虽这么说,某些日期时间计算比其他日期时间计算容易。虽然几个月确实很棘手,但这是在Tensorflow中提取星期几和一天中的小时的示例。分钟和秒钟也应该可行。

MILIS_PER_HOUR = 1000 * 60 * 60
MILIS_PER_DAY = MILIS_PER_HOUR * 24

HOUR_CYCLE = 24
DAY_CYCLE = 7

MONDAY_MIDNIGHT = 1558310400000


def extract_timestamps(timestamps_ms):
  """Converts batched ms timestamps into one-hot encoded hours+weekdays."""
  monday_diff = tf.subtract(timestamps_ms, MONDAY_MIDNIGHT)
  hours = _int_mod(monday_diff, MILIS_PER_HOUR, HOUR_CYCLE)
  weekdays = _int_mod(monday_diff, MILIS_PER_DAY, DAY_CYCLE)
  return tf.concat([
      _compact_one_hot(hours, HOUR_CYCLE),
      _compact_one_hot(weekdays, DAY_CYCLE)
  ],
                   axis=1)


def _compact_one_hot(indices, depth):
  return tf.reshape(tf.one_hot(indices, depth), [-1, depth])


def _int_mod(x, x_scale, y):
  return tf.cast(tf.mod(tf.divide(x, x_scale), y), dtype=tf.uint8)