From 71e9bba7a4d8a5b8fde10b2f14424159556d9877 Mon Sep 17 00:00:00 2001 From: PatReis Date: Thu, 14 Dec 2023 15:36:45 +0100 Subject: [PATCH] ran more test training. --- kgcnn/layers/geom.py | 35 +- kgcnn/layers/polynom.py | 86 +++- kgcnn/layers/relational.py | 2 +- training/hyper/hyper_mp_jdft2d.py | 220 ++++++++++ training/hyper/hyper_qm7.py | 406 +++++++++++++++++- .../rGIN/rGIN_ESOLDataset_score.yaml | 137 ++++++ .../results/ESOLDataset/rGIN/rGIN_hyper.json | 1 + .../DimeNetPP_FreeSolvDataset_score.yaml | 137 ++++++ .../DimeNetPP/DimeNetPP_hyper.json | 1 + training/results/README.md | 29 +- training/train_graph.py | 2 +- 11 files changed, 1002 insertions(+), 54 deletions(-) create mode 100644 training/results/ESOLDataset/rGIN/rGIN_ESOLDataset_score.yaml create mode 100644 training/results/ESOLDataset/rGIN/rGIN_hyper.json create mode 100644 training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_FreeSolvDataset_score.yaml create mode 100644 training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_hyper.json diff --git a/kgcnn/layers/geom.py b/kgcnn/layers/geom.py index b4c03cca..6a054d22 100644 --- a/kgcnn/layers/geom.py +++ b/kgcnn/layers/geom.py @@ -5,8 +5,9 @@ from keras import ops, Layer from keras.layers import Layer, Subtract, Multiply, Add, Subtract from kgcnn.layers.gather import GatherNodes, GatherState, GatherNodesOutgoing -from kgcnn.layers.polynom import spherical_bessel_jn_zeros, spherical_bessel_jn_normalization_prefactor, \ - tf_spherical_bessel_jn, tf_spherical_harmonics_yl +from kgcnn.layers.polynom import spherical_bessel_jn_zeros, spherical_bessel_jn_normalization_prefactor +from kgcnn.layers.polynom import tf_spherical_bessel_jn, tf_spherical_harmonics_yl +from kgcnn.layers.polynom import SphericalBesselJnExplicit, SphericalHarmonicsYl from kgcnn.ops.axis import get_positive_axis from kgcnn.ops.core import cross as kgcnn_cross @@ -1107,23 +1108,26 @@ def get_config(self): class SphericalBasisLayer(Layer): r"""Expand a distance into a Bessel Basis with :math:`l=m=0`, according to `Klicpera et al. 2020 `__ . - - Args: - num_spherical (int): Number of spherical basis functions - num_radial (int): Number of radial basis functions - cutoff (float): Cutoff distance c - envelope_exponent (int): Degree of the envelope to smoothen at cutoff. Default is 5. - """ def __init__(self, num_spherical, num_radial, cutoff, envelope_exponent=5, + fused: bool = True, **kwargs): - super(SphericalBasisLayer, self).__init__(**kwargs) + """Initialize layer. + Args: + num_spherical (int): Number of spherical basis functions + num_radial (int): Number of radial basis functions + cutoff (float): Cutoff distance c + envelope_exponent (int): Degree of the envelope to smoothen at cutoff. Default is 5. + fused (bool): Whether to use fused implementation. Default is True. + """ + super(SphericalBasisLayer, self).__init__(**kwargs) assert num_radial <= 64 + self.fused = fused self.num_radial = int(num_radial) self.num_spherical = num_spherical self.cutoff = cutoff @@ -1135,6 +1139,9 @@ def __init__(self, num_spherical, self.bessel_norm = spherical_bessel_jn_normalization_prefactor(num_spherical, num_radial) self.layer_gather_out = GatherNodesOutgoing() + # non-explicit spherical bessel function seems faster. + # self.layers_spherical_jn = [SphericalBesselJnExplicit(n=n, fused=fused) for n in range(self.num_spherical)] + self.layers_spherical_yl = [SphericalHarmonicsYl(l=l, fused=fused) for l in range(self.num_spherical)] def envelope(self, inputs): p = self.envelope_exponent + 1 @@ -1164,6 +1171,7 @@ def call(self, inputs, **kwargs): rbf = [] for n in range(self.num_spherical): for k in range(self.num_radial): + # rbf += [self.bessel_norm[n, k] * self.layers_spherical_jn[n](d_scaled * self.bessel_n_zeros[n][k])] rbf += [self.bessel_norm[n, k] * tf_spherical_bessel_jn(d_scaled * self.bessel_n_zeros[n][k], n)] rbf = ops.stack(rbf, axis=1) @@ -1172,7 +1180,8 @@ def call(self, inputs, **kwargs): rbf_env = self.layer_gather_out([rbf_env, angle_index], **kwargs) # rbf_env = tf.gather(rbf_env, id_expand_kj[:, 1]) - cbf = [tf_spherical_harmonics_yl(angles[:, 0], n) for n in range(self.num_spherical)] + # cbf = [tf_spherical_harmonics_yl(angles[:, 0], n) for n in range(self.num_spherical)] + cbf = [self.layers_spherical_yl[n](angles[:, 0]) for n in range(self.num_spherical)] cbf = ops.stack(cbf, axis=1) cbf = ops.repeat(cbf, self.num_radial, axis=1) out = rbf_env * cbf @@ -1182,6 +1191,6 @@ def call(self, inputs, **kwargs): def get_config(self): """Update config.""" config = super(SphericalBasisLayer, self).get_config() - config.update({"num_radial": self.num_radial, "cutoff": self.cutoff, + config.update({"num_radial": self.num_radial, "cutoff": self.cutoff, "fused": self.fused, "envelope_exponent": self.envelope_exponent, "num_spherical": self.num_spherical}) - return config \ No newline at end of file + return config diff --git a/kgcnn/layers/polynom.py b/kgcnn/layers/polynom.py index dc6e4141..5ef6b32b 100644 --- a/kgcnn/layers/polynom.py +++ b/kgcnn/layers/polynom.py @@ -127,18 +127,21 @@ class SphericalBesselJnExplicit(Layer): \sum_{k=0}^{\left\lfloor(n-1)/2\right\rfloor}(-1)^{k}\frac{a_{2k+1}(n+\tfrac{1}{2})}{z^{2k+2}}.` """ - def __init__(self, n=0, **kwargs): + def __init__(self, n=0, fused: bool = False, **kwargs): r"""Initialize layer with constant n. Args: n (int): Positive integer for the bessel order :math:`n`. + fused (bool): Whether to compute polynomial in a fused tensor representation. """ super(SphericalBesselJnExplicit, self).__init__(**kwargs) self.n = n + self.fused = fused self._pre_factor_sin = [] self._pre_factor_cos = [] self._powers_sin = [] self._powers_cos = [] + for k in range(int(np.floor(n / 2)) + 1): if 2 * k < n + 1: fac_sin = float(sp.special.factorial(n + 2 * k) / np.power(2, 2 * k) / sp.special.factorial( @@ -146,6 +149,7 @@ def __init__(self, n=0, **kwargs): pow_sin = - (2 * k + 1) self._pre_factor_sin.append(fac_sin) self._powers_sin.append(pow_sin) + for k in range(int(np.floor((n - 1) / 2)) + 1): if 2 * k + 1 < n + 1: fac_cos = float(sp.special.factorial(n + 2 * k + 1) / np.power(2, 2 * k + 1) / sp.special.factorial( @@ -154,6 +158,12 @@ def __init__(self, n=0, **kwargs): self._pre_factor_cos.append(fac_cos) self._powers_cos.append(pow_cos) + if self.fused: + self._pre_factor_sin = ops.convert_to_tensor(self._pre_factor_sin, dtype=self.dtype) + self._pre_factor_cos = ops.convert_to_tensor(self._pre_factor_cos, dtype=self.dtype) + self._powers_sin = ops.convert_to_tensor(self._powers_sin, dtype=self.dtype) + self._powers_cos = ops.convert_to_tensor(self._powers_cos, dtype=self.dtype) + def build(self, input_shape): """Build layer.""" super(SphericalBesselJnExplicit, self).build(input_shape) @@ -170,12 +180,16 @@ def call(self, x, **kwargs): n = self.n sin_x = ops.sin(x - n * np.pi / 2) cos_x = ops.cos(x - n * np.pi / 2) - sum_sin = ops.zeros_like(x) - sum_cos = ops.zeros_like(x) - for a, r in zip(self._pre_factor_sin, self._powers_sin): - sum_sin += a * ops.power(x, r) - for b, s in zip(self._pre_factor_cos, self._powers_cos): - sum_cos += b * ops.power(x, s) + if not self.fused: + sum_sin = ops.zeros_like(x) + sum_cos = ops.zeros_like(x) + for a, r in zip(self._pre_factor_sin, self._powers_sin): + sum_sin += a * ops.power(x, r) + for b, s in zip(self._pre_factor_cos, self._powers_cos): + sum_cos += b * ops.power(x, s) + else: + sum_sin = ops.sum(self._pre_factor_sin * ops.power(ops.expand_dims(x, axis=-1), self._powers_sin), axis=-1) + sum_cos = ops.sum(self._pre_factor_cos * ops.power(ops.expand_dims(x, axis=-1), self._powers_cos), axis=-1) return sum_sin * sin_x + sum_cos * cos_x def get_config(self): @@ -261,19 +275,25 @@ class LegendrePolynomialPn(Layer): """ - def __init__(self, n=0, **kwargs): + def __init__(self, n=0, fused: bool = False, **kwargs): r"""Initialize layer with constant n. Args: n (int): Positive integer for :math:`n` in :math:`P_n(x)`. + fused (bool): Whether to compute polynomial in a fused tensor representation. """ super(LegendrePolynomialPn, self).__init__(**kwargs) + self.fused = fused self.n = n self._pre_factors = [ float((-1) ** k * sp.special.factorial(2 * n - 2 * k) / sp.special.factorial(n - k) / sp.special.factorial( n - 2 * k) / sp.special.factorial(k) / 2 ** n) for k in range(0, int(np.floor(n / 2)) + 1) ] self._powers = [float(n - 2 * k) for k in range(0, int(np.floor(n / 2)) + 1)] + if self.fused: + # Or maybe also as weight. + self._powers = ops.convert_to_tensor(self._powers, dtype=self.dtype) + self._pre_factors = ops.convert_to_tensor(self._pre_factors, dtype=self.dtype) def build(self, input_shape): """Build layer.""" @@ -288,15 +308,18 @@ def call(self, x, **kwargs): Returns: Tensor: Legendre Polynomial of order :math:`n`. """ - out_sum = ops.zeros_like(x) - for a, r in zip(self._pre_factors, self._powers): - out_sum = out_sum + a * ops.power(x, r) + if not self.fused: + out_sum = ops.zeros_like(x) + for a, r in zip(self._pre_factors, self._powers): + out_sum = out_sum + a * ops.power(x, r) + else: + out_sum = ops.sum(self._pre_factors * ops.power(ops.expand_dims(x, axis=-1), self._powers), axis=-1) return out_sum def get_config(self): """Update layer config.""" config = super(LegendrePolynomialPn, self).get_config() - config.update({"n": self.n}) + config.update({"n": self.n, "fused": self.fused}) return config @@ -347,19 +370,25 @@ class SphericalHarmonicsYl(Layer): """ - def __init__(self, l=0, **kwargs): + def __init__(self, l=0, fused: bool = False, **kwargs): r"""Initialize layer with constant l. Args: l (int): Positive integer for :math:`l` in :math:`Y_l(\cos\theta)`. + fused (bool): Whether to compute polynomial in a fused tensor representation. """ super(SphericalHarmonicsYl, self).__init__(**kwargs) self.l = l + self.fused = fused self._pre_factors = [ float((-1) ** k * sp.special.factorial(2 * l - 2 * k) / sp.special.factorial(l - k) / sp.special.factorial( l - 2 * k) / sp.special.factorial(k) / 2 ** l) for k in range(0, int(np.floor(l / 2)) + 1)] self._powers = [float(l - 2 * k) for k in range(0, int(np.floor(l / 2)) + 1)] self._scale = float(np.sqrt((2 * l + 1) / 4 / np.pi)) + if self.fused: + # Or maybe also as weight. + self._powers = ops.convert_to_tensor(self._powers, dtype=self.dtype) + self._pre_factors = ops.convert_to_tensor(self._pre_factors, dtype=self.dtype) def build(self, input_shape): """Build layer.""" @@ -375,16 +404,19 @@ def call(self, theta, **kwargs): Tensor: Spherical harmonics for :math:`m=0` and constant non-integer :math:`l`. """ x = ops.cos(theta) - out_sum = ops.zeros_like(x) - for a, r in zip(self._pre_factors, self._powers): - out_sum = out_sum + a * ops.power(x, r) + if not self.fused: + out_sum = ops.zeros_like(x) + for a, r in zip(self._pre_factors, self._powers): + out_sum = out_sum + a * ops.power(x, r) + else: + out_sum = ops.sum(self._pre_factors * ops.power(ops.expand_dims(x, axis=-1), self._powers), axis=-1) out_sum = out_sum * self._scale return out_sum def get_config(self): """Update layer config.""" config = super(SphericalHarmonicsYl, self).get_config() - config.update({"l": self.l}) + config.update({"l": self.l, "fused": self.fused}) return config @@ -433,15 +465,17 @@ class AssociatedLegendrePolynomialPlm(Layer): \cdot \binom{l}{k}\binom{\frac{l+k-1}{2}}{l}`. """ - def __init__(self, l: int = 0, m: int = 0, **kwargs): + def __init__(self, l: int = 0, m: int = 0, fused: bool = False, **kwargs): r"""Initialize layer with constant m, l. Args: l (int): Positive integer for :math:`l` in :math:`P_{l}^{m}(x)`. m (int): Positive/Negative integer for :math:`m` in :math:`P_{l}^{m}(x)`. + fused (bool): Whether to compute polynomial in a fused tensor representation. """ super(AssociatedLegendrePolynomialPlm, self).__init__(**kwargs) self.m = m + self.fused = fused self.l = l if np.abs(m) > l: raise ValueError("Error: Legendre polynomial must have -l<= m <= l") @@ -464,6 +498,11 @@ def __init__(self, l: int = 0, m: int = 0, **kwargs): sp.special.binom((l + k - 1) / 2, l)) self._pre_factors.append(fac) + if self.fused: + # Or maybe also as weight. + self._powers = ops.convert_to_tensor(self._powers, dtype=self.dtype) + self._pre_factors = ops.convert_to_tensor(self._pre_factors, dtype=self.dtype) + def build(self, input_shape): """Build layer.""" super(AssociatedLegendrePolynomialPlm, self).build(input_shape) @@ -480,13 +519,16 @@ def call(self, x, **kwargs): neg_m = self._neg_m m = self._m x_pre_factor = ops.power(1 - ops.square(x), m / 2) * self._x_pre_factor - sum_out = ops.zeros_like(x) - for a, r in zip(self._pre_factors, self._powers): - sum_out += ops.power(x, r) * a + if not self.fused: + sum_out = ops.zeros_like(x) + for a, r in zip(self._pre_factors, self._powers): + sum_out += ops.power(x, r) * a + else: + sum_out = ops.sum(self._pre_factors * ops.power(ops.expand_dims(x, axis=-1), self._powers), axis=-1) return sum_out * x_pre_factor * neg_m def get_config(self): """Update layer config.""" config = super(AssociatedLegendrePolynomialPlm, self).get_config() - config.update({"l": self.l, "m": self.m}) + config.update({"l": self.l, "m": self.m, "fused": self.fused}) return config diff --git a/kgcnn/layers/relational.py b/kgcnn/layers/relational.py index 0fbc5aaa..bbfa3145 100644 --- a/kgcnn/layers/relational.py +++ b/kgcnn/layers/relational.py @@ -259,6 +259,6 @@ def get_config(self): }) config_act = self._layer_activation.get_config() for x in ["activation", "activity_regularizer"]: - if x in config_act: + if x in config_act.keys(): config.update({x: config_act[x]}) return config diff --git a/training/hyper/hyper_mp_jdft2d.py b/training/hyper/hyper_mp_jdft2d.py index c99397cb..d387f7e2 100644 --- a/training/hyper/hyper_mp_jdft2d.py +++ b/training/hyper/hyper_mp_jdft2d.py @@ -215,4 +215,224 @@ "kgcnn_version": "4.0.0" } }, + "Megnet.make_crystal_model": { + "model": { + "module_name": "kgcnn.literature.Megnet", + "class_name": "make_crystal_model", + "config": { + 'name': "Megnet", + 'inputs': [ + {'shape': (None,), 'name': "node_number", 'dtype': 'int64', 'ragged': True}, + {'shape': (None, 3), 'name': "node_coordinates", 'dtype': 'float32', 'ragged': True}, + {'shape': (None, 2), 'name': "range_indices", 'dtype': 'int64', 'ragged': True}, + {'shape': [1], 'name': "charge", 'dtype': 'float32', 'ragged': False}, + {'shape': (None, 3), 'name': "range_image", 'dtype': 'int64', 'ragged': True}, + {'shape': (3, 3), 'name': "graph_lattice", 'dtype': 'float32', 'ragged': False} + ], + "input_tensor_type": "ragged", + 'input_embedding': None, + "input_node_embedding": {"input_dim": 95, "output_dim": 64}, + "input_edge_embedding": {"input_dim": 100, "output_dim": 64}, + "make_distance": True, "expand_distance": True, + 'gauss_args': {"bins": 25, "distance": 5, "offset": 0.0, "sigma": 0.4}, + 'meg_block_args': {'node_embed': [64, 32, 32], 'edge_embed': [64, 32, 32], + 'env_embed': [64, 32, 32], 'activation': 'kgcnn>softplus2'}, + 'set2set_args': {'channels': 16, 'T': 3, "pooling_method": "sum", "init_qstar": "0"}, + 'node_ff_args': {"units": [64, 32], "activation": "kgcnn>softplus2"}, + 'edge_ff_args': {"units": [64, 32], "activation": "kgcnn>softplus2"}, + 'state_ff_args': {"units": [64, 32], "activation": "kgcnn>softplus2"}, + 'nblocks': 3, 'has_ff': True, 'dropout': None, 'use_set2set': True, + 'verbose': 10, + 'output_embedding': 'graph', + 'output_mlp': {"use_bias": [True, True, True], "units": [32, 16, 1], + "activation": ['kgcnn>softplus2', 'kgcnn>softplus2', 'linear']} + } + }, + "training": { + "cross_validation": {"class_name": "KFold", + "config": {"n_splits": 5, "random_state": 42, "shuffle": True}}, + "fit": { + "batch_size": 32, "epochs": 1000, "validation_freq": 10, "verbose": 2, + "callbacks": [ + {"class_name": "kgcnn>LinearLearningRateScheduler", "config": { + "learning_rate_start": 0.0005, "learning_rate_stop": 0.5e-05, "epo_min": 100, "epo": 1000, + "verbose": 0} + } + ] + }, + "compile": { + "optimizer": {"class_name": "Adam", "config": {"learning_rate": 0.0005}}, + "loss": "mean_absolute_error" + }, + "scaler": { + "class_name": "StandardLabelScaler", + "module_name": "kgcnn.data.transform.scaler.standard", + "config": {"with_std": True, "with_mean": True, "copy": True} + }, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "MatProjectJdft2dDataset", + "module_name": "kgcnn.data.datasets.MatProjectJdft2dDataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_range_periodic", "max_distance": 5.0}} + ] + }, + "data_unit": "meV/atom" + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" + } + }, + "DimeNetPP.make_crystal_model": { + "model": { + "class_name": "make_crystal_model", + "module_name": "kgcnn.literature.DimeNetPP", + "config": { + "name": "DimeNetPP", + "inputs": [ + {"shape": [None], "name": "node_number", "dtype": "int64", "ragged": True}, + {"shape": [None, 3], "name": "node_coordinates", "dtype": "float32", "ragged": True}, + {"shape": [None, 2], "name": "range_indices", "dtype": "int64", "ragged": True}, + {"shape": [None, 2], "name": "angle_indices", "dtype": "int64", "ragged": True}, + {'shape': (None, 3), 'name': "range_image", 'dtype': 'int64', 'ragged': True}, + {'shape': (3, 3), 'name': "graph_lattice", 'dtype': 'float32', 'ragged': False} + ], + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 95, "output_dim": 128, + "embeddings_initializer": {"class_name": "RandomUniform", + "config": {"minval": -1.7320508075688772, + "maxval": 1.7320508075688772}}}, + "emb_size": 128, "out_emb_size": 256, "int_emb_size": 64, "basis_emb_size": 8, + "num_blocks": 4, "num_spherical": 7, "num_radial": 6, + "cutoff": 5.0, "envelope_exponent": 5, + "num_before_skip": 1, "num_after_skip": 2, "num_dense_output": 3, + "num_targets": 1, "extensive": False, "output_init": "zeros", + "activation": "swish", "verbose": 10, + "output_embedding": "graph", + "use_output_mlp": False, + "output_mlp": {}, + } + }, + "training": { + "cross_validation": {"class_name": "KFold", + "config": {"n_splits": 5, "random_state": 42, "shuffle": True}}, + "fit": { + "batch_size": 16, "epochs": 780, "validation_freq": 10, "verbose": 2, "callbacks": [], + "validation_batch_size": 8 + }, + "compile": { + "optimizer": { + "class_name": "Adam", + "config": { + "learning_rate": { + "class_name": "kgcnn>LinearWarmupExponentialDecay", "config": { + "learning_rate": 0.001, "warmup_steps": 3000.0, "decay_steps": 4000000.0, + "decay_rate": 0.01 + } + }, + "use_ema": True, + "amsgrad": True, + } + }, + "loss": "mean_absolute_error" + }, + "scaler": { + "class_name": "StandardLabelScaler", + "module_name": "kgcnn.data.transform.scaler.standard", + "config": {"with_std": True, "with_mean": True, "copy": True} + }, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "MatProjectJdft2dDataset", + "module_name": "kgcnn.data.datasets.MatProjectJdft2dDataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_range_periodic", "max_distance": 5.0, "max_neighbours": 17}}, + {"map_list": {"method": "set_angle", "allow_multi_edges": True, "allow_reverse_edges": True}} + ] + }, + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" + } + }, + "NMPN.make_crystal_model": { + "model": { + "class_name": "make_crystal_model", + "module_name": "kgcnn.literature.NMPN", + "config": { + "name": "NMPN", + "inputs": [ + {"shape": [None], "name": "node_number", "dtype": "int64", "ragged": True}, + {"shape": [None, 3], "name": "node_coordinates", "dtype": "float32", "ragged": True}, + {"shape": [None, 2], "name": "range_indices", "dtype": "int64", "ragged": True}, + {'shape': (None, 3), 'name': "range_image", 'dtype': 'int64', 'ragged': True}, + {'shape': (3, 3), 'name': "graph_lattice", 'dtype': 'float32', 'ragged': False} + ], + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 95, "output_dim": 64}, + "input_edge_embedding": {"input_dim": 5, "output_dim": 64}, + "set2set_args": {"channels": 32, "T": 3, "pooling_method": "sum", "init_qstar": "0"}, + "pooling_args": {"pooling_method": "segment_mean"}, + "use_set2set": True, + "depth": 3, + "node_dim": 128, + "verbose": 10, + "geometric_edge": True, "make_distance": True, "expand_distance": True, + "output_embedding": "graph", + "output_mlp": {"use_bias": [True, True, False], "units": [25, 25, 1], + "activation": ["selu", "selu", "linear"]}, + } + }, + "training": { + "cross_validation": {"class_name": "KFold", + "config": {"n_splits": 5, "random_state": 42, "shuffle": True}}, + "fit": { + "batch_size": 16, "epochs": 700, "validation_freq": 10, "verbose": 2, + "callbacks": [ + {"class_name": "kgcnn>LinearLearningRateScheduler", "config": { + "learning_rate_start": 1e-04, "learning_rate_stop": 1e-05, "epo_min": 50, "epo": 700, + "verbose": 0 + } + } + ] + }, + "compile": { + "optimizer": {"class_name": "Adam", "config": {"learning_rate": 1e-04}}, + "loss": "mean_absolute_error" + }, + "scaler": { + "class_name": "StandardLabelScaler", + "module_name": "kgcnn.data.transform.scaler.standard", + "config": {"with_std": True, "with_mean": True, "copy": True} + }, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "MatProjectJdft2dDataset", + "module_name": "kgcnn.data.datasets.MatProjectJdft2dDataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_range_periodic", "max_distance": 5.0}} + ] + }, + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" + } + }, } \ No newline at end of file diff --git a/training/hyper/hyper_qm7.py b/training/hyper/hyper_qm7.py index 7c5558ff..5c113c9b 100644 --- a/training/hyper/hyper_qm7.py +++ b/training/hyper/hyper_qm7.py @@ -69,6 +69,146 @@ "kgcnn_version": "4.0.0" } }, + "Megnet": { + "model": { + "class_name": "make_model", + "module_name": "kgcnn.literature.Megnet", + "config": { + "name": "Megnet", + "inputs": [ + {"shape": [None], "name": "node_number", "dtype": "int64", "ragged": True}, + {"shape": [None, 3], "name": "node_coordinates", "dtype": "float32", "ragged": True}, + {"shape": [None, 2], "name": "range_indices", "dtype": "int64", "ragged": True}, + {"shape": [2], "name": "graph_attributes", "dtype": "float32", "ragged": False} + ], + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 10, "output_dim": 16}, + "input_graph_embedding": {"input_dim": 100, "output_dim": 64}, + "gauss_args": {"bins": 20, "distance": 4, "offset": 0.0, "sigma": 0.4}, + "meg_block_args": {"node_embed": [64, 32, 32], "edge_embed": [64, 32, 32], + "env_embed": [64, 32, 32], "activation": "kgcnn>softplus2"}, + "set2set_args": {"channels": 16, "T": 3, "pooling_method": "sum", "init_qstar": "0"}, + "node_ff_args": {"units": [64, 32], "activation": "kgcnn>softplus2"}, + "edge_ff_args": {"units": [64, 32], "activation": "kgcnn>softplus2"}, + "state_ff_args": {"units": [64, 32], "activation": "kgcnn>softplus2"}, + "nblocks": 3, "has_ff": True, "dropout": None, "use_set2set": True, + "verbose": 10, + "output_embedding": "graph", + "output_mlp": {"use_bias": [True, True, True], "units": [32, 16, 1], + "activation": ["kgcnn>softplus2", "kgcnn>softplus2", "linear"]}, + } + }, + "training": { + "cross_validation": None, + "fit": { + "batch_size": 32, "epochs": 800, "validation_freq": 10, "verbose": 2, + "callbacks": [ + {"class_name": "kgcnn>LinearLearningRateScheduler", "config": { + "learning_rate_start": 0.0005, "learning_rate_stop": 1e-05, "epo_min": 100, "epo": 800, + "verbose": 0 + } + } + ] + }, + "compile": { + "optimizer": {"class_name": "Adam", "config": {"learning_rate": 0.0005}}, + "loss": "mean_absolute_error", + # "metrics": [{"class_name": "Addons>RSquare", "config": {"dtype": "float32", "y_shape": (1,)}}] + }, + "scaler": {"class_name": "QMGraphLabelScaler", "config": { + "atomic_number": "node_number", + "scaler": [{"class_name": "StandardLabelScaler", + "config": {"with_std": True, "with_mean": True, "copy": True}} + ] + }}, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "QM7Dataset", + "module_name": "kgcnn.data.datasets.QM7Dataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_range", "max_distance": 4, "max_neighbours": 30}} + ] + }, + "data_unit": "kcal/mol" + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" + } + }, + "NMPN": { + "model": { + "class_name": "make_model", + "module_name": "kgcnn.literature.NMPN", + "config": { + "name": "NMPN", + "inputs": [ + {"shape": [None], "name": "node_number", "dtype": "int64", "ragged": True}, + {"shape": [None, 3], "name": "node_coordinates", "dtype": "float32", "ragged": True}, + {"shape": [None, 2], "name": "edge_indices", "dtype": "int64", "ragged": True} + ], + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 95, "output_dim": 64}, + "input_edge_embedding": {"input_dim": 5, "output_dim": 64}, + "set2set_args": {"channels": 32, "T": 3, "pooling_method": "sum", "init_qstar": "0"}, + "pooling_args": {"pooling_method": "scatter_sum"}, + "use_set2set": True, + "depth": 3, + "node_dim": 128, + "verbose": 10, + "geometric_edge": True, "make_distance": True, "expand_distance": True, + "output_embedding": "graph", + "output_mlp": {"use_bias": [True, True, False], "units": [25, 25, 1], + "activation": ["selu", "selu", "linear"]}, + } + }, + "training": { + "cross_validation": None, + "fit": { + "batch_size": 32, "epochs": 500, "validation_freq": 10, "verbose": 2, + "callbacks": [ + {"class_name": "kgcnn>LinearLearningRateScheduler", "config": { + "learning_rate_start": 0.0005, "learning_rate_stop": 1e-05, "epo_min": 50, "epo": 500, + "verbose": 0 + } + } + ] + }, + "compile": { + "optimizer": {"class_name": "Adam", "config": {"learning_rate": 0.0005}}, + "loss": "mean_absolute_error" + }, + "scaler": {"class_name": "QMGraphLabelScaler", "config": { + "atomic_number": "node_number", + "scaler": [{"class_name": "StandardLabelScaler", + "config": {"with_std": True, "with_mean": True, "copy": True}} + ] + }}, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "QM7Dataset", + "module_name": "kgcnn.data.datasets.QM7Dataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_range", "max_distance": 4, "max_neighbours": 30}} + ] + }, + "data_unit": "kcal/mol" + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" + } + }, "PAiNN": { "model": { "class_name": "make_model", @@ -80,7 +220,9 @@ {"shape": [None, 3], "name": "node_coordinates", "dtype": "float32", "ragged": True}, {"shape": [None, 2], "name": "range_indices", "dtype": "int64", "ragged": True} ], - "input_embedding": {"node": {"input_dim": 95, "output_dim": 128}}, + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 95, "output_dim": 128}, "equiv_initialize_kwargs": {"dim": 3, "method": "eps"}, "bessel_basis": {"num_radial": 20, "cutoff": 5.0, "envelope_exponent": 5}, "pooling_args": {"pooling_method": "sum"}, "conv_args": {"units": 128, "cutoff": None}, @@ -96,24 +238,20 @@ }, "compile": { "optimizer": { - "class_name": "Addons>MovingAverage", "config": { - "optimizer": { - "class_name": "Adam", "config": { - "learning_rate": { - "class_name": "kgcnn>LinearWarmupExponentialDecay", "config": { - "learning_rate": 0.001, "warmup_steps": 150.0, "decay_steps": 200000.0, - "decay_rate": 0.01 - } - }, "amsgrad": True + "class_name": "Adam", "config": { + "learning_rate": { + "class_name": "kgcnn>LinearWarmupExponentialDecay", "config": { + "learning_rate": 0.001, "warmup_steps": 150.0, "decay_steps": 200000.0, + "decay_rate": 0.01 } - }, - "average_decay": 0.999 + }, "amsgrad": True, "use_ema": True } }, "loss": "mean_absolute_error" }, "scaler": {"class_name": "QMGraphLabelScaler", "config": { - "scaler": [{"class_name": "StandardScaler", + "atomic_number": "node_number", + "scaler": [{"class_name": "StandardLabelScaler", "config": {"with_std": True, "with_mean": True, "copy": True}} ] }}, @@ -133,7 +271,245 @@ "info": { "postfix": "", "postfix_file": "", - "kgcnn_version": "2.1.1" + "kgcnn_version": "4.0.0" + } + }, + "DimeNetPP": { + "model": { + "class_name": "make_model", + "module_name": "kgcnn.literature.DimeNetPP", + "config": { + "name": "DimeNetPP", + "inputs": [ + {"shape": [None], "name": "node_number", "dtype": "int64", "ragged": True}, + {"shape": [None, 3], "name": "node_coordinates", "dtype": "float32", "ragged": True}, + {"shape": [None, 2], "name": "range_indices", "dtype": "int64", "ragged": True}, + {"shape": [None, 2], "name": "angle_indices", "dtype": "int64", "ragged": True} + ], + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 95, "output_dim": 128, + "embeddings_initializer": {"class_name": "RandomUniform", + "config": {"minval": -1.7320508075688772, + "maxval": 1.7320508075688772}}}, + "emb_size": 128, "out_emb_size": 256, "int_emb_size": 64, "basis_emb_size": 8, + "num_blocks": 4, "num_spherical": 7, "num_radial": 6, + "cutoff": 5.0, "envelope_exponent": 5, + "num_before_skip": 1, "num_after_skip": 2, "num_dense_output": 3, + "num_targets": 1, "extensive": False, "output_init": "zeros", + "activation": "swish", "verbose": 10, + "output_embedding": "graph", + "use_output_mlp": False, + "output_mlp": {}, + } + }, + "training": { + "cross_validation": None, + "fit": { + "batch_size": 10, "epochs": 872, "validation_freq": 10, "verbose": 2, "callbacks": [] + }, + "compile": { + "optimizer": { + "class_name": "Adam", + "config": { + "learning_rate": { + "class_name": "kgcnn>LinearWarmupExponentialDecay", "config": { + "learning_rate": 0.001, "warmup_steps": 150.0, "decay_steps": 200000.0, + "decay_rate": 0.01 + } + }, + "use_ema": True, + "amsgrad": True, + } + }, + "loss": "mean_absolute_error" + }, + "scaler": {"class_name": "QMGraphLabelScaler", "config": { + "atomic_number": "node_number", + "scaler": [{"class_name": "StandardLabelScaler", + "config": {"with_std": True, "with_mean": True, "copy": True}} + ] + }}, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "QM7Dataset", + "module_name": "kgcnn.data.datasets.QM7Dataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_range", "max_distance": 5, "max_neighbours": 1000}}, + {"map_list": {"method": "set_angle"}} + ] + }, + "data_unit": "kcal/mol" + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" + } + }, + "MXMNet": { + "model": { + "class_name": "make_model", + "module_name": "kgcnn.literature.MXMNet", + "config": { + "name": "MXMNet", + "inputs": [ + {"shape": (None,), "name": "node_number", "dtype": "int64", "ragged": True}, + {"shape": (None, 3), "name": "node_coordinates", "dtype": "float32", "ragged": True}, + {"shape": (None, 1), "name": "edge_weights", "dtype": "float32", "ragged": True}, + {"shape": (None, 2), "name": "edge_indices", "dtype": "int64", "ragged": True}, + {"shape": (None, 2), "name": "range_indices", "dtype": "int64", "ragged": True}, + {"shape": [None, 2], "name": "angle_indices_1", "dtype": "int64", "ragged": True}, + {"shape": [None, 2], "name": "angle_indices_2", "dtype": "int64", "ragged": True}, + ], + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 95, "output_dim": 32}, + "input_edge_embedding": {"input_dim": 5, "output_dim": 32}, + "bessel_basis_local": {"num_radial": 16, "cutoff": 5.0, "envelope_exponent": 5}, + "bessel_basis_global": {"num_radial": 16, "cutoff": 5.0, "envelope_exponent": 5}, + "spherical_basis_local": {"num_spherical": 7, "num_radial": 6, "cutoff": 5.0, "envelope_exponent": 5}, + "mlp_rbf_kwargs": {"units": 32, "activation": "swish"}, + "mlp_sbf_kwargs": {"units": 32, "activation": "swish"}, + "global_mp_kwargs": {"units": 32}, + "local_mp_kwargs": {"units": 32, "output_units": 1, + "output_kernel_initializer": "glorot_uniform"}, + "use_edge_attributes": False, + "depth": 4, + "verbose": 10, + "node_pooling_args": {"pooling_method": "sum"}, + "output_embedding": "graph", "output_to_tensor": True, + "use_output_mlp": False, + "output_mlp": {"use_bias": [True], "units": [1], + "activation": ["linear"]} + } + }, + "training": { + "cross_validation": None, + "fit": { + "batch_size": 128, "epochs": 900, "validation_freq": 10, "verbose": 2, + "callbacks": [ + {"class_name": "kgcnn>LinearWarmupExponentialLRScheduler", "config": { + "lr_start": 1e-03, "gamma": 0.9961697, "epo_warmup": 1, "verbose": 1, "steps_per_epoch": 45}} + ] + }, + "compile": { + "optimizer": {"class_name": "Adam", "config": {"learning_rate": 1e-03, "global_clipnorm": 1000}}, + "loss": "mean_absolute_error", + "metrics": [ + "mean_absolute_error", "mean_squared_error", + # No scaling needed. + {"class_name": "RootMeanSquaredError", "config": {"name": "scaled_root_mean_squared_error"}}, + {"class_name": "MeanAbsoluteError", "config": {"name": "scaled_mean_absolute_error"}}, + ] + }, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "QM7Dataset", + "module_name": "kgcnn.data.datasets.QM7Dataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_edge_weights_uniform"}}, + {"map_list": {"method": "set_range", "max_distance": 5, "max_neighbours": 1000}}, + {"map_list": {"method": "set_angle", "range_indices": "edge_indices", "edge_pairing": "jk", + "angle_indices": "angle_indices_1", + "angle_indices_nodes": "angle_indices_nodes_1", + "angle_attributes": "angle_attributes_1"}}, + {"map_list": {"method": "set_angle", "range_indices": "edge_indices", "edge_pairing": "ik", + "allow_self_edges": True, + "angle_indices": "angle_indices_2", + "angle_indices_nodes": "angle_indices_nodes_2", + "angle_attributes": "angle_attributes_2"}} + ] + }, + "data_unit": "kcal/mol" + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" + } + }, + "EGNN": { + "model": { + "class_name": "make_model", + "module_name": "kgcnn.literature.EGNN", + "config": { + "name": "EGNN", + "inputs": [ + {"shape": (None,), "name": "node_number", "dtype": "int64", "ragged": True}, + {"shape": (None, 3), "name": "node_coordinates", "dtype": "float32", "ragged": True}, + {"shape": (None,), "name": "edge_number", "dtype": "int64", "ragged": True}, + {"shape": (None, 2), "name": "edge_indices", "dtype": "int64", "ragged": True}, + ], + "input_tensor_type": "ragged", + "input_embedding": None, + "input_node_embedding": {"input_dim": 95, "output_dim": 64}, + "input_edge_embedding": {"input_dim": 95, "output_dim": 64}, + "depth": 4, + "node_mlp_initialize": None, + "use_edge_attributes": True, + "edge_mlp_kwargs": {"units": [64, 64], "activation": ["swish", "linear"]}, + "edge_attention_kwargs": None, # {"units: 1", "activation": "sigmoid"} + "use_normalized_difference": False, + "expand_distance_kwargs": None, + "coord_mlp_kwargs": {"units": [64, 1], "activation": ["swish", "linear"]}, # option: "tanh" at the end. + "pooling_coord_kwargs": {"pooling_method": "mean"}, + "pooling_edge_kwargs": {"pooling_method": "sum"}, + "node_normalize_kwargs": None, + "node_mlp_kwargs": {"units": [64, 64], "activation": ["swish", "linear"]}, + "use_skip": True, + "verbose": 10, + "node_pooling_kwargs": {"pooling_method": "sum"}, + "output_embedding": "graph", + "output_to_tensor": True, + "output_mlp": {"use_bias": [True, True], "units": [64, 1], + "activation": ["swish", "linear"]} + } + }, + "training": { + "cross_validation": None, + "fit": { + "batch_size": 64, "epochs": 800, "validation_freq": 10, "verbose": 2, + "callbacks": [ + {"class_name": "kgcnn>LinearLearningRateScheduler", "config": { + "learning_rate_start": 5e-04, "learning_rate_stop": 1e-05, "epo_min": 100, "epo": 800, + "verbose": 0} + } + ] + }, + "compile": { + "optimizer": {"class_name": "Adam", "config": {"learning_rate": 5e-04}}, + "loss": "mean_absolute_error" + }, + "scaler": {"class_name": "QMGraphLabelScaler", "config": { + "atomic_number": "node_number", + "scaler": [{"class_name": "StandardLabelScaler", + "config": {"with_std": True, "with_mean": True, "copy": True}} + ] + }}, + "multi_target_indices": None + }, + "data": { + "dataset": { + "class_name": "QM7Dataset", + "module_name": "kgcnn.data.datasets.QM7Dataset", + "config": {}, + "methods": [ + {"map_list": {"method": "set_range", "max_distance": 4, "max_neighbours": 10000}} + ] + }, + "data_unit": "kcal/mol" + }, + "info": { + "postfix": "", + "postfix_file": "", + "kgcnn_version": "4.0.0" } }, -} +} \ No newline at end of file diff --git a/training/results/ESOLDataset/rGIN/rGIN_ESOLDataset_score.yaml b/training/results/ESOLDataset/rGIN/rGIN_ESOLDataset_score.yaml new file mode 100644 index 00000000..db48208e --- /dev/null +++ b/training/results/ESOLDataset/rGIN/rGIN_ESOLDataset_score.yaml @@ -0,0 +1,137 @@ +OS: posix_linux +backend: tensorflow +cuda_available: 'True' +data_unit: mol/L +date_time: '2023-12-12 18:35:09' +device_id: '[LogicalDevice(name=''/device:CPU:0'', device_type=''CPU''), LogicalDevice(name=''/device:GPU:0'', + device_type=''GPU'')]' +device_memory: '[]' +device_name: '[{}, {''compute_capability'': (7, 0), ''device_name'': ''Tesla V100-SXM2-32GB''}]' +epochs: +- 300 +- 300 +- 300 +- 300 +- 300 +execute_folds: null +kgcnn_version: 4.0.0 +loss: +- 0.06891623139381409 +- 0.08703047782182693 +- 0.07188896834850311 +- 0.086659736931324 +- 0.07865843176841736 +max_loss: +- 0.6902263164520264 +- 1.2159408330917358 +- 1.223171353340149 +- 1.017735242843628 +- 1.100204586982727 +max_scaled_mean_absolute_error: +- 1.4458162784576416 +- 2.613835573196411 +- 2.610182285308838 +- 2.134319543838501 +- 2.3372929096221924 +max_scaled_root_mean_squared_error: +- 1.854567289352417 +- 3.6885979175567627 +- 4.057342529296875 +- 2.862278938293457 +- 3.4802727699279785 +max_val_loss: +- 0.5959348082542419 +- 0.6211386322975159 +- 0.7748539447784424 +- 0.63406902551651 +- 0.6914217472076416 +max_val_scaled_mean_absolute_error: +- 1.2987128496170044 +- 1.274141550064087 +- 1.7961366176605225 +- 1.3855613470077515 +- 1.641784906387329 +max_val_scaled_root_mean_squared_error: +- 1.5767138004302979 +- 1.5299566984176636 +- 2.204049825668335 +- 1.7289438247680664 +- 2.091233015060425 +min_loss: +- 0.06447353214025497 +- 0.07674770057201385 +- 0.06476769596338272 +- 0.08389663696289062 +- 0.076246477663517 +min_scaled_mean_absolute_error: +- 0.13657978177070618 +- 0.16468554735183716 +- 0.13808824121952057 +- 0.17485226690769196 +- 0.16056039929389954 +min_scaled_root_mean_squared_error: +- 0.2653881311416626 +- 0.29289868474006653 +- 0.2553676664829254 +- 0.32293936610221863 +- 0.29353877902030945 +min_val_loss: +- 0.2188309282064438 +- 0.20521749556064606 +- 0.21844886243343353 +- 0.20826256275177002 +- 0.2942042350769043 +min_val_scaled_mean_absolute_error: +- 0.48806631565093994 +- 0.4528730511665344 +- 0.5052175521850586 +- 0.4887813925743103 +- 0.5430429577827454 +min_val_scaled_root_mean_squared_error: +- 0.6954429745674133 +- 0.6553791165351868 +- 0.6827008128166199 +- 0.6831845045089722 +- 0.7266396284103394 +model_class: make_model +model_name: rGIN +model_version: '2023-10-12' +multi_target_indices: null +number_histories: 5 +scaled_mean_absolute_error: +- 0.1457095593214035 +- 0.18562214076519012 +- 0.1532096564769745 +- 0.18182307481765747 +- 0.16873066127300262 +scaled_root_mean_squared_error: +- 0.2827938497066498 +- 0.3874676823616028 +- 0.2984892725944519 +- 0.3426379859447479 +- 0.3297834098339081 +seed: 42 +time_list: +- '0:04:57.678327' +- '0:04:54.108201' +- '0:04:54.943137' +- '0:04:52.761328' +- '0:04:51.582109' +val_loss: +- 0.24066579341888428 +- 0.21967864036560059 +- 0.2276894450187683 +- 0.22162340581417084 +- 0.3200714588165283 +val_scaled_mean_absolute_error: +- 0.5116941928863525 +- 0.47883230447769165 +- 0.5264890789985657 +- 0.4987364113330841 +- 0.5824056267738342 +val_scaled_root_mean_squared_error: +- 0.7174263596534729 +- 0.6942570805549622 +- 0.7032650113105774 +- 0.692295253276825 +- 0.7636691331863403 diff --git a/training/results/ESOLDataset/rGIN/rGIN_hyper.json b/training/results/ESOLDataset/rGIN/rGIN_hyper.json new file mode 100644 index 00000000..acb8d4ae --- /dev/null +++ b/training/results/ESOLDataset/rGIN/rGIN_hyper.json @@ -0,0 +1 @@ +{"model": {"class_name": "make_model", "module_name": "kgcnn.literature.rGIN", "config": {"name": "rGIN", "inputs": [{"shape": [null, 41], "name": "node_attributes", "dtype": "float32"}, {"shape": [null, 2], "name": "edge_indices", "dtype": "int64"}, {"shape": [], "name": "total_nodes", "dtype": "int64"}, {"shape": [], "name": "total_edges", "dtype": "int64"}], "input_tensor_type": "padded", "input_embedding": null, "input_node_embedding": {"input_dim": 96, "output_dim": 95}, "depth": 5, "dropout": 0.05, "gin_mlp": {"units": [64, 64], "use_bias": true, "activation": ["relu", "linear"], "use_normalization": true, "normalization_technique": "graph"}, "rgin_args": {"random_range": 100}, "last_mlp": {"use_bias": true, "units": [64, 32, 1], "activation": ["relu", "relu", "linear"]}, "output_embedding": "graph", "output_mlp": {"activation": "linear", "units": 1}}}, "training": {"fit": {"batch_size": 32, "epochs": 300, "validation_freq": 1, "verbose": 2, "callbacks": []}, "compile": {"optimizer": {"class_name": "Adam", "config": {"learning_rate": {"module": "keras.optimizers.schedules", "class_name": "ExponentialDecay", "config": {"initial_learning_rate": 0.001, "decay_steps": 1600, "decay_rate": 0.5, "staircase": false}}}}, "loss": "mean_absolute_error"}, "cross_validation": {"class_name": "KFold", "config": {"n_splits": 5, "random_state": 42, "shuffle": true}}, "scaler": {"class_name": "StandardLabelScaler", "config": {"with_std": true, "with_mean": true, "copy": true}}}, "data": {"data_unit": "mol/L"}, "info": {"postfix": "", "postfix_file": "", "kgcnn_version": "4.0.0"}, "dataset": {"class_name": "ESOLDataset", "module_name": "kgcnn.data.datasets.ESOLDataset", "config": {}, "methods": [{"set_attributes": {}}, {"map_list": {"method": "count_nodes_and_edges"}}]}} \ No newline at end of file diff --git a/training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_FreeSolvDataset_score.yaml b/training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_FreeSolvDataset_score.yaml new file mode 100644 index 00000000..c8d67786 --- /dev/null +++ b/training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_FreeSolvDataset_score.yaml @@ -0,0 +1,137 @@ +OS: posix_linux +backend: tensorflow +cuda_available: 'True' +data_unit: mol/L +date_time: '2023-12-12 18:53:46' +device_id: '[LogicalDevice(name=''/device:CPU:0'', device_type=''CPU''), LogicalDevice(name=''/device:GPU:0'', + device_type=''GPU'')]' +device_memory: '[]' +device_name: '[{}, {''compute_capability'': (7, 0), ''device_name'': ''Tesla V100-SXM2-32GB''}]' +epochs: +- 872 +- 872 +- 872 +- 872 +- 872 +execute_folds: null +kgcnn_version: 4.0.0 +loss: +- 0.001331917941570282 +- 0.0011453432962298393 +- 0.0009194796439260244 +- 0.0008912073099054396 +- 0.0009718958754092455 +max_loss: +- 0.6555431485176086 +- 0.6481980681419373 +- 0.6911538243293762 +- 0.6752273440361023 +- 0.6471794247627258 +max_scaled_mean_absolute_error: +- 2.484971523284912 +- 2.540062427520752 +- 2.7164807319641113 +- 2.5817506313323975 +- 2.4705941677093506 +max_scaled_root_mean_squared_error: +- 3.451993942260742 +- 3.431015729904175 +- 3.62593412399292 +- 3.476752519607544 +- 3.2993834018707275 +max_val_loss: +- 0.289265900850296 +- 0.34285831451416016 +- 0.25503766536712646 +- 0.23428811132907867 +- 0.3620230555534363 +max_val_scaled_mean_absolute_error: +- 1.1023350954055786 +- 1.3426930904388428 +- 1.0204569101333618 +- 0.9060389399528503 +- 1.367928385734558 +max_val_scaled_root_mean_squared_error: +- 1.538962483406067 +- 1.9180909395217896 +- 1.324093222618103 +- 1.324705719947815 +- 1.9752460718154907 +min_loss: +- 0.000914640782866627 +- 0.0009519258164800704 +- 0.0009070526575669646 +- 0.0008212162065319717 +- 0.0008074666257016361 +min_scaled_mean_absolute_error: +- 0.003475399687886238 +- 0.0037277652882039547 +- 0.0035875660832971334 +- 0.0031720902770757675 +- 0.0030714119784533978 +min_scaled_root_mean_squared_error: +- 0.005956957116723061 +- 0.005531820934265852 +- 0.005346158519387245 +- 0.004751825239509344 +- 0.004536818712949753 +min_val_loss: +- 0.15473777055740356 +- 0.15225329995155334 +- 0.1186520978808403 +- 0.16552594304084778 +- 0.17181915044784546 +min_val_scaled_mean_absolute_error: +- 0.5871344804763794 +- 0.6022188663482666 +- 0.46851953864097595 +- 0.6342915892601013 +- 0.661505937576294 +min_val_scaled_root_mean_squared_error: +- 0.8899828791618347 +- 0.9912939071655273 +- 0.7117149829864502 +- 1.0383665561676025 +- 1.158407211303711 +model_class: make_model +model_name: DimeNetPP +model_version: '2023-12-04' +multi_target_indices: null +number_histories: 5 +scaled_mean_absolute_error: +- 0.005060957279056311 +- 0.004507708828896284 +- 0.003644420998170972 +- 0.00345625844784081 +- 0.0037164902314543724 +scaled_root_mean_squared_error: +- 0.007279715500771999 +- 0.0066460855305194855 +- 0.005390545353293419 +- 0.005128670483827591 +- 0.005642118398100138 +seed: 42 +time_list: +- '0:35:10.059750' +- '0:35:44.514729' +- '0:34:31.564701' +- '0:35:38.367265' +- '0:35:08.769118' +val_loss: +- 0.16997817158699036 +- 0.16003873944282532 +- 0.1205698549747467 +- 0.1710919737815857 +- 0.17615197598934174 +val_scaled_mean_absolute_error: +- 0.6491948962211609 +- 0.6259752511978149 +- 0.47717341780662537 +- 0.6501429677009583 +- 0.6810979247093201 +val_scaled_root_mean_squared_error: +- 0.9722352027893066 +- 1.0427885055541992 +- 0.7481921911239624 +- 1.1206653118133545 +- 1.2673488855361938 diff --git a/training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_hyper.json b/training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_hyper.json new file mode 100644 index 00000000..ac66a3ba --- /dev/null +++ b/training/results/FreeSolvDataset/DimeNetPP/DimeNetPP_hyper.json @@ -0,0 +1 @@ +{"model": {"class_name": "make_model", "module_name": "kgcnn.literature.DimeNetPP", "config": {"name": "DimeNetPP", "inputs": [{"shape": [null], "name": "node_number", "dtype": "int64"}, {"shape": [null, 3], "name": "node_coordinates", "dtype": "float32"}, {"shape": [null, 2], "name": "range_indices", "dtype": "int64"}, {"shape": [null, 2], "name": "angle_indices", "dtype": "int64"}, {"shape": [], "name": "total_nodes", "dtype": "int64"}, {"shape": [], "name": "total_ranges", "dtype": "int64"}, {"shape": [], "name": "total_angles", "dtype": "int64"}], "input_tensor_type": "padded", "input_embedding": null, "cast_disjoint_kwargs": {}, "input_node_embedding": {"input_dim": 95, "output_dim": 128, "embeddings_initializer": {"class_name": "RandomUniform", "config": {"minval": -1.7320508075688772, "maxval": 1.7320508075688772}}}, "emb_size": 128, "out_emb_size": 256, "int_emb_size": 64, "basis_emb_size": 8, "num_blocks": 4, "num_spherical": 7, "num_radial": 6, "cutoff": 5.0, "envelope_exponent": 5, "num_before_skip": 1, "num_after_skip": 2, "num_dense_output": 3, "num_targets": 128, "extensive": false, "output_init": "zeros", "activation": "swish", "verbose": 10, "output_embedding": "graph", "output_mlp": {"use_bias": [true, false], "units": [128, 1], "activation": ["swish", "linear"]}}}, "training": {"fit": {"batch_size": 10, "epochs": 872, "validation_freq": 10, "verbose": 2, "callbacks": []}, "compile": {"optimizer": {"class_name": "Adam", "config": {"learning_rate": {"class_name": "kgcnn>LinearWarmupExponentialDecay", "config": {"learning_rate": 0.001, "warmup_steps": 30.0, "decay_steps": 40000.0, "decay_rate": 0.01}}, "use_ema": true, "amsgrad": true}}, "loss": "mean_absolute_error"}, "cross_validation": {"class_name": "KFold", "config": {"n_splits": 5, "random_state": 42, "shuffle": true}}, "scaler": {"class_name": "StandardLabelScaler", "config": {"with_std": true, "with_mean": true, "copy": true}}}, "data": {"data_unit": "mol/L"}, "dataset": {"class_name": "FreeSolvDataset", "module_name": "kgcnn.data.datasets.FreeSolvDataset", "config": {}, "methods": [{"set_attributes": {}}, {"map_list": {"method": "set_range", "max_distance": 4, "max_neighbours": 20}}, {"map_list": {"method": "set_angle"}}, {"map_list": {"method": "count_nodes_and_edges", "total_edges": "total_ranges", "count_edges": "range_indices"}}, {"map_list": {"method": "count_nodes_and_edges", "total_edges": "total_angles", "count_edges": "angle_indices"}}]}, "info": {"postfix": "", "postfix_file": "", "kgcnn_version": "4.0.0"}} \ No newline at end of file diff --git a/training/results/README.md b/training/results/README.md index c3a54ab8..8c962ae4 100644 --- a/training/results/README.md +++ b/training/results/README.md @@ -56,14 +56,24 @@ ESOL consists of 1128 compounds as smiles and their corresponding water solubili | model | kgcnn | epochs | MAE [log mol/L] | RMSE [log mol/L] | |:------------|:--------|---------:|:-----------------------|:-----------------------| -| AttentiveFP | 4.0.0 | 200 | **0.4351 ± 0.0110** | **0.6080 ± 0.0207** | +| AttentiveFP | 4.0.0 | 200 | 0.4351 ± 0.0110 | 0.6080 ± 0.0207 | +| DGIN | 4.0.0 | 300 | 0.4434 ± 0.0252 | 0.6225 ± 0.0420 | | DMPNN | 4.0.0 | 300 | 0.4401 ± 0.0165 | 0.6203 ± 0.0292 | +| EGNN | 4.0.0 | 800 | 0.4507 ± 0.0152 | 0.6563 ± 0.0370 | | GAT | 4.0.0 | 500 | 0.4818 ± 0.0240 | 0.6919 ± 0.0694 | | GATv2 | 4.0.0 | 500 | 0.4598 ± 0.0234 | 0.6650 ± 0.0409 | | GCN | 4.0.0 | 800 | 0.4613 ± 0.0205 | 0.6534 ± 0.0513 | | GIN | 4.0.0 | 300 | 0.5369 ± 0.0334 | 0.7954 ± 0.0861 | +| GNNFilm | 4.0.0 | 800 | 0.4854 ± 0.0368 | 0.6724 ± 0.0436 | | GraphSAGE | 4.0.0 | 500 | 0.4874 ± 0.0228 | 0.6982 ± 0.0608 | +| INorp | 4.0.0 | 500 | 0.5055 ± 0.0436 | 0.7297 ± 0.0786 | +| MAT | 4.0.0 | 400 | 0.5064 ± 0.0299 | 0.7194 ± 0.0630 | +| MEGAN | 4.0.0 | 400 | **0.4281 ± 0.0201** | **0.6062 ± 0.0252** | +| Megnet | 4.0.0 | 800 | 0.5679 ± 0.0310 | 0.8196 ± 0.0480 | | NMPN | 4.0.0 | 800 | 0.5046 ± 0.0266 | 0.7193 ± 0.0607 | +| PAiNN | 4.0.0 | 250 | 0.4857 ± 0.0598 | 0.6650 ± 0.0674 | +| RGCN | 4.0.0 | 800 | 0.4703 ± 0.0251 | 0.6529 ± 0.0318 | +| rGIN | 4.0.0 | 300 | 0.5196 ± 0.0351 | 0.7142 ± 0.0263 | | Schnet | 4.0.0 | 800 | 0.4777 ± 0.0294 | 0.6977 ± 0.0538 | #### FreeSolvDataset @@ -72,12 +82,27 @@ FreeSolv (MoleculeNet) consists of 642 compounds as smiles and their correspondi | model | kgcnn | epochs | MAE [log mol/L] | RMSE [log mol/L] | |:----------|:--------|---------:|:-----------------------|:-----------------------| -| DMPNN | 4.0.0 | 300 | **0.5487 ± 0.0754** | **0.9206 ± 0.1889** | +| CMPNN | 4.0.0 | 600 | 0.5202 ± 0.0504 | 0.9339 ± 0.1286 | +| DGIN | 4.0.0 | 300 | 0.5489 ± 0.0374 | 0.9448 ± 0.0787 | +| DimeNetPP | 4.0.0 | 872 | 0.6167 ± 0.0719 | 1.0302 ± 0.1717 | +| DMPNN | 4.0.0 | 300 | 0.5487 ± 0.0754 | **0.9206 ± 0.1889** | +| EGNN | 4.0.0 | 800 | 0.5386 ± 0.0548 | 1.0363 ± 0.1237 | | GAT | 4.0.0 | 500 | 0.6051 ± 0.0861 | 1.0326 ± 0.1819 | | GATv2 | 4.0.0 | 500 | 0.6151 ± 0.0247 | 1.0535 ± 0.0817 | | GCN | 4.0.0 | 800 | 0.6400 ± 0.0834 | 1.0876 ± 0.1393 | | GIN | 4.0.0 | 300 | 0.8100 ± 0.1016 | 1.2695 ± 0.1192 | +| GNNFilm | 4.0.0 | 800 | 0.6562 ± 0.0552 | 1.1597 ± 0.1245 | | GraphSAGE | 4.0.0 | 500 | 0.5894 ± 0.0675 | 1.0009 ± 0.1491 | +| HamNet | 4.0.0 | 400 | 0.6619 ± 0.0428 | 1.1410 ± 0.1120 | +| HDNNP2nd | 4.0.0 | 500 | 1.0201 ± 0.1559 | 1.6351 ± 0.3419 | +| INorp | 4.0.0 | 500 | 0.6612 ± 0.0188 | 1.1155 ± 0.1061 | +| MAT | 4.0.0 | 400 | 0.8115 ± 0.0649 | 1.3099 ± 0.1235 | +| MEGAN | 4.0.0 | 400 | 0.6303 ± 0.0550 | 1.0429 ± 0.1031 | +| Megnet | 4.0.0 | 800 | 0.8878 ± 0.0528 | 1.4134 ± 0.1200 | +| MoGAT | 4.0.0 | 200 | 0.7097 ± 0.0374 | 1.0911 ± 0.1334 | +| MXMNet | 4.0.0 | 900 | 1.1386 ± 0.1979 | 3.0487 ± 2.1757 | +| RGCN | 4.0.0 | 800 | **0.5128 ± 0.0810** | 0.9228 ± 0.1887 | +| rGIN | 4.0.0 | 300 | 0.8503 ± 0.0613 | 1.3285 ± 0.0976 | | Schnet | 4.0.0 | 800 | 0.6070 ± 0.0285 | 1.0603 ± 0.0549 | #### ISO17Dataset diff --git a/training/train_graph.py b/training/train_graph.py index 1954c8ff..a4d6180e 100644 --- a/training/train_graph.py +++ b/training/train_graph.py @@ -24,7 +24,7 @@ parser = argparse.ArgumentParser(description='Train a GNN on a graph regression or classification task.') parser.add_argument("--hyper", required=False, help="Filepath to hyperparameter config file (.py or .json).", default="hyper/hyper_freesolv.py") -parser.add_argument("--category", required=False, help="Graph model to train.", default="MAT") +parser.add_argument("--category", required=False, help="Graph model to train.", default="DimeNetPP") parser.add_argument("--model", required=False, help="Graph model to train.", default=None) parser.add_argument("--dataset", required=False, help="Name of the dataset.", default=None) parser.add_argument("--make", required=False, help="Name of the class for model.", default=None)