Write the code to calculate the Gaussian kernel, which needs to be calculated in the Gaussian process, at Baku speed.
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))
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
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