Python 在Tensorflow中';如何将一个元素映射为多个元素?

Python 在Tensorflow中';如何将一个元素映射为多个元素?,python,tensorflow,tensorflow-datasets,Python,Tensorflow,Tensorflow Datasets,在tensorflowDataset管道中,我想定义一个自定义映射函数,它接受单个输入元素(数据样本)并返回多个元素(数据样本) 下面的代码是我的尝试,以及期望的结果 我无法很好地理解tf.data.Dataset().flat_map()上的文档是否适用于这里 将tensorflow导入为tf 输入=[10,20,30] 定义我的地图功能(i): return[[i,i+1,i+2].#Fyi[[i],[i+1],[i+2]]引发异常 ds=tf.data.Dataset.from_tenso

在tensorflow
Dataset
管道中,我想定义一个自定义映射函数,它接受单个输入元素(数据样本)并返回多个元素(数据样本)

下面的代码是我的尝试,以及期望的结果

我无法很好地理解
tf.data.Dataset().flat_map()
上的文档是否适用于这里

将tensorflow导入为tf
输入=[10,20,30]
定义我的地图功能(i):
return[[i,i+1,i+2].#Fyi[[i],[i+1],[i+2]]引发异常
ds=tf.data.Dataset.from_tensor_切片(输入)
ds=ds.map(map\u func=lambda输入:tf.py\u func(
func=my\u map\u func,inp=[input],Tout=[tf.int64]
))
element=ds.make_one_shot_iterator().get_next()
使用tf.Session()作为sess:
对于范围(9)内的uu:
打印(sess.run(元素))
结果:

(array([10, 11, 12]),)
(array([20, 21, 22]),)
(array([30, 31, 32]),)
预期结果:

(10)
(11)
(12)
(20)
(21)
(22)
(30)
(31)
(32)

要实现这一目标还需要两个步骤。首先,map函数需要返回numpy数组,而不是列表

然后您可以使用
flat\u map
结合
Dataset()。从张量切片()
将其展平。下面的代码现在生成所需的结果:

在Tensorflow 1.5中测试(复制/粘贴可运行示例)


如果要返回多个变量,可以使用以下方法:在本例中,我输入一个字符串(例如文件名),然后输出字符串和整数的倍数。在本例中,我为[10,20,30]的每个整数重复该字符串

复制/粘贴可运行示例:

import tensorflow as tf
import numpy as np

input = [b'testA', b'testB', b'testC']

def my_map_func(input):
  return np.array([input, input, input]), np.array([10, 20, 30])

ds = tf.data.Dataset.from_tensor_slices(input)
ds = ds.map(map_func=lambda input: tf.py_func(
    func=my_map_func, inp=[input], Tout=[tf.string, tf.int64]))
ds = ds.flat_map(lambda mystr, myint: tf.data.Dataset().zip((
  tf.data.Dataset().from_tensor_slices(mystr),
  tf.data.Dataset().from_tensor_slices(myint))
))

element = ds.make_one_shot_iterator().get_next()

with tf.Session() as sess:
  for _ in range(9):
    print(sess.run(element))

一种清洁的溶液,使用来自张量切片的
平面图

import tensorflow as tf

input = [10, 20, 30]

ds = tf.data.Dataset.from_tensor_slices(input)
ds = ds.flat_map(lambda x: tf.data.Dataset.from_tensor_slices([x, x+1, x+2]))
element = ds.make_one_shot_iterator().get_next()

with tf.Session() as sess:
    for _ in range(9):
        print(sess.run(element))

# 10
# 11
# 12
# 20
# 21
# 22
# 30
# 31
# 32

只是想补充一点,这可以在每个元素都是字典的数据集上实现。例如,如果输入数据集的一个元素

{ 'feat1': [2,4], 'feat2': [3]}
对于要根据feat1中的元素拆分为元素的每个元素,您可以编写:

def split(element):
    dict_of_new_elements = {
        'feat1': [
            element['feat1'][:, 0],
            element['feat1'][:, 1]]
        'feat2': [
            element['feat2'],
            element['feat2']]
    }
    return tf.data.Dataset.from_tensor_slices(dict_of_new_elements)
dataset.flat_map(split)
这将产生

[
    {'feat1': 2, 'feat2': 3},
    {'feat1': 4, 'feat2': 3},
]

在tensorflow 1.8中,from_tensor_切片和zip现在是静态方法,因此平面映射行应该是:ds=ds.flat_映射(lambda mystr,myint:tf.data.Dataset.zip((tf.data.Dataset.from_tensor_切片(mystr),tf.data.Dataset.from_tensor_切片(myint)))“引用自doc。出于性能原因,我们鼓励您尽可能使用TensorFlow操作来预处理数据。
lambda x:[[x,x+1,x+2]
应该是更好的解决方案。
[
    {'feat1': 2, 'feat2': 3},
    {'feat1': 4, 'feat2': 3},
]