【问题标题】:Chunk tensorflow dataset records into multiple records将 tensorflow 数据集记录分块为多条记录
【发布时间】:2021-07-30 00:53:44
【问题描述】:

我有一个未批处理的 tensorflow 数据集,如下所示:

ds = ...
for record in ds.take(3):
    print('data shape={}'.format(record['data'].shape))

-> data shape=(512, 512, 87)
-> data shape=(512, 512, 277)
-> data shape=(512, 512, 133)

我想以深度 5 的块将数据提供给我的网络。在上面的示例中,形状 (512, 512, 87) 的张量将分为 17 个形状张量 (512, 512, 5)。矩阵的最后 2 行 (tensor[:,:, 85:87]) 应该被丢弃。

例如:

chunked_ds = ...
for record in chunked_ds.take(1):
    print('chunked data shape={}'.format(record['data'].shape))

-> chunked data shape=(512, 512, 5)

我怎样才能从dschunked_dstf.data.Dataset.window() 看起来像我需要的,但我无法让它工作。

【问题讨论】:

  • 嗨,您能否分享一个打算在其上完成此操作的数据集。一些虚拟数据集就可以了。

标签: tensorflow conv-neural-network tensorflow-datasets tfrecord


【解决方案1】:

这实际上可以使用tf.data.Dataset-only 操作来完成:

data = tf.random.normal( shape=[ 10 , 512 , 512 , 87 ] )
ds = tf.data.Dataset.from_tensor_slices( ( data ) )
chunk_size = 5
chunked_ds = ds.flat_map(lambda x: tf.data.Dataset.from_tensor_slices(tf.transpose(x, perm=[2, 0, 1])).batch(chunk_size, drop_remainder=True)) \
                    .map(lambda rec: tf.transpose(rec, perm=[1, 2, 0]))

那里发生了什么:

首先,我们将每条记录视为一个单独的数据集并对其进行置换,以便最后一个维度成为批量维度(flat_map 将再次将我们的内部数据集展平为张量)

.flat_map(lambda x: tf.data.Dataset.from_tensor_slices(tf.transpose(x, perm=[2, 0, 1])

然后我们将它按 5 分批,但我们不关心余数

.batch(chunk_size, drop_remainder=True))

最后,重新排列张量,使我们在开始时有 512x512:

.map(lambda rec: tf.transpose(rec, perm=[1, 2, 0]))

【讨论】:

  • 完美。这个解决方案很棒!
【解决方案2】:

为了表达我的解决方案,我将首先创建一个虚拟数据集,其中每个形状有 10 个样本[ 512 , 512 , 87 ]

data = tf.random.normal( shape=[ 10 , 512 , 512 , 87 ] )
ds = tf.data.Dataset.from_tensor_slices( ( data ) )

在执行以下代码时,

for record in ds.take( 3 ):
    print( record.shape )

我们得到输出,

(512, 512, 87)
(512, 512, 87)
(512, 512, 87)

为方便起见,我创建了一个数据集,其中最后一个维度的长度是一个常数,即 87(这与您的方法相矛盾)。但提供的解决方案与最后一个维度的长度无关。

解决办法,

# chunk/window size
chunk_depth = 5

# array to store the chunks
chunks = []

# Iterating through each sample in ds ( Note: ds.as_numpy_iterator() returns NumPy arrays )
for sample in ds.as_numpy_iterator():
    # Length of the last dimension
    feature_size = sample.shape[ 2 ]
    # No. of chunks that can be produced
    num_chunks = feature_size // chunk_depth
    # Perform slicing along the last dimension, storing the "chunks" in the chunks array.
    for i in range( 0 , num_chunks , chunk_depth ):
        chunk = sample[ : , : , i : i + chunk_depth ]
        chunks.append( chunk )

# Convert array -> tf.data.Dataset
chunked_ds = tf.data.Dataset.from_tensor_slices( ( chunks ) )

以下代码的输出,

for sample in chunked_ds.take( 1 ):
    print( sample.shape )

正如问题中所预期的那样,

(512, 512, 5)

该解决方案以Colab notebook 的形式提供。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2017-02-24
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    相关资源
    最近更新 更多