【问题标题】:Converting Double For Loop to Numpy Linear Algebra for Dual Form SVM将双 For 循环转换为双形式 SVM 的 Numpy 线性代数
【发布时间】:2020-07-16 05:42:59
【问题描述】:

我正在尝试创建一个 Dual Form SVM,它现在运行速度非常慢但正确。我目前有这个目标函数(这是瓶颈)......

ij = 0
for i in range(len(x)):
    for j in range(len(x)):
        ij += y[i]*y[j]*a[i]*a[j]*np.dot(x[i].T, x[j])
ij /= 2

这运行得很慢。我需要以某种方式将其转换为线性代数以使用 NumPy 加速它,但我倾向于为此而苦苦挣扎。

仅供参考:a、y 和 x 长度相同。 a 和 y 包含所有浮点数。 x 是浮点数的二维向量。

【问题讨论】:

  • 小样本数组将使我们的答案更容易测试。否则,我们必须编写一两个测试用例。
  • 最好的方法取决于数组的大小。最简单的事情(在较大的数组上也非常好是使用 einsum。例如。np.einsum("i,j,i,j,ix,jx->",y,y,a,a,x,x,optimize="optimal")/2
  • @max9111 哇,进步很大!我考虑过使用np.einsum,但无法按预期工作,最后以旧方式完成。你知道optimize="optimal" 在内部做什么吗?
  • 找到最佳收缩(最小化 FLOP 的数量)。我建议看一下np.print(np.einsum_path("i,j,i,j,ix,jx->",y,y,a,a,x,x,optimize="optimal")[1]),以了解 einsum 实际做了什么。源代码可以在这里找到github.com/numpy/numpy/blob/v1.17.0/numpy/core/einsumfunc.py 无论如何,总是提供一些相关的输入数据,如果有人知道输入数组有多大,那么给出答案会容易得多。一个简单的 np.random.rand() 就足够了。
  • @max9111 感谢您的回复!您应该将其发布为答案,这比我的要好。

标签: python numpy svm linear-algebra


【解决方案1】:
y[i]*y[j]*a[i]*a[j]*np.dot(x[i].T, x[j])

我认为 ij 总和可以写成广播外积,然后是扁平总和

temp = y[:,None]*y*a[:,None]*a*(x.T@x)

temp = temp.sum()

我是在没有测试的情况下编写的,所以可能存在错误。

 ya = y*a
 temp = np.outer(ya,ya)
 temp *= x.T@x

【讨论】:

    【解决方案2】:

    我认为有一种更好/更清洁的方法,但在这里它是我最好的。

    def np_way():
        # Compute 1st part: y[i]*y[j]*a[i]*a[j]
        ay = a*y
        ya = np.outer(ay, ay)
        # print(ya)
        # Compute 2nd part: np.dot(x[i].T, x[j])
        _dot = np.outer(x, x)
        dot = _dot[::2, ::2] + _dot[1::2, 1::2]
        # print(dot)
        return (ya * dot).sum()/2
    

    你可以取消注释来调试它。

    我已将您的代码放入 original_way() 函数中,并将 ir 与 np_way() 进行了比较,因此我可以 timeit

    %timeit original_way()
    %timeit np_way()
    1 loop, best of 3: 708 ms per loop
    100 loops, best of 3: 3.21 ms per loop
    

    结果是长度为500np_way()original_way() 快大约 220 倍。

    【讨论】:

    • @TrevorDalton 这能回答你的问题吗?
    猜你喜欢
    • 1970-01-01
    • 2021-04-27
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多