Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix failed docs building, update the docs, and allow tests for CLI to fail #89

Merged
merged 6 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor: rename some internal functions, and rename module.py to `…
…modules.py`;
  • Loading branch information
WenjieDu committed May 5, 2023
commit 9ee11487727911f659e6ae79d9722c516b9d4c2f
56 changes: 56 additions & 0 deletions docs/pypots.cli.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
pypots.cli package
==================

pypots.cli.base module
----------------------

.. automodule:: pypots.cli.base
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

pypots.cli.dev module
---------------------

.. automodule:: pypots.cli.dev
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

pypots.cli.doc module
---------------------

.. automodule:: pypots.cli.doc
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

pypots.cli.env module
---------------------

.. automodule:: pypots.cli.env
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

pypots.cli.pypots\_cli module
-----------------------------

.. automodule:: pypots.cli.pypots_cli
:members:
:undoc-members:
:show-inheritance:
:inherited-members:

Module contents
---------------

.. automodule:: pypots.cli
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
18 changes: 6 additions & 12 deletions pypots/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,22 +54,16 @@ class BaseModel(ABC):

"""

# leverage typing to show type hints in IDEs
# SAVING_STRATEGY = Literal["best", "better"]
SAVING_STRATEGY = [None, "best", "better"]

def __init__(
self,
device: Optional[Union[str, torch.device]] = None,
saving_path: str = None,
model_saving_strategy: Optional[str] = "best",
):

assert model_saving_strategy in [
None,
"best",
"better",
], f"saving_strategy must be one of {self.SAVING_STRATEGY}, but got f{model_saving_strategy}."
saving_strategies = [None, "best", "better"]
assert (
model_saving_strategy in saving_strategies
), f"saving_strategy must be one of {saving_strategies}, but got f{model_saving_strategy}."

self.device = None
self.saving_path = saving_path
Expand Down Expand Up @@ -121,7 +115,7 @@ def __init__(
f"the tensorboard file will be saved to {tb_saving_path}"
)

def save_log_into_tb_file(self, step: int, stage: str, loss_dict: dict) -> None:
def _save_log_into_tb_file(self, step: int, stage: str, loss_dict: dict) -> None:
"""Saving training logs into the tensorboard file specified by the given path `tb_file_saving_path`.

Parameters
Expand Down Expand Up @@ -190,7 +184,7 @@ def save_model(
f'Failed to save the model to "{saving_path}" because of the below error! \n{e}'
)

def auto_save_model_if_necessary(
def _auto_save_model_if_necessary(
self,
training_finished: bool = True,
saving_name: str = None,
Expand Down
6 changes: 3 additions & 3 deletions pypots/classification/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def _train_model(

# save training loss logs into the tensorboard file for every step if in need
if self.summary_writer is not None:
self.save_log_into_tb_file(training_step, "training", results)
self._save_log_into_tb_file(training_step, "training", results)

# mean training loss of the current epoch
mean_train_loss = np.mean(epoch_train_loss_collector)
Expand All @@ -232,7 +232,7 @@ def _train_model(
val_loss_dict = {
"classification_loss": mean_val_loss,
}
self.save_log_into_tb_file(epoch, "validating", val_loss_dict)
self._save_log_into_tb_file(epoch, "validating", val_loss_dict)

logger.info(
f"epoch {epoch}: "
Expand All @@ -249,7 +249,7 @@ def _train_model(
self.best_model_dict = self.model.state_dict()
self.patience = self.original_patience
# save the model if necessary
self.auto_save_model_if_necessary(
self._auto_save_model_if_necessary(
training_finished=False,
saving_name=f"{self.__class__.__name__}_epoch{epoch}_loss{mean_loss}",
)
Expand Down
24 changes: 2 additions & 22 deletions pypots/classification/brits/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,12 @@

from pypots.classification.base import BaseNNClassifier
from pypots.classification.brits.dataset import DatasetForBRITS
from pypots.classification.brits.modules import RITS
from pypots.imputation.brits.model import (
RITS as imputation_RITS,
_BRITS as imputation_BRITS,
)


class RITS(imputation_RITS):
def __init__(
self,
n_steps: int,
n_features: int,
rnn_hidden_size: int,
n_classes: int,
device: Union[str, torch.device],
):
super().__init__(n_steps, n_features, rnn_hidden_size, device)
self.dropout = nn.Dropout(p=0.25)
self.classifier = nn.Linear(self.rnn_hidden_size, n_classes)

def forward(self, inputs: dict, direction: str = "forward") -> dict:
ret_dict = super().forward(inputs, direction)
logits = self.classifier(ret_dict["final_hidden_state"])
ret_dict["prediction"] = torch.softmax(logits, dim=1)
return ret_dict


class _BRITS(imputation_BRITS, nn.Module):
def __init__(
self,
Expand Down Expand Up @@ -361,7 +341,7 @@ def fit(
self.model.eval() # set the model as eval status to freeze it.

# Step 3: save the model if necessary
self.auto_save_model_if_necessary(training_finished=True)
self._auto_save_model_if_necessary(training_finished=True)

def classify(self, X: Union[dict, str], file_type: str = "h5py"):
"""Classify the input data with the trained model.
Expand Down
35 changes: 35 additions & 0 deletions pypots/classification/brits/modules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""
PyTorch BRITS model for both the time-series imputation task and the classification task.
"""

# Created by Wenjie Du <[email protected]>
# License: GPL-v3

from typing import Union

import torch
import torch.nn as nn

from pypots.imputation.brits.model import (
RITS as imputation_RITS,
)


class RITS(imputation_RITS):
def __init__(
self,
n_steps: int,
n_features: int,
rnn_hidden_size: int,
n_classes: int,
device: Union[str, torch.device],
):
super().__init__(n_steps, n_features, rnn_hidden_size, device)
self.dropout = nn.Dropout(p=0.25)
self.classifier = nn.Linear(self.rnn_hidden_size, n_classes)

def forward(self, inputs: dict, direction: str = "forward") -> dict:
ret_dict = super().forward(inputs, direction)
logits = self.classifier(ret_dict["final_hidden_state"])
ret_dict["prediction"] = torch.softmax(logits, dim=1)
return ret_dict
4 changes: 2 additions & 2 deletions pypots/classification/grud/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

from pypots.classification.base import BaseNNClassifier
from pypots.classification.grud.dataset import DatasetForGRUD
from pypots.imputation.brits.module import TemporalDecay
from pypots.imputation.brits.modules import TemporalDecay


class _GRUD(nn.Module):
Expand Down Expand Up @@ -311,7 +311,7 @@ def fit(
self.model.eval() # set the model as eval status to freeze it.

# Step 3: save the model if necessary
self.auto_save_model_if_necessary(training_finished=True)
self._auto_save_model_if_necessary(training_finished=True)

def classify(self, X: Union[dict, str], file_type: str = "h5py") -> np.ndarray:
"""Classify the input data with the trained model.
Expand Down
4 changes: 2 additions & 2 deletions pypots/classification/raindrop/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

from pypots.classification.base import BaseNNClassifier
from pypots.classification.grud.dataset import DatasetForGRUD
from pypots.classification.raindrop.module import (
from pypots.classification.raindrop.modules import (
PositionalEncoding,
ObservationPropagation,
)
Expand Down Expand Up @@ -517,7 +517,7 @@ def fit(
self.model.eval() # set the model as eval status to freeze it.

# Step 3: save the model if necessary
self.auto_save_model_if_necessary(training_finished=True)
self._auto_save_model_if_necessary(training_finished=True)

def classify(self, X: Union[dict, str], file_type: str = "h5py") -> np.ndarray:
"""Classify the input data with the trained model.
Expand Down
10 changes: 5 additions & 5 deletions pypots/clustering/crli/model.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Torch implementation of CRLI (Clustering Representation Learning on Incomplete time-series data).

Please refer to :cite:``ma2021CRLI``.
Please refer to :cite:`ma2021CRLI`.
"""

# Created by Wenjie Du <[email protected]>
Expand All @@ -18,7 +18,7 @@

from pypots.clustering.base import BaseNNClusterer
from pypots.clustering.crli.dataset import DatasetForCRLI
from pypots.clustering.crli.module import Generator, Decoder, Discriminator
from pypots.clustering.crli.modules import Generator, Decoder, Discriminator
from pypots.utils.logging import logger
from pypots.utils.metrics import cal_mse

Expand Down Expand Up @@ -292,7 +292,7 @@ def _train_model(
"generation_loss": mean_step_train_G_loss,
"discrimination_loss": mean_step_train_D_loss,
}
self.save_log_into_tb_file(
self._save_log_into_tb_file(
training_step, "training", loss_results
)
mean_epoch_train_D_loss = np.mean(epoch_train_loss_D_collector)
Expand All @@ -309,7 +309,7 @@ def _train_model(
self.best_model_dict = self.model.state_dict()
self.patience = self.original_patience
# save the model if necessary
self.auto_save_model_if_necessary(
self._auto_save_model_if_necessary(
training_finished=False,
saving_name=f"{self.__class__.__name__}_epoch{epoch}_loss{mean_loss}",
)
Expand Down Expand Up @@ -376,7 +376,7 @@ def fit(
self.model.eval() # set the model as eval status to freeze it.

# Step 3: save the model if necessary
self.auto_save_model_if_necessary(training_finished=True)
self._auto_save_model_if_necessary(training_finished=True)

def cluster(
self,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Torch implementation of CRLI (Clustering Representation Learning on Incomplete time-series data).

Please refer to :cite:``ma2021CRLI``.
Please refer to :cite:`ma2021CRLI` for details.
"""

# Created by Wenjie Du <[email protected]>
Expand Down
14 changes: 8 additions & 6 deletions pypots/clustering/vader/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from torch.utils.data import DataLoader

from pypots.clustering.base import BaseNNClusterer
from pypots.clustering.vader.module import (
from pypots.clustering.vader.modules import (
GMMLayer,
PeepholeLSTMCell,
ImplicitImputation,
Expand Down Expand Up @@ -412,7 +412,9 @@ def _train_model(

# save pre-training loss logs into the tensorboard file for every step if in need
if self.summary_writer is not None:
self.save_log_into_tb_file(pretraining_step, "pretraining", results)
self._save_log_into_tb_file(
pretraining_step, "pretraining", results
)

with torch.no_grad():
sample_collector = []
Expand Down Expand Up @@ -485,7 +487,7 @@ def _train_model(

# save training loss logs into the tensorboard file for every step if in need
if self.summary_writer is not None:
self.save_log_into_tb_file(training_step, "training", results)
self._save_log_into_tb_file(training_step, "training", results)

# mean training loss of the current epoch
mean_train_loss = np.mean(epoch_train_loss_collector)
Expand All @@ -506,7 +508,7 @@ def _train_model(
val_loss_dict = {
"loss": mean_val_loss,
}
self.save_log_into_tb_file(epoch, "validating", val_loss_dict)
self._save_log_into_tb_file(epoch, "validating", val_loss_dict)

logger.info(
f"epoch {epoch}: "
Expand All @@ -523,7 +525,7 @@ def _train_model(
self.best_model_dict = self.model.state_dict()
self.patience = self.original_patience
# save the model if necessary
self.auto_save_model_if_necessary(
self._auto_save_model_if_necessary(
training_finished=False,
saving_name=f"{self.__class__.__name__}_epoch{epoch}_loss{mean_loss}",
)
Expand Down Expand Up @@ -594,7 +596,7 @@ def fit(
self.model.eval() # set the model as eval status to freeze it.

# Step 3: save the model if necessary
self.auto_save_model_if_necessary(training_finished=True)
self._auto_save_model_if_necessary(training_finished=True)

def cluster(self, X: Union[dict, str], file_type: str = "h5py") -> np.ndarray:
"""Cluster the input with the trained model.
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions pypots/data/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def __init__(
else: # data from array
X = data["X"]
y = None if "y" not in data.keys() else data["y"]
self.X, self.y = self.check_input(X, y)
self.X, self.y = self._check_input(X, y)

self.sample_num = self._get_sample_num()

Expand Down Expand Up @@ -103,7 +103,7 @@ def __len__(self) -> int:
return self.sample_num

@staticmethod
def check_input(
def _check_input(
X: Union[np.ndarray, torch.Tensor, list],
y: Optional[Union[np.ndarray, torch.Tensor, list]] = None,
out_dtype: str = "tensor",
Expand Down
4 changes: 2 additions & 2 deletions pypots/forecasting/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def _train_model(

# save training loss logs into the tensorboard file for every step if in need
if self.summary_writer is not None:
self.save_log_into_tb_file(training_step, "training", results)
self._save_log_into_tb_file(training_step, "training", results)

# mean training loss of the current epoch
mean_train_loss = np.mean(epoch_train_loss_collector)
Expand All @@ -219,7 +219,7 @@ def _train_model(
val_loss_dict = {
"imputation_loss": mean_val_loss,
}
self.save_log_into_tb_file(epoch, "validating", val_loss_dict)
self._save_log_into_tb_file(epoch, "validating", val_loss_dict)

logger.info(
f"epoch {epoch}: "
Expand Down
2 changes: 1 addition & 1 deletion pypots/forecasting/bttf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""

The package for BTTF model .
"""

# Created by Wenjie Du <[email protected]>
Expand Down
Loading