我在理解Estimator API和tf.estimator.EvalSpec
的某些细节时遇到了一些麻烦。
在EvalSpec
中,用户应给出一个input_fn
。调用input_fn应该返回A tuple (features, labels)
。
据我了解,这些功能可以是由“功能名称”作为键的字典,其值是值的张量。例如,如果我有一批100个示例,并且有一个称为“权重”的特征,我将在特征字典中创建一个条目,该条目的形状为张量(100,1),具有关键权重,并且所有权重均例子,对吧?
但是:
还有我最感兴趣的问题:
这些类型的功能是否与Estimator API“兼容”?
谢谢!
答案 0 :(得分:0)
我对Estimator
API还是陌生的,但是通过S.O我学到了很多东西。社区,并会尝试回答您的问题。
首先,我想向您介绍此colab。目前,这是我在Estimator
中使用的约定。
您是正确的,因为input_fn
和TRAIN
模式的EVAL
都是(features, labels)
形式的元组。
所以让我们解决您的第一个问题:
如果我的初始特征已经是一个张量,例如“ size”,它是3个double值的数组,该怎么办?如何通过input_fn输入它?
好吧,这需要我回溯一下您输入的内容:
一批100个示例和一个称为“权重”的特征,我将在特征字典中创建一个形状为(100,1)的张量的条目,
为确保我理解正确,您是在说,如果不是Tensor
或[100, 1]
,而是形状为Tensor
的{{1}},情况3加倍,所以[100, <size>]
?
如果是这种情况,那完全没有问题。在链接的colab中,输入的单个示例的形状为[100, 3]
。因此,[20, 7]
中的Tensor
很简单。
简而言之,就是将您指定为元组的[3]
部分的任何内容都传递给features
。因此,您要传递model_fn
的{{1}},则返回Tensor
的元组。但是,正如另一位用户在S.O.上向我指出的那样。我会向您提供相同的建议-使用字典,例如
[batch_size, size]
作为参考,让我们以colab中的([batch_size, size], labels)
为例,我在上面做了与上面建议相同的事情:
my_data = # Tensor with shape [batch_size, size]
features = {'my_data': my_data}
...
return (features, labels)
为简单起见,我假设您正在使用input_fn
。如果您的数据未存储为TF def input_fn(filenames:list, params):
mode = params['mode'] if 'mode' in params else 'train'
batch_size = params['batch_size']
shuffle(filenames) # <--- far more efficient than tf dataset shuffle
dataset = tf.data.TFRecordDataset(filenames)
# using fio's SCHEMA fill the TF Feature placeholders with values
dataset = dataset.map(lambda record: fio.from_record(record))
# using fio's SCHEMA restructure and unwrap (if possible) features (because tf records require wrapping everything into a list)
dataset = dataset.map(lambda context, features: fio.reconstitute((context, features)))
# dataset should be a tuple of (features, labels)
dataset = dataset.map(lambda context, features: (
{"input_tensors": features[I_FEATURE]}, # features <--- wrapping it in a dictionary
features[O_FEATURE] # labels
)
)
,则需要替换第1行。
tf.data.Dataset
但是,您可以构建数据集,例如Record
, 1. dataset = tf.data.TFRecordDataset(filenames)
2. dataset = dataset.map(lambda record: fio.from_record(record))
3. dataset = dataset.map(lambda context, features: fio.reconstitute((context, features)))
等,并删除第2行和第3行,因为您无需从TF {{1}中恢复FeatureColumn
} s。
现在让我们解决第二个问题,可变长度数组。
与上面的一样!将其包装在字典中并返回。
除了从TF from_tensor_slices
s中恢复(Sequence)Example
的显着例外外,这是正确的,在那里您将需要Record