Calculate Gaussian kernel at explosive speed even with python

Introduction

Write the code to calculate the Gaussian kernel, which needs to be calculated in the Gaussian process, at Baku speed.

code

I wrote it in Numba to speed it up. It's a pity that the code itself is a little redundant due to the restrictions imposed by Numba, but the effect of speeding up is enormous. There were restrictions such as describing by multiplication by square to speed up with Numba, and not using numpy functions in functions defined by myself.

from numba import jit, void, f8
import numpy as np
import time


@jit(void(f8[:, :], f8[:, :]))
def gauss_gram_mat(x, K):
  n_points = len(x)
  n_dim = len(x[0])
  b = 0
  sgm = 0.2

  for j in range(n_points):
    for i in range(n_points):
      for k in range(n_dim):
        b = (x[i][k] - x[j][k]) / sgm
        K[i][j] += b * b


def gauss_gram_mat_normal(x, K):
  n_points = len(x)
  n_dim = len(x[0])
  b = 0
  sgm = 0.2

  for j in range(n_points):
    for i in range(n_points):
      for k in range(n_dim):
        b = (x[i][k] - x[j][k]) / sgm
        K[i][j] += b * b


n_dim = 10
n_points = 2000
x = np.random.rand(n_points, n_dim)
K = np.zeros((n_points, n_points))

start = time.time()

gauss_gram_mat(x, K)
K = np.exp(- K / 2)

print("Namba: {}".format(time.time() - start))

start = time.time()

gauss_gram_mat_normal(x, K)
K = np.exp(- K / 2)

print("Normal: {}".format(time.time() - start))

Verification

Although there is only one pattern, the calculation speeds are compared between the normal code and the Numba code for the number of points and the number of dimensions above.

Apparently it's nearly 500 times faster. (If you use the inclusion notation etc., it will be faster without Numba, but it is impossible so far.)

Numba: 0.11480522155761719
Normal: 50.70034885406494

Supplement

I also verified it with Numpy.

import numpy as np
import time

n_dim = 10
n_points = 2000
sgm = 0.2
x = np.random.rand(n_points, n_dim)

now = time.time()
K = np.exp(- 0.5 * (((x - x[:, None]) / sgm) ** 2).sum(axis=2))
print("Numpy: {}".format(time.time() - start))

The result is that Numba is faster than Numpy.

Numpy: 0.3936312198638916

Recommended Posts

Calculate Gaussian kernel at explosive speed even with python
Python template for log analysis at explosive speed
Explosive speed with Python (Bottle)! Web API development
Kernel Method with Python
Perform half-width / full-width conversion at high speed with Python
Measure WiFi speed with Python
How to scrape at speed per second with Python Selenium
Roughly speed up Python with numba
How to calculate date with python
Calculate and display standard weight with python
Convert memo at once with Python 2to3
[TPU] [Transformers] Make BERT at explosive speed
Image processing with Python 100 knocks # 9 Gaussian filter
Instantly convert Model to Dictionary with Django and initialize Form at explosive speed
[Python] Clustering with an infinitely mixed Gaussian model
Convert multiple proto files at once with python