如何分割成块(子矩阵),或处理一个巨大的矩阵,在 numpy 上给出内存错误?
How to split in chunks (submatrices), or handle a huge matrix giving memory error on numpy?
我有一个非常大的矩阵,不能简单地放入内存。我必须使用的矩阵有 483798149136
个元素,这意味着 4830 亿个浮点数。
我考虑的方法是将这个巨大的矩阵以某种方式拆分成适合内存的不同子矩阵,对这些子矩阵执行 pooling 操作,然后将它们全部连接起来重建原始矩阵,这将希望在所有池化操作之后适合内存。
如有错误请指正,此方法只是我的一个想法,好坏我不知道。如果您有任何更好的替代想法,我愿意接受任何建议。
重现此矩阵的代码为:
a = np.arange(695556).reshape(834,834)
np.meshgrid(a,a)
我一直在阅读 post and this post,以及同一站点中的其他书籍,但其中 none 为此类问题提供了真正的解决方案,他们只是给出了模糊的建议.
我现在的问题是:
我的拆分和合并方法可行吗?还有其他更好的方法吗?
我如何(用代码术语)将这个矩阵拆分成多个部分(如 windows 或多维内核)并稍后再次重建它
有没有办法在 numpy 中以块的形式处理矩阵,以使用矩阵层执行运算,如乘法、加法等...
Python有没有专门的包可以帮助处理这种矩阵问题
编辑
鉴于一些用户问我整个操作的目标,我将提供一些信息:
我正在做一个 3d 打印项目。在此过程中,有激光束熔化金属粉末以制造复杂的金属件。这块里面有层,激光一层层熔化金属。
我有3个csv文件,每个包含一个834 x 834的矩阵。第一个矩阵包含激光束通过粉末床熔化金属时X轴的坐标值,第二个矩阵是Y轴相同,第三个矩阵表示激光在同一像素点熔化的时间。这些值以秒为单位。
所以我有了激光通过X轴和Y轴的坐标,以及熔化每个点所需的时间。
此矩阵来自每个制造件的截面图像。
问题在于某个像素的温度和激光停留在该像素的时间会影响激光到达该像素时的第 n 个像素。所以我想创建一个距离矩阵,告诉我图像的每个像素在欧氏距离方面的不同或相似程度。
这就是为什么如果我有例如 2 834 x 834 矩阵,我需要创建一个 695556 x 695556 矩阵,矩阵中每个点之间的距离。这就是为什么如此巨大并且无法放入内存的原因。
不知道是我给的信息太多了,还是解释的乱七八糟。你可以问任何你需要的,我会尽力澄清,但要点是我需要创建这个巨大的距离矩阵,以便了解像素之间的数学距离,然后了解像素之间发生的事情之间的关系打印时作品的某些点以及在其他点需要发生什么以避免制造缺陷。
非常感谢您
毕竟,我找到了解决问题的方法。使用 dask 可以轻松处理这个巨大的矩阵。 Dask 是一个 python 库,它允许分布式计算和数据划分成块以优化内存使用。它非常方便,因为它确实允许您以非常低的计算和内存成本处理字面意义上的大量数据,显然,它不如内存计算快,但我认为很多人会很高兴知道这一点。
这个包优化的不错,经常更新。最好的是它有 numpy/pandas 语法,它也以与数组相同的方式处理数据帧,如果你知道 pandas/numpy 你会感觉像在家里一样 dask。
您可以像这样创建一个 dask 分布式数组:
import numpy as np
import dask.array as da
Y = da.random.normal(size=(695556, 695556),
chunks=(1000, 1000))
然后,您可以像这样对其进行一些操作:
y = Y.mean(axis=0)[0:100].compute()
此外,如果您使用 memory_profiler
package,您还可以监控您的内存和 CPU 使用情况,并查看您的大量数据在计算中消耗了多少内存。
我发现一些实际例子非常说明问题 here。
此外,可以找到此库中的解释性数组范围here。
最后,Python 3.X here.
中有关高性能计算的指南
希望这对遇到同样问题的人有所帮助。
由于矩阵计算是逐行或逐列进行的,我认为您可以轻松地减少它们。考虑 200 个 25x50 矩阵乘以 50x100 矩阵你应该得到 200 次 25x100 矩阵对吗?
首先,您可以将 200 拆分为 n,例如有时乘以 20,然后连接生成的 numpy 数组。比这更好的是,您可以使用 50 x m 而不是 50x100 和 numpy 将 25x50 与 50x10 相乘,然后再次连接(重塑连接再次重塑或使用高级索引)。
值得一提的部分来了:
例如,您有两个 10E9x10E9 矩阵并希望将它们相乘。将它们分成 20x20 的子部分并将它们相乘,然后求和并重塑结果。假设你有一个内存很少的 gpu,我相信你可以在一个进程中将数据流式传输到它的内存,同时使用多处理让它乘以之前的数据块。我从未尝试过,但我打算使用 cupy 或 pyopencl 在 GT 1030 或 6500 XT 上进行尝试,并将编辑此 post 并将其添加为示例。
还有一种方法不涉及re-inventing所有这些。
https://medium.com/analytics-vidhya/matrix-multiplication-at-scale-using-map-reduce-d5dc16710095
我有一个非常大的矩阵,不能简单地放入内存。我必须使用的矩阵有 483798149136
个元素,这意味着 4830 亿个浮点数。
我考虑的方法是将这个巨大的矩阵以某种方式拆分成适合内存的不同子矩阵,对这些子矩阵执行 pooling 操作,然后将它们全部连接起来重建原始矩阵,这将希望在所有池化操作之后适合内存。
如有错误请指正,此方法只是我的一个想法,好坏我不知道。如果您有任何更好的替代想法,我愿意接受任何建议。
重现此矩阵的代码为:
a = np.arange(695556).reshape(834,834)
np.meshgrid(a,a)
我一直在阅读
我现在的问题是:
我的拆分和合并方法可行吗?还有其他更好的方法吗?
我如何(用代码术语)将这个矩阵拆分成多个部分(如 windows 或多维内核)并稍后再次重建它
有没有办法在 numpy 中以块的形式处理矩阵,以使用矩阵层执行运算,如乘法、加法等...
Python有没有专门的包可以帮助处理这种矩阵问题
编辑
鉴于一些用户问我整个操作的目标,我将提供一些信息:
我正在做一个 3d 打印项目。在此过程中,有激光束熔化金属粉末以制造复杂的金属件。这块里面有层,激光一层层熔化金属。
我有3个csv文件,每个包含一个834 x 834的矩阵。第一个矩阵包含激光束通过粉末床熔化金属时X轴的坐标值,第二个矩阵是Y轴相同,第三个矩阵表示激光在同一像素点熔化的时间。这些值以秒为单位。
所以我有了激光通过X轴和Y轴的坐标,以及熔化每个点所需的时间。
此矩阵来自每个制造件的截面图像。
问题在于某个像素的温度和激光停留在该像素的时间会影响激光到达该像素时的第 n 个像素。所以我想创建一个距离矩阵,告诉我图像的每个像素在欧氏距离方面的不同或相似程度。
这就是为什么如果我有例如 2 834 x 834 矩阵,我需要创建一个 695556 x 695556 矩阵,矩阵中每个点之间的距离。这就是为什么如此巨大并且无法放入内存的原因。
不知道是我给的信息太多了,还是解释的乱七八糟。你可以问任何你需要的,我会尽力澄清,但要点是我需要创建这个巨大的距离矩阵,以便了解像素之间的数学距离,然后了解像素之间发生的事情之间的关系打印时作品的某些点以及在其他点需要发生什么以避免制造缺陷。
非常感谢您
毕竟,我找到了解决问题的方法。使用 dask 可以轻松处理这个巨大的矩阵。 Dask 是一个 python 库,它允许分布式计算和数据划分成块以优化内存使用。它非常方便,因为它确实允许您以非常低的计算和内存成本处理字面意义上的大量数据,显然,它不如内存计算快,但我认为很多人会很高兴知道这一点。
这个包优化的不错,经常更新。最好的是它有 numpy/pandas 语法,它也以与数组相同的方式处理数据帧,如果你知道 pandas/numpy 你会感觉像在家里一样 dask。
您可以像这样创建一个 dask 分布式数组:
import numpy as np
import dask.array as da
Y = da.random.normal(size=(695556, 695556),
chunks=(1000, 1000))
然后,您可以像这样对其进行一些操作:
y = Y.mean(axis=0)[0:100].compute()
此外,如果您使用 memory_profiler
package,您还可以监控您的内存和 CPU 使用情况,并查看您的大量数据在计算中消耗了多少内存。
我发现一些实际例子非常说明问题 here。
此外,可以找到此库中的解释性数组范围here。
最后,Python 3.X here.
中有关高性能计算的指南希望这对遇到同样问题的人有所帮助。
由于矩阵计算是逐行或逐列进行的,我认为您可以轻松地减少它们。考虑 200 个 25x50 矩阵乘以 50x100 矩阵你应该得到 200 次 25x100 矩阵对吗? 首先,您可以将 200 拆分为 n,例如有时乘以 20,然后连接生成的 numpy 数组。比这更好的是,您可以使用 50 x m 而不是 50x100 和 numpy 将 25x50 与 50x10 相乘,然后再次连接(重塑连接再次重塑或使用高级索引)。
值得一提的部分来了: 例如,您有两个 10E9x10E9 矩阵并希望将它们相乘。将它们分成 20x20 的子部分并将它们相乘,然后求和并重塑结果。假设你有一个内存很少的 gpu,我相信你可以在一个进程中将数据流式传输到它的内存,同时使用多处理让它乘以之前的数据块。我从未尝试过,但我打算使用 cupy 或 pyopencl 在 GT 1030 或 6500 XT 上进行尝试,并将编辑此 post 并将其添加为示例。
还有一种方法不涉及re-inventing所有这些。 https://medium.com/analytics-vidhya/matrix-multiplication-at-scale-using-map-reduce-d5dc16710095