【发布时间】:2013-12-16 23:32:43
【问题描述】:
我正在整理一些基本的 Python 代码,这些代码包含映射到矩阵列表的标签字典(矩阵表示分类图像),我只是试图从所有内容中减去平均图像,然后将数据集中在一个 0 - 1 的比例。由于某种原因,这段代码似乎运行缓慢。当仅迭代 500 个 48x48 图像时,运行大约需要 10 秒,这并不能真正扩展到我正在使用的图像数量。查看 cProfile 结果后,看起来大部分时间都花在了 _center 函数上。
我觉得我在这里可能没有充分使用 numpy,并且想知道是否有人比我更有经验的人有一些技巧来加快速度,或者可以指出我在这里做的一些愚蠢的事情。代码贴在下面:
def __init__(self, master_dict, normalization = lambda x: math.exp(x)):
"""
master_dict should be a dictionary mapping classes to lists of matrices
example = {
"cats": [[[]...], [[]...]...],
"dogs": [[[]...], [[]...]...]
}
have to be python lists, not numpy arrays
normalization represents the 0-1 normalization scheme used. Defaults to simple linear
"""
normalization = np.vectorize(normalization)
full_tensor = np.array(reduce(operator.add, master_dict.values()))
centering = np.sum(np.array(reduce(operator.add, master_dict.values())), axis=0)/len(full_tensor)
self.data = {key: self._center(np.array(value), centering, normalization) for key,value in master_dict.items()}
self.normalization = normalization
def _center(self, list_of_arrays, centering_factor, normalization_scheme):
"""
Centering scheme for arrays
"""
arrays = list_of_arrays - centering_factor
normalize = lambda a: (a - np.min(a)) / (np.max(a) - np.min(a))
return normalization_scheme([normalize(array) for array in arrays])
另外,在你问之前,我对输入格式没有大量的控制权,但如果这真的是这里的限制因素,我可能会弄清楚一些事情。
【问题讨论】:
-
在执行操作之前,您能否在内部将
master_dict中的“矩阵”转换为 numpy 数组?我觉得你在浪费一些时间不断转换为np.array。我知道这可能不是瓶颈,但它确实是。 -
另外,请查看:docs.scipy.org/doc/numpy/reference/generated/…。使用这个 numpy 内置标准化函数可能会比您的
lambda更快。 -
最后,如果您使用
np.exp而不是np.vectorize(lambda x: math.exp),您可能会从normalization获得更好的性能。所有math函数都具有numpy等效项,并且在numpy数组上应该比矢量化等效项更快。 -
@SethMMorton 感谢您的建议!可悲的是,您链接到的 scipy 文档指的是一种与我在这里所做的非常不同的规范化。最初将数组转换为 np 数组的问题是我在前几行中使用了很多 python-list 特定技巧,但是如果在 numpy 中有一个好方法可以做到这一点,我很乐意切换到更多高性能版本。最后,numpy.exp 替换实际上产生了巨大的变化!这节省了我 30% 的执行时间!
-
我很确定
reduce行可以替换为full_tensor = np.concatenate(master_dict.values())但在我测试的小示例中似乎并没有快多少。
标签: python optimization numpy normalization