将具有许多二进制数据特征的大量观察结果提供给 TensorFlow
Feeding lots of observations with many binary data features to TensorFlow
我有大约 170 万个观察值。他们每个人都有大约 4000 个布尔特征和 4 个浮点数 labels/targets。这些特征是稀疏的并且近似均匀分布(4000 个布尔值中的大约 150 个被设置为每次观察 True
)。
如果我将整个 (1700000, 4000)
矩阵存储为原始 numpy 文件(npz
格式),它需要大约 100 MB 的磁盘 space。如果我通过 np.load()
加载它,需要几分钟时间,我的 RAM 使用量会增加大约 7 GB,这本身就没问题。
问题是,我必须将 feed_dict
中的布尔值转换为 tf.placeholder
,以便 tf.data.Dataset
能够使用它。此过程需要另外 7 GB 的 RAM。我的计划是在未来收集更多的数据(在某个时候可能会超过 1000 万个观察值)。
问题:那么如何将数据馈送到我的 DNN(前馈,密集,不 卷积和 不 循环)而不产生瓶颈并且以 TensorFlow 固有的方式?我原以为这是一个非常标准的设置,很多人应该有这个问题——为什么不呢? wrong/different 与没有问题的人相比,我该怎么做?
我听说 tfrecord format is well integrated 使用 TensorFlow 并且能够延迟加载,但我认为将这种格式用于我的特征结构是个坏主意,因为它会为每次观察创建一个 Message
并保存特征为 map
,所有特征的键为字符串 per observation.
我找到了一个解决方案,名为 tf.data.Dataset.from_generator
。
这基本上可以解决问题:
def generate_train_data(self, batch_size: int) -> typing.Iterable[typing.Tuple[np.ndarray, np.ndarray]]:
row_id = 0
features = self.get_features()
targets = self.get_targets()
test_amount = self.get_test_data_amount()
while row_id < features.shape[0]:
limit = min(features.shape[0] - test_amount, row_id + batch_size)
feature_batch = features[row_id:limit, :]
target_batch = targets[row_id:limit, :]
yield (feature_batch, target_batch)
del feature_batch, target_batch
row_id += batch_size
并创建 tf.data.Dataset
类似于:
train_data = tf.data.Dataset.from_generator(
data.generate_train_data,
output_types=(tf.bool, tf.bool),
output_shapes=(
(None, data.get_feature_amount()),
(None, data.get_target_amount()),
),
args=(batch_size,),
).repeat()
这当然不会打乱数据,但改造起来非常容易……
我有大约 170 万个观察值。他们每个人都有大约 4000 个布尔特征和 4 个浮点数 labels/targets。这些特征是稀疏的并且近似均匀分布(4000 个布尔值中的大约 150 个被设置为每次观察 True
)。
如果我将整个 (1700000, 4000)
矩阵存储为原始 numpy 文件(npz
格式),它需要大约 100 MB 的磁盘 space。如果我通过 np.load()
加载它,需要几分钟时间,我的 RAM 使用量会增加大约 7 GB,这本身就没问题。
问题是,我必须将 feed_dict
中的布尔值转换为 tf.placeholder
,以便 tf.data.Dataset
能够使用它。此过程需要另外 7 GB 的 RAM。我的计划是在未来收集更多的数据(在某个时候可能会超过 1000 万个观察值)。
问题:那么如何将数据馈送到我的 DNN(前馈,密集,不 卷积和 不 循环)而不产生瓶颈并且以 TensorFlow 固有的方式?我原以为这是一个非常标准的设置,很多人应该有这个问题——为什么不呢? wrong/different 与没有问题的人相比,我该怎么做?
我听说 tfrecord format is well integrated 使用 TensorFlow 并且能够延迟加载,但我认为将这种格式用于我的特征结构是个坏主意,因为它会为每次观察创建一个 Message
并保存特征为 map
,所有特征的键为字符串 per observation.
我找到了一个解决方案,名为 tf.data.Dataset.from_generator
。
这基本上可以解决问题:
def generate_train_data(self, batch_size: int) -> typing.Iterable[typing.Tuple[np.ndarray, np.ndarray]]:
row_id = 0
features = self.get_features()
targets = self.get_targets()
test_amount = self.get_test_data_amount()
while row_id < features.shape[0]:
limit = min(features.shape[0] - test_amount, row_id + batch_size)
feature_batch = features[row_id:limit, :]
target_batch = targets[row_id:limit, :]
yield (feature_batch, target_batch)
del feature_batch, target_batch
row_id += batch_size
并创建 tf.data.Dataset
类似于:
train_data = tf.data.Dataset.from_generator(
data.generate_train_data,
output_types=(tf.bool, tf.bool),
output_shapes=(
(None, data.get_feature_amount()),
(None, data.get_target_amount()),
),
args=(batch_size,),
).repeat()
这当然不会打乱数据,但改造起来非常容易……