使用许多压缩的numpy文件的Tensorflow数据集

时间:2018-11-29 17:45:50

标签: python numpy tensorflow dataset data-handling

我有一个大型数据集,我想在Tensorflow中进行训练。

数据以压缩的numpy格式存储(使用numpy.savez_compressed)。每个文件的图像数量因生成方式而异。

当前,我使用基于Keras序列的生成器对象进行训练,但我想完全移至没有Keras的Tensorflow。

我正在TF网站上查看Dataset API,但不清楚如何使用它来读取numpy数据。

我的第一个想法是

import glob
import tensorflow as tf
import numpy as np

def get_data_from_filename(filename):
   npdata = np.load(open(filename))
   return npdata['features'],npdata['labels']

# get files
filelist = glob.glob('*.npz')

# create dataset of filenames
ds = tf.data.Dataset.from_tensor_slices(filelist)
ds.flat_map(get_data_from_filename)

但是,这会将TF Tensor占位符传递给实际的numpy函数,并且numpy需要标准字符串。这导致错误:

File "test.py", line 6, in get_data_from_filename
   npdata = np.load(open(filename))
TypeError: coercing to Unicode: need string or buffer, Tensor found

我正在考虑的另一种选择(但似乎有些混乱)是创建一个基于TF占位符的数据集对象,然后在我的numpy文件的epoch-batch循环中填充它。

有什么建议吗?

1 个答案:

答案 0 :(得分:2)

您可以定义一个包装器,并像这样使用pyfunc:

def get_data_from_filename(filename):
   npdata = np.load(filename)
   return npdata['features'], npdata['labels']

def get_data_wrapper(filename):
   # Assuming here that both your data and label is float type.
   features, labels = tf.py_func(
       get_data_from_filename, [filename], (tf.float32, tf.float32)) 
   return tf.data.Dataset.from_tensor_slices((features, labels))

# Create dataset of filenames.
ds = tf.data.Dataset.from_tensor_slices(filelist)
ds.flat_map(get_data_wrapper)

如果数据集非常大且存在内存问题,则可以考虑使用interleaveparallel_interleavefrom_generator方法的组合。 from_generator方法在内部使用py_func,因此您可以直接读取np文件,然后在python中定义生成器。