general-deep-learning / docs /tutorial.md
yetrun's picture
ver3: 将源码迁入 src/deep_learning 包,重塑训练流水线,规范 data/model 契约
07cb7d3
|
Raw
History Blame Contribute Delete
11.7 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade

使用教程

这份教程帮助你快速跑通项目,并在现有任务的基础上替换数据、替换模型或新增任务。

快速入门:跑通图片分类任务

建议先从 tasks/image_classification/runner.py 开始。图片分类任务最直观,只要准备好猫狗图片目录,就可以完整体验训练、样例验证和模型导出。

1. 准备环境

本地开发使用 environment.yml

conda env create -f environment.yml
conda activate general-dl

如果环境已经存在,可以更新:

conda env update -f environment.yml --prune
conda activate general-dl

Linux 服务器或正式训练环境使用 environment-linux.yml

2. 准备数据

图片分类任务默认读取这些目录:

~/data/cat-vs-dog/PetImagesMini/train
~/data/cat-vs-dog/PetImagesMini/val
~/data/cat-vs-dog/PetImagesMini/test

目录应按 Keras 图片分类数据集格式组织,也就是每个类别一个子目录:

train/
  Cat/
    cat1.jpg
  Dog/
    dog1.jpg
val/
  Cat/
  Dog/
test/
  Cat/
  Dog/

如果你的数据放在别处,修改 tasks/image_classification/runner.pyCatsVsDogsDataSourcetrain_pathvalidation_pathtest_path

3. 选择运行环境

项目用 ENV 环境变量选择配置:

ENV=dev
ENV=prod

ENV=dev 会选择开发配置,通常是小数据、小模型、少轮数,用来快速验证。ENV=prod 会选择正式配置,通常训练更久、模型更大。

如果不设置 ENV,默认使用正式配置。

4. 运行训练

ENV=dev python -m tasks.image_classification.runner train

训练时会生成:

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. 使用训练检查点跑样例

如果你刚训练完,还没有导出模型,可以用训练检查点跑样例:

ENV=dev python -m tasks.image_classification.runner test checkpoint=train

这个动作会加载 local/tasks/image_classification/checkpoints/ 下的训练检查点,并打印若干样例的真实类别、预测类别和置信度。

6. 导出模型

ENV=dev python -m tasks.image_classification.runner export

导出的 Keras 模型会保存到:

local/saved/models/image_classification/

正式环境的导出目录是:

saved/models/image_classification/

7. 使用导出模型跑样例

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

图片分类任务的核心结构如下:

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" 为例:

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):使用模型跑几个样例,并打印或保存结果

最小形状如下:

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():返回分词器、反解码函数、词表大小和结束标记等推理资源

最小形状如下:

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)

最小形状如下:

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)

最小形状如下:

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. 新建数据源

例如:

src/deep_learning/data/my_task/dataset.py

如果是有监督任务,实现 training_ds()test_examples(model)。如果是文本生成任务,实现 doc_ds()tokens_ds()tokenizer_bundle()

2. 新建模型构建器

例如:

src/deep_learning/models/my_task.py

简单模型可以直接放在 src/deep_learning/models/my_task.py,模型较复杂时再建目录拆分。无论是哪种任务,都把模型构建、训练模型编译放在模型构建器里。

3. 新建任务入口

例如:

tasks/my_task/runner.py

先准备开发配置:

SupervisedModelPipeline(
    name="my_task",
    data_source=MyDataSource(...),
    model_builder=MyModelBuilder(...),
    training_rule=TrainingRule(
        epochs=1,
        steps_per_epoch=1
    )
)

再准备正式配置,把数据路径、模型规模和训练轮数替换成正式训练需要的值。

4. 先跑开发训练

ENV=dev python -m tasks.my_task.runner train

5. 用训练检查点跑样例

ENV=dev python -m tasks.my_task.runner test checkpoint=train

6. 导出模型

ENV=dev python -m tasks.my_task.runner export

7. 用导出模型跑样例

ENV=dev python -m tasks.my_task.runner test

常见问题

检查点保存在哪里?

开发环境保存在:

local/tasks/<task_name>/checkpoints/

正式环境也会使用任务运行目录:

local/tasks/<task_name>/checkpoints/

导出模型保存在哪里?

开发环境保存在:

local/saved/models/<task_name>/

正式环境保存在:

saved/models/<task_name>/

日志保存在哪里?

任务配置日志保存在:

local/tasks/<task_name>/logs/config.txt

TensorBoard 日志保存在:

local/tasks/<task_name>/tensorboard/

启动 TensorBoard:

tensorboard --logdir=local/tasks/<task_name>/tensorboard

为什么同时需要开发配置和正式配置?

开发配置用于快速确认数据、模型和流程都能跑通。正式配置用于完整训练。这样可以先用很小的成本发现路径、形状和配置问题。

如何指定加载第几轮 checkpoint?

在任务入口里配置 CheckpointLoadRules。例如图片分类正式配置中:

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 只描述训练跑多久,例如 epochssteps_per_epoch

没有 checkpoint 时哪些动作会失败?

train 可以在没有检查点时从新模型开始训练。export 需要训练检查点。test 默认读取导出模型,如果没有导出模型会失败;如果传 checkpoint=train,它会读取训练检查点。

文本任务为什么需要词表?

文本模型训练的是 token id,不是原始字符串。词表用来把文本转成 token id,也用来把生成结果从 token id 转回文字。文本任务的数据源需要通过 tokenizer_bundle() 提供这些资源。