Skip to content

在定义了所有配置之后,我们需要将它们整合在一起,这就是 TabularModel 发挥作用的地方。TabularModel 是核心的工作马,它负责协调和设置所有内容。

TabularModel 解析配置并:

  1. 初始化模型
  2. 设置实验跟踪框架
  3. 初始化和设置 TabularDatamodule,它处理所有数据转换并为 DataLoader 做准备
  4. 设置回调函数和 Pytorch Lightning Trainer
  5. 使您能够训练、保存、加载和预测

初始化 Tabular Model

基本用法:

  • data_config: DataConfig: DataConfig 对象或 yaml 文件的路径。
  • model_config: ModelConfig: ModelConfig 的子类或 yaml 文件的路径。根据配置类型确定运行哪个模型。
  • optimizer_config: OptimizerConfig: OptimizerConfig 对象或 yaml 文件的路径。
  • trainer_config: TrainerConfig: TrainerConfig 对象或 yaml 文件的路径。
  • experiment_config: ExperimentConfig: ExperimentConfig 对象或 yaml 文件的路径。

使用示例

tabular_model = TabularModel(
    data_config=data_config,
    model_config=model_config,
    optimizer_config=optimizer_config,
    trainer_config=trainer_config,
    experiment_config=experiment_config,
)

模型扫描

PyTorch Tabular 还提供了一种简单的方法来检查不同模型和配置在给定数据集上的性能。这是通过 model_sweep 函数完成的。它接受一个模型配置列表或 pytorch_tabular.MODEL_PRESETS 中定义的预设之一,并在数据上训练它们。然后根据提供的指标对模型进行排名并返回最佳模型。

这些是主要的参数: - task: 预测任务的类型。可以是 'classification' 或 'regression' - train: 训练数据 - test: 用于评估性能的测试数据 - 所有配置对象都可以作为对象或 yaml 文件的路径传递。 - models: 要比较的模型列表。这可以是 pytorch_tabular.MODEL_SWEEP_PRESETS 中定义的预设之一,或 ModelConfig 对象的列表。 - metrics: 训练期间需要跟踪的指标列表。指标应为 torchmetrics 中实现的功能指标之一。默认情况下,分类为准确率,回归为均方误差。 - metrics_prob_input: 配置中定义的分类指标是强制参数。这定义了指标函数的输入是概率还是类别。长度应与指标数量相同。默认为 None。 - metrics_params: 要传递给指标函数的参数。 - rank_metric: 用于对模型进行排名的指标。元组的第一个元素是指标名称,第二个元素是方向。默认为 ('loss', "lower_is_better")。 - return_best_model: 如果为 True,将返回最佳模型。默认为 True。

使用示例

sweep_df, best_model = model_sweep(
    task="classification",  # 可以是 "classification", "regression"
    train=train,
    test=test,
    data_config=data_config,
    optimizer_config=optimizer_config,
    trainer_config=trainer_config,
    model_list="lite",  # pytorch_tabular.MODEL_SWEEP_PRESETS 中定义的预设之一
    common_model_args=dict(head="LinearHead", head_config=head_config),
    metrics=['accuracy', "f1_score"], # 训练期间跟踪的指标
    metrics_params=[{}, {"average": "weighted"}],
    metrics_prob_input=[False, True],
    rank_metric=("accuracy", "higher_is_better"), # 用于对模型进行排名的指标。
    progress_bar=True, # 如果为 True,将显示进度条
    verbose=False # 如果为 True,将打印每个模型的结果
)

更多示例,请查看教程笔记本 - Model Sweep 以获取示例用法。

高级用法

  • config: DictConfig: 另一种初始化 TabularModel 的方法是使用 omegaconf 中的 Dictconfig。虽然不推荐,但您可以创建一个包含所有参数的普通字典,并从 omegaconf 创建一个 DictConfig 并在此处传递。缺点是您将跳过所有验证(包括类型验证和逻辑验证)。这主要用于从检查点加载保存的模型。
  • model_callable: Optional[Callable]: 通常,模型可调用对象和参数是从 ModelConfig 推断出来的。但在特殊情况下,例如使用自定义模型时,您可以将类(而不是初始化对象)传递给此参数并覆盖基于配置的初始化。

训练 API(监督学习)

有两种用于训练或“拟合”模型的 API。

  1. 高级 API
  2. 低级 API

低级 API 更灵活,允许您自定义训练循环。高级 API 更易于使用,推荐用于大多数用例。

高级API

pytorch_tabular.TabularModel.fit(train, validation=None, loss=None, metrics=None, metrics_prob_inputs=None, optimizer=None, optimizer_params=None, train_sampler=None, target_transform=None, max_epochs=None, min_epochs=None, seed=42, callbacks=None, datamodule=None, cache_data='memory', handle_oom=True)

fit方法,接收数据并触发训练.

Parameters:

Name Type Description Default
train DataFrame

训练数据框

required
validation Optional[DataFrame]

如果提供,将在训练过程中使用此数据框作为验证集. 用于早停和日志记录.如果未提供,将使用20%的训练数据作为验证集. 默认为None.

None
loss Optional[Module]

自定义损失函数,不在标准PyTorch库中

None
metrics Optional[List[Callable]]

自定义度量函数(可调用对象),具有 签名metric_fn(y_hat, y),并适用于torch张量输入.对于分类任务,y_hat预期形状为 (batch_size, num_classes),对于回归任务,y_hat预期形状为(batch_size, 1),y预期形状为 (batch_size, 1)

None
metrics_prob_inputs Optional[List[bool]]

这是分类度量的强制参数. 如果度量函数需要概率作为输入,请设置为True. 列表的长度应等于度量函数的数量.默认为None.

None
optimizer Optional[Optimizer]

自定义优化器,是标准PyTorch优化器的替代品. 这应该是类,而不是初始化的对象

None
optimizer_params Optional[Dict]

用于初始化自定义优化器的参数.

None
train_sampler Optional[Sampler]

自定义PyTorch批次采样器,将传递给DataLoaders. 对于处理不平衡数据和其他自定义批次策略很有用

None
target_transform Optional[Union[TransformerMixin, Tuple(Callable)]]

如果提供,在模型训练前对目标应用变换,在预测时应用逆变换. 参数可以是具有inverse_transform方法的sklearn Transformer, 或由可调用对象组成的元组(transform_func, inverse_transform_func)

None
max_epochs Optional[int]

覆盖要运行的最大轮数.默认为None.

None
min_epochs Optional[int]

覆盖要运行的最小轮数.默认为None.

None
seed Optional[int]

(int): 用于可重复性的随机种子.默认为42.

42
callbacks Optional[List[Callback]]

训练期间使用的回调列表.默认为None.

None
datamodule Optional[TabularDatamodule]

数据模块. 如果提供,将忽略其他参数如train、test等,并使用数据模块. 默认为None.

None
cache_data str

决定如何在数据加载器中缓存数据.如果设置为 "memory",将在内存中缓存.如果设置为有效路径,将在该路径中缓存.默认为"memory".

'memory'
handle_oom bool

如果为True,将尝试优雅地处理OOM错误.默认为True.

True

Returns:

Type Description
Trainer

pl.Trainer: PyTorch Lightning Trainer实例

Source code in src/pytorch_tabular/tabular_model.py
    def fit(
        self,
        train: Optional[DataFrame],
        validation: Optional[DataFrame] = None,
        loss: Optional[torch.nn.Module] = None,
        metrics: Optional[List[Callable]] = None,
        metrics_prob_inputs: Optional[List[bool]] = None,
        optimizer: Optional[torch.optim.Optimizer] = None,
        optimizer_params: Dict = None,
        train_sampler: Optional[torch.utils.data.Sampler] = None,
        target_transform: Optional[Union[TransformerMixin, Tuple]] = None,
        max_epochs: Optional[int] = None,
        min_epochs: Optional[int] = None,
        seed: Optional[int] = 42,
        callbacks: Optional[List[pl.Callback]] = None,
        datamodule: Optional[TabularDatamodule] = None,
        cache_data: str = "memory",
        handle_oom: bool = True,
    ) -> pl.Trainer:
        """    fit方法,接收数据并触发训练.

Parameters:
    train (DataFrame): 训练数据框

    validation (Optional[DataFrame], optional):
        如果提供,将在训练过程中使用此数据框作为验证集.
        用于早停和日志记录.如果未提供,将使用20%的训练数据作为验证集.
        默认为None.

    loss (Optional[torch.nn.Module], optional): 自定义损失函数,不在标准PyTorch库中

    metrics (Optional[List[Callable]], optional): 自定义度量函数(可调用对象),具有
        签名metric_fn(y_hat, y),并适用于torch张量输入.对于分类任务,y_hat预期形状为
        (batch_size, num_classes),对于回归任务,y_hat预期形状为(batch_size, 1),y预期形状为
        (batch_size, 1)

    metrics_prob_inputs (Optional[List[bool]], optional): 这是分类度量的强制参数.
        如果度量函数需要概率作为输入,请设置为True.
        列表的长度应等于度量函数的数量.默认为None.

    optimizer (Optional[torch.optim.Optimizer], optional):
        自定义优化器,是标准PyTorch优化器的替代品.
        这应该是类,而不是初始化的对象

    optimizer_params (Optional[Dict], optional): 用于初始化自定义优化器的参数.

    train_sampler (Optional[torch.utils.data.Sampler], optional):
        自定义PyTorch批次采样器,将传递给DataLoaders.
        对于处理不平衡数据和其他自定义批次策略很有用

    target_transform (Optional[Union[TransformerMixin, Tuple(Callable)]], optional):
        如果提供,在模型训练前对目标应用变换,在预测时应用逆变换.
        参数可以是具有inverse_transform方法的sklearn Transformer,
        或由可调用对象组成的元组(transform_func, inverse_transform_func)

    max_epochs (Optional[int]): 覆盖要运行的最大轮数.默认为None.

    min_epochs (Optional[int]): 覆盖要运行的最小轮数.默认为None.

    seed: (int): 用于可重复性的随机种子.默认为42.

    callbacks (Optional[List[pl.Callback]], optional):
        训练期间使用的回调列表.默认为None.

    datamodule (Optional[TabularDatamodule], optional): 数据模块.
        如果提供,将忽略其他参数如train、test等,并使用数据模块.
        默认为None.

    cache_data (str): 决定如何在数据加载器中缓存数据.如果设置为
        "memory",将在内存中缓存.如果设置为有效路径,将在该路径中缓存.默认为"memory".

    handle_oom (bool): 如果为True,将尝试优雅地处理OOM错误.默认为True.

Returns:
    pl.Trainer: PyTorch Lightning Trainer实例
"""
        assert self.config.task != "ssl", (
            "`fit` is not valid for SSL task. Please use `pretrain` for" " semi-supervised learning"
        )
        if metrics is not None:
            assert len(metrics) == len(
                metrics_prob_inputs or []
            ), "The length of `metrics` and `metrics_prob_inputs` should be equal"
        seed = seed or self.config.seed
        if seed:
            seed_everything(seed)
        if datamodule is None:
            datamodule = self.prepare_dataloader(
                train,
                validation,
                train_sampler,
                target_transform,
                seed,
                cache_data,
            )
        else:
            if train is not None:
                warnings.warn(
                    "train data and datamodule is provided."
                    " Ignoring the train data and using the datamodule."
                    " Set either one of them to None to avoid this warning."
                )
        model = self.prepare_model(
            datamodule,
            loss,
            metrics,
            metrics_prob_inputs,
            optimizer,
            optimizer_params or {},
        )

        return self.train(model, datamodule, callbacks, max_epochs, min_epochs, handle_oom)

pytorch_tabular.TabularModel.cross_validate(cv, train, metric=None, return_oof=False, groups=None, verbose=True, reset_datamodule=True, handle_oom=True, **kwargs)

交叉验证模型.

Parameters:

Name Type Description Default
cv 可选[Union[int, Iterable, BaseCrossValidator]]

确定交叉验证的分割策略. 可能的输入包括:

  • None,使用默认的5折交叉验证(回归问题使用KFold,分类问题使用StratifiedKFold),
  • 整数,指定(Stratified)KFold中的折数,
  • 一个可迭代对象,生成(train, test)索引数组的分割.
  • 一个scikit-learn的CV分割器.
required
train DataFrame

带有标签的训练数据

required
metric (可选[Union[str, Callable]], 可选)

用于评估的指标. 如果为None,将使用配置中的第一个指标.如果提供字符串,将使用定义的该指标.如果提供可调用对象,将使用该函数作为指标.我们期望可调用对象的形式为metric(y_true, y_pred).对于分类问题,y_pred是一个包含每个类别的概率(_probability)和最终预测(prediction)的数据框.对于回归问题,它是一个包含最终预测(_prediction)的数据框. 默认为None.

None
return_oof (bool, 可选)

如果为True,将返回交叉验证结果以及折叠外的预测. 默认为False.

False
groups (可选[Union[str, ndarray]], 可选)

用于分割样本的组标签.如果提供,将作为交叉验证器split方法的groups参数. 如果输入为字符串,将使用输入数据框中该名称的列作为组标签.如果输入为类数组对象,将使用该组标签.唯一的约束是组标签的大小应与输入数据框的行数相同. 默认为None.

None
verbose (bool, 可选)

如果为True,将记录结果. 默认为True.

True
reset_datamodule (bool, 可选)

如果为True,将在每次迭代时重置datamodule. 这将更慢,因为我们将为每个折叠拟合变换.如果为False,我们采用一种近似方法,即一旦变换在第一个折叠上拟合,它们将对所有其他折叠有效. 默认为True.

True
handle_oom (bool, 可选)

如果为True,将优雅地处理内存不足错误.

True
**kwargs

传递给模型fit方法的其他关键字参数.

{}

Returns:

Name Type Description
DataFrame

包含交叉验证结果的数据框

Source code in src/pytorch_tabular/tabular_model.py
    def cross_validate(
        self,
        cv: Optional[Union[int, Iterable, BaseCrossValidator]],
        train: DataFrame,
        metric: Optional[Union[str, Callable]] = None,
        return_oof: bool = False,
        groups: Optional[Union[str, np.ndarray]] = None,
        verbose: bool = True,
        reset_datamodule: bool = True,
        handle_oom: bool = True,
        **kwargs,
    ):
        """交叉验证模型.

Parameters:
    cv (可选[Union[int, Iterable, BaseCrossValidator]]): 确定交叉验证的分割策略.
        可能的输入包括:

        - None,使用默认的5折交叉验证(回归问题使用KFold,分类问题使用StratifiedKFold),
        - 整数,指定(Stratified)KFold中的折数,
        - 一个可迭代对象,生成(train, test)索引数组的分割.
        - 一个scikit-learn的CV分割器.

    train (DataFrame): 带有标签的训练数据

    metric (可选[Union[str, Callable]], 可选): 用于评估的指标.
        如果为None,将使用配置中的第一个指标.如果提供字符串,将使用定义的该指标.如果提供可调用对象,将使用该函数作为指标.我们期望可调用对象的形式为`metric(y_true, y_pred)`.对于分类问题,`y_pred`是一个包含每个类别的概率(<class>_probability)和最终预测(prediction)的数据框.对于回归问题,它是一个包含最终预测(<target>_prediction)的数据框.
        默认为None.

    return_oof (bool, 可选): 如果为True,将返回交叉验证结果以及折叠外的预测.
        默认为False.

    groups (可选[Union[str, np.ndarray]], 可选): 用于分割样本的组标签.如果提供,将作为交叉验证器`split`方法的`groups`参数.
        如果输入为字符串,将使用输入数据框中该名称的列作为组标签.如果输入为类数组对象,将使用该组标签.唯一的约束是组标签的大小应与输入数据框的行数相同.
        默认为None.

    verbose (bool, 可选): 如果为True,将记录结果.
        默认为True.

    reset_datamodule (bool, 可选): 如果为True,将在每次迭代时重置datamodule.
        这将更慢,因为我们将为每个折叠拟合变换.如果为False,我们采用一种近似方法,即一旦变换在第一个折叠上拟合,它们将对所有其他折叠有效.
        默认为True.

    handle_oom (bool, 可选): 如果为True,将优雅地处理内存不足错误.
    **kwargs: 传递给模型`fit`方法的其他关键字参数.

Returns:
    DataFrame: 包含交叉验证结果的数据框
"""
        cv = self._check_cv(cv)
        prep_dl_kwargs, prep_model_kwargs, train_kwargs = self._split_kwargs(kwargs)
        is_callable_metric = False
        if metric is None:
            metric = "test_" + self.config.metrics[0]
        elif isinstance(metric, str):
            metric = metric if metric.startswith("test_") else "test_" + metric
        elif callable(metric):
            is_callable_metric = True

        if isinstance(cv, BaseCrossValidator):
            it = enumerate(cv.split(train, y=train[self.config.target], groups=groups))
        else:
            # when iterable is directly passed
            it = enumerate(cv)
        cv_metrics = []
        datamodule = None
        model = None
        oof_preds = []
        for fold, (train_idx, val_idx) in it:
            if verbose:
                logger.info(f"Running Fold {fold+1}/{cv.get_n_splits()}")
            # train_fold = train.iloc[train_idx]
            # val_fold = train.iloc[val_idx]
            if reset_datamodule:
                datamodule = None
            if datamodule is None:
                # Initialize datamodule and model in the first fold
                # uses train data from this fold to fit all transformers
                datamodule = self.prepare_dataloader(
                    train=train.iloc[train_idx], validation=train.iloc[val_idx], seed=42, **prep_dl_kwargs
                )
                model = self.prepare_model(datamodule, **prep_model_kwargs)
            else:
                # Preprocess the current fold data using the fitted transformers and save in datamodule
                datamodule.train, _ = datamodule.preprocess_data(train.iloc[train_idx], stage="inference")
                datamodule.validation, _ = datamodule.preprocess_data(train.iloc[val_idx], stage="inference")

            # Train the model
            handle_oom = train_kwargs.pop("handle_oom", handle_oom)
            self.train(model, datamodule, handle_oom=handle_oom, **train_kwargs)
            if return_oof or is_callable_metric:
                preds = self.predict(train.iloc[val_idx], include_input_features=False)
                oof_preds.append(preds)
            if is_callable_metric:
                cv_metrics.append(metric(train.iloc[val_idx][self.config.target], preds))
            else:
                result = self.evaluate(train.iloc[val_idx], verbose=False)
                cv_metrics.append(result[0][metric])
            if verbose:
                logger.info(f"Fold {fold+1}/{cv.get_n_splits()} score: {cv_metrics[-1]}")
            self.model.reset_weights()
        return cv_metrics, oof_preds

低级API

低级API更加灵活,允许你编写更复杂的逻辑,如交叉验证、集成等。低级API更为冗长,需要你编写更多代码,但它为用户提供了更多的控制。

fit方法被拆分为三个子方法:

  1. prepare_dataloader

  2. prepare_model

  3. train

prepare_dataloader

此方法负责设置TabularDataModule并返回该对象。你可以使用save_dataloader保存此对象,稍后使用load_datamodule加载它以跳过数据准备步骤。这在进行交叉验证或集成时非常有用。

pytorch_tabular.TabularModel.prepare_dataloader(train, validation=None, train_sampler=None, target_transform=None, seed=42, cache_data='memory')

准备用于训练和验证的数据加载器.

Parameters:

Name Type Description Default
train DataFrame

训练数据框

required
validation Optional[DataFrame]

如果提供,将在训练过程中使用此数据框作为验证集. 用于早停和日志记录.如果未提供,将使用训练数据的20%作为验证集. 默认为 None.

None
train_sampler Optional[Sampler]

自定义的 PyTorch 批次采样器,将传递给 DataLoaders. 适用于处理不平衡数据和其他自定义批次策略.

None
target_transform Optional[Union[TransformerMixin, Tuple(Callable)]]

如果提供,在模型训练前对目标应用此变换,并在预测时应用逆变换. 参数可以是具有 inverse_transform 方法的 sklearn Transformer,或 由可调用对象组成的元组 (transform_func, inverse_transform_func).

None
seed Optional[int]

用于可重复性的随机种子.默认为 42.

42
cache_data str

决定如何在数据加载器中缓存数据.如果设置为 "memory",将在内存中缓存.如果设置为有效路径,将在该路径中缓存.默认为 "memory".

'memory'

Returns:

Name Type Description
TabularDatamodule TabularDatamodule

准备好的数据模块

Source code in src/pytorch_tabular/tabular_model.py
    def prepare_dataloader(
        self,
        train: DataFrame,
        validation: Optional[DataFrame] = None,
        train_sampler: Optional[torch.utils.data.Sampler] = None,
        target_transform: Optional[Union[TransformerMixin, Tuple]] = None,
        seed: Optional[int] = 42,
        cache_data: str = "memory",
    ) -> TabularDatamodule:
        """准备用于训练和验证的数据加载器.

Parameters:
    train (DataFrame): 训练数据框

    validation (Optional[DataFrame], optional):
        如果提供,将在训练过程中使用此数据框作为验证集.
        用于早停和日志记录.如果未提供,将使用训练数据的20%作为验证集.
        默认为 None.

    train_sampler (Optional[torch.utils.data.Sampler], optional):
        自定义的 PyTorch 批次采样器,将传递给 DataLoaders.
        适用于处理不平衡数据和其他自定义批次策略.

    target_transform (Optional[Union[TransformerMixin, Tuple(Callable)]], optional):
        如果提供,在模型训练前对目标应用此变换,并在预测时应用逆变换.
        参数可以是具有 inverse_transform 方法的 sklearn Transformer,或
        由可调用对象组成的元组 (transform_func, inverse_transform_func).

    seed (Optional[int], optional): 用于可重复性的随机种子.默认为 42.

    cache_data (str): 决定如何在数据加载器中缓存数据.如果设置为
        "memory",将在内存中缓存.如果设置为有效路径,将在该路径中缓存.默认为 "memory".

Returns:
    TabularDatamodule: 准备好的数据模块
"""
        if self.verbose:
            logger.info("Preparing the DataLoaders")
        target_transform = self._check_and_set_target_transform(target_transform)

        datamodule = TabularDatamodule(
            train=train,
            validation=validation,
            config=self.config,
            target_transform=target_transform,
            train_sampler=train_sampler,
            seed=seed,
            cache_data=cache_data,
            verbose=self.verbose,
        )
        datamodule.prepare_data()
        datamodule.setup("fit")
        return datamodule

prepare_model

此方法负责设置和初始化模型,并接受准备好的datamodule作为输入。它返回模型实例。

pytorch_tabular.TabularModel.prepare_model(datamodule, loss=None, metrics=None, metrics_prob_inputs=None, optimizer=None, optimizer_params=None)

准备模型以进行训练.

Parameters:

Name Type Description Default
datamodule TabularDatamodule

数据模块

required
loss (Optional[Module], 可选)

自定义损失函数,不在标准 PyTorch 库中

None
metrics (Optional[List[Callable]], 可选)

自定义度量函数(可调用对象),具有 metric_fn(y_hat, y) 签名并作用于 torch 张量输入

None
metrics_prob_inputs (Optional[List[bool]], 可选)

这是分类度量的必填参数.如果度量函数需要概率作为输入,请设置为 True. 列表的长度应等于度量函数的数量.默认为 None.

None
optimizer (Optional[Optimizer], 可选)

自定义优化器,是标准 PyTorch 优化器的直接替代品. 这应该是类,而不是初始化的对象

None
optimizer_params (Optional[Dict], 可选)

用于初始化自定义优化器的参数.

None

Returns:

Name Type Description
BaseModel BaseModel

准备好的模型

Source code in src/pytorch_tabular/tabular_model.py
    def prepare_model(
        self,
        datamodule: TabularDatamodule,
        loss: Optional[torch.nn.Module] = None,
        metrics: Optional[List[Callable]] = None,
        metrics_prob_inputs: Optional[List[bool]] = None,
        optimizer: Optional[torch.optim.Optimizer] = None,
        optimizer_params: Dict = None,
    ) -> BaseModel:
        """准备模型以进行训练.

Parameters:
    datamodule (TabularDatamodule): 数据模块

    loss (Optional[torch.nn.Module], 可选): 自定义损失函数,不在标准 PyTorch 库中

    metrics (Optional[List[Callable]], 可选): 自定义度量函数(可调用对象),具有 metric_fn(y_hat, y) 签名并作用于 torch 张量输入

    metrics_prob_inputs (Optional[List[bool]], 可选): 这是分类度量的必填参数.如果度量函数需要概率作为输入,请设置为 True.
        列表的长度应等于度量函数的数量.默认为 None.

    optimizer (Optional[torch.optim.Optimizer], 可选):
        自定义优化器,是标准 PyTorch 优化器的直接替代品.
        这应该是类,而不是初始化的对象

    optimizer_params (Optional[Dict], 可选): 用于初始化自定义优化器的参数.

Returns:
    BaseModel: 准备好的模型
"""
        if self.verbose:
            logger.info(f"Preparing the Model: {self.config._model_name}")
        # Fetching the config as some data specific configs have been added in the datamodule
        self.inferred_config = self._read_parse_config(datamodule.update_config(self.config), InferredConfig)
        model = self.model_callable(
            self.config,
            custom_loss=loss,  # Unused in SSL tasks
            custom_metrics=metrics,  # Unused in SSL tasks
            custom_metrics_prob_inputs=metrics_prob_inputs,  # Unused in SSL tasks
            custom_optimizer=optimizer,
            custom_optimizer_params=optimizer_params or {},
            inferred_config=self.inferred_config,
        )
        # Data Aware Initialization(for the models that need it)
        model.data_aware_initialization(datamodule)
        if self.model_state_dict_path is not None:
            self._load_weights(model, self.model_state_dict_path)
        if self.track_experiment and self.config.log_target == "wandb":
            self.logger.watch(model, log=self.config.exp_watch, log_freq=self.config.exp_log_freq)
        return model

train

此方法负责训练模型,并接受准备好的datamodule和模型作为输入。它返回训练后的模型实例。

pytorch_tabular.TabularModel.train(model, datamodule, callbacks=None, max_epochs=None, min_epochs=None, handle_oom=True)

训练模型.

Parameters:

Name Type Description Default
model LightningModule

要训练的PyTorch Lightning模型.

required
datamodule TabularDatamodule

数据模块

required
callbacks Optional[List[Callback]]

训练期间使用的回调函数列表.默认为None.

None
max_epochs Optional[int]

覆盖要运行的最大epoch数.默认为None.

None
min_epochs Optional[int]

覆盖要运行的最小epoch数.默认为None.

None
handle_oom bool

如果为True,将尝试优雅地处理OOM错误.默认为True.

True

Returns:

Type Description
Trainer

pl.Trainer: PyTorch Lightning Trainer实例

Source code in src/pytorch_tabular/tabular_model.py
    def train(
        self,
        model: pl.LightningModule,
        datamodule: TabularDatamodule,
        callbacks: Optional[List[pl.Callback]] = None,
        max_epochs: int = None,
        min_epochs: int = None,
        handle_oom: bool = True,
    ) -> pl.Trainer:
        """    训练模型.

Parameters:
    model (pl.LightningModule): 要训练的PyTorch Lightning模型.

    datamodule (TabularDatamodule): 数据模块

    callbacks (Optional[List[pl.Callback]], optional):
        训练期间使用的回调函数列表.默认为None.

    max_epochs (Optional[int]): 覆盖要运行的最大epoch数.默认为None.

    min_epochs (Optional[int]): 覆盖要运行的最小epoch数.默认为None.

    handle_oom (bool): 如果为True,将尝试优雅地处理OOM错误.默认为True.

Returns:
    pl.Trainer: PyTorch Lightning Trainer实例
"""
        self._prepare_for_training(model, datamodule, callbacks, max_epochs, min_epochs)
        train_loader, val_loader = (
            self.datamodule.train_dataloader(),
            self.datamodule.val_dataloader(),
        )
        self.model.train()
        if self.config.auto_lr_find and (not self.config.fast_dev_run):
            if self.verbose:
                logger.info("Auto LR Find Started")
            with OutOfMemoryHandler(handle_oom=handle_oom) as oom_handler:
                result = Tuner(self.trainer).lr_find(
                    self.model,
                    train_dataloaders=train_loader,
                    val_dataloaders=val_loader,
                )
            if oom_handler.oom_triggered:
                raise OOMException(
                    "OOM detected during LR Find. Try reducing your batch_size or the"
                    " model parameters." + "/n" + "Original Error: " + oom_handler.oom_msg
                )
            if self.verbose:
                logger.info(
                    f"Suggested LR: {result.suggestion()}. For plot and detailed"
                    " analysis, use `find_learning_rate` method."
                )
            self.model.reset_weights()
            # Parameters in models needs to be initialized again after LR find
            self.model.data_aware_initialization(self.datamodule)
        self.model.train()
        if self.verbose:
            logger.info("Training Started")
        with OutOfMemoryHandler(handle_oom=handle_oom) as oom_handler:
            self.trainer.fit(self.model, train_loader, val_loader)
        if oom_handler.oom_triggered:
            raise OOMException(
                "OOM detected during Training. Try reducing your batch_size or the"
                " model parameters."
                "/n" + "Original Error: " + oom_handler.oom_msg
            )
        self._is_fitted = True
        if self.verbose:
            logger.info("Training the model completed")
        if self.config.load_best:
            self.load_best_model()
        return self.trainer

训练API(自监督学习)

对于自监督学习,存在一个不同的API,因为过程不同。

  1. pytorch_tabular.TabularModel.pretrain: 此方法负责预训练模型。它接受输入数据框和其他参数,以在提供的数据上进行预训练。
  2. pytorch_tabular.TabularModel.create_finetune_model: 如果我们想使用预训练模型进行微调,我们需要创建一个带有预训练权重的新模型。此方法负责创建微调模型。它接受预训练模型并返回一个微调模型。返回的对象是TabularModel的单独实例,可用于微调模型。
  3. pytorch_tabular.TabularModel.finetune: 此方法负责微调模型,并且只能与通过create_finetune_model创建的模型一起使用。它接受输入数据框和其他参数,以在提供的数据上进行微调。

注意

传递给pretrain的数据框不需要包含目标列。但即使你在DataConfig中定义了目标列,它也会被忽略。但传递给finetune的数据框必须包含目标列。

pytorch_tabular.TabularModel.pretrain(train, validation=None, optimizer=None, optimizer_params=None, max_epochs=None, min_epochs=None, seed=42, callbacks=None, datamodule=None, cache_data='memory')

预训练方法,接收数据并触发训练.

Parameters:

Name Type Description Default
train DataFrame

训练数据框

required
validation Optional[DataFrame]

如果提供,将在训练过程中使用此数据框作为验证集. 用于早停和日志记录.如果未提供,将使用训练数据的20%作为验证集.默认为None.

None
optimizer Optional[Optimizer]

自定义优化器,可作为标准PyTorch优化器的替代品. 应为类,而非初始化对象.

None
optimizer_params Optional[Dict]

用于初始化自定义优化器的参数.

None
max_epochs Optional[int]

覆盖要运行的最大周期数.默认为None.

None
min_epochs Optional[int]

覆盖要运行的最小周期数.默认为None.

None
seed Optional[int]

(int): 随机种子,用于可重复性.默认为42.

42
callbacks Optional[List[Callback]]

训练过程中使用的回调列表. 默认为None.

None
datamodule Optional[TabularDatamodule]

数据模块.如果提供,将忽略其他参数如train、test等, 并使用数据模块.默认为None.

None
cache_data str

决定如何在数据加载器中缓存数据.如果设置为"memory",将在内存中缓存. 如果设置为有效路径,将在该路径中缓存.默认为"memory".

'memory'

Returns: pl.Trainer: PyTorch Lightning Trainer实例

Source code in src/pytorch_tabular/tabular_model.py
    def pretrain(
        self,
        train: Optional[DataFrame],
        validation: Optional[DataFrame] = None,
        optimizer: Optional[torch.optim.Optimizer] = None,
        optimizer_params: Dict = None,
        # train_sampler: Optional[torch.utils.data.Sampler] = None,
        max_epochs: Optional[int] = None,
        min_epochs: Optional[int] = None,
        seed: Optional[int] = 42,
        callbacks: Optional[List[pl.Callback]] = None,
        datamodule: Optional[TabularDatamodule] = None,
        cache_data: str = "memory",
    ) -> pl.Trainer:
        """    预训练方法,接收数据并触发训练.

Parameters:
    train (DataFrame): 训练数据框

    validation (Optional[DataFrame], optional): 如果提供,将在训练过程中使用此数据框作为验证集.
        用于早停和日志记录.如果未提供,将使用训练数据的20%作为验证集.默认为None.

    optimizer (Optional[torch.optim.Optimizer], optional): 自定义优化器,可作为标准PyTorch优化器的替代品.
        应为类,而非初始化对象.

    optimizer_params (Optional[Dict], optional): 用于初始化自定义优化器的参数.

    max_epochs (Optional[int]): 覆盖要运行的最大周期数.默认为None.

    min_epochs (Optional[int]): 覆盖要运行的最小周期数.默认为None.

    seed: (int): 随机种子,用于可重复性.默认为42.

    callbacks (Optional[List[pl.Callback]], optional): 训练过程中使用的回调列表.
        默认为None.

    datamodule (Optional[TabularDatamodule], optional): 数据模块.如果提供,将忽略其他参数如train、test等,
        并使用数据模块.默认为None.

    cache_data (str): 决定如何在数据加载器中缓存数据.如果设置为"memory",将在内存中缓存.
        如果设置为有效路径,将在该路径中缓存.默认为"memory".
Returns:
    pl.Trainer: PyTorch Lightning Trainer实例
"""
        assert self.config.task == "ssl", (
            f"`pretrain` is not valid for {self.config.task} task. Please use `fit`" " instead."
        )
        seed = seed or self.config.seed
        if seed:
            seed_everything(seed)
        if datamodule is None:
            datamodule = self.prepare_dataloader(
                train,
                validation,
                train_sampler=None,
                target_transform=None,
                seed=seed,
                cache_data=cache_data,
            )
        else:
            if train is not None:
                warnings.warn(
                    "train data and datamodule is provided."
                    " Ignoring the train data and using the datamodule."
                    " Set either one of them to None to avoid this warning."
                )
        model = self.prepare_model(
            datamodule,
            optimizer,
            optimizer_params or {},
        )

        return self.train(model, datamodule, callbacks, max_epochs, min_epochs)

pytorch_tabular.TabularModel.create_finetune_model(task, head, head_config, train, validation=None, train_sampler=None, target_transform=None, target=None, optimizer_config=None, trainer_config=None, experiment_config=None, loss=None, metrics=None, metrics_prob_input=None, metrics_params=None, optimizer=None, optimizer_params=None, learning_rate=None, target_range=None, seed=42)

创建一个新的TabularModel模型,使用预训练权重以及新的任务和头部.

Parameters:

Name Type Description Default
task str

要执行的任务.可以是 "regression" 或 "classification" 之一.

required
head str

用于模型的头部.应为 pytorch_tabular.models.common.heads 中定义的头部之一.默认为 LinearHead.可选值为: [None,LinearHead,MixtureDensityHead].

required
head_config Dict

定义头部的配置字典.如果留空,将初始化为默认的线性头部.

required
train DataFrame

带有标签的训练数据.

required
validation Optional[DataFrame]

带有标签的验证数据.默认为 None.

None
train_sampler Optional[Sampler]

如果提供,将用作训练的批次采样器.默认为 None.

None
target_transform Optional[Union[TransformerMixin, Tuple]]

如果提供,将在训练前用于转换目标,并在预测后进行逆转换.

None
target Optional[str]

如果未在初始预训练阶段提供,则为目标列名称.默认为 None.

None
optimizer_config Optional[OptimizerConfig]

如果提供,将重新定义微调阶段的优化器.默认为 None.

None
trainer_config Optional[TrainerConfig]

如果提供,将重新定义微调阶段的训练器.默认为 None.

None
experiment_config Optional[ExperimentConfig]

如果提供,将重新定义微调阶段的实验配置.默认为 None.

None
loss Optional[Module]

如果提供,将用作微调阶段的损失函数.默认情况下,回归任务为 MSELoss,分类任务为 CrossEntropyLoss.

None
metrics Optional[List[Callable]]

用于微调阶段的指标列表(可以是可调用对象或字符串).如果是字符串,应为 torchmetrics.functional 中实现的功能性指标之一.默认为 None.

None
metrics_prob_input Optional[List[bool]]

分类指标的强制参数. 这定义了指标函数的输入是概率还是类别.长度应与指标数量相同.默认为 None.

None
metrics_params Optional[Dict]

与指标顺序相同的指标参数. 例如,多类别的 f1_score 需要参数 average 来完全定义指标.默认为 None.

None
optimizer Optional[Optimizer]

自定义优化器,是标准 PyTorch 优化器的替代品.如果提供,将忽略 OptimizerConfig.默认为 None.

None
optimizer_params Dict

优化器的参数.默认为 {}.

None
learning_rate Optional[float]

要使用的学习率.默认为 1e-3.

None
target_range Optional[Tuple[float, float]]

回归任务的目标范围.分类任务中忽略.默认为 None.

None
seed Optional[int]

随机种子,用于可重复性.默认为 42.

42

Returns:

Name Type Description
TabularModel TabularModel

用于微调的新 TabularModel 模型

Source code in src/pytorch_tabular/tabular_model.py
    def create_finetune_model(
        self,
        task: str,
        head: str,
        head_config: Dict,
        train: DataFrame,
        validation: Optional[DataFrame] = None,
        train_sampler: Optional[torch.utils.data.Sampler] = None,
        target_transform: Optional[Union[TransformerMixin, Tuple]] = None,
        target: Optional[str] = None,
        optimizer_config: Optional[OptimizerConfig] = None,
        trainer_config: Optional[TrainerConfig] = None,
        experiment_config: Optional[ExperimentConfig] = None,
        loss: Optional[torch.nn.Module] = None,
        metrics: Optional[List[Union[Callable, str]]] = None,
        metrics_prob_input: Optional[List[bool]] = None,
        metrics_params: Optional[Dict] = None,
        optimizer: Optional[torch.optim.Optimizer] = None,
        optimizer_params: Dict = None,
        learning_rate: Optional[float] = None,
        target_range: Optional[Tuple[float, float]] = None,
        seed: Optional[int] = 42,
    ):
        """创建一个新的TabularModel模型,使用预训练权重以及新的任务和头部.

Parameters:
    task (str): 要执行的任务.可以是 "regression" 或 "classification" 之一.

    head (str): 用于模型的头部.应为 `pytorch_tabular.models.common.heads` 中定义的头部之一.默认为 LinearHead.可选值为:
        [`None`,`LinearHead`,`MixtureDensityHead`].

    head_config (Dict): 定义头部的配置字典.如果留空,将初始化为默认的线性头部.

    train (DataFrame): 带有标签的训练数据.

    validation (Optional[DataFrame], optional): 带有标签的验证数据.默认为 None.

    train_sampler (Optional[torch.utils.data.Sampler], optional): 如果提供,将用作训练的批次采样器.默认为 None.

    target_transform (Optional[Union[TransformerMixin, Tuple]], optional): 如果提供,将在训练前用于转换目标,并在预测后进行逆转换.

    target (Optional[str], optional): 如果未在初始预训练阶段提供,则为目标列名称.默认为 None.

    optimizer_config (Optional[OptimizerConfig], optional):
        如果提供,将重新定义微调阶段的优化器.默认为 None.

    trainer_config (Optional[TrainerConfig], optional):
        如果提供,将重新定义微调阶段的训练器.默认为 None.

    experiment_config (Optional[ExperimentConfig], optional):
        如果提供,将重新定义微调阶段的实验配置.默认为 None.

    loss (Optional[torch.nn.Module], optional):
        如果提供,将用作微调阶段的损失函数.默认情况下,回归任务为 MSELoss,分类任务为 CrossEntropyLoss.

    metrics (Optional[List[Callable]], optional): 用于微调阶段的指标列表(可以是可调用对象或字符串).如果是字符串,应为 ``torchmetrics.functional`` 中实现的功能性指标之一.默认为 None.

    metrics_prob_input (Optional[List[bool]], optional): 分类指标的强制参数.
        这定义了指标函数的输入是概率还是类别.长度应与指标数量相同.默认为 None.

    metrics_params (Optional[Dict], optional): 与指标顺序相同的指标参数.
        例如,多类别的 f1_score 需要参数 `average` 来完全定义指标.默认为 None.

    optimizer (Optional[torch.optim.Optimizer], optional):
        自定义优化器,是标准 PyTorch 优化器的替代品.如果提供,将忽略 OptimizerConfig.默认为 None.

    optimizer_params (Dict, optional): 优化器的参数.默认为 {}.

    learning_rate (Optional[float], optional): 要使用的学习率.默认为 1e-3.

    target_range (Optional[Tuple[float, float]], optional): 回归任务的目标范围.分类任务中忽略.默认为 None.

    seed (Optional[int], optional): 随机种子,用于可重复性.默认为 42.

Returns:
    TabularModel (TabularModel): 用于微调的新 TabularModel 模型
"""
        config = self.config
        optimizer_params = optimizer_params or {}
        if target is None:
            assert (
                hasattr(config, "target") and config.target is not None
            ), "`target` cannot be None if it was not set in the initial `DataConfig`"
        else:
            assert isinstance(target, list), "`target` should be a list of strings"
            config.target = target
        config.task = task
        # Add code to update configs with newly provided ones
        if optimizer_config is not None:
            for key, value in optimizer_config.__dict__.items():
                config[key] = value
            if len(optimizer_params) > 0:
                config.optimizer_params = optimizer_params
            else:
                config.optimizer_params = {}
        if trainer_config is not None:
            for key, value in trainer_config.__dict__.items():
                config[key] = value
        if experiment_config is not None:
            for key, value in experiment_config.__dict__.items():
                config[key] = value
        else:
            if self.track_experiment:
                # Renaming the experiment run so that a different log is created for finetuning
                if self.verbose:
                    logger.info("Renaming the experiment run for finetuning as" f" {config['run_name'] + '_finetuned'}")
                config["run_name"] = config["run_name"] + "_finetuned"

        datamodule = self.datamodule.copy(
            train=train,
            validation=validation,
            target_transform=target_transform,
            train_sampler=train_sampler,
            seed=seed,
            config_override={"target": target} if target is not None else {},
        )
        model_callable = _GenericModel
        inferred_config = OmegaConf.structured(datamodule._inferred_config)
        # Adding dummy attributes for compatibility. Not used because custom metrics are provided
        if not hasattr(config, "metrics"):
            config.metrics = "dummy"
        if not hasattr(config, "metrics_params"):
            config.metrics_params = {}
        if not hasattr(config, "metrics_prob_input"):
            config.metrics_prob_input = metrics_prob_input or [False]
        if metrics is not None:
            assert len(metrics) == len(metrics_params), "Number of metrics and metrics_params should be same"
            assert len(metrics) == len(metrics_prob_input), "Number of metrics and metrics_prob_input should be same"
            metrics = [getattr(torchmetrics.functional, m) if isinstance(m, str) else m for m in metrics]
        if task == "regression":
            loss = loss or torch.nn.MSELoss()
            if metrics is None:
                metrics = [torchmetrics.functional.mean_squared_error]
                metrics_params = [{}]
        elif task == "classification":
            loss = loss or torch.nn.CrossEntropyLoss()
            if metrics is None:
                metrics = [torchmetrics.functional.accuracy]
                metrics_params = [
                    {
                        "task": "multiclass",
                        "num_classes": inferred_config.output_dim,
                        "top_k": 1,
                    }
                ]
                metrics_prob_input = [False]
            else:
                for i, mp in enumerate(metrics_params):
                    # For classification task, output_dim == number of classses
                    metrics_params[i]["task"] = mp.get("task", "multiclass")
                    metrics_params[i]["num_classes"] = mp.get("num_classes", inferred_config.output_dim)
                    metrics_params[i]["top_k"] = mp.get("top_k", 1)
        else:
            raise ValueError(f"Task {task} not supported")
        # Forming partial callables using metrics and metric params
        metrics = [partial(m, **mp) for m, mp in zip(metrics, metrics_params)]
        self.model.mode = "finetune"
        if learning_rate is not None:
            config.learning_rate = learning_rate
        config.target_range = target_range
        model_args = {
            "backbone": self.model,
            "head": head,
            "head_config": head_config,
            "config": config,
            "inferred_config": inferred_config,
            "custom_loss": loss,
            "custom_metrics": metrics,
            "custom_metrics_prob_inputs": metrics_prob_input,
            "custom_optimizer": optimizer,
            "custom_optimizer_params": optimizer_params,
        }
        # Initializing with default metrics, losses, and optimizers. Will revert once initialized
        model = model_callable(
            **model_args,
        )
        tabular_model = TabularModel(config=config, verbose=self.verbose)
        tabular_model.model = model
        tabular_model.datamodule = datamodule
        # Setting a flag to identify this as a fine-tune model
        tabular_model._is_finetune_model = True
        return tabular_model

pytorch_tabular.TabularModel.finetune(max_epochs=None, min_epochs=None, callbacks=None, freeze_backbone=False)

微调模型于提供的数据上.

Parameters:

Name Type Description Default
max_epochs (Optional[int], 可选)

训练的最大周期数.默认为 None.

None
min_epochs (Optional[int], 可选)

训练的最小周期数.默认为 None.

None
callbacks (Optional[List[Callback]], 可选)

如果提供,将添加到 Trainer 的回调中. 默认为 None.

None
freeze_backbone (bool, 可选)

如果为 True,将通过关闭梯度来冻结主干网络. 默认为 False,这意味着预训练的权重在微调期间也会进一步调整.

False

Returns:

Type Description
Trainer

pl.Trainer: Trainer 对象

Source code in src/pytorch_tabular/tabular_model.py
    def finetune(
        self,
        max_epochs: Optional[int] = None,
        min_epochs: Optional[int] = None,
        callbacks: Optional[List[pl.Callback]] = None,
        freeze_backbone: bool = False,
    ) -> pl.Trainer:
        """微调模型于提供的数据上.

Parameters:
    max_epochs (Optional[int], 可选): 训练的最大周期数.默认为 None.

    min_epochs (Optional[int], 可选): 训练的最小周期数.默认为 None.

    callbacks (Optional[List[pl.Callback]], 可选): 如果提供,将添加到 Trainer 的回调中.
        默认为 None.

    freeze_backbone (bool, 可选): 如果为 True,将通过关闭梯度来冻结主干网络.
        默认为 False,这意味着预训练的权重在微调期间也会进一步调整.

Returns:
    pl.Trainer: Trainer 对象
"""
        assert self._is_finetune_model, (
            "finetune() can only be called on a finetune model created using" " `TabularModel.create_finetune_model()`"
        )
        seed_everything(self.config.seed)
        if freeze_backbone:
            for param in self.model.backbone.parameters():
                param.requires_grad = False
        return self.train(
            self.model,
            self.datamodule,
            callbacks=callbacks,
            max_epochs=max_epochs,
            min_epochs=min_epochs,
        )

模型评估

pytorch_tabular.TabularModel.predict(test, quantiles=[0.25, 0.5, 0.75], n_samples=100, ret_logits=False, include_input_features=False, device=None, progress_bar=None, test_time_augmentation=False, num_tta=5, alpha_tta=0.1, aggregate_tta='mean', tta_seed=42)

使用训练好的模型对新数据进行预测,并以数据框形式返回结果.

Parameters:

Name Type Description Default
test DataFrame

包含训练期间定义的特征的新数据框

required
quantiles 可选[List]

对于概率模型(如混合密度网络),这指定了除了central_tendency之外要提取的不同分位数并添加到数据框中. 对于其他模型,此参数被忽略.默认为 [0.25, 0.5, 0.75]

[0.25, 0.5, 0.75]
n_samples 可选[int]

从后验分布中抽取的样本数量,用于估计分位数. 对于非概率模型,此参数被忽略.默认为 100

100
ret_logits bool

标志,用于返回原始模型输出/logits(除了骨干特征)以及数据框.默认为 False

False
include_input_features bool

已弃用: 标志,用于在返回的数据框中包含输入特征.默认为 True

False
progress_bar Optional[str]

选择用于跟踪进度的进度条."rich" 或 "tqdm" 将设置相应的进度条.如果为 None,则不显示进度条.

None
test_time_augmentation bool

如果为 True,将使用测试时增强来生成预测. 该方法与此处描述的方法非常相似, 但我们还在嵌入输入中添加噪声以处理分类特征. (x_{aug} = x_{orig} + lpha * \epsilon) 其中 (\epsilon \sim \mathcal{N}(0, 1)) 默认为 False

False
num_tta float

为 TTA 运行的增强次数.默认为 0.0

5
alpha_tta float

要添加到输入特征的高斯噪声的标准差

0.1
aggregate_tta (Union[str, Callable], 可选)

用于聚合每次增强预测的函数.如果为 str,应为 "mean", "median", "min", 或 "max" 之一 用于回归.对于分类,前面的选项应用于置信度分数(软投票),然后转换为最终预测.分类还提供了一个额外的选项 "hard_voting". 如果为可调用对象,应为一个函数,该函数接收一个包含 3D 数组(num_samples, num_cv, num_targets)的列表,并返回一个 2D 数组 的最终概率(num_samples, num_targets).默认为 "mean".

'mean'
tta_seed int

用于 TTA 中添加噪声的随机种子.默认为 42.

42

Returns:

Name Type Description
DataFrame DataFrame

返回一个包含预测和特征(如果 include_input_features=True)的数据框. 如果是分类,则返回概率和最终预测

Source code in src/pytorch_tabular/tabular_model.py
    def predict(
        self,
        test: DataFrame,
        quantiles: Optional[List] = [0.25, 0.5, 0.75],
        n_samples: Optional[int] = 100,
        ret_logits=False,
        include_input_features: bool = False,
        device: Optional[torch.device] = None,
        progress_bar: Optional[str] = None,
        test_time_augmentation: Optional[bool] = False,
        num_tta: Optional[float] = 5,
        alpha_tta: Optional[float] = 0.1,
        aggregate_tta: Optional[str] = "mean",
        tta_seed: Optional[int] = 42,
    ) -> DataFrame:
        """使用训练好的模型对新数据进行预测,并以数据框形式返回结果.

Parameters:
    test (DataFrame): 包含训练期间定义的特征的新数据框

    quantiles (可选[List]): 对于概率模型(如混合密度网络),这指定了除了`central_tendency`之外要提取的不同分位数并添加到数据框中.
        对于其他模型,此参数被忽略.默认为 [0.25, 0.5, 0.75]

    n_samples (可选[int]): 从后验分布中抽取的样本数量,用于估计分位数.
        对于非概率模型,此参数被忽略.默认为 100

    ret_logits (bool): 标志,用于返回原始模型输出/logits(除了骨干特征)以及数据框.默认为 False

    include_input_features (bool): 已弃用: 标志,用于在返回的数据框中包含输入特征.默认为 True

    progress_bar: 选择用于跟踪进度的进度条."rich" 或 "tqdm" 将设置相应的进度条.如果为 None,则不显示进度条.

    test_time_augmentation (bool): 如果为 True,将使用测试时增强来生成预测.
        该方法与[此处](https://kozodoi.me/blog/20210908/tta-tabular)描述的方法非常相似,
        但我们还在嵌入输入中添加噪声以处理分类特征.                \(x_{aug} = x_{orig} + \alpha * \epsilon\) 其中 \(\epsilon \sim \mathcal{N}(0, 1)\)
        默认为 False
    num_tta (float): 为 TTA 运行的增强次数.默认为 0.0

    alpha_tta (float): 要添加到输入特征的高斯噪声的标准差

    aggregate_tta (Union[str, Callable], 可选): 用于聚合每次增强预测的函数.如果为 str,应为 "mean", "median", "min", 或 "max" 之一
        用于回归.对于分类,前面的选项应用于置信度分数(软投票),然后转换为最终预测.分类还提供了一个额外的选项
        "hard_voting".
        如果为可调用对象,应为一个函数,该函数接收一个包含 3D 数组(num_samples, num_cv, num_targets)的列表,并返回一个 2D 数组
        的最终概率(num_samples, num_targets).默认为 "mean".

    tta_seed (int): 用于 TTA 中添加噪声的随机种子.默认为 42.

Returns:
    DataFrame: 返回一个包含预测和特征(如果 `include_input_features=True`)的数据框.
        如果是分类,则返回概率和最终预测
"""
        warnings.warn(
            "`include_input_features` will be deprecated in the next release."
            " Please add index columns to the test dataframe if you want to"
            " retain some features like the key or id",
            DeprecationWarning,
        )
        if test_time_augmentation:
            assert num_tta > 0, "num_tta should be greater than 0"
            assert alpha_tta > 0, "alpha_tta should be greater than 0"
            assert include_input_features is False, "include_input_features cannot be True for TTA."
            if not callable(aggregate_tta):
                assert aggregate_tta in [
                    "mean",
                    "median",
                    "min",
                    "max",
                    "hard_voting",
                ], "aggregate should be one of 'mean', 'median', 'min', 'max', or" " 'hard_voting'"
            if self.config.task == "regression":
                assert aggregate_tta != "hard_voting", "hard_voting is only available for classification"

            torch.manual_seed(tta_seed)

            def add_noise(module, input, output):
                return output + alpha_tta * torch.randn_like(output, memory_format=torch.contiguous_format)

            # Register the hook to the embedding_layer
            handle = self.model.embedding_layer.register_forward_hook(add_noise)
            pred_prob_l = []
            for _ in range(num_tta):
                pred_df = self._predict(
                    test,
                    quantiles,
                    n_samples,
                    ret_logits,
                    include_input_features=False,
                    device=device,
                    progress_bar=progress_bar or "None",
                )
                pred_idx = pred_df.index
                if self.config.task == "classification":
                    pred_prob_l.append(pred_df.values[:, : -len(self.config.target)])
                elif self.config.task == "regression":
                    pred_prob_l.append(pred_df.values)
            pred_df = self._combine_predictions(pred_prob_l, pred_idx, aggregate_tta, None)
            # Remove the hook
            handle.remove()
        else:
            pred_df = self._predict(
                test,
                quantiles,
                n_samples,
                ret_logits,
                include_input_features,
                device,
                progress_bar,
            )
        return pred_df

pytorch_tabular.TabularModel.evaluate(test=None, test_loader=None, ckpt_path=None, verbose=True)

使用配置中已设置的损失和指标对数据框进行评估.

Parameters:

Name Type Description Default
test 可选[DataFrame]

要评估的数据框.如果未提供,将尝试使用拟合期间提供的测试数据.如果两者均未提供,将返回一个空字典.

None
test_loader (可选[DataLoader], 可选)

用于评估的数据加载器.如果提供,将使用该数据加载器而不是测试数据框或拟合期间提供的测试数据.默认为None.

None
ckpt_path (可选[Union[str, Path]], 可选)

要加载的检查点路径.如果未提供,将尝试使用训练期间的最佳检查点.

None
verbose (bool, 可选)

如果为真,将打印结果.默认为True.

True

Returns: 最终的测试结果字典.

Source code in src/pytorch_tabular/tabular_model.py
    def evaluate(
        self,
        test: Optional[DataFrame] = None,
        test_loader: Optional[torch.utils.data.DataLoader] = None,
        ckpt_path: Optional[Union[str, Path]] = None,
        verbose: bool = True,
    ) -> Union[dict, list]:
        """    使用配置中已设置的损失和指标对数据框进行评估.

Parameters:
    test (可选[DataFrame]): 要评估的数据框.如果未提供,将尝试使用拟合期间提供的测试数据.如果两者均未提供,将返回一个空字典.

    test_loader (可选[torch.utils.data.DataLoader], 可选): 用于评估的数据加载器.如果提供,将使用该数据加载器而不是测试数据框或拟合期间提供的测试数据.默认为None.

    ckpt_path (可选[Union[str, Path]], 可选): 要加载的检查点路径.如果未提供,将尝试使用训练期间的最佳检查点.

    verbose (bool, 可选): 如果为真,将打印结果.默认为True.
Returns:
    最终的测试结果字典.
"""
        assert not (test_loader is None and test is None), (
            "Either `test_loader` or `test` should be provided."
            " If `test_loader` is not provided, `test` should be provided."
        )
        if test_loader is None:
            test_loader = self.datamodule.prepare_inference_dataloader(test)
        result = self.trainer.test(
            model=self.model,
            dataloaders=test_loader,
            ckpt_path=ckpt_path,
            verbose=verbose,
        )
        return result

pytorch_tabular.TabularModel.cross_validate(cv, train, metric=None, return_oof=False, groups=None, verbose=True, reset_datamodule=True, handle_oom=True, **kwargs)

交叉验证模型.

Parameters:

Name Type Description Default
cv 可选[Union[int, Iterable, BaseCrossValidator]]

确定交叉验证的分割策略. 可能的输入包括:

  • None,使用默认的5折交叉验证(回归问题使用KFold,分类问题使用StratifiedKFold),
  • 整数,指定(Stratified)KFold中的折数,
  • 一个可迭代对象,生成(train, test)索引数组的分割.
  • 一个scikit-learn的CV分割器.
required
train DataFrame

带有标签的训练数据

required
metric (可选[Union[str, Callable]], 可选)

用于评估的指标. 如果为None,将使用配置中的第一个指标.如果提供字符串,将使用定义的该指标.如果提供可调用对象,将使用该函数作为指标.我们期望可调用对象的形式为metric(y_true, y_pred).对于分类问题,y_pred是一个包含每个类别的概率(_probability)和最终预测(prediction)的数据框.对于回归问题,它是一个包含最终预测(_prediction)的数据框. 默认为None.

None
return_oof (bool, 可选)

如果为True,将返回交叉验证结果以及折叠外的预测. 默认为False.

False
groups (可选[Union[str, ndarray]], 可选)

用于分割样本的组标签.如果提供,将作为交叉验证器split方法的groups参数. 如果输入为字符串,将使用输入数据框中该名称的列作为组标签.如果输入为类数组对象,将使用该组标签.唯一的约束是组标签的大小应与输入数据框的行数相同. 默认为None.

None
verbose (bool, 可选)

如果为True,将记录结果. 默认为True.

True
reset_datamodule (bool, 可选)

如果为True,将在每次迭代时重置datamodule. 这将更慢,因为我们将为每个折叠拟合变换.如果为False,我们采用一种近似方法,即一旦变换在第一个折叠上拟合,它们将对所有其他折叠有效. 默认为True.

True
handle_oom (bool, 可选)

如果为True,将优雅地处理内存不足错误.

True
**kwargs

传递给模型fit方法的其他关键字参数.

{}

Returns:

Name Type Description
DataFrame

包含交叉验证结果的数据框

Source code in src/pytorch_tabular/tabular_model.py
    def cross_validate(
        self,
        cv: Optional[Union[int, Iterable, BaseCrossValidator]],
        train: DataFrame,
        metric: Optional[Union[str, Callable]] = None,
        return_oof: bool = False,
        groups: Optional[Union[str, np.ndarray]] = None,
        verbose: bool = True,
        reset_datamodule: bool = True,
        handle_oom: bool = True,
        **kwargs,
    ):
        """交叉验证模型.

Parameters:
    cv (可选[Union[int, Iterable, BaseCrossValidator]]): 确定交叉验证的分割策略.
        可能的输入包括:

        - None,使用默认的5折交叉验证(回归问题使用KFold,分类问题使用StratifiedKFold),
        - 整数,指定(Stratified)KFold中的折数,
        - 一个可迭代对象,生成(train, test)索引数组的分割.
        - 一个scikit-learn的CV分割器.

    train (DataFrame): 带有标签的训练数据

    metric (可选[Union[str, Callable]], 可选): 用于评估的指标.
        如果为None,将使用配置中的第一个指标.如果提供字符串,将使用定义的该指标.如果提供可调用对象,将使用该函数作为指标.我们期望可调用对象的形式为`metric(y_true, y_pred)`.对于分类问题,`y_pred`是一个包含每个类别的概率(<class>_probability)和最终预测(prediction)的数据框.对于回归问题,它是一个包含最终预测(<target>_prediction)的数据框.
        默认为None.

    return_oof (bool, 可选): 如果为True,将返回交叉验证结果以及折叠外的预测.
        默认为False.

    groups (可选[Union[str, np.ndarray]], 可选): 用于分割样本的组标签.如果提供,将作为交叉验证器`split`方法的`groups`参数.
        如果输入为字符串,将使用输入数据框中该名称的列作为组标签.如果输入为类数组对象,将使用该组标签.唯一的约束是组标签的大小应与输入数据框的行数相同.
        默认为None.

    verbose (bool, 可选): 如果为True,将记录结果.
        默认为True.

    reset_datamodule (bool, 可选): 如果为True,将在每次迭代时重置datamodule.
        这将更慢,因为我们将为每个折叠拟合变换.如果为False,我们采用一种近似方法,即一旦变换在第一个折叠上拟合,它们将对所有其他折叠有效.
        默认为True.

    handle_oom (bool, 可选): 如果为True,将优雅地处理内存不足错误.
    **kwargs: 传递给模型`fit`方法的其他关键字参数.

Returns:
    DataFrame: 包含交叉验证结果的数据框
"""
        cv = self._check_cv(cv)
        prep_dl_kwargs, prep_model_kwargs, train_kwargs = self._split_kwargs(kwargs)
        is_callable_metric = False
        if metric is None:
            metric = "test_" + self.config.metrics[0]
        elif isinstance(metric, str):
            metric = metric if metric.startswith("test_") else "test_" + metric
        elif callable(metric):
            is_callable_metric = True

        if isinstance(cv, BaseCrossValidator):
            it = enumerate(cv.split(train, y=train[self.config.target], groups=groups))
        else:
            # when iterable is directly passed
            it = enumerate(cv)
        cv_metrics = []
        datamodule = None
        model = None
        oof_preds = []
        for fold, (train_idx, val_idx) in it:
            if verbose:
                logger.info(f"Running Fold {fold+1}/{cv.get_n_splits()}")
            # train_fold = train.iloc[train_idx]
            # val_fold = train.iloc[val_idx]
            if reset_datamodule:
                datamodule = None
            if datamodule is None:
                # Initialize datamodule and model in the first fold
                # uses train data from this fold to fit all transformers
                datamodule = self.prepare_dataloader(
                    train=train.iloc[train_idx], validation=train.iloc[val_idx], seed=42, **prep_dl_kwargs
                )
                model = self.prepare_model(datamodule, **prep_model_kwargs)
            else:
                # Preprocess the current fold data using the fitted transformers and save in datamodule
                datamodule.train, _ = datamodule.preprocess_data(train.iloc[train_idx], stage="inference")
                datamodule.validation, _ = datamodule.preprocess_data(train.iloc[val_idx], stage="inference")

            # Train the model
            handle_oom = train_kwargs.pop("handle_oom", handle_oom)
            self.train(model, datamodule, handle_oom=handle_oom, **train_kwargs)
            if return_oof or is_callable_metric:
                preds = self.predict(train.iloc[val_idx], include_input_features=False)
                oof_preds.append(preds)
            if is_callable_metric:
                cv_metrics.append(metric(train.iloc[val_idx][self.config.target], preds))
            else:
                result = self.evaluate(train.iloc[val_idx], verbose=False)
                cv_metrics.append(result[0][metric])
            if verbose:
                logger.info(f"Fold {fold+1}/{cv.get_n_splits()} score: {cv_metrics[-1]}")
            self.model.reset_weights()
        return cv_metrics, oof_preds

pytorch_tabular.TabularModel.bagging_predict(cv, train, test, groups=None, verbose=True, reset_datamodule=True, return_raw_predictions=False, aggregate='mean', weights=None, handle_oom=True, **kwargs)

Bagging 预测测试数据.

Parameters:

Name Type Description Default
cv 可选[Union[int, Iterable, BaseCrossValidator]]

确定交叉验证的分割策略. 可能的输入包括:

  • None,使用默认的5折交叉验证(回归使用KFold,分类使用StratifiedKFold),
  • 整数,指定(Stratified)KFold中的折数,
  • 可迭代对象,生成(训练, 测试)索引对作为数组.
  • scikit-learn的CV分割器.
required
train DataFrame

带有标签的训练数据

required
test DataFrame

需要预测的测试数据

required
groups (可选[Union[str, ndarray]], 可选)

在分割时使用的样本组标签.如果提供,将作为交叉验证器split方法的groups参数. 如果输入是字符串,将使用输入数据框中该名称的列作为组标签.如果输入是类数组对象,将使用该组标签. 唯一的约束是组标签的大小应与输入数据框的行数相同.默认为None.

None
verbose (bool, 可选)

如果为True,将记录结果.默认为True.

True
reset_datamodule (bool, 可选)

如果为True,将在每次迭代时重置datamodule. 由于每次折叠都会拟合变换,因此速度会较慢.如果为False,我们采用一种近似方法,即一旦在第一次折叠上拟合了变换, 它们将对所有其他折叠有效.默认为True.

True
return_raw_predictions (bool, 可选)

如果为True,将返回每次折叠的原始预测.默认为False.

False
aggregate (Union[str, Callable], 可选)

用于聚合每次折叠预测的函数.如果为字符串,应为"mean"、"median"、"min"或"max"之一, 用于回归.对于分类,前面的选项应用于置信度分数(软投票),然后转换为最终预测.分类还提供额外的选项"hard_voting". 如果为可调用对象,应为接受3D数组列表(样本数, 交叉验证数, 目标数)并返回最终概率2D数组(样本数, 目标数)的函数.默认为"mean".

'mean'
weights (可选[List[float]], 可选)

用于聚合每次折叠预测的权重.如果为None,将使用相等的权重.仅在aggregate为"mean"时使用. 默认为None.

None
handle_oom (bool, 可选)

如果为True,将优雅地处理内存不足错误.

True
**kwargs

传递给模型fit方法的其他关键字参数.

{}

Returns:

Name Type Description
DataFrame

包含集成预测的数据框.

Source code in src/pytorch_tabular/tabular_model.py
    def bagging_predict(
        self,
        cv: Optional[Union[int, Iterable, BaseCrossValidator]],
        train: DataFrame,
        test: DataFrame,
        groups: Optional[Union[str, np.ndarray]] = None,
        verbose: bool = True,
        reset_datamodule: bool = True,
        return_raw_predictions: bool = False,
        aggregate: Union[str, Callable] = "mean",
        weights: Optional[List[float]] = None,
        handle_oom: bool = True,
        **kwargs,
    ):
        """    Bagging 预测测试数据.

Parameters:
    cv (可选[Union[int, Iterable, BaseCrossValidator]]): 确定交叉验证的分割策略.
        可能的输入包括:

        - None,使用默认的5折交叉验证(回归使用KFold,分类使用StratifiedKFold),
        - 整数,指定(Stratified)KFold中的折数,
        - 可迭代对象,生成(训练, 测试)索引对作为数组.
        - scikit-learn的CV分割器.

    train (DataFrame): 带有标签的训练数据

    test (DataFrame): 需要预测的测试数据

    groups (可选[Union[str, np.ndarray]], 可选): 在分割时使用的样本组标签.如果提供,将作为交叉验证器`split`方法的`groups`参数.
        如果输入是字符串,将使用输入数据框中该名称的列作为组标签.如果输入是类数组对象,将使用该组标签.
        唯一的约束是组标签的大小应与输入数据框的行数相同.默认为None.

    verbose (bool, 可选): 如果为True,将记录结果.默认为True.

    reset_datamodule (bool, 可选): 如果为True,将在每次迭代时重置datamodule.
        由于每次折叠都会拟合变换,因此速度会较慢.如果为False,我们采用一种近似方法,即一旦在第一次折叠上拟合了变换,
        它们将对所有其他折叠有效.默认为True.

    return_raw_predictions (bool, 可选): 如果为True,将返回每次折叠的原始预测.默认为False.

    aggregate (Union[str, Callable], 可选): 用于聚合每次折叠预测的函数.如果为字符串,应为"mean"、"median"、"min"或"max"之一,
        用于回归.对于分类,前面的选项应用于置信度分数(软投票),然后转换为最终预测.分类还提供额外的选项"hard_voting".
        如果为可调用对象,应为接受3D数组列表(样本数, 交叉验证数, 目标数)并返回最终概率2D数组(样本数, 目标数)的函数.默认为"mean".

    weights (可选[List[float]], 可选): 用于聚合每次折叠预测的权重.如果为None,将使用相等的权重.仅在`aggregate`为"mean"时使用.
        默认为None.

    handle_oom (bool, 可选): 如果为True,将优雅地处理内存不足错误.

    **kwargs: 传递给模型`fit`方法的其他关键字参数.

Returns:
    DataFrame: 包含集成预测的数据框.
"""
        if weights is not None:
            assert len(weights) == cv.n_splits, "Number of weights should be equal to the number of folds"
        assert self.config.task in [
            "classification",
            "regression",
        ], "Bagging is only available for classification and regression"
        if not callable(aggregate):
            assert aggregate in ["mean", "median", "min", "max", "hard_voting"], (
                "aggregate should be one of 'mean', 'median', 'min', 'max', or" " 'hard_voting'"
            )
        if self.config.task == "regression":
            assert aggregate != "hard_voting", "hard_voting is only available for classification"
        cv = self._check_cv(cv)
        prep_dl_kwargs, prep_model_kwargs, train_kwargs = self._split_kwargs(kwargs)
        pred_prob_l = []
        datamodule = None
        model = None
        for fold, (train_idx, val_idx) in enumerate(cv.split(train, y=train[self.config.target], groups=groups)):
            if verbose:
                logger.info(f"Running Fold {fold+1}/{cv.get_n_splits()}")
            train_fold = train.iloc[train_idx]
            val_fold = train.iloc[val_idx]
            if reset_datamodule:
                datamodule = None
            if datamodule is None:
                # Initialize datamodule and model in the first fold
                # uses train data from this fold to fit all transformers
                datamodule = self.prepare_dataloader(train=train_fold, validation=val_fold, seed=42, **prep_dl_kwargs)
                model = self.prepare_model(datamodule, **prep_model_kwargs)
            else:
                # Preprocess the current fold data using the fitted transformers and save in datamodule
                datamodule.train, _ = datamodule.preprocess_data(train_fold, stage="inference")
                datamodule.validation, _ = datamodule.preprocess_data(val_fold, stage="inference")

            # Train the model
            handle_oom = train_kwargs.pop("handle_oom", handle_oom)
            self.train(model, datamodule, handle_oom=handle_oom, **train_kwargs)
            fold_preds = self.predict(test, include_input_features=False)
            pred_idx = fold_preds.index
            if self.config.task == "classification":
                pred_prob_l.append(fold_preds.values[:, : -len(self.config.target)])
            elif self.config.task == "regression":
                pred_prob_l.append(fold_preds.values)
            if verbose:
                logger.info(f"Fold {fold+1}/{cv.get_n_splits()} prediction done")
            self.model.reset_weights()
        pred_df = self._combine_predictions(pred_prob_l, pred_idx, aggregate, weights)
        if return_raw_predictions:
            return pred_df, pred_prob_l
        else:
            return pred_df

模型和数据模块的保存与加载

保存模型、数据模块和配置

pytorch_tabular.TabularModel.save_config(dir)

将配置保存到指定目录.

Source code in src/pytorch_tabular/tabular_model.py
def save_config(self, dir: str) -> None:
    """将配置保存到指定目录."""
    with open(os.path.join(dir, "config.yml"), "w") as fp:
        OmegaConf.save(self.config, fp, resolve=True)

pytorch_tabular.TabularModel.save_datamodule(dir, inference_only=False)

Saves the datamodule in the specified directory.

Parameters:

Name Type Description Default
dir str

保存datamodule的目录路径

required
inference_only bool

如果为True,将仅保存不带数据的推理datamodule. 这不能用于进一步训练,但可用于推理.默认为False.

False
Source code in src/pytorch_tabular/tabular_model.py
    def save_datamodule(self, dir: str, inference_only: bool = False) -> None:
        """    Saves the datamodule in the specified directory.

Args:
    dir (str): 保存datamodule的目录路径
    inference_only (bool): 如果为True,将仅保存不带数据的推理datamodule.
        这不能用于进一步训练,但可用于推理.默认为False.
"""
        if inference_only:
            dm = self.datamodule.inference_only_copy()
        else:
            dm = self.datamodule

        joblib.dump(dm, os.path.join(dir, "datamodule.sav"))

pytorch_tabular.TabularModel.save_model(dir, inference_only=False)

保存模型和检查点在指定目录中.

Parameters:

Name Type Description Default
dir str

保存模型的目录路径

required
inference_only bool

如果为True,将仅保存数据模块的推理版本

False
Source code in src/pytorch_tabular/tabular_model.py
    def save_model(self, dir: str, inference_only: bool = False) -> None:
        """    保存模型和检查点在指定目录中.

Parameters:
    dir (str): 保存模型的目录路径
    inference_only (bool): 如果为True,将仅保存数据模块的推理版本
"""
        if os.path.exists(dir) and (os.listdir(dir)):
            logger.warning("Directory is not empty. Overwriting the contents.")
            for f in os.listdir(dir):
                os.remove(os.path.join(dir, f))
        os.makedirs(dir, exist_ok=True)
        self.save_config(dir)
        self.save_datamodule(dir, inference_only=inference_only)
        if hasattr(self.config, "log_target") and self.config.log_target is not None:
            joblib.dump(self.logger, os.path.join(dir, "exp_logger.sav"))
        if hasattr(self, "callbacks"):
            joblib.dump(self.callbacks, os.path.join(dir, "callbacks.sav"))
        self.trainer.save_checkpoint(os.path.join(dir, "model.ckpt"))
        custom_params = {}
        custom_params["custom_loss"] = getattr(self.model, "custom_loss", None)
        custom_params["custom_metrics"] = getattr(self.model, "custom_metrics", None)
        custom_params["custom_metrics_prob_inputs"] = getattr(self.model, "custom_metrics_prob_inputs", None)
        custom_params["custom_optimizer"] = getattr(self.model, "custom_optimizer", None)
        custom_params["custom_optimizer_params"] = getattr(self.model, "custom_optimizer_params", None)
        joblib.dump(custom_params, os.path.join(dir, "custom_params.sav"))
        if self.custom_model:
            joblib.dump(self.model_callable, os.path.join(dir, "custom_model_callable.sav"))

pytorch_tabular.TabularModel.save_model_for_inference(path, kind='pytorch', onnx_export_params={'opset_version': 12})

保存模型以供推理.

Parameters:

Name Type Description Default
path Union[str, Path]

保存模型的路径

required
kind str

"pytorch" 或 "onnx"(实验性)

'pytorch'
onnx_export_params Dict

传递给 torch.onnx.export 的 ONNX 导出参数

{'opset_version': 12}

Returns:

Name Type Description
bool bool

如果模型成功保存则为 True

Source code in src/pytorch_tabular/tabular_model.py
    def save_model_for_inference(
        self,
        path: Union[str, Path],
        kind: str = "pytorch",
        onnx_export_params: Dict = {"opset_version": 12},
    ) -> bool:
        """保存模型以供推理.

Parameters:
    path (Union[str, Path]): 保存模型的路径
    kind (str): "pytorch" 或 "onnx"(实验性)
    onnx_export_params (Dict): 传递给 torch.onnx.export 的 ONNX 导出参数

Returns:
    bool: 如果模型成功保存则为 True
"""
        if kind == "pytorch":
            torch.save(self.model, str(path))
            return True
        elif kind == "onnx":
            # Export the model
            onnx_export_params["input_names"] = ["categorical", "continuous"]
            onnx_export_params["output_names"] = onnx_export_params.get("output_names", ["output"])
            onnx_export_params["dynamic_axes"] = {
                onnx_export_params["input_names"][0]: {0: "batch_size"},
                onnx_export_params["output_names"][0]: {0: "batch_size"},
            }
            cat = torch.zeros(
                self.config.batch_size,
                len(self.config.categorical_cols),
                dtype=torch.int,
            )
            cont = torch.randn(
                self.config.batch_size,
                len(self.config.continuous_cols),
                requires_grad=True,
            )
            x = {"continuous": cont, "categorical": cat}
            torch.onnx.export(self.model, x, str(path), **onnx_export_params)
            return True
        else:
            raise ValueError("`kind` must be either pytorch or onnx")

pytorch_tabular.TabularModel.save_weights(path)

保存模型权重到指定目录.

Parameters:

Name Type Description Default
path str

保存模型的文件路径

required
Source code in src/pytorch_tabular/tabular_model.py
    def save_weights(self, path: Union[str, Path]) -> None:
        """保存模型权重到指定目录.

Parameters:
    path (str): 保存模型的文件路径
"""
        torch.save(self.model.state_dict(), path)

加载模型和数据模块

pytorch_tabular.TabularModel.load_best_model()

在训练完成后加载最佳模型.

Source code in src/pytorch_tabular/tabular_model.py
def load_best_model(self) -> None:
    """在训练完成后加载最佳模型."""
    if self.trainer.checkpoint_callback is not None:
        if self.verbose:
            logger.info("Loading the best model")
        ckpt_path = self.trainer.checkpoint_callback.best_model_path
        if ckpt_path != "":
            if self.verbose:
                logger.debug(f"Model Checkpoint: {ckpt_path}")
            ckpt = pl_load(ckpt_path, map_location=lambda storage, loc: storage)
            self.model.load_state_dict(ckpt["state_dict"])
        else:
            logger.warning("No best model available to load. Did you run it more than 1" " epoch?...")
    else:
        logger.warning(
            "No best model available to load. Checkpoint Callback needs to be" " enabled for this to work"
        )

pytorch_tabular.TabularModel.load_model(dir, map_location=None, strict=True) classmethod

加载保存在目录中的模型.

Parameters:

Name Type Description Default
dir str

保存模型的目录,包含检查点

required
map_location Union[Dict[str, str], str, device, int, Callable, None])

如果你的检查点保存了一个GPU模型,而你现在在CPU上或不同数量的GPU上加载,使用这个参数来映射到新的设置.行为与torch.load()中的相同

None
strict bool)

是否严格要求checkpoint_path中的键与该模块的状态字典返回的键完全匹配.默认值: True.

True

Returns:

Name Type Description
TabularModel TabularModel

保存的TabularModel

Source code in src/pytorch_tabular/tabular_model.py
    @classmethod
    def load_model(cls, dir: str, map_location=None, strict=True):
        """加载保存在目录中的模型.

Parameters:
    dir (str): 保存模型的目录,包含检查点
    map_location (Union[Dict[str, str], str, device, int, Callable, None]) : 如果你的检查点保存了一个GPU模型,而你现在在CPU上或不同数量的GPU上加载,使用这个参数来映射到新的设置.行为与torch.load()中的相同
    strict (bool) : 是否严格要求checkpoint_path中的键与该模块的状态字典返回的键完全匹配.默认值: True.

Returns:
    TabularModel (TabularModel): 保存的TabularModel
"""
        config = OmegaConf.load(os.path.join(dir, "config.yml"))
        datamodule = joblib.load(os.path.join(dir, "datamodule.sav"))
        if (
            hasattr(config, "log_target")
            and (config.log_target is not None)
            and os.path.exists(os.path.join(dir, "exp_logger.sav"))
        ):
            logger = joblib.load(os.path.join(dir, "exp_logger.sav"))
        else:
            logger = None
        if os.path.exists(os.path.join(dir, "callbacks.sav")):
            callbacks = joblib.load(os.path.join(dir, "callbacks.sav"))
            # Excluding Gradient Accumulation Scheduler Callback as we are creating
            # a new one in trainer
            callbacks = [c for c in callbacks if not isinstance(c, GradientAccumulationScheduler)]
        else:
            callbacks = []
        if os.path.exists(os.path.join(dir, "custom_model_callable.sav")):
            model_callable = joblib.load(os.path.join(dir, "custom_model_callable.sav"))
            custom_model = True
        else:
            model_callable = getattr_nested(config._module_src, config._model_name)
            # model_callable = getattr(
            #     getattr(models, config._module_src), config._model_name
            # )
            custom_model = False
        inferred_config = datamodule.update_config(config)
        inferred_config = OmegaConf.structured(inferred_config)
        model_args = {
            "config": config,
            "inferred_config": inferred_config,
        }
        custom_params = joblib.load(os.path.join(dir, "custom_params.sav"))
        if custom_params.get("custom_loss") is not None:
            model_args["loss"] = "MSELoss"  # For compatibility. Not Used
        if custom_params.get("custom_metrics") is not None:
            model_args["metrics"] = ["mean_squared_error"]  # For compatibility. Not Used
            model_args["metrics_params"] = [{}]  # For compatibility. Not Used
            model_args["metrics_prob_inputs"] = [False]  # For compatibility. Not Used
        if custom_params.get("custom_optimizer") is not None:
            model_args["optimizer"] = "Adam"  # For compatibility. Not Used
        if custom_params.get("custom_optimizer_params") is not None:
            model_args["optimizer_params"] = {}  # For compatibility. Not Used

        # Initializing with default metrics, losses, and optimizers. Will revert once initialized
        try:
            model = model_callable.load_from_checkpoint(
                checkpoint_path=os.path.join(dir, "model.ckpt"),
                map_location=map_location,
                strict=strict,
                **model_args,
            )
        except RuntimeError as e:
            if (
                "Unexpected key(s) in state_dict" in str(e)
                and "loss.weight" in str(e)
                and "custom_loss.weight" in str(e)
            ):
                # Custom loss will be loaded after the model is initialized
                # continuing with strict=False
                model = model_callable.load_from_checkpoint(
                    checkpoint_path=os.path.join(dir, "model.ckpt"),
                    map_location=map_location,
                    strict=False,
                    **model_args,
                )
            else:
                raise e
        if custom_params.get("custom_optimizer") is not None:
            model.custom_optimizer = custom_params["custom_optimizer"]
        if custom_params.get("custom_optimizer_params") is not None:
            model.custom_optimizer_params = custom_params["custom_optimizer_params"]
        if custom_params.get("custom_loss") is not None:
            model.loss = custom_params["custom_loss"]
        if custom_params.get("custom_metrics") is not None:
            model.custom_metrics = custom_params.get("custom_metrics")
            model.hparams.metrics = [m.__name__ for m in custom_params.get("custom_metrics")]
            model.hparams.metrics_params = [{}]
            model.hparams.metrics_prob_input = custom_params.get("custom_metrics_prob_inputs")
        model._setup_loss()
        model._setup_metrics()
        tabular_model = cls(config=config, model_callable=model_callable)
        tabular_model.model = model
        tabular_model.custom_model = custom_model
        tabular_model.datamodule = datamodule
        tabular_model.callbacks = callbacks
        tabular_model.trainer = tabular_model._prepare_trainer(callbacks=callbacks)
        # tabular_model.trainer.model = model
        tabular_model.logger = logger
        return tabular_model

pytorch_tabular.TabularModel.load_weights(path)

加载指定目录中的模型权重.

Parameters:

Name Type Description Default
path str

要从中加载模型的文件路径

required

Returns:

Type Description
None

None

Source code in src/pytorch_tabular/tabular_model.py
    def load_weights(self, path: Union[str, Path]) -> None:
        """加载指定目录中的模型权重.

Parameters:
    path (str): 要从中加载模型的文件路径

Returns:
    None
"""
        self._load_weights(self.model, path)

其他功能

pytorch_tabular.TabularModel.find_learning_rate(model, datamodule, min_lr=1e-08, max_lr=1, num_training=100, mode='exponential', early_stop_threshold=4.0, plot=True, callbacks=None)

允许用户进行一系列良好的初始学习率测试,以减少选择合适起始学习率的猜测工作.

Parameters:

Name Type Description Default
model LightningModule

要训练的PyTorch Lightning模型.

required
datamodule TabularDatamodule

数据模块

required
min_lr Optional[float]

要调查的最小学习率

1e-08
max_lr Optional[float]

要调查的最大学习率

1
num_training Optional[int]

要测试的学习率数量

100
mode Optional[str]

搜索策略,可以是'linear'或'exponential'.如果设置为 'linear',学习率将通过在每个批次后线性增加来搜索.如果设置为'exponential',将指数增加学习率.

'exponential'
early_stop_threshold Optional[float]

停止搜索的阈值.如果在任何时候损失大于 early_stop_threshold*best_loss,则停止搜索.要禁用,请设置为None.

4.0
plot bool

如果为真,将使用matplotlib绘图

True
callbacks Optional[List]

如果提供,将添加到Trainer的回调中.

None

Returns:

Type Description
Tuple[float, DataFrame]

建议的学习率和学习率查找器的结果

Source code in src/pytorch_tabular/tabular_model.py
    def find_learning_rate(
        self,
        model: pl.LightningModule,
        datamodule: TabularDatamodule,
        min_lr: float = 1e-8,
        max_lr: float = 1,
        num_training: int = 100,
        mode: str = "exponential",
        early_stop_threshold: Optional[float] = 4.0,
        plot: bool = True,
        callbacks: Optional[List] = None,
    ) -> Tuple[float, DataFrame]:
        """    允许用户进行一系列良好的初始学习率测试,以减少选择合适起始学习率的猜测工作.

Parameters:
    model (pl.LightningModule): 要训练的PyTorch Lightning模型.

    datamodule (TabularDatamodule): 数据模块

    min_lr (Optional[float], optional): 要调查的最小学习率

    max_lr (Optional[float], optional): 要调查的最大学习率

    num_training (Optional[int], optional): 要测试的学习率数量

    mode (Optional[str], optional): 搜索策略,可以是'linear'或'exponential'.如果设置为
        'linear',学习率将通过在每个批次后线性增加来搜索.如果设置为'exponential',将指数增加学习率.

    early_stop_threshold (Optional[float], optional): 停止搜索的阈值.如果在任何时候损失大于
        early_stop_threshold*best_loss,则停止搜索.要禁用,请设置为None.

    plot (bool, optional): 如果为真,将使用matplotlib绘图

    callbacks (Optional[List], optional): 如果提供,将添加到Trainer的回调中.

Returns:
    建议的学习率和学习率查找器的结果
"""
        self._prepare_for_training(model, datamodule, callbacks, max_epochs=None, min_epochs=None)
        train_loader, _ = datamodule.train_dataloader(), datamodule.val_dataloader()
        lr_finder = Tuner(self.trainer).lr_find(
            model=self.model,
            train_dataloaders=train_loader,
            val_dataloaders=None,
            min_lr=min_lr,
            max_lr=max_lr,
            num_training=num_training,
            mode=mode,
            early_stop_threshold=early_stop_threshold,
        )
        if plot:
            fig = lr_finder.plot(suggest=True)
            fig.show()
        new_lr = lr_finder.suggestion()
        # cancelling the model and trainer that was loaded
        self.model = None
        self.trainer = None
        self.datamodule = None
        self.callbacks = None
        return new_lr, DataFrame(lr_finder.results)

pytorch_tabular.TabularModel.summary(model=None, max_depth=-1)

打印模型的摘要.

Parameters:

Name Type Description Default
max_depth int

遍历模块并显示在摘要中的最大深度. 默认为 -1,表示将显示所有模块.

-1
Source code in src/pytorch_tabular/tabular_model.py
    def summary(self, model=None, max_depth: int = -1) -> None:
        """    打印模型的摘要.

Parameters:
    max_depth (int): 遍历模块并显示在摘要中的最大深度.
        默认为 -1,表示将显示所有模块.
"""
        if model is not None:
            print(summarize(model, max_depth=max_depth))
        elif self.has_model:
            print(summarize(self.model, max_depth=max_depth))
        else:
            rich_print(f"[bold green]{self.__class__.__name__}[/bold green]")
            rich_print("-" * 100)
            rich_print("[bold yellow]Config[/bold yellow]")
            rich_print("-" * 100)
            pprint(self.config.__dict__["_content"])
            rich_print(
                ":triangular_flag:[bold red]Full Model Summary once model has "
                "been initialized or passed in as an argument[/bold red]"
            )

pytorch_tabular.TabularModel.feature_importance()

返回模型的特征重要性,格式为pandas DataFrame.

Source code in src/pytorch_tabular/tabular_model.py
def feature_importance(self) -> DataFrame:
    """返回模型的特征重要性,格式为pandas DataFrame."""
    return self.model.feature_importance()