Tensorflow 数据集 API:映射函数为每个输入生成多个输出
Tensorflow Dataset API: map function producing multiple outputs per one input
TL;DR:我的 input_fn
一步从 1 生成 7 张图像。我想单独使用它们中的每一张(1x1000x1000x3 7 次)而不是作为单个图像 (7x1000x1000x3),至于能够将它们洗牌并在多个批次中混合。
我的数据、图像非常大:5000x9000x3
特征和 5000x9000x1
标签,所以我将它们存储为 JPEG 并将压缩图像提供给 input_fn
、gen_fn
解压缩它们并 parser_fn
输出 7x1000x1000x3
& 7x1000x1000x1
(7 个随机作物,始终作为嵌套元组)。现在的问题是,我不希望我的输入是那些 7
图像,而是将 7
作为 "the batch size"。我的尝试如下:
# Where `gen_fn` outputs JPEG encoded strings (bytes in python)
dataset = tf.dataset.Dataset.from_generator(gen_fn, (tf.string,
tf.string))
print(dataset) # debug, shown below
# Produces ([7, 1000, 1000, 3], [7, 1000, 1000, 1])
dataset = dataset.map(lambda features, labels: parser_fn)
print(dataset) # debug, shown below
# Attempts to flatten out the 0th dimension
# Effectively produces ([1000, 1000, 3], [1000, 1000, 1])
dataset = dataset.flat_map(lambda x,y: tf.dataset.Dataset.from_tensor_slices((x, y))
print(dataset) # debug, shown below
# Shuffle all of them to avoid biasing the network
# dataset = dataset.shuffle(63) # 9*7
# Prefetch, repeat (does not have any effect, tested)
dataset = dataset.prefetch(1)
print(dataset) # debug, shown below
dataset = dataset.repeat(1)
print(dataset) # debug, shown below
# Batch
dataset = dataset.batch(1)
print(dataset) # debug, shown below
itr = dataset.make_one_shot_iterator()
features, labels = itr.get_next()
return features, labels
打印到控制台
<FlatMapDataset shapes: (<unknown>, <unknown>), types: (tf.string, tf.string)>
<MapDataset shapes: ((7, 1000, 1000, 3), (7, 1000, 1000, 1)), types: (tf.float32, tf.float32)>
<FlatMapDataset shapes: ((1000, 1000, 3), (1000, 1000, 1)), types: (tf.float32, tf.float32)>
<PrefetchDataset shapes: ((1000, 1000, 3), (1000, 1000, 1)), types: (tf.float32, tf.float32)>
<RepeatDataset shapes: ((1000, 1000, 3), (1000, 1000, 1)), types: (tf.float32, tf.float32)>
<BatchDataset shapes: ((?, 1000, 1000, 3), (?, 1000, 1000, 1)), types: (tf.float32, tf.float32)>
它加载正常,但一旦开始训练我得到 TypeError: If shallow structure is a sequence, input must also be a sequence. Input has type: <class 'list'>.
完全删除 batch
调用工作正常并输出 1000x1000x3
"batches".
按照 中的建议,我尝试使用 padded_batch
而不是 batch
作为:
dataset = dataset.padded_batch(self.__batch_size, dataset.output_shapes)
导致
<PaddedBatchDataset shapes: ((?, 1000, 1000, 3), (?, 1000, 1000, 1)), types: (tf.float32, tf.float32)>
但遗憾的是得到了同样的结果。
一个 github 问题 https://github.com/tensorflow/tensorflow/issues/14451 建议多次重复初始图像。但这要么意味着多次解压缩同一图像(节省内存,速度慢得多),要么重复多次全分辨率图像(每次重复意味着 400MB)。
图像是我架构中的一个瓶颈,我可以预处理所有作物,但这将意味着失去一些潜在的随机作物和数据增强。重复不是一个选项(time/memory 约束)并且我无法使该代码工作,知道可能是什么问题吗?
事实证明,这段代码运行良好,并将最初的 7 个随机裁剪结果展平。
错误,而不是上面片段中的 shown/included,而是来自我的生成器,它生成了一个列表而不是一个元组。为了让 Tensorflow 正确理解生成器正在产生 2 个值(特征,
标签),它必须 return 一个 tuple
,但我的错误地产生了一个 list
,以有效地告诉 Tensorflow 只有 1 个值。
主要的挫折是错误是在运行时抛出的,而不是在构建图形时抛出的,因此调试它变得相当困难并且主要由反复试验组成。
TL;DR:我的 input_fn
一步从 1 生成 7 张图像。我想单独使用它们中的每一张(1x1000x1000x3 7 次)而不是作为单个图像 (7x1000x1000x3),至于能够将它们洗牌并在多个批次中混合。
我的数据、图像非常大:5000x9000x3
特征和 5000x9000x1
标签,所以我将它们存储为 JPEG 并将压缩图像提供给 input_fn
、gen_fn
解压缩它们并 parser_fn
输出 7x1000x1000x3
& 7x1000x1000x1
(7 个随机作物,始终作为嵌套元组)。现在的问题是,我不希望我的输入是那些 7
图像,而是将 7
作为 "the batch size"。我的尝试如下:
# Where `gen_fn` outputs JPEG encoded strings (bytes in python)
dataset = tf.dataset.Dataset.from_generator(gen_fn, (tf.string,
tf.string))
print(dataset) # debug, shown below
# Produces ([7, 1000, 1000, 3], [7, 1000, 1000, 1])
dataset = dataset.map(lambda features, labels: parser_fn)
print(dataset) # debug, shown below
# Attempts to flatten out the 0th dimension
# Effectively produces ([1000, 1000, 3], [1000, 1000, 1])
dataset = dataset.flat_map(lambda x,y: tf.dataset.Dataset.from_tensor_slices((x, y))
print(dataset) # debug, shown below
# Shuffle all of them to avoid biasing the network
# dataset = dataset.shuffle(63) # 9*7
# Prefetch, repeat (does not have any effect, tested)
dataset = dataset.prefetch(1)
print(dataset) # debug, shown below
dataset = dataset.repeat(1)
print(dataset) # debug, shown below
# Batch
dataset = dataset.batch(1)
print(dataset) # debug, shown below
itr = dataset.make_one_shot_iterator()
features, labels = itr.get_next()
return features, labels
打印到控制台
<FlatMapDataset shapes: (<unknown>, <unknown>), types: (tf.string, tf.string)>
<MapDataset shapes: ((7, 1000, 1000, 3), (7, 1000, 1000, 1)), types: (tf.float32, tf.float32)>
<FlatMapDataset shapes: ((1000, 1000, 3), (1000, 1000, 1)), types: (tf.float32, tf.float32)>
<PrefetchDataset shapes: ((1000, 1000, 3), (1000, 1000, 1)), types: (tf.float32, tf.float32)>
<RepeatDataset shapes: ((1000, 1000, 3), (1000, 1000, 1)), types: (tf.float32, tf.float32)>
<BatchDataset shapes: ((?, 1000, 1000, 3), (?, 1000, 1000, 1)), types: (tf.float32, tf.float32)>
它加载正常,但一旦开始训练我得到 TypeError: If shallow structure is a sequence, input must also be a sequence. Input has type: <class 'list'>.
完全删除 batch
调用工作正常并输出 1000x1000x3
"batches".
按照 padded_batch
而不是 batch
作为:
dataset = dataset.padded_batch(self.__batch_size, dataset.output_shapes)
导致
<PaddedBatchDataset shapes: ((?, 1000, 1000, 3), (?, 1000, 1000, 1)), types: (tf.float32, tf.float32)>
但遗憾的是得到了同样的结果。
一个 github 问题 https://github.com/tensorflow/tensorflow/issues/14451 建议多次重复初始图像。但这要么意味着多次解压缩同一图像(节省内存,速度慢得多),要么重复多次全分辨率图像(每次重复意味着 400MB)。
图像是我架构中的一个瓶颈,我可以预处理所有作物,但这将意味着失去一些潜在的随机作物和数据增强。重复不是一个选项(time/memory 约束)并且我无法使该代码工作,知道可能是什么问题吗?
事实证明,这段代码运行良好,并将最初的 7 个随机裁剪结果展平。
错误,而不是上面片段中的 shown/included,而是来自我的生成器,它生成了一个列表而不是一个元组。为了让 Tensorflow 正确理解生成器正在产生 2 个值(特征,
标签),它必须 return 一个 tuple
,但我的错误地产生了一个 list
,以有效地告诉 Tensorflow 只有 1 个值。
主要的挫折是错误是在运行时抛出的,而不是在构建图形时抛出的,因此调试它变得相当困难并且主要由反复试验组成。