TL; DR:我的input_fn
一步生成7张图片。我想单独使用它们(1x1000x1000x3 7次)而不是单张图像(7x1000x1000x3),以便能够将它们混合并在多批次之间混合。
我的数据,图片非常大:5000x9000x3
个功能和5000x9000x1
标签,因此我将它们存储为JPEG并将压缩的图像提供给input_fn
,gen_fn
解压缩他们和parser_fn
输出7x1000x1000x3
& 7x1000x1000x1
(7种随机作物,总是作为嵌套元组)。现在的问题是,我不希望我的输入是那些7
图像,而是将7
作为“批量大小”。我的尝试如下:
# 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
“批次”。
根据How do I create padded batches in Tensorflow for tf.train.SequenceExample data using the DataSet API?的建议,我尝试使用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)。
图像是我的架构中的瓶颈,我可以对所有作物进行预处理,但这意味着会丢失一些潜在的随机作物和数据增加。重复不是一个选项(时间/内存限制),我不能让代码工作,任何想法可能是错的?
答案 0 :(得分:2)
事实证明,此代码可以完美地工作,并使最初的7个随机作物变平。
错误,未显示/包含在上面的剪辑中,而是来自我的生成器,它产生了一个列表而不是一个元组。为了让Tensorflow正确理解发生器正在产生2个值(特征,
标签),它必须返回一个tuple
,但是我错误地产生list
,以便有效地告诉Tensorflow只有一个值。
主要的挫折是在运行时抛出的错误,而不是在构建图形时,因此调试它变得相当困难,主要包括反复试验。