Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python “如何将数据加载到内存中”;“提前”;避免从磁盘读取?_Python_Memory Management_Data Generation - Fatal编程技术网

Python “如何将数据加载到内存中”;“提前”;避免从磁盘读取?

Python “如何将数据加载到内存中”;“提前”;避免从磁盘读取?,python,memory-management,data-generation,Python,Memory Management,Data Generation,我正在用笔记本电脑的GPU(GeForce GTX 1050)在一些自定义图像数据集上直接训练一个ConvNet(Keras,python)。在培训期间监控我的GPU时,我注意到它的使用率仅为其容量的10%左右,甚至更低。进一步调查使我了解到,通过访问存储磁盘中的数据,培训遇到了瓶颈(我正在使用数据生成器) 我还注意到,虽然磁盘的使用率为100%,但我的内存却没有(使用率约为65%)。我想:让我们“提前”将下一批数据加载到内存中(或下几个批),同时GPU在当前批上进行训练,,然后直接从内存访问加

我正在用笔记本电脑的GPU(GeForce GTX 1050)在一些自定义图像数据集上直接训练一个ConvNet(Keras,python)。在培训期间监控我的GPU时,我注意到它的使用率仅为其容量的10%左右,甚至更低。进一步调查使我了解到,通过访问存储磁盘中的数据,培训遇到了瓶颈(我正在使用数据生成器)

我还注意到,虽然磁盘的使用率为100%,但我的内存却没有(使用率约为65%)。我想:让我们“提前”将下一批数据加载到内存中(或下几个批),同时GPU在当前批上进行训练,,然后直接从内存访问加载的批,避免昂贵的磁盘读取。我在stack overflow和其他平台上查找了一些文档或代码,但没有找到任何相关内容

我找到了一个临时解决方案来避免这种磁盘读取瓶颈,那就是将数据粘贴到我的操作系统磁盘(SSD)上。它运行得非常好,将训练时间减少了10-15倍。但由于SSD磁盘上的存储容量有限(100 Gb),当我要处理更重的数据时(通常,我现在正在使用重采样图像(64,64),但我计划将其放大到(128,128)甚至更多),此解决方案将不起作用

下面是我的发电机的代码,以便您更好地了解情况:

def生成器(self,passs=np.inf):
#初始化历元计数
db=self.db
纪元=0
#继续无限循环——一旦我们完成了,模型就会停止
#达到所需的纪元数
随着时代的流逝:
#随机性的随机数据集索引
如果self.shuffle==True:np.random.shuffle(self.dataset\u索引)
#在HDF5数据集索引上循环
对于np.arange中的i(0,self.numImages,self.batchSize):
十、 Y=[],[]
如果self.gaussian_test==True:#TODO:添加高斯测试
对于self.dataset_索引中的j[i:i+self.batchSize]:
y=db[db[self.gen_type+“_index”][j][“label”][()]
X.append(np.random.normal(loc=y,scale=0.2,size=(1,64,64)))
Y.append(Y)
其他:
对于self.dataset_索引中的j[i:i+self.batchSize]:
附加(db[db[self.gen_type+“_index”][j][“array”][()]))
Y.append(db[db[self.gen_type+“_index”][j][“label”][()]))
X=np.数组(X)
Y=np.数组(Y)
Y=到_分类(Y,num_类=6)
#生成图像和标签的元组
产量(X,Y)
#增加历代的总数
纪元+=1

我不知道如何继续,但我非常确定这应该是可能的…

因为我现在还没有收到任何答案,我将把我的发现分享给任何对这个话题感兴趣的人。实际上,我想要的想法是使用多重处理

(I):经过一些研究,我发现Keras fit_generator()通过参数use_multiprocessing=Trueworkers=n允许这种多重处理。但这种方法有其局限性:

  • 首先,生成器必须是线程安全的。如果生成器是从Keras.utils.Sequence类继承的,则它已经是线程安全的。否则,请参阅本文,您将学习如何创建一个装饰器,使生成器线程安全
  • 其次,如果您使用的是Windows计算机,则无法设置use\u multiprocessing=True,因为它没有实现。尽管如此,我意识到您仍然可以设置workers=n>1,但我认为您的生成器将不会是线程安全的,这是一个问题
(II):由于我使用的是Windows电脑,所以这对我不起作用。然后,我发现其他资源(,)建议使用TensorFlow QueueRunner类。这似乎是最有效和最健壮的解决方案,但您需要使用TensorFlow,如果您必须第一次深入了解它,这可能会非常耗时。我还没有尝试这个解决方案,因为我希望在未来几天内迁移到AWS云,因此允许我使用第一个解决方案