几何矩阵乘法

Sla*_*off 7 python numpy matrix-multiplication

我正在开发一个构建几何(而不是算术)神经网络的项目.为了构造传递函数,我想使用几何求和而不是算术求和.

为了使事情更清楚,我将在代码中描述:

def arithmetic_matrix_multiplication(matrix1, matrix2):
    new_matrix = np.zeros(len(matrix1),len(matrix2[0]))
    for i in range(len(matrix1)):
        for j in range(len(matrix2[0])):
            for k in range(len(matrix2)):
                new_matrix[i][j] += matrix1[i][k]*matrix2[k][j]
    return new_matrix

def geometric_matrix_multiplication(matrix1, matrix2):
    new_matrix = np.ones(len(matrix1),len(matrix2[0]))
    for i in range(len(matrix1)):
        for j in range(len(matrix2[0])):
            for k in range(len(matrix2)):
                new_matrix[i][j] *= matrix1[i][k]*matrix2[k][j]
    return new_matrix
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这是一个非常小的变化.唯一的问题是,以同样的方式,我永远不会真正编写和使用上面的算术代码(我会使用numpy.dot),我真的不想实际使用上面的几何代码.有没有办法利用numpy的矩阵乘法来实现几何结果?我无法想到一个,而且我没有找到任何明显的解决方案,这远远不是最优的.

Jai*_*ime 6

你不必要地使事情变得复杂......因为你有一个单一的操作,乘法,这是可交换的,你可以随意交换你执行它们的顺序,即你不需要将项目的matrix1项目乘以matrix2,和一旦你计算了所有这些,就将它们相乘.相反,您可以先将所有相关项matrix1组合在一起,然后将所有相关项matrix2组合在一起,然后将两个结果值相乘.所以你可以编写你的函数非常简单:

def fast_geometric_matrix_multiplication(matrix1, matrix2):
    return np.prod(matrix1, axis=1)[:, None] * np.prod(matrix2, axis=0)
Run Code Online (Sandbox Code Playgroud)

它有,如果你是乘形状的矩阵额外的优势(m, k)(k, n)你所期望的是具有做m*n*2*k乘法,而这种方法只需要m*k + n*k + m*n,这势必会比你目前正在做的事情为几乎任何阵列形状小得多.

而且当然:

In [24]: a = np.random.rand(100, 200)
    ...: b = np.random.rand(200, 50)
    ...: 

In [25]: np.allclose(geometric_matrix_multiplication(a, b),
    ...:             fast_geometric_matrix_multiplication(a, b))
Out[25]: True

In [26]: %timeit geometric_matrix_multiplication(a, b)
1 loops, best of 3: 1.39 s per loop

In [27]: %timeit fast_geometric_matrix_multiplication(a, b)
10000 loops, best of 3: 74.2 us per loop

In [28]: %timeit np.prod(a[:, None, :]*b[..., None].T, axis=2)
100 loops, best of 3: 5.97 ms per loop
Run Code Online (Sandbox Code Playgroud)