以下代码是我保存numpy数组的方式,保存后大约为27GB。图像数据超过200K,每个形状为(224,224,3)
hf = h5py.File('cropped data/features_train.h5', 'w')
for i,each in enumerate(features_train):
hf.create_dataset(str(i), data=each)
hf.close()
这是我用来加载数据的方法,需要花费数小时才能加载。
features_train = np.zeros(shape=(1,224,224,3))
hf = h5py.File('cropped data/features_train.h5', 'r')
for key in hf.keys():
x = hf.get(key)
x = np.array(x)
features_train = np.append(features_train,np.array([x]),axis=0)
hf.close()
所以,对于这种大数据量,有没有人有更好的解决方案?
您没有告诉我们您的服务器有多少物理RAM,但是27 GiB听起来“很多”。考虑将您的跑步分成几批。
[java领域中有一个古老的锯,问“为什么它具有二次运行时间?”,也就是说,“为什么这么慢?”
String s = ""
for (int i = 0; i < 1e6, i++) {
s += "x";
}
答案是到最后,在每次迭代中,我们读取的内容大约为一百万个字符然后编写它们,然后附加一个字符。成本为O(1e12)。标准解决方案是使用StringBuilder,所以我们回来了到预期的O(1e6)。
[这里,我担心调用np.append()
会将我们带入二次状态。
[要验证,用简单的评估替换features_train
分配np.array([x])
的值,因此我们花了一些时间进行计算,然后立即将其丢弃在每次迭代中使用该值。如果猜想是正确的,则运行时会小得多。
要进行补救,请避免致电.append()
。而是使用np.zeros()
预先分配27 GiB(或np.empty()
)然后在循环中分配每个新读取的数组到其预分配插槽的偏移量中。线性运行时将使任务更快地完成。