我一直在尝试填充用于 Keras 模型的训练数据集。使用 numpy 的
append
函数一切 works 都很好,但是它 非常慢。这是我现在正在做的事情:
def populateData():
images = np.zeros([1, 4, 512, 512, 6])
for m in range(2):
for n in range(4):
batch_np = np.zeros([4, 512, 512, 6])
# Doing stuff with the batch...
# ...
images = np.append(images, batch_np, axis=0)
随着数组的大小随着每次传递而增长,numpy 附加新数据所花费的时间几乎呈指数增长。因此,例如,第一次传递大约需要 1 秒,第三次传递只需 3 秒多一点。当我完成十几个或更多的时候,每个
append
操作需要很多minutes(!)。根据目前的进度,可能需要几天才能完成。
我希望能够在下一个冰河时代之前的某个时间填充我的训练数据集。除了“获得更好的硬件”之外,我能做些什么来加速
np.append(...)
?我的理解是 Numpy 的 append
函数每次调用此函数时都会复制整个数组。是否有一个等价的函数 not 每次都执行复制?还是改用参考值,然后修改它?
我尝试使用 Python 的内置
list append
函数重写其中的一些内容,但它不像 numpy 的附加函数那样提供 axis
支持。因此,虽然这看起来快得多,但它对于这种多维设置并不适用。
TL;DR:有没有办法在附加到 Python 列表时指定轴?如果没有,是否有更优化的方法沿指定轴附加到 N 维数组/加速
numpy.append
?
您可以使用
np.stack
并使用 python 列表:
images = []
for m in range(2):
for n in range(4):
batch_np = np.zeros([4, 512, 512, 6])
...
images.append(batch_np)
images = np.stack(images, axis=0)
输出:
>>> images.shape
(8, 4, 512, 512, 6)
或者在循环之前分配整个数组:
M = 2
N = 4
images = np.zeros([M*N, N, 512, 512, 6])
for i, m in enumerate(range(M)):
for j, n in enumerate(range(N)):
batch_np = np.zeros([N, 512, 512, 6])
images[i+j] = batch_np
输出:
>>> images.shape
(8, 4, 512, 512, 6)
为什么你需要指定一个带有列表追加的轴?这两个循环产生相同的形状:
In [62]: arr = np.zeros([0,3,4])
...: for i in range(5):
...: arr = np.append(arr, np.ones((1,3,4)), axis=0)
...: arr.shape
Out[62]: (5, 3, 4)
In [63]: alist = []
...: for i in range(5):
...: alist.append(np.ones((3,4)))
...: arr = np.array(alist)
In [64]: arr.shape
Out[64]: (5, 3, 4)
stack
与默认轴 0 做同样的事情:
In [65]: np.stack(alist, axis=0).shape
Out[65]: (5, 3, 4)
In [66]: np.stack(alist, axis=1).shape
Out[66]: (3, 5, 4)