【发布时间】:2019-06-17 15:49:18
【问题描述】:
我正在使用笔记本电脑的 GPU(GeForce GTX 1050)直接在一些自定义图像数据集上训练 ConvNet(Keras、python)。在训练期间监控我的 GPU 时,我注意到它只使用了大约 10% 的容量,甚至更少。进一步调查使我了解到通过访问我的存储磁盘中的数据导致训练成为瓶颈(我正在使用数据生成器)。
我还注意到,虽然磁盘以 100% 的容量使用,但我的内存却没有(大约 65% 的使用率)。我想:让我们“提前”将下一批数据加载到内存中(或几个下一批),同时 GPU 正在对当前批次进行训练,然后直接访问加载的批次从内存,避免昂贵的磁盘读取。我在堆栈溢出和其他平台上查找了一些文档或代码,但没有找到任何相关内容。
我发现避免这种磁盘读取瓶颈的一个临时解决方案是将我的数据粘贴到我的操作系统磁盘上,这是一个 SSD。 它工作得很好,将训练时间减少了 10- 15.但由于我在 SSD 磁盘 (100 Gb) 上的存储容量有限,因此当我处理较重的数据时,此解决方案将不起作用(通常,我现在使用重新采样的图像 (64, 64),但我计划升级到 (128, 128) 甚至更多)。
下面是我的生成器的代码,以便您更好地了解情况:
def generator(self, passes=np.inf):
# initialize the epoch count
db = self.db
epochs = 0
# keep looping infinitely -- the model will stop once we have
# reach the desired number of epochs
while epochs < passes:
# shuffle dataset_indices for stochasticity
if self.shuffle == True: np.random.shuffle(self.dataset_indices)
# loop over the HDF5 dataset_indices
for i in np.arange(0, self.numImages, self.batchSize):
X, Y = [], []
if self.gaussian_test == True: # TODO : Add gaussian testing
for j in self.dataset_indices[i:i + self.batchSize]:
y = db[db[self.gen_type + "_indices"][j]]["label"][()]
X.append(np.random.normal(loc=y, scale=0.2, size=(1, 64, 64)))
Y.append(y)
else:
for j in self.dataset_indices[i:i + self.batchSize]:
X.append(db[db[self.gen_type + "_indices"][j]]["array"][()])
Y.append(db[db[self.gen_type + "_indices"][j]]["label"][()])
X = np.array(X)
Y = np.array(Y)
Y = to_categorical(Y, num_classes=6)
# yield a tuple of images and labels
yield (X, Y)
# increment the total number of epochs
epochs += 1
我不确定如何进行,但我很确定应该可以...
【问题讨论】:
标签: python memory-management data-generation