ludwig 问题:在训练过程中经常预测相同的样本 翻译结果:在训练过程中经常预测相同的样本

ttvkxqim  于 2个月前  发布在  其他
关注(0)|答案(3)|浏览(32)

描述用例

我想通过检查训练过程中预测值的变化来监控几个样本,例如在每个epoch结束时。

描述您希望的解决方案

我希望利用Callbacks来实现这个功能。可以在Callback示例中保存包含样本的数据框,然后在on_epoch_end()方法中计算它们的预测值。
我没有成功实现它。然而,我已经找到了Predictor类和PandasDataset(Manager)类,但我有一种感觉,我开始使用一些不适合像我这样的最终用户使用的类。

ne5o7dgx

ne5o7dgx1#

你好,@MarselScheer。
在训练过程中,Ludwig使用ProgressTracker来存储评估期间的指标和其他工件。
进度跟踪器提供给on_eval_end()on_epoch_end()回调函数。
关于如何继续的建议:

  • 在评估期间,向已经传递给回调函数的ProgressTracker添加一小部分预测结果
  • 从评估中导出一部分预测结果并将它们通过回调函数一起传递给ProgressTracker
uelo1irk

uelo1irk2#

对不起,我不明白。我尝试总结你提出的伪代码

# The progress tracker is provided to the on_eval_end() and on_epoch_end() callbacks.
class MyCallback:

    def on_eval_end(..., progress_tracker):
        # during eval, add a small sample of predictions to ProgressTracker, which is already passed to callbacks
        progress_tracker.my_sample_preds.append(sample_preds)

    def on_epoch_end(..., progress_tracker):
        # export a sample of predictions from eval and pipe them through to callbacks, alongside ProgressTracker.
        self.my_export_of_sample_preds(progress_tracker.my_sample_preds)

我的主要问题是,我不知道如何在回调函数中计算 sample_preds 。我已经意识到有一些类可能会帮助,但目前我还不清楚如何正确地使用它们。这是我希望如何解决它的简单方法

class MyCallBack:
    def __init__(self, sample_df):
        self.df = sample_df

    def on_xyz(self, trainer, progress_tracker, ...):
        preds = trainer.model.predict(self.df)
        self.save(progress_tracker.steps, self.df, preds) # might store on disk or send to wandb or other service

问题是 trainer.model 不是 LudwigModel 。我看到训练器本身在训练过程中使用 Predictor 类进行评估
ludwig/ludwig/trainers/trainer.py
第1252行到第1259行的代码
| | predictor=Predictor( |
| | self.dist_model, |
| | batch_size=batch_size, |
| | distributed=self.distributed, |
| | report_tqdm_to_ray=self.report_tqdm_to_ray, |
| | model=self.model, |
| | ) |
| | metrics, _=predictor.batch_evaluation(dataset, collect_predictions=False, dataset_name=dataset_name) |
所以,如果我想要模仿这一点,我需要以某种方式将我的 polars/pandas-dataframe sample_df 转换为数据集,可能使用
ludwig/ludwig/data/dataset/pandas.py
第117行的代码
| | classPandasDatasetManager(DatasetManager): |
在这一点上,我感觉自己做得不对,深入了解内部是如何实现的,并开始使用不适合像我这样的最终用户使用的类。

ylamdve6

ylamdve63#

我进一步调查了代码库,这里是一个回调函数,至少不会再抛出错误了

from ludwig.data.preprocessing import preprocess_for_prediction
from ludwig.models.predictor import Predictor

class MyCallback(Callback):
    def __init__(self, df):
        self.df = df

    def on_preprocess_end(
        self,
        training_set,
        validation_set,
        test_set,
        training_set_metadata,
    ):
        self.training_set_metadata = training_set_metadata

    def on_train_start(self, model, config, config_fp):
        self.ds = preprocess_for_prediction(
            config=config,
            dataset=self.df,
            training_set_metadata=self.training_set_metadata,
        )[0]

    def on_epoch_end(self, trainer, progress_tracker, save_path):
        predictor = Predictor(
            trainer.dist_model,
            batch_size=128,
            distributed=trainer.distributed,
            report_tqdm_to_ray=False,
            model=trainer.model,
        )
        print(progress_tracker.steps, predictor.batch_predict(self.ds))

它对我来说或多或少是合理的,尽管我不知道是否已经将后处理应用于这些预测。然而,我仍然感觉我在使用Perdictor()和preprocess_for_prediction()来操作ludwig的内部工作原理,这感觉不太对。
希望这个具体的实现能让我更容易地找到正确的方向:)

相关问题