我正在尝试使用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)步骤?
答案 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)