From 1b2fb00af8a2ee3061eee99e7dfc94d25c8baa6d Mon Sep 17 00:00:00 2001 From: Hossein Rajaby Faghihi Date: Wed, 1 Nov 2023 16:03:59 +0000 Subject: [PATCH] adding doctsrings to programs --- domiknows/program/model/lossModel.py | 69 ++++++++- domiknows/program/model/pytorch.py | 202 +++++++++++++++++++++++++-- domiknows/program/program.py | 127 +++++++++++++++++ 3 files changed, 382 insertions(+), 16 deletions(-) diff --git a/domiknows/program/model/lossModel.py b/domiknows/program/model/lossModel.py index 970dad06..f1a30d75 100644 --- a/domiknows/program/model/lossModel.py +++ b/domiknows/program/model/lossModel.py @@ -14,6 +14,29 @@ class LossModel(torch.nn.Module): def __init__(self, graph, tnorm='P', sample = False, sampleSize = 0, sampleGlobalLoss = False, device='auto'): + """ + This function initializes a LossModel object with the given parameters and sets up the + necessary variables and constraints. + + :param graph: The `graph` parameter is an object that represents the logical constraints of a + graph. It contains information about the nodes, edges, and constraints of the graph + :param tnorm: The `tnorm` parameter specifies the type of t-norm to be used in the model. + T-norms are a family of binary operations that are used to model logical conjunction (AND) in + fuzzy logic. The default value is 'P', which stands for the product t-norm, defaults to P + (optional) + :param sample: The `sample` parameter is a boolean flag that determines whether to use sampling + during training. If set to `True`, the model will use sampling to estimate the loss function. If + set to `False`, the model will not use sampling and will use the exact loss function, defaults + to False (optional) + :param sampleSize: The `sampleSize` parameter determines the size of the sample used for + training. It specifies the number of samples that will be randomly selected from the dataset for + each training iteration, defaults to 0 (optional) + :param sampleGlobalLoss: The parameter `sampleGlobalLoss` is a boolean flag that determines + whether to sample the global loss during training. If `sampleGlobalLoss` is set to `True`, the + global loss will be sampled. Otherwise, it will not be sampled, defaults to False (optional) + :param device: The `device` parameter specifies the device (CPU or GPU) on which the model will + be trained and evaluated. It can take the following values:, defaults to auto (optional) + """ super().__init__() self.graph = graph self.build = True @@ -59,6 +82,13 @@ def reset(self): self.loss.reset() def get_lmbd(self, key): + """ + The function `get_lmbd` returns a clamped value from a dictionary based on a given key. + + :param key: The key parameter is used to access a specific value in the lmbd dictionary + :return: the value of `self.lmbd[self.lmbd_index[key]]` after clamping it to a maximum value of + `self.lmbd_p[self.lmbd_index[key]]`. + """ return self.lmbd[self.lmbd_index[key]].clamp(max=self.lmbd_p[self.lmbd_index[key]]) def forward(self, builder, build=None): @@ -96,18 +126,32 @@ def forward(self, builder, build=None): # (*out, datanode, builder) return lmbd_loss, datanode, builder +# The `PrimalDualModel` class is a subclass of `LossModel` that implements a primal-dual optimization +# algorithm. class PrimalDualModel(LossModel): logger = logging.getLogger(__name__) def __init__(self, graph, tnorm='P', device='auto'): + """ + The above function is the constructor for a class that initializes an object with a graph, + tnorm, and device parameters. + + :param graph: The `graph` parameter is the input graph that the coding assistant is being + initialized with. It represents the structure of the graph and can be used to perform various + operations on the graph, such as adding or removing nodes and edges, calculating node and edge + properties, and traversing the graph + :param tnorm: The tnorm parameter is used to specify the type of t-norm to be used in the graph. + A t-norm is a binary operation that generalizes the concept of conjunction (logical AND) to + fuzzy logic. The 'P' value for tnorm indicates that the product t-norm should, defaults to P + (optional) + :param device: The `device` parameter specifies the device on which the computations will be + performed. It can take the following values:, defaults to auto (optional) + """ super().__init__(graph, tnorm=tnorm, device=device) class SampleLossModel(torch.nn.Module): logger = logging.getLogger(__name__) - # def __init__(self, graph, sample = False, sampleSize = 0, sampleGlobalLoss = False): - # super().__init__(graph, sample=sample, sampleSize=sampleSize, sampleGlobalLoss=sampleGlobalLoss) - def __init__(self, graph, tnorm='P', sample = False, sampleSize = 0, sampleGlobalLoss = False, device='auto'): @@ -148,12 +192,31 @@ def reset(self): self.loss.reset() def get_lmbd(self, key): + """ + The function `get_lmbd` returns the value of `self.lmbd` at the index specified by + `self.lmbd_index[key]`, ensuring that the value is non-negative. + + :param key: The `key` parameter is used to access a specific element in the `self.lmbd` list. It + is used as an index to retrieve the corresponding value from the list + :return: the value of `self.lmbd[self.lmbd_index[key]]`. + """ if self.lmbd[self.lmbd_index[key]] < 0: with torch.no_grad(): self.lmbd[self.lmbd_index[key]] = 0 return self.lmbd[self.lmbd_index[key]] def forward(self, builder, build=None): + """ + The `forward` function calculates the loss for a PrimalDualModel using a DataNodeBuilder and + returns the loss value, the DataNode, and the builder. + + :param builder: The `builder` parameter is an instance of the `DataNodeBuilder` class. It is + used to create a batch root data node and retrieve a data node + :param build: The `build` parameter is an optional argument that specifies whether the + `DataNodeBuilder` should be invoked or not. If `build` is `None`, then the value of `self.build` + is used. If `build` is `True`, then the `createBatchRootDN()` method + :return: three values: lmbd_loss, datanode, and builder. + """ if build is None: build = self.build self.iter_step += 1 diff --git a/domiknows/program/model/pytorch.py b/domiknows/program/model/pytorch.py index 685c847c..f0280ad6 100644 --- a/domiknows/program/model/pytorch.py +++ b/domiknows/program/model/pytorch.py @@ -14,18 +14,42 @@ from ..metric import MetricTracker from domiknows.utils import setDnSkeletonMode, getDnSkeletonMode + class TorchModel(torch.nn.Module): - def __init__(self, graph, device='auto'): + + def __init__(self, graph, device='auto', ignore_modules=False): + """ + The function initializes an object with a graph, device, and build flag. + + :param graph: The `graph` parameter is an object that represents the computational graph. It + contains the nodes and edges that define the operations and data flow in the graph + :param device: The `device` parameter specifies the device on which the graph will be executed. + It can be set to `'auto'` to automatically select the device based on the availability of GPUs. + Alternatively, it can be set to a specific device, such as `'cpu'` or `'cuda:0', defaults to auto + (optional) + :param ignore_modules: The `ignore_modules` parameter is a boolean flag that determines whether + or not to ignore any modules in the graph. If set to `True`, any modules present in the graph + will be ignored during training. If set to `False`, all modules in the graph will be considered + during training, defaults to False (optional) + """ super().__init__() self.graph = graph self.mode(Mode.TRAIN) self.build = True self.device = device - for learner in self.graph.get_sensors(TorchLearner): - self.add_module(learner.fullname, learner.model) + if not ignore_modules: ### added for the inference only models which do not update the initial parameters + for learner in self.graph.get_sensors(TorchLearner): + self.add_module(learner.fullname, learner.model) def mode(self, mode=None): + """ + The mode function sets the mode of the object and performs certain actions based on the mode. + + :param mode: The `mode` parameter is used to specify the mode of operation for the code. It can + take one of the following values: + :return: The method is returning the value of the `_mode` attribute. + """ if mode is None: return self._mode if mode in (Mode.TEST, Mode.POPULATE): @@ -73,6 +97,22 @@ def data_hash(self, data_item): raise ValueError(f'To enable cache for {self}, data item must either contain a identifier key "id" or picklable (might be slow): \n{key_message}\n{dump_message}') def forward(self, data_item, build=None): + """ + The `forward` function takes a data item, performs various operations on it based on the graph + structure, and returns the output. + + :param data_item: The `data_item` parameter is the input data that will be passed through the + forward pass of the neural network. It can be either a dictionary or an iterable object. If it + is an iterable, it will be converted into a dictionary where the keys are the indices of the + elements in the iterable + :param build: The `build` parameter is a boolean flag that indicates whether the method should + build a data node or not. If `build` is `True`, the method will build a data node and return the + loss, metric, data node, and builder. If `build` is `False`, the method + :return: If the `build` parameter is `True`, the function returns a tuple containing `(loss, + metric, datanode, builder)`. + If the `build` parameter is `False`, the function returns a tuple containing the values returned + by the `populate` method. + """ if build is None: build = self.build data_hash = None @@ -120,8 +160,31 @@ def model_helper(Model, *args, **kwargs): class PoiModel(TorchModel): - def __init__(self, graph, poi=None, loss=None, metric=None, device='auto'): - super().__init__(graph, device) + def __init__(self, graph, poi=None, loss=None, metric=None, device='auto', ignore_modules=False): + """ + The function initializes an object with various parameters for graph processing. + + :param graph: The graph parameter is used to specify the graph structure. It represents the + connections between nodes in the graph + :param poi: The "poi" parameter stands for "point of interest". It is used to specify a specific + node or set of nodes in the graph that you are interested in. This can be useful when you want to + perform operations or calculations only on a subset of nodes in the graph. If no point of interest + :param loss: The `loss` parameter is used to specify the loss function that will be used during + training. It is typically a function that measures the difference between the predicted output and + the true output. The choice of loss function depends on the specific task and the type of data being + used. Some common loss functions include + :param metric: The `metric` parameter is used to specify the evaluation metric to be used during + training and evaluation of the model. It is typically a function that takes the predicted values and + the ground truth values as inputs and returns a scalar value representing the performance of the + model. Examples of common evaluation metrics include accuracy, + :param device: The `device` parameter specifies the device on which the computation will be + performed. It can take the following values:, defaults to auto (optional) + :param ignore_modules: The `ignore_modules` parameter is a boolean flag that determines whether to + ignore any modules in the graph. If set to `True`, any modules present in the graph will be ignored + during the initialization process. If set to `False` (default), all modules in the graph will be + considered during initialization, defaults to False (optional) + """ + super().__init__(graph, device, ignore_modules=ignore_modules) if poi is None: self.poi = self.default_poi() else: @@ -144,6 +207,12 @@ def __init__(self, graph, poi=None, loss=None, metric=None, device='auto'): self.metric = {'': metric} def default_poi(self): + """ + The function `default_poi` returns a list of properties from a graph that have more than one + instance of the `TorchSensor` class. + :return: a list of properties that have more than one instance of the `TorchSensor` class in the + graph. + """ poi = [] for prop in self.graph.get_properties(): if len(list(prop.find(TorchSensor))) > 1: @@ -151,6 +220,14 @@ def default_poi(self): return poi def find_sensors(self, prop): + """ + The function `find_sensors` finds pairs of sensors in a given property that have one sensor + labeled as the target and the other sensor as the output. + + :param prop: The parameter "prop" is expected to be an object that has a method called "find" + which takes a class name as an argument and returns a list of objects of that class. In this + case, it is being used to find objects of the class "TorchSensor" + """ for sensor1, sensor2 in combinations(prop.find(TorchSensor), r=2): if sensor1.label: target_sensor = sensor1 @@ -175,6 +252,19 @@ def reset(self): metric.reset() def poi_loss(self, data_item, _, sensors): + """ + The function calculates the loss for a given data item using a set of sensors. + + :param data_item: The `data_item` parameter represents a single data item that is being + processed. It could be any type of data, depending on the context of your code + :param _: The underscore "_" is a convention in Python to indicate that a variable is not going + to be used in the code. It is often used as a placeholder for a variable that needs to be + present for the function signature but is not actually used within the function. In this case, + it seems that the variable + :param sensors: The `sensors` parameter is a list of sensor functions. These sensor functions + take a `data_item` as input and return some output + :return: the calculated local_loss. + """ if not self.loss: return 0 @@ -192,6 +282,22 @@ def poi_loss(self, data_item, _, sensors): return local_loss def poi_metric(self, data_item, prop, sensors, datanode=None): + """ + The `poi_metric` function calculates a local metric based on the given data item, property, + sensors, and optional datanode. + + :param data_item: The `data_item` parameter is a single data item that is being processed. It + could be any type of data, depending on the context of your code + :param prop: The "prop" parameter is a property or attribute of the data item that is being + evaluated + :param sensors: The `sensors` parameter is a list of sensor functions. These sensor functions + take a `data_item` as input and return a value. The `sensors` list contains multiple sensor + functions that will be called to collect data for the metric calculation + :param datanode: The `datanode` parameter is an optional argument that represents the data node + for which the metric is being calculated. It is used as an input to the metric function to + provide additional context or information for the calculation + :return: the local_metric value. + """ if not self.metric: return None outs = [sensor(data_item) for sensor in sensors] @@ -206,6 +312,21 @@ def poi_metric(self, data_item, prop, sensors, datanode=None): return local_metric def populate(self, builder, datanode = None, run=True): + """ + The `populate` function evaluates sensors, calculates loss and metrics, and returns the total + loss and metric values. + + :param builder: The `builder` parameter is an object that is used to construct and populate data + nodes in a data structure. It is likely an instance of a class that provides methods for + creating and manipulating data nodes + :param datanode: The `datanode` parameter is an optional argument that represents a data node in + the builder. It is used to store the metric values calculated during the population process. If + `datanode` is not provided, a new batch root data node is created and assigned to `datanode` + :param run: The `run` parameter is a boolean flag that determines whether the sensors should be + evaluated or not. If `run` is `True`, the sensors will be evaluated by calling their `__call__` + method. If `run` is `False`, the sensors will not be evaluated, defaults to True (optional) + :return: two values: `loss` and `metric`. + """ loss = 0 metric = {} @@ -234,8 +355,43 @@ def populate(self, builder, datanode = None, run=True): return loss, metric class SolverModel(PoiModel): - def __init__(self, graph, poi=None, loss=None, metric=None, inferTypes=None, inference_with = None, probKey = ("local" , "softmax"), device='auto', probAcc=None): - super().__init__(graph, poi=poi, loss=loss, metric=metric, device=device) + def __init__(self, graph, poi=None, loss=None, metric=None, inferTypes=None, inference_with = None, probKey = ("local" , "softmax"), device='auto', probAcc=None, ignore_modules=False): + """ + The function initializes an object with various parameters for graph-based inference. + + :param graph: The graph parameter is used to specify the graph structure that the model will be + trained on. It can be a graph object or a graph file + :param poi: The "poi" parameter stands for "point of interest". It is used to specify a specific + node or set of nodes in the graph that you want to focus on or perform operations on. If you don't + specify any value for "poi", it will default to None, meaning that the entire graph + :param loss: The `loss` parameter is used to specify the loss function to be used during training. + It is typically a function that measures the difference between the predicted output and the true + output. The choice of loss function depends on the specific task and the type of data being used. + Some common loss functions include mean + :param metric: The `metric` parameter is used to specify the evaluation metric to be used during + training and inference. It is typically a function that takes the predicted values and the ground + truth values as inputs and returns a scalar value representing the performance of the model. Common + examples of evaluation metrics include accuracy, precision, recall + :param inferTypes: The `inferTypes` parameter is used to specify the types of nodes in the graph + that should be inferred. It is a list of strings, where each string represents a type of node. Only + nodes with these types will be inferred during the graph inference process + :param inference_with: The "inference_with" parameter is used to specify the type of inference to be + performed. It determines how the model will make predictions or inferences based on the input data. + The possible values for this parameter can vary depending on the specific implementation or + framework being used. Some common options include "classification + :param probKey: The `probKey` parameter is a tuple that specifies the type of probability + distribution to use for inference. The first element of the tuple specifies the type of distribution + to use for local inference, and the second element specifies the type of distribution to use for + softmax inference + :param device: The `device` parameter specifies the device on which the computations will be + performed. It can take the following values:, defaults to auto (optional) + :param probAcc: The `probAcc` parameter is the values of accuracies used inside the new ILP variation: + :param ignore_modules: The `ignore_modules` parameter is a boolean flag that determines whether to + ignore certain modules during the inference process. If set to `True`, the inference process will + not consider these modules. If set to `False`, all modules will be considered during inference, + defaults to False (optional) + """ + super().__init__(graph, poi=poi, loss=loss, metric=metric, device=device, ignore_modules=ignore_modules) if inferTypes == None: self.inferTypes = ['ILP'] @@ -251,6 +407,15 @@ def __init__(self, graph, poi=None, loss=None, metric=None, inferTypes=None, inf self.probAcc = probAcc def inference(self, builder): + """ + The `inference` function takes a builder object, iterates over a list of properties, and performs + inference using different types of models based on the `inferTypes` list. + + :param builder: The `builder` parameter is an object that is used to construct a computation + graph. It is typically used to define the inputs, operations, and outputs of a neural network + model + :return: the `datanode` object. + """ # import time # start = time.time() for i, prop in enumerate(self.poi): @@ -277,11 +442,11 @@ def inference(self, builder): for infertype in self.inferTypes: # sub_start = time.time() { - 'ILP': lambda :datanode.inferILPResults(*self.inference_with, key=self.probKey, fun=None, epsilon=None, Acc=self.probAcc), 'local/argmax': lambda :datanode.inferLocal(), 'local/softmax': lambda :datanode.inferLocal(), 'argmax': lambda :datanode.infer(), 'softmax': lambda :datanode.infer(), + 'ILP': lambda :datanode.inferILPResults(*self.inference_with, key=self.probKey, fun=None, epsilon=None, Acc=self.probAcc), 'GBI': lambda :datanode.inferGBIResults(*self.inference_with, model=self), }[infertype]() # sub_end = time.time() @@ -292,6 +457,20 @@ def inference(self, builder): return datanode def populate(self, builder, run=True): + """ + The `populate` function takes a `builder` object, performs inference on it, and then calls the + `populate` method of the superclass with the resulting `datanode`, returning the `datanode`, + `lose`, and `metric` values. + + :param builder: The "builder" parameter is an object that is used to build or construct the data + node. It is likely an instance of a class that has methods for creating and manipulating data + nodes + :param run: The "run" parameter is a boolean flag that determines whether to run the population + process immediately after populating the data node. If set to True, the population process will + be executed; if set to False, the population process will be skipped, defaults to True + (optional) + :return: three values: datanode, lose, and metric. + """ datanode = self.inference(builder) lose, metric = super().populate(builder, datanode = datanode, run=False) @@ -356,8 +535,7 @@ def loss(self): def metric(self): # return self.metrics_tracker pass - - + class PoiModelDictLoss(PoiModel): def __init__(self, graph, poi=None, loss=None, metric=None, dictloss=None, device='auto'): self.loss_tracker = MacroAverageTracker() @@ -420,9 +598,7 @@ def populate(self, builder, run=True): return loss, metric else: return super().populate(builder, run=True) - - - + # class PoiModelDictLoss(TorchModel): # def __init__(self, graph, poi=None, loss=None, metric=None): # super().__init__(graph) diff --git a/domiknows/program/program.py b/domiknows/program/program.py index 26b7c31d..4328c1a4 100644 --- a/domiknows/program/program.py +++ b/domiknows/program/program.py @@ -157,6 +157,22 @@ def __call__(self, stepName, metricName, metricResult): class LearningBasedProgram(): def __init__(self, graph, Model, logger=None, db=False, **kwargs): + """ + This function initializes an object with a graph, a model, a logger, and other optional + parameters. + + :param graph: The `graph` parameter is an object that represents a graph or network structure. + It is likely used in the `Model` class to define the architecture of the neural network + :param Model: The `Model` parameter is the class that represents the machine learning model you + want to use. It should have an `__init__` method that takes the `graph` and any additional + keyword arguments (`**kwargs`) as parameters. The `Model` class is used to create an instance of + the + :param logger: The `logger` parameter is an optional logger object that can be used for logging + messages and debugging information. If no logger is provided, a default logger will be used + :param db: The `db` parameter is a boolean flag that indicates whether or not to perform + database updates. If `db` is `True`, database updates will be performed. If `db` is `False`, no + database updates will be performed, defaults to False (optional) + """ self.graph = graph self.logger = logger or logging.getLogger(__name__) @@ -196,6 +212,17 @@ def to(self, device='auto'): self.model.device = self.device def calculateMetricDelta(self, metric1, metric2): + """ + The function calculates the difference between two metrics and returns the delta. + + :param metric1: The first metric, represented as a dictionary. Each key in the dictionary + represents a category, and the corresponding value is another dictionary where the keys + represent subcategories and the values represent the metric values + :param metric2: The `metric2` parameter is a dictionary representing a metric. It has a nested + structure where the keys represent categories and the values represent subcategories and their + corresponding values + :return: a dictionary called metricDelta. + """ metricDelta = {} for k, v in metric1.value().items(): metricDelta[k] = {} @@ -208,6 +235,18 @@ def calculateMetricDelta(self, metric1, metric2): return metricDelta def call_epoch(self, name, dataset, epoch_fn, **kwargs): + """ + The function `call_epoch` logs information about the loss and metrics of a model during an epoch + and updates a database if specified. + + :param name: The name of the epoch or task being performed. It is used for logging purposes + :param dataset: The `dataset` parameter is the input dataset that will be used for training or + evaluation. It is typically a collection of data samples that the model will process + :param epoch_fn: The `epoch_fn` parameter is a function that represents a single epoch of + training or evaluation. It takes the `dataset` as input and performs the necessary operations + for that epoch, such as forward and backward passes, updating model parameters, and calculating + metrics + """ if dataset is not None: self.logger.info(f'{name}:') desc = name if self.epoch is None else f'Epoch {self.epoch} {name}' @@ -270,6 +309,31 @@ def train( test_every_epoch=False, Optim=None, **kwargs): + """ + The `train` function is used to train a model on a given training set, with optional validation + and testing sets, for a specified number of epochs. + + :param training_set: The training set is the dataset used to train the model. It typically + consists of input data and corresponding target labels + :param valid_set: The valid_set parameter is used to specify the validation dataset. It is + typically a separate portion of the training dataset that is used to evaluate the model's + performance during training and tune hyperparameters + :param test_set: The `test_set` parameter is used to specify the dataset that will be used for + testing the model's performance after each epoch of training. It is typically a separate dataset + from the training and validation sets, and is used to evaluate the model's generalization + ability on unseen data + :param device: The device on which the model will be trained (e.g., 'cpu' or 'cuda') + :param train_epoch_num: The number of epochs to train the model for. An epoch is a complete pass + through the entire training dataset, defaults to 1 (optional) + :param test_every_epoch: The parameter "test_every_epoch" is a boolean flag that determines + whether to perform testing after every epoch during training. If set to True, testing will be + performed after each epoch. If set to False, testing will only be performed once at the end of + training, defaults to False (optional) + :param Optim: The `Optim` parameter is used to specify the optimizer to be used for training the + model. It should be a class that implements the optimization algorithm, such as + `torch.optim.SGD` or `torch.optim.Adam`. The optimizer is responsible for updating the model's + parameters based on the computed gradients + """ if device is not None: self.to(device) if Optim is not None and list(self.model.parameters()): @@ -293,6 +357,14 @@ def train( self.stop = None def train_epoch(self, dataset, **kwargs): + """ + The function `train_epoch` trains a model on a dataset for one epoch, updating the model's + parameters based on the calculated loss and performing gradient descent if an optimizer is + provided. + + :param dataset: The `dataset` parameter is the training dataset that contains the input data and + corresponding labels. It is used to iterate over the data items during training + """ self.model.mode(Mode.TRAIN) self.model.reset() for data_item in dataset: @@ -308,11 +380,29 @@ def train_epoch(self, dataset, **kwargs): yield (loss, metric, *output[:1]) def test(self, dataset, device=None, **kwargs): + """ + The function `test` is used to test a model on a given dataset, with an optional device argument + for specifying the device to run the test on. + + :param dataset: The dataset parameter is the dataset object that contains the testing data. It + is used to evaluate the performance of the model on the testing data + :param device: The "device" parameter is used to specify the device on which the model should be + tested. It can be set to "None" if you want to test the model on the CPU, or it can be set to a + specific device such as "cuda" if you want to test the model on + """ if device is not None: self.to(device) self.call_epoch('Testing', dataset, self.test_epoch, **kwargs) def test_epoch(self, dataset, **kwargs): + """ + The function `test_epoch` is used to evaluate a model on a dataset during the testing phase, + yielding the loss, metric, and output for each data item. + + :param dataset: The `dataset` parameter is the input dataset that you want to test your model + on. It could be a list, generator, or any other iterable object that provides the data items to + be tested. Each data item should be in a format that can be processed by your model + """ self.model.mode(Mode.TEST) self.model.reset() with torch.no_grad(): @@ -331,6 +421,17 @@ def populate_one(self, data_item, grad = False, device=None): return next(self.populate_epoch([data_item], grad = grad)) def populate_epoch(self, dataset, grad = False): + """ + The `populate_epoch` function is used to iterate over a dataset and yield the output of a model + for each data item, either with or without gradient calculations. + + :param dataset: The `dataset` parameter is the input data that you want to use to populate the + model. It could be a list, array, or any other iterable object that contains the data items + :param grad: The `grad` parameter is a boolean flag that determines whether or not to compute + gradients during the epoch. If `grad` is set to `False`, the epoch will be executed in + evaluation mode without computing gradients. If `grad` is set to `True`, the epoch will be + executed in training, defaults to False (optional) + """ self.model.mode(Mode.POPULATE) self.model.reset() @@ -360,12 +461,38 @@ def populate_epoch(self, dataset, grad = False): yield detuple(*output[:1]) def save(self, path, **kwargs): + """ + The function saves the state dictionary of a model to a specified path using the torch.save() + function. + + :param path: The path where the model's state dictionary will be saved + """ torch.save(self.model.state_dict(), path, **kwargs) def load(self, path, **kwargs): + """ + The function loads a saved model state dictionary from a specified path. + + :param path: The path parameter is the file path to the saved model state dictionary + """ self.model.load_state_dict(torch.load(path, **kwargs)) def verifyResultsLC(self,data,constraint_names=None,device=None): + """ + The function `verifyResultsLC` calculates and prints the accuracy of constraint verification + results for a given dataset. + + :param data: The `data` parameter is the input data that will be used to populate the datanode. + It is passed to the `populate` method of the current object (`self`) along with an optional + `device` parameter + :param constraint_names: The `constraint_names` parameter is a list of constraint names that you + want to verify the results for. If this parameter is not provided or is set to `None`, then the + function will verify the results for all constraints available in the `verifyResult` dictionary + :param device: The `device` parameter is used to specify the device on which the calculations + should be performed. It is an optional parameter and if not provided, the default device will be + used + :return: None. + """ import numpy as np datanode_ac,datanode_t=[],[] all_ac, all_t = [], []