如何解决将 tensorflow 数据集记录分成多条记录
我有一个未成批的 tensorflow
数据集,如下所示:
ds = ...
for record in ds.take(3):
print('data shape={}'.format(record['data'].shape))
-> data shape=(512,512,87)
-> data shape=(512,277)
-> data shape=(512,133)
我想将数据以深度为 5 的块形式提供给我的网络。在上面的示例中,形状 (512,87) 的张量将被分成 17 个形状 (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,5)
我如何从ds
到chunked_ds
? tf.data.Dataset.window()
看起来像我需要的,但我无法让它工作。
解决方法
这实际上可以使用 tf.data.Dataset
-only 操作来完成:
data = tf.random.normal( shape=[ 10,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,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,1])
然后我们以 5 为单位进行批处理,但我们不关心余数
.batch(chunk_size,drop_remainder=True))
最后,重新排列张量,以便我们在开始时有 512x512:
.map(lambda rec: tf.transpose(rec,0]))
,
为了表达我的解决方案,我将首先创建一个虚拟数据集,其中每个形状为 [ 512,87 ]
的样本有 10 个,
data = tf.random.normal( shape=[ 10,87 ] )
ds = tf.data.Dataset.from_tensor_slices( ( data ) )
在执行以下代码时,
for record in ds.take( 3 ):
print( record.shape )
我们得到输出,
(512,87)
(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,5)
该解决方案以 Colab notebook 的形式提供。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。