Python TensorFlow扩展数据访问器.tf\u数据集\u工厂()形状差异

Python TensorFlow扩展数据访问器.tf\u数据集\u工厂()形状差异,python,tensorflow,keras,parquet,tfx,Python,Tensorflow,Keras,Parquet,Tfx,在尝试将普通的tensorflow/keras工作流转换为tensorflow扩展管道时,我面临着一个令人困惑的问题 简而言之:使用tfx组件生成的数据集的形状与使用同一数据的tf.data.Dataset.from_tensor_slices()手动创建的数据集的形状不同,并且不能输入到keras模型中 可复制示例 1.数据生成 假设我们使用以下方法创建示例数据集: 将熊猫作为pd导入 随机输入 df=pd.DataFrame({ 'a':[范围(100)内x的浮动(x)], 'b':[范围(

在尝试将普通的tensorflow/keras工作流转换为tensorflow扩展管道时,我面临着一个令人困惑的问题

简而言之:使用tfx组件生成的数据集的形状与使用同一数据的
tf.data.Dataset.from_tensor_slices()
手动创建的数据集的形状不同,并且不能输入到keras模型中

可复制示例 1.数据生成 假设我们使用以下方法创建示例数据集:

将熊猫作为pd导入
随机输入
df=pd.DataFrame({
'a':[范围(100)内x的浮动(x)],
'b':[范围(100)内x的浮动(x+1)],
'c':[范围(100)内x的浮动(x**2)],
'target':[random.randint(0,2)表示范围(100)内的uu],
})
df.to_拼花地板({my_path})
2.模型生成 为了简单起见,让我们使用一个虚拟密集模型

来自tensorflow.keras导入顺序
从tensorflow.keras.layers导入稠密
从tensorflow.keras.optimizers导入新加坡元
def build_模型():
模型=顺序()
添加(密集(8,输入_形状=(3),激活=(relu'))
model.add(密集型(3,activation='softmax'))
model.compile(
优化器=SGD(),
loss=“稀疏\分类\交叉熵”,
度量=[“稀疏分类精度”],
)
回归模型
3.工作原理:手动创建数据集 然后,可以使用以下方法将此拼花地板文件加载回pandas df并转换为tensorflow数据集:

将tensorflow导入为tf
_批量大小=4
dataset=tf.data.dataset.from_tensor_切片((
tf.cast(df['a','b','c']].值,tf.float32),
tf.cast(df['target'].value,tf.int32),
)).batch(_batch_SIZE,drop_rements=True)
这将提供一个具有
cardinality()=
的数据集,该数据集可以提供给上面的玩具模型

4.什么不起作用:制作tensorflow扩展管道 我尝试通过应用稍加修改的tfx来复制这些结果:

来自tfx\u bsl.tfxio导入数据集\u选项
从tfx.components导入SchemaGen
从tfx.components导入统计数据Gen
来自tfx.components导入培训师
从tfx.dsl.components.base导入执行器_spec
从tfx.components.example\u gen.component导入文件basedexamplegen
从tfx.components.example_gen.custom_executors导入拼花执行器
从tfx.components.trainer.executor导入GenericeExecutor
从tfx.orchestration导入元数据
从tfx.orchestration导入管道
从tfx.proto导入培训师_pb2
从tfx.proto导入示例\u gen\u pb2
从tfx.utils.io_utils导入parse_pbtxt_文件
_批量大小=4
_LABEL_KEY='target'
_纪元=10
定义输入fn(文件模式、数据存取器、模式)->数据集:
数据集=数据访问器.tf\u数据集\u工厂(
文件模式,
dataset_options.TensorFlowDatasetOptions(
批次大小=\u批次大小,
label\u key=\u label\u key,
num_epochs=_epochs,
),
模式,
)
返回数据集
def build_模型():
“”“同上”“”
...
回归模型
def运行参数(参数):
schema=parse_pbtxt_文件(fn_args.schema_文件,schema_pb2.schema())
列车数据集=\u输入\u fn(
fn_args.train_文件,
fn_args.data_访问器,
模式,
)
评估数据集=\u输入\u fn(
fn_args.eval_文件,
fn_args.data_访问器,
模式,
)
模型=构建模型()
模型拟合(
列车运行数据集,
每个历元的步数=fn\u args.train\u步数,
验证数据=评估数据集,
验证步骤=fn\u args.eval\u步骤,
时代=_时代,
)
model.save(fn_args.serving_model_dir,save_format='tf')
def_创建_管道(
管道名称:str,
管道_根:str,
数据根:str,
模块_文件:str,
元数据路径:str,
拆分:dict,
)->管道。管道:
split\u config=示例\u gen\u pb2.SplitConfig(
分裂=[
示例\u gen\u pb2.SplitConfig.Split(name=name,hash\u bucket=bucket)
对于名称,split.items()中的bucket
]
)
示例_gen=FileBasedExampleGen(
输入\基础=数据\根,
custom_executor_spec=executor_spec.executor ClassSpec(拼花地板执行器.执行器),
output\u config=example\u gen\u pb2.output(split\u config=split\u config),
)
统计数据生成=统计数据生成(示例=示例生成输出['examples'])
推断模式=SchemaGen(统计数据=statistics\u gen.outputs['statistics'])
教练(
模块文件=模块文件,
custom_executor_spec=executor_spec.ExecutorClassSpec(GenericeExecutor),
示例=示例生成输出['examples'],
schema=推断schema.outputs['schema'],
train_args=培训师_pb2.TrainArgs(),
eval_args=trainer_pb2.EvalArgs()
)
组件=[示例生成、统计生成、推断模式、培训师]
metadata\u config=metadata.sqlite\u metadata\u连接\u配置(元数据\u路径)
_管道=管道。管道(
管道名称=管道名称,
管道根=管道根,
组件=组件,
元数据\连接\配置=元数据\配置,
)
回流管
但是,ExampleGen生成的数据集具有基数
tf.Tensor(-2,shape=(),dtype=int64)
,并在馈送到同一模型时给出以下错误消息:

ValueError: Layer sequential expects 1 inputs, but it received 3 input tensors. Inputs received: [<tensorflow.python.framework.sparse_tensor.SparseTensor object at 0x7f40353373d0>, <tensorflow.python.framework.sparse_tensor.SparseTensor object at 0x7f4035337710>, <tensorflow.python.framework.sparse_tensor.SparseTensor object at 0x7f40352e3190>]
ValueError:Layer sequential需要1个输入,但收到3个输入张量。收到的投入:[,]
重要提示:即使将数据存储为
csv
文件并使用
CsvExampleGen
读取,问题仍然存在,这使得问题不太可能由数据本身引起

此外,成批处理tfx输出数据集对结果没有影响

我想尽一切办法都没有用。tfx引擎盖下发生的事情的相对模糊性也无助于调试。有人知道问题出在哪里吗

编辑1 我注意到两点