summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Luevano Alvarado <55825613+luevano@users.noreply.github.com>2020-03-07 10:11:53 -0700
committerDavid Luevano Alvarado <55825613+luevano@users.noreply.github.com>2020-03-07 10:11:53 -0700
commitf57f38c2886052bef92b3885acc2790ac5bc340d (patch)
treee7df0fa546df2de6552ff0378edecd929ea87dba
parent00301d1a9a8a7f975b64fe4ef85458f6a40776f7 (diff)
Add laplacian kernel
-rw-r--r--ml_exp/__init__.py3
-rw-r--r--ml_exp/do_ml.py61
-rw-r--r--ml_exp/kernels.py55
3 files changed, 101 insertions, 18 deletions
diff --git a/ml_exp/__init__.py b/ml_exp/__init__.py
index bc5afe03a..e49104e12 100644
--- a/ml_exp/__init__.py
+++ b/ml_exp/__init__.py
@@ -24,6 +24,7 @@ from ml_exp.compound import Compound
from ml_exp.representations import coulomb_matrix, lennard_jones_matrix,\
get_helping_data, adjacency_matrix, check_bond, bag_of_bonds
from ml_exp.qm7db import qm7db
+from ml_exp.kernels import gaussian_kernel, laplacian_kernel
from ml_exp.do_ml import simple_ml, do_ml
__all__ = ['Compound',
@@ -34,5 +35,7 @@ __all__ = ['Compound',
'check_bond',
'bag_of_bonds',
'qm7db',
+ 'gaussian_kernel',
+ 'laplacian_kernel',
'simple_ml',
'do_ml']
diff --git a/ml_exp/do_ml.py b/ml_exp/do_ml.py
index f4742b66d..b30d73811 100644
--- a/ml_exp/do_ml.py
+++ b/ml_exp/do_ml.py
@@ -30,7 +30,7 @@ except ImportError:
print('Tensorflow couldn\'t be imported. Maybe it is not installed.')
TF_AV = False
from ml_exp.misc import printc
-from ml_exp.kernels import gaussian_kernel
+from ml_exp.kernels import gaussian_kernel, laplacian_kernel
from ml_exp.qm7db import qm7db
@@ -93,11 +93,18 @@ def simple_ml(descriptors,
with tf.device('GPU:0'):
X_tr = descriptors[:training_size]
Y_tr = energies[:training_size]
- K_tr = gaussian_kernel(X_tr,
- X_tr,
- sigma,
- use_tf=use_tf)
-
+ if identifier == 'BOB':
+ K_tr = laplacian_kernel(X_tr,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
+ else:
+ K_tr = gaussian_kernel(X_tr,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
+
+ # Adding a small value on the diagonal for cho_solve.
dv = tf.linalg.tensor_diag(tf.constant(1e-8,
shape=(training_size),
dtype=tf.float64))
@@ -108,10 +115,16 @@ def simple_ml(descriptors,
X_te = descriptors[-test_size:]
Y_te = energies[-test_size:]
- K_te = gaussian_kernel(X_te,
- X_tr,
- sigma,
- use_tf=use_tf)
+ if identifier == 'BOB':
+ K_te = laplacian_kernel(X_te,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
+ else:
+ K_te = gaussian_kernel(X_te,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
Y_te = tf.expand_dims(Y_te, 1)
Y_pr = tf.tensordot(K_te, alpha, 1)
@@ -120,10 +133,16 @@ def simple_ml(descriptors,
else:
X_tr = descriptors[:training_size]
Y_tr = energies[:training_size]
- K_tr = gaussian_kernel(X_tr,
- X_tr,
- sigma,
- use_tf=use_tf)
+ if identifier == 'BOB':
+ K_tr = laplacian_kernel(X_tr,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
+ else:
+ K_tr = gaussian_kernel(X_tr,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
# Adding a small value on the diagonal for cho_solve.
K_tr[np.diag_indices_from(K_tr)] += 1e-8
@@ -132,10 +151,16 @@ def simple_ml(descriptors,
X_te = descriptors[-test_size:]
Y_te = energies[-test_size:]
- K_te = gaussian_kernel(X_te,
- X_tr,
- sigma,
- use_tf=use_tf)
+ if identifier == 'BOB':
+ K_te = laplacian_kernel(X_te,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
+ else:
+ K_te = gaussian_kernel(X_te,
+ X_tr,
+ sigma,
+ use_tf=use_tf)
Y_pr = np.dot(K_te, alpha)
mae = np.mean(np.abs(Y_pr - Y_te))
diff --git a/ml_exp/kernels.py b/ml_exp/kernels.py
index abc71f7af..488232392 100644
--- a/ml_exp/kernels.py
+++ b/ml_exp/kernels.py
@@ -83,3 +83,58 @@ def gaussian_kernel(X1,
norm = np.linalg.norm(X2 - X1[i], axis=-1)
K[i, :] = np.exp(i_sigma * np.square(norm))
return K
+
+
+def laplacian_kernel(X1,
+ X2,
+ sigma,
+ use_tf=True):
+ """
+ Calculates the Laplacian Kernel.
+ X1: first representations.
+ X2: second representations.
+ sigma: kernel width.
+ use_tf: if tensorflow should be used.
+ """
+ # If tf is to be used but couldn't be imported, don't try to use it.
+ if use_tf and not TF_AV:
+ use_tf = False
+
+ X1_size = X1.shape[0]
+ X2_size = X2.shape[0]
+ i_sigma = -0.5 / sigma
+
+ if use_tf:
+ if tf.config.experimental.list_physical_devices('GPU'):
+ with tf.device('GPU:0'):
+ X1 = tf.convert_to_tensor(X1)
+ X2 = tf.convert_to_tensor(X2)
+ X2r = tf.rank(X2)
+
+ def cond(i, _):
+ return tf.less(i, X1_size)
+
+ def body(i, K):
+ if X2r == 3:
+ norm = tf.norm(X2 - X1[i], axis=(1, 2))
+ else:
+ norm = tf.norm(X2 - X1[i], axis=-1)
+
+ return (i + 1,
+ K.write(i, tf.exp(i_sigma * norm)))
+
+ K = tf.TensorArray(dtype=tf.float64,
+ size=X1_size)
+ i_state = (0, K)
+ n, K = tf.while_loop(cond, body, i_state)
+ K = K.stack()
+ else:
+ K = np.zeros((X1_size, X2_size), dtype=np.float64)
+ # Faster way of calculating the kernel (no numba support).
+ for i in range(X1_size):
+ if X2.ndim == 3:
+ norm = np.linalg.norm(X2 - X1[i], axis=(1, 2))
+ else:
+ norm = np.linalg.norm(X2 - X1[i], axis=-1)
+ K[i, :] = np.exp(i_sigma * norm)
+ return K