# 使用教程 这份教程帮助你快速跑通项目,并在现有任务的基础上替换数据、替换模型或新增任务。 ## 快速入门:跑通图片分类任务 建议先从 `tasks/image_classification/runner.py` 开始。图片分类任务最直观,只要准备好猫狗图片目录,就可以完整体验训练、样例验证和模型导出。 ### 1. 准备环境 本地开发使用 `environment.yml`: ```bash conda env create -f environment.yml conda activate general-dl ``` 如果环境已经存在,可以更新: ```bash conda env update -f environment.yml --prune conda activate general-dl ``` Linux 服务器或正式训练环境使用 `environment-linux.yml`。 ### 2. 准备数据 图片分类任务默认读取这些目录: ```text ~/data/cat-vs-dog/PetImagesMini/train ~/data/cat-vs-dog/PetImagesMini/val ~/data/cat-vs-dog/PetImagesMini/test ``` 目录应按 Keras 图片分类数据集格式组织,也就是每个类别一个子目录: ```text train/ Cat/ cat1.jpg Dog/ dog1.jpg val/ Cat/ Dog/ test/ Cat/ Dog/ ``` 如果你的数据放在别处,修改 `tasks/image_classification/runner.py` 中 `CatsVsDogsDataSource` 的 `train_path`、`validation_path` 和 `test_path`。 ### 3. 选择运行环境 项目用 `ENV` 环境变量选择配置: ```bash ENV=dev ENV=prod ``` `ENV=dev` 会选择开发配置,通常是小数据、小模型、少轮数,用来快速验证。`ENV=prod` 会选择正式配置,通常训练更久、模型更大。 如果不设置 `ENV`,默认使用正式配置。 ### 4. 运行训练 ```bash ENV=dev python -m tasks.image_classification.runner train ``` 训练时会生成: ```text local/tasks/image_classification/logs/config.txt local/tasks/image_classification/checkpoints/model_epoch_001.weights.h5 local/tasks/image_classification/tensorboard/ ``` 其中 `logs/config.txt` 会记录本次任务配置,`checkpoints` 保存训练检查点,`tensorboard` 保存 TensorBoard 日志。 ### 5. 使用训练检查点跑样例 如果你刚训练完,还没有导出模型,可以用训练检查点跑样例: ```bash ENV=dev python -m tasks.image_classification.runner test checkpoint=train ``` 这个动作会加载 `local/tasks/image_classification/checkpoints/` 下的训练检查点,并打印若干样例的真实类别、预测类别和置信度。 ### 6. 导出模型 ```bash ENV=dev python -m tasks.image_classification.runner export ``` 导出的 Keras 模型会保存到: ```text local/saved/models/image_classification/ ``` 正式环境的导出目录是: ```text saved/models/image_classification/ ``` ### 7. 使用导出模型跑样例 ```bash ENV=dev python -m tasks.image_classification.runner test ``` 不传 `checkpoint=train` 时,`test` 默认读取已导出的 `.keras` 模型。 ## 流水线教程:任务脚本应该长什么样 `tasks/*/runner.py` 是每个任务的配置中心。它通常做四件事: - 创建开发配置 - 创建正式配置 - 用 `resolve_env(dev_conf, prod_conf)` 按 `ENV` 选择配置 - 把选中的 Pipeline 交给 `PipelineRunner` 图片分类任务的核心结构如下: ```python pipeline = resolve_env( SupervisedModelPipeline( name="image_classification", data_source=..., model_builder=..., training_rule=... ), SupervisedModelPipeline( name="image_classification", data_source=..., model_builder=..., training_rule=..., checkpoint_load_rules=... ) ) pipeline_runner = PipelineRunner(pipeline) if __name__ == "__main__": pipeline_runner() ``` `PipelineRunner` 暴露三个动作: - `train`:训练模型 - `export`:从检查点导出 `.keras` 模型 - `test`:运行样例验证 `name` 很重要,它会影响产物路径。以 `name="image_classification"` 为例: ```text local/tasks/image_classification/logs/ local/tasks/image_classification/checkpoints/ local/tasks/image_classification/tensorboard/ local/saved/models/image_classification/ ``` 有监督任务使用 `SupervisedModelPipeline`,例如图片分类、图像分割。文本生成任务使用 `TextGenerationPipeline`,例如诗歌生成和 Wiki GPT。 ## 数据源教程:Pipeline 期待你提供什么 数据源负责把你的原始数据变成 Pipeline 能使用的数据。 ### 有监督任务数据源 有监督任务的数据源需要提供: - `training_ds()`:返回训练集和验证集 - `test_examples(model)`:使用模型跑几个样例,并打印或保存结果 最小形状如下: ```python class MyDataSource: def training_ds(self): train_ds = ... validation_ds = ... return train_ds, validation_ds def test_examples(self, model): examples_ds = ... for images, labels in examples_ds: predictions = model.predict(images) print(predictions) ``` `training_ds()` 返回的两个对象会直接传给 Keras 的 `model.fit()`。`test_examples(model)` 接收的是可用于推理的 Keras 模型。 ### 文本生成任务数据源 文本生成任务的数据源需要提供: - `doc_ds()`:返回原始文本数据 - `tokens_ds()`:返回训练用 token 数据 - `tokenizer_bundle()`:返回分词器、反解码函数、词表大小和结束标记等推理资源 最小形状如下: ```python class MyTextDataSource: data_dir = "data/my_text" sequence_length = 100 batch_size = 32 validation_batches = 0 def doc_ds(self): return docs_ds def tokens_ds(self): return tokens_ds def tokenizer_bundle(self): return tokenizer_bundle ``` `tokens_ds()` 返回的数据应能被文本模型训练使用,通常每个元素是 `(input_ids, target_ids)`。批次大小和验证集切分相关配置统一放在数据源中配置。 ## 模型构建教程:Pipeline 期待模型构建器做什么 模型构建器负责创建训练模型、把训练产物转换成推理产物,以及从完整模型文件加载推理产物。 ### 有监督模型构建器 有监督模型构建器需要提供: - `build_training_artifact()` - `compile_training_model(model)` - `convert_to_inference_artifact(training_artifact)` - `load_inference_artifact(model_path)` 最小形状如下: ```python class MyModelBuilder: def build_training_artifact(self): model = build_model() return ModelArtifact(model=model) def compile_training_model(self, model): model.compile( optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"] ) def convert_to_inference_artifact(self, training_artifact): return training_artifact def load_inference_artifact(self, model_path): model = keras.models.load_model(str(model_path)) return ModelArtifact(model=model) ``` 训练模型和推理模型可以相同,也可以不同。新手接入时可以先让 `convert_to_inference_artifact()` 直接返回 `training_artifact`。 ### 文本生成模型构建器 文本生成模型构建器需要提供: - `build_training_artifact(vocab_size, sequence_length)` - `compile_training_model(model)` - `convert_to_inference_artifact(training_artifact)` - `load_inference_artifact(model_path)` 最小形状如下: ```python class MyTextModelBuilder: def build_training_artifact(self, vocab_size, sequence_length): model = build_text_model(vocab_size, sequence_length) return TextGenerationModel(model=model, generate=generate_fn) def compile_training_model(self, model): model.compile(...) def convert_to_inference_artifact(self, training_artifact): return training_artifact def load_inference_artifact(self, model_path): model = keras.models.load_model(str(model_path)) return TextGenerationModel(model=model, generate=generate_fn) ``` 文本任务训练时会从数据源的 `tokenizer_bundle()` 里读取 `vocab_size`,从数据源读取 `sequence_length`,再交给模型构建器。 ## 从零接入一个新任务 推荐先复制一个已有任务,再逐步替换。 ### 1. 新建数据源 例如: ```text src/deep_learning/data/my_task/dataset.py ``` 如果是有监督任务,实现 `training_ds()` 和 `test_examples(model)`。如果是文本生成任务,实现 `doc_ds()`、`tokens_ds()` 和 `tokenizer_bundle()`。 ### 2. 新建模型构建器 例如: ```text src/deep_learning/models/my_task.py ``` 简单模型可以直接放在 `src/deep_learning/models/my_task.py`,模型较复杂时再建目录拆分。无论是哪种任务,都把模型构建、训练模型编译放在模型构建器里。 ### 3. 新建任务入口 例如: ```text tasks/my_task/runner.py ``` 先准备开发配置: ```python SupervisedModelPipeline( name="my_task", data_source=MyDataSource(...), model_builder=MyModelBuilder(...), training_rule=TrainingRule( epochs=1, steps_per_epoch=1 ) ) ``` 再准备正式配置,把数据路径、模型规模和训练轮数替换成正式训练需要的值。 ### 4. 先跑开发训练 ```bash ENV=dev python -m tasks.my_task.runner train ``` ### 5. 用训练检查点跑样例 ```bash ENV=dev python -m tasks.my_task.runner test checkpoint=train ``` ### 6. 导出模型 ```bash ENV=dev python -m tasks.my_task.runner export ``` ### 7. 用导出模型跑样例 ```bash ENV=dev python -m tasks.my_task.runner test ``` ## 常见问题 ### 检查点保存在哪里? 开发环境保存在: ```text local/tasks//checkpoints/ ``` 正式环境也会使用任务运行目录: ```text local/tasks//checkpoints/ ``` ### 导出模型保存在哪里? 开发环境保存在: ```text local/saved/models// ``` 正式环境保存在: ```text saved/models// ``` ### 日志保存在哪里? 任务配置日志保存在: ```text local/tasks//logs/config.txt ``` TensorBoard 日志保存在: ```text local/tasks//tensorboard/ ``` 启动 TensorBoard: ```bash tensorboard --logdir=local/tasks//tensorboard ``` ### 为什么同时需要开发配置和正式配置? 开发配置用于快速确认数据、模型和流程都能跑通。正式配置用于完整训练。这样可以先用很小的成本发现路径、形状和配置问题。 ### 如何指定加载第几轮 checkpoint? 在任务入口里配置 `CheckpointLoadRules`。例如图片分类正式配置中: ```python checkpoint_load_rules=CheckpointLoadRules( export=CheckpointConfig(epoch=13), test=CheckpointConfig(dirs=[resolve_saved("models/image_classification")], suffix=".keras") ) ``` 这表示导出时优先加载第 13 轮训练检查点,测试时从已导出的模型目录读取 `.keras` 文件。 ### `batch_size` 应该放在哪里? `batch_size` 和验证集切分相关配置统一放在数据源中配置。数据源决定数据如何生成,`TrainingRule` 只描述训练跑多久,例如 `epochs` 和 `steps_per_epoch`。 ### 没有 checkpoint 时哪些动作会失败? `train` 可以在没有检查点时从新模型开始训练。`export` 需要训练检查点。`test` 默认读取导出模型,如果没有导出模型会失败;如果传 `checkpoint=train`,它会读取训练检查点。 ### 文本任务为什么需要词表? 文本模型训练的是 token id,不是原始字符串。词表用来把文本转成 token id,也用来把生成结果从 token id 转回文字。文本任务的数据源需要通过 `tokenizer_bundle()` 提供这些资源。