【发布时间】:2018-05-03 01:43:37
【问题描述】:
我正在训练一个神经网络,我拥有的训练集存储在一个 1.5Tb hdf5 文件中,该文件被分割成 125 个组 (grp0...grp124)。每组包含 2 个数据集“x”和“y”,它们是保存为 hdf5 格式的 numpy 数组。每个数据集 x 和 y 包含大约 10,000 个训练示例,给出或取几百个(这些组的大小不统一,总共大约 120 万个训练示例)。我想要做的是从这个 hdf5 文件动态生成随机训练小批量。现在,我用于生成此类批处理的代码如下所示:
#grps is a dictionary of group sizes (they are not exactly uniform)
def data_gen(PATH,grps,batch_size=32):
while(True):
pick_grp = random.randint(0,len(grps)-1)
size = grps['grp_'+str(pick_grp)]
indices = random.sample(range(size),batch_size)
with h5py.File(PATH,'r') as f:
X = f['grp'+str(pick_grp)]['x'][indices]
Y = f['grp'+str(pick_grp)]['y'][indices]
yield (X,Y)
如您所见,我要做的是选择一个随机 grp,然后从该 grp 中选择一个随机的 batch_sized 数量的训练示例。使用 numpy 数组,这种切片会起作用,但显然 h5py 不支持数据集的这种切片,我得到错误
TypeError: Indexing elements must be in increasing order
当我尝试运行此代码时。或者,我可以使用 for 循环一次手动构建一批训练示例,但我认为这会完全减慢我的代码速度。我使用 GeForce 1080Ti 运行 mini-batch,因此单个 mini-batch 的训练速度非常快。我不想被构建小批量的 CPU 进程所束缚。有没有聪明的方法来做我想做的事?我还考虑过简单地选择一个随机起始索引,然后从 grps 中获取一个小批量,例如:
i = random.randint(0,size-batch_size-1)
X=f['grp'+str(pick_grp)]['x'][i:i+batch_size]
我可以在拿到小批量后对其进行洗牌。但这意味着相邻的训练样本很可能总是出现在同一个小批量中。我不知道这会对神经网络训练产生什么样的影响(如果有的话),但它似乎对我现在拥有的随机索引切片方法来说不是最理想的。理想情况下,我还希望能够从一个小批量中的 125 个组中的任何一个中获取示例(由于在生成此 hdf5 文件期间的内存限制,该文件被分割为 125 个组),但我还没有弄清楚一种方法来做到这一点。
【问题讨论】:
-
你试过排序
indices吗? -
哦哇...这工作!很简单!大声笑...您可以将此作为解决方案发布,我会接受。
-
我一直在尝试做完全相同的事情,但能够从你最后提到的 125 组时尚中的任何一个中取样。我的文件大小也不统一。您找到潜在的解决方案了吗?