From 37d4093608005edafac59752d5970e8875c315cd Mon Sep 17 00:00:00 2001 From: omsh Date: Fri, 26 Apr 2024 02:14:30 +0300 Subject: [PATCH] more and more fixes --- Makefile | 2 + docs/codify_package_titles.py | 4 +- docs/conf.py | 3 + docs/dlomix.data.processing.rst | 4 +- docs/dlomix.data.rst | 4 +- docs/dlomix.eval.rst | 4 +- docs/dlomix.layers.rst | 4 +- docs/dlomix.losses.rst | 4 +- docs/dlomix.models.rst | 4 +- docs/dlomix.pipelines.rst | 4 +- docs/dlomix.reports.rst | 4 +- docs/dlomix.rst | 4 +- docs/index.rst | 10 +-- docs/notes/citation.rst | 2 +- src/dlomix/eval/rt_eval.py | 21 +++++- src/dlomix/layers/attention.py | 112 ++++++++++++++++++++++++++++++++ src/dlomix/losses/intensity.py | 10 ++- 17 files changed, 170 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index d6dbe16c..64a20559 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,8 @@ lint: pylint --disable=R,C ./src/dlomix/* build-docs: + sphinx-apidoc -M -f -E -o docs/ src/dlomix/ + python docs/codify_package_titles.py cd docs && make clean html cd docs/_build/html/ && open index.html diff --git a/docs/codify_package_titles.py b/docs/codify_package_titles.py index 64408853..eb1768e0 100644 --- a/docs/codify_package_titles.py +++ b/docs/codify_package_titles.py @@ -9,9 +9,11 @@ def replace_first_line(filename): with open(filename, "r+") as file: lines = file.readlines() first_word = lines[0].split()[0] - lines[0] = f"``{first_word}`` package\n" + lines[0] = f"``{first_word}``\n" + lines[1] = "=" * len(lines[0]) + "\n" file.seek(0) file.writelines(lines) + file.truncate() # Replace the first line for each .rst file diff --git a/docs/conf.py b/docs/conf.py index 541cf74f..deb3fd77 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,6 +14,9 @@ import sys sys.path.insert(0, os.path.abspath("..")) +sys.path.insert(0, os.path.abspath("../src/")) +sys.path.insert(0, os.path.abspath("../src/dlomix/")) + # -- Project information ----------------------------------------------------- diff --git a/docs/dlomix.data.processing.rst b/docs/dlomix.data.processing.rst index 9919455e..c87ce085 100644 --- a/docs/dlomix.data.processing.rst +++ b/docs/dlomix.data.processing.rst @@ -1,5 +1,5 @@ -``dlomix.data.processing`` package -============================== +``dlomix.data.processing`` +=========================== .. automodule:: dlomix.data.processing :members: diff --git a/docs/dlomix.data.rst b/docs/dlomix.data.rst index c979b14f..0461562b 100644 --- a/docs/dlomix.data.rst +++ b/docs/dlomix.data.rst @@ -1,5 +1,5 @@ -``dlomix.data`` package -=================== +``dlomix.data`` +================ .. automodule:: dlomix.data :members: diff --git a/docs/dlomix.eval.rst b/docs/dlomix.eval.rst index 321148de..1d0f7d6a 100644 --- a/docs/dlomix.eval.rst +++ b/docs/dlomix.eval.rst @@ -1,5 +1,5 @@ -``dlomix.eval`` package -=================== +``dlomix.eval`` +================ .. automodule:: dlomix.eval :members: diff --git a/docs/dlomix.layers.rst b/docs/dlomix.layers.rst index 9e2cd518..46900ffb 100644 --- a/docs/dlomix.layers.rst +++ b/docs/dlomix.layers.rst @@ -1,5 +1,5 @@ -``dlomix.layers`` package -===================== +``dlomix.layers`` +================== .. automodule:: dlomix.layers :members: diff --git a/docs/dlomix.losses.rst b/docs/dlomix.losses.rst index bf374d0a..f837328c 100644 --- a/docs/dlomix.losses.rst +++ b/docs/dlomix.losses.rst @@ -1,5 +1,5 @@ -``dlomix.losses`` package -===================== +``dlomix.losses`` +================== .. automodule:: dlomix.losses :members: diff --git a/docs/dlomix.models.rst b/docs/dlomix.models.rst index 24b8cfdd..2ec20d29 100644 --- a/docs/dlomix.models.rst +++ b/docs/dlomix.models.rst @@ -1,5 +1,5 @@ -``dlomix.models`` package -===================== +``dlomix.models`` +================== .. automodule:: dlomix.models :members: diff --git a/docs/dlomix.pipelines.rst b/docs/dlomix.pipelines.rst index 806f3a30..4cba49f3 100644 --- a/docs/dlomix.pipelines.rst +++ b/docs/dlomix.pipelines.rst @@ -1,5 +1,5 @@ -``dlomix.pipelines`` package -======================== +``dlomix.pipelines`` +===================== .. automodule:: dlomix.pipelines :members: diff --git a/docs/dlomix.reports.rst b/docs/dlomix.reports.rst index 07e6ec12..5d97edbd 100644 --- a/docs/dlomix.reports.rst +++ b/docs/dlomix.reports.rst @@ -1,5 +1,5 @@ -``dlomix.reports`` package -====================== +``dlomix.reports`` +=================== .. automodule:: dlomix.reports :members: diff --git a/docs/dlomix.rst b/docs/dlomix.rst index 35cf949e..52c490c4 100644 --- a/docs/dlomix.rst +++ b/docs/dlomix.rst @@ -1,5 +1,5 @@ -``dlomix`` package -============== +``dlomix`` +=========== .. automodule:: dlomix :members: diff --git a/docs/index.rst b/docs/index.rst index 5fe29f56..bb043a04 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -33,24 +33,20 @@ The goal of DLOmix is to be easy to use and flexible, while still providing the .. toctree:: :glob: - :maxdepth: 1 + :reversed: + :maxdepth: 2 :caption: How To - - notes/installation - notes/quickstart -.. notes/citation + notes/* .. toctree:: - :glob: :maxdepth: 2 :caption: Package Reference dlomix - Indices and tables * :ref:`genindex` diff --git a/docs/notes/citation.rst b/docs/notes/citation.rst index 2e1ce681..05ef4431 100644 --- a/docs/notes/citation.rst +++ b/docs/notes/citation.rst @@ -1,4 +1,4 @@ Citation ======== -DLOmix is in its early stages of development. \ No newline at end of file +DLOmix is in its early stages of development. Stay tuned for a publication. diff --git a/src/dlomix/eval/rt_eval.py b/src/dlomix/eval/rt_eval.py index 1aafedf4..c07712c0 100644 --- a/src/dlomix/eval/rt_eval.py +++ b/src/dlomix/eval/rt_eval.py @@ -4,7 +4,8 @@ class TimeDeltaMetric(tf.keras.metrics.Metric): - r"""Implementation of the time delta metric as a Keras Metric. + """ + Implementation of the time delta metric as a Keras Metric. Parameters ---------- @@ -46,6 +47,19 @@ def __init__( self.double_delta = double_delta def update_state(self, y_true, y_pred, sample_weight=None): + """ + Update the metric state. + + Parameters + ---------- + y_true : tf.Tensor + True values of the target. + y_pred : tf.Tensor + Predicted values of the target. + sample_weight : tf.Tensor, optional + Sample weights. Defaults to None. + """ + # rescale if self.rescale_targets: y_true = y_true * self.std + self.mean @@ -91,7 +105,10 @@ def delta95_metric(y_true, y_pred): def TimeDeltaMetric2(): - """95th percentile of absolute error between label and prediction""" + """ + The 95th percentile of absolute error between label and prediction + + """ def calc_metric(y_true, y_pred, sample_weight=None): # compute residuals and sort diff --git a/src/dlomix/layers/attention.py b/src/dlomix/layers/attention.py index 74dc249f..061728d1 100644 --- a/src/dlomix/layers/attention.py +++ b/src/dlomix/layers/attention.py @@ -4,16 +4,46 @@ class DecoderAttentionLayer(tf.keras.layers.Layer): + """ + Decoder attention layer. + + Parameters + ---------- + time_steps : int + Number of time steps in the input data. + """ + def __init__(self, time_steps): super(DecoderAttentionLayer, self).__init__() self.time_steps = time_steps def build(self, input_shape): + """ + Build the layer. + + Parameters + ---------- + input_shape : tuple + Shape of the input tensor. + """ self.permute = tf.keras.layers.Permute((2, 1)) self.dense = tf.keras.layers.Dense(self.time_steps, activation="softmax") self.multiply = tf.keras.layers.Multiply() def call(self, inputs): + """ + Perform the forward pass of the layer. + + Parameters + ---------- + inputs : tensor + Input tensor. + + Returns + ------- + tensor + Output tensor. + """ x = self.permute(inputs) x = self.dense(x) x = self.permute(x) @@ -22,6 +52,29 @@ def call(self, inputs): class AttentionLayer(tf.keras.layers.Layer): + """ + Attention layer. + + Parameters + ---------- + context : bool, optional + Whether to use context or not. Defaults to False. + W_regularizer : str, optional + Regularizer for the weights. Defaults to None. + b_regularizer : str, optional + Regularizer for the bias. Defaults to None. + u_regularizer : str, optional + Regularizer for the context. Defaults to None. + W_constraint : str, optional + Constraint for the weights. Defaults to None. + b_constraint : str, optional + Constraint for the bias. Defaults to None. + u_constraint : str, optional + Constraint for the context. Defaults to None. + bias : bool, optional + Whether to use bias or not. Defaults to True. + """ + def __init__( self, context=False, @@ -47,6 +100,14 @@ def __init__( super(AttentionLayer, self).__init__(**kwargs) def build(self, input_shape): + """ + Build the layer. + + Parameters + ---------- + input_shape : tuple + Shape of the input tensor. + """ assert len(input_shape) == 3 self.W = self.add_weight( shape=(input_shape[-1],), @@ -77,9 +138,39 @@ def build(self, input_shape): self.built = True def compute_mask(self, input, input_mask=None): + """ + Compute the mask for the layer. + + Parameters + ---------- + input : tensor + Input tensor. + input_mask : tensor, optional + Input mask tensor. Defaults to None. + + Returns + ------- + tensor + Mask tensor. + """ return None def call(self, x, mask=None): + """ + Perform the forward pass of the layer. + + Parameters + ---------- + x : tensor + Input tensor. + mask : tensor, optional + Mask tensor. Defaults to None. + + Returns + ------- + tensor + Output tensor. + """ a = K.squeeze(K.dot(x, K.expand_dims(self.W)), axis=-1) if self.bias: a += self.b @@ -95,9 +186,30 @@ def call(self, x, mask=None): return K.sum(weighted_input, axis=1) def compute_output_shape(self, input_shape): + """ + Compute the output shape of the layer. + + Parameters + ---------- + input_shape : tuple + Shape of the input tensor. + + Returns + ------- + tuple + Shape of the output tensor. + """ return input_shape[0], input_shape[-1] def get_config(self): + """ + Get the configuration of the layer. + + Returns + ------- + dict + Configuration dictionary. + """ config = { "bias": self.bias, "context": self.context, diff --git a/src/dlomix/losses/intensity.py b/src/dlomix/losses/intensity.py index 6c9dfb76..8db3a4ee 100644 --- a/src/dlomix/losses/intensity.py +++ b/src/dlomix/losses/intensity.py @@ -4,7 +4,11 @@ def masked_spectral_distance(y_true, y_pred): - """Masked, normalized spectral angles between true and pred vectors + """ + Calculates the masked spectral distance between true and predicted intensity vectors. + The masked spectral distance is a metric for comparing the similarity between two intensity vectors, + + Masked, normalized spectral angles between true and pred vectors > arccos(1*1 + 0*0) = 0 > SL = 0 > high correlation > arccos(0*1 + 1*0) = pi/2 > SL = 1 > low correlation """ @@ -35,21 +39,25 @@ def masked_pearson_correlation_distance(y_true, y_pred): Calculates the masked Pearson correlation distance between true and predicted intensity vectors. The masked Pearson correlation distance is a metric for comparing the similarity between two intensity vectors, taking into account only the non-negative values in the true values tensor (which represent valid peaks). + Parameters: ----------- y_true : tf.Tensor A tensor containing the true values, with shape `(batch_size, num_values)`. y_pred : tf.Tensor A tensor containing the predicted values, with the same shape as `y_true`. + Returns: -------- tf.Tensor A tensor containing the masked Pearson correlation distance between `y_true` and `y_pred`. + Raises: ------- ValueError If `y_true` and `y_pred` have different shapes. """ + epsilon = K.epsilon() # Masking: we multiply values by (true + 1) because then the peaks that cannot