我目前正在尝试加载我的数据以在TensorFlow中训练网络。我在创建DataSet对象时遇到了麻烦。
问题背景: 我当前的数据集是一组10万个样本。每个样本都有14个以浮点数表示的特征。标签是一个512K值0.0或1.0的数组。数据保存在二进制文件中,该文件具有14 * 4字节的数据,然后对每个样本在接下来的64000字节中对标签进行位映射。
我的网络将tf.float32类型用于特征和预测。我使用的是TF r1.13。
我确实尝试使用tf.data.FixedLengthRecordDataSet,但是我无法成功将位图转换为tf.float32类型张量,这主要是由于缺乏对该过程的了解。因此,我切换到了tf.data.DataSet.from_generator。
目前,我有:
class Generator:
def __init__(self, files: typing.Union[typing.List[str], typing.Tuple[str], str], structure: BinaryStructure,
grid: typing.Union[typing.List[int], typing.Tuple[int], int] = None):
if isinstance(files, str):
self._files = tuple([files])
elif isinstance(files, list):
self._files = tuple(files)
elif isinstance(files, tuple):
self._files = files
else:
raise TypeError('Expected a single string or a list of strings.')
if not all(isinstance(t, str) for t in self._files):
raise TypeError('Expected string type for file.')
if isinstance(structure, BinaryStructure):
self._structure = copy.deepcopy(structure)
else:
raise TypeError('Expected BinaryStructure type.')
if grid:
if isinstance(grid, int):
self.grid = np.array([grid, grid, grid], dtype=np.int)
elif isinstance(grid, list):
self.grid = np.array(grid, dtype=np.int)
elif isinstance(grid, tuple):
self.grid = np.array(grid, dtype=np.int)
else:
raise TypeError('Expected a single int or a list of ints.')
self._offset = (8 - (np.prod(self.grid) % 8)) % 8
else:
self._offset = 0
self._num_samples = 0
for f in self._files:
sz = os.path.getsize(f)
ssz = self._structure.get_stream_length()
if sz % ssz:
raise RuntimeError(
f'Expected fixed length input of N * {ssz}. Files {f} size {sz} does not match expected values.')
else:
self._num_samples += sz // ssz
self._current_sample = -1
self._f_current_sample = -1
self._current_file = -1
self._file_handle = None
def __iter__(self):
it = copy.copy(self)
it._current_sample = -1
it._f_current_sample = -1
it._current_file = -1
it._file_handle = None
return it
def __next__(self):
self._current_sample += 1
if self._current_file == -1:
if self.open_next_file():
raise IOError('Failed to open file.')
if self._current_sample < self._num_samples:
buffer = self.read_sample()
if len(buffer) == 0:
if self.open_next_file():
raise RuntimeError('Iterator failed to buffer the next sample.')
buffer = self.read_sample()
sample = GridData(buffer, self._structure, self._offset)
sample.generate_output()
return np.array(sample.input, dtype=np.float32), np.array(sample.output, dtype=np.float32)
else:
raise StopIteration
下面我将用它来创建数据集
def get_data_set(files: typing.Union[typing.List[str], typing.Tuple[str], str], structure: BinaryStructure,
grid: typing.Union[typing.List[int], typing.Tuple[int], int] = None, batch: int = 1):
dg = dr.Generator(files, structure, grid)
tds = tf.data.Dataset.from_generator(lambda: dg, (tf.float32, tf.float32), dg.get_output_shape()).batch(
batch_size=batch)
return dg.get_num_samples(), tds
我需要能够将来自此生成器的数据分为2组,一组用于训练,一组用于评估。我当前的代码可以吗?尽管此代码中的生成器详尽地读取了我的所有数据,但它能够跳过样本并仅读取所需数量的样本。
因为这是我第一次使用tf.data.DataSet,所以我不知道TF中生成器的性能影响。在这方面的任何建议也将不胜感激。