当我学习用 Python 编写神经网络时,我刚刚编写了以下线性关联网络,该网络接受 K
输入向量 x_1, ..., x_K
,长度分别为 L
和 {{1 }} 输出向量的相应长度 K
并使用梯度下降找到最佳权重。
由于在调整 N
、K
和 L
时计算时间爆炸非常快,我一直在寻找如何加快速度。我发现了 cupy,但在这种情况下,cupy 比 numpy 慢得多。 为什么会这样?将代码更改为cupy 变体时,我只将每个N
替换为np
,因为我将cupy 导入为cp
。
我也用过cp
,但后来我不得不f = njit()(ManyAssociations.fit)
而不是写return W
。 有什么方法可以在课堂内使用 njit,或者除此之外还有更好的方法来使用 numba/cuda 吗?事实证明,在第一次函数调用“热身”后,速度要快得多,但在 ManyAssociations.weights = W
周围的上述形状的向量时,它仍然达到了极限。
还有什么其他的好方法可以加速像下面这样的代码?我可以更有效地写作吗?我可以更好地使用 GPU 吗?
K = L = N = 9
答案 0 :(得分:1)
我发现了cupy,但是在这种情况下cupy比numpy慢得多。为什么会这样?
GPU 上的计算被分成称为内核的基本计算密集型构建块。内核由 CPU 提交给 GPU。 每个内核调用都需要一些时间:CPU 必须与 GPU 通信并且经常使用相对较慢的 PCI 互连(两者都应该同步),应该在 GPU 上进行分配,以便生成的数据可以编写等。CuPy 包天真地将每个基本的 Numpy 指令转换为 GPU 内核。 由于您的循环执行了很多小内核,因此开销很大。因此,如果您希望使用 CuPy 在 GPU 上更快地编写代码,您需要处理大量数据块或直接编写您自己的内核(这很难,因为 GPU 非常复杂)。< /p> <块引用>
有没有什么方法可以在课堂内使用 njit 或者除此之外有没有更好的方法来使用 numba/cuda?
您可以使用 @jitclass
。您可以在 documentation 中找到更多信息。
此外,您可以利用并行性来加快编码速度。为此,您可以例如将 range
替换为 prange
并将属性 parallel=True
添加到 Numba 的 njit
。您可以找到更多信息here。
还有什么其他的好方法可以加速像下面这样的代码?我可以更有效地写作吗?我可以更好地使用 GPU 吗?
神经网络通常计算量很大。 Numba 应该相当不错,以获得相当高的性能。但是如果你想要一个快速的代码,那么你要么需要使用更高级别的库,要么通过重写库自己做的事情来弄脏你的手(可能使用更低级别的代码)。 使用神经网络的标准方法是使用专用库,如 TensorFlow、PyTorch、Keras 等。AFAIK,前者是灵活且高度优化的,尽管它比另一个低级。