# ft-transformer-test **Repository Path**: lang_junnan_admin/ft-transformer-test ## Basic Information - **Project Name**: ft-transformer-test - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-18 - **Last Updated**: 2026-09-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ft-transformer-test 基于 **FT-Transformer**(Feature Tokenizer + Transformer)的表格数据多分类项目。 FT-Transformer 来自论文 *Revisiting Deep Learning Models for Tabular Data*(NeurIPS 2021), 是目前表格数据上效果最好的深度学习模型之一。它的核心思想是把每条样本的每个特征都转成一个 向量(token),再用 Transformer 的自注意力机制学习特征之间的交互关系。 本项目目标是:**根据历史数据训练模型,当接收一组未知的特征值时,预测出它的结果类别**—— 这和你的业务(200 个特征 → 卫星健康/卫星偏移/严重偏离/掉落/未知 等结果)完全一致。 --- ## 1. 目录结构 ``` ft-transformer-test/ ├── pyproject.toml # uv 项目配置(依赖、脚本入口) ├── README.md # 本文档 ├── .gitignore # 忽略 data/outputs/.venv 等 └── src/ft_transformer_test/ ├── __init__.py # 包说明 ├── data.py # 数据读取(本地 covertype)+ 体检日志 + 切分 + 预处理 ├── model.py # FT-Transformer 模型(从零实现) ├── utils.py # 公共工具(随机种子、checkpoint 保存/加载) ├── train.py # 训练脚本 ├── tune.py # Optuna 自动调参 └── predict.py # 本地推理(加载模型预测) ``` --- ## 2. 环境安装 项目用 [uv](https://docs.astral.sh/uv/) 管理,所有依赖已在 `pyproject.toml` 中声明。 ```bash cd ft-transformer-test uv sync # 一键创建虚拟环境并安装全部依赖 ``` > 首次运行 `uv sync` 会下载 PyTorch(约几百 MB),耐心等待即可。 --- ## 3. 数据集 默认使用 **Forest Covertype**(森林覆盖类型,UCI),文件已下载到本地、**无需联网**: | 项目 | 值 | | --- | --- | | 数据文件 | `data/covertype/covtype.data.gz`(无表头 CSV,55 列 = 54 特征 + 标签) | | 样本数 | 581,012 | | 特征数 | 54(10 个连续数值 + 4 个荒野区二值 + 40 个土壤类型二值,全部按数值处理) | | 类别数 | 7(森林覆盖类型;原始标签 1~7,加载时转为 0~6) | > **注意**:`data/` 目录被 gitignore,换机器训练时要手动把 `covtype.data.gz` 拷贝过去。 > 类别分布不平衡(Lodgepole Pine 占近一半,Cottonwood/Willow 只有约 2700 条), > 训练日志里的"数据集体检报告"会打印每类占比。 备选:`--dataset digits` 用 scikit-learn **内置**手写数字数据集(1,797 条 / 64 特征 / 10 类, 无需任何文件),适合快速冒烟测试整条流水线。 训练/调参入口都会先打印一份"数据集体检报告"(`inspect_dataset`):总体信息、每个特征的 min/max/mean、类别分布占比、张量 shape/dtype、第 1 条样本的逐特征取值——边跑边学最直接的窗口。 **如何换成你的真实轨道数据(200 特征 / 5 分类 / 2000 万条)?** 只需新增一个读取你 CSV/数据库的函数(可参考 `data.py` 里的 `load_covertype`), 返回同样的 `TabularData`,其余切分、预处理、训练、推理逻辑完全复用。 分类特征(如"卫星型号")也能支持——把它们作为 `cat_cardinalities` 传入模型即可。 --- ## 4. 快速开始 ### 4.1 快速冒烟测试(几十秒跑通全流程) ```bash uv run python -m ft_transformer_test.train --max-samples 4000 --epochs 2 ``` 只抽 4000 条、训 2 轮,用来确认"读数据 → 体检日志 → 训练 → 保存"整条链路没问题。 ### 4.2 正式训练(全量 581,012 条) ```bash uv run python -m ft_transformer_test.train --epochs 30 --batch-size 256 ``` 有 GPU 的机器上会自动用 CUDA;CPU 上全量数据会比较慢,建议先冒烟测试。 训练完成后会生成: - `outputs/best_model.pt`:模型权重 + 配置 + 特征/类别名 + 指标 - `outputs/preprocessor.joblib`:预处理器(推理时必须复用) 常用参数(`python -m ft_transformer_test.train --help` 可查看全部): | 参数 | 说明 | 默认 | | --- | --- | --- | | `--dataset` | covertype(本地) / digits(内置小数据) | covertype | | `--max-samples` | 最大样本数(全量 581012;冒烟测试可设 4000) | None(全部) | | `--epochs` | 训练轮数 | 30 | | `--batch-size` | 批大小 | 256 | | `--lr` | 学习率 | 1e-3 | | `--d-token` | token 维度 | 192 | | `--n-blocks` | Transformer 块数 | 3 | | `--n-heads` | 注意力头数 | 8 | --- ## 5. 调参(Optuna 自动搜索) ```bash uv run python -m ft_transformer_test.tune --n-trials 20 --epochs 10 ``` Optuna 会围绕验证集准确率自动搜索:`d_token`、`n_blocks`、`n_heads`、各类 dropout、 `lr`、`weight_decay`。结束后打印最佳参数,并写入 `best_params.json`。 **推荐流程**:先用较少轮数 `--epochs 10` 调参,找到最佳参数后,把它们写回 `train.py` 的默认值(或命令行参数),再用更多轮数训练。 --- ## 6. 推理与调用 ### 6.1 单条样本预测 ```bash # covertype:54 个原始特征值,按 feature_names 顺序(Elevation, Aspect, Slope, ...),逗号分隔 uv run python -m ft_transformer_test.predict --features "2841,190,18,688,-38,2350,223,238,149,1980,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" ``` 输出预测类别名和各类别概率。特征顺序可查 checkpoint 里的 `feature_names`。 ### 6.2 在代码里调用 ```python from ft_transformer_test.predict import Predictor p = Predictor("outputs/best_model.pt", "outputs/preprocessor.joblib") pred_name, probs = p.predict([2596, 51, 3, ...]) # 传原始特征 list print(pred_name, probs) ``` `predict` 也支持按特征名传 `dict`,内部会自动按 `feature_names` 排序。 --- ## 7. 原理简述(FT-Transformer) 1. **FeatureTokenizer**:把每个特征转成 `d_token` 维向量。 - 数值特征:`token_i = x_i * w_i + b_i`(每个特征独立的权重/偏置向量); - 分类特征:用 `Embedding` 查表。 2. **拼 [CLS] token**:在所有特征 token 前加一个可学习的 `[CLS]` token。 3. **Transformer 编码器**:多层 Pre-Norm 的 `多头自注意力 + FFN(ReGLU)`,让特征两两交互。 4. **分类头**:取 `[CLS]` 的最终表示,过 `LayerNorm -> ReLU -> Linear` 得到各类别 logits。 所有代码都在 `model.py` 中,**逐行中文注释**,建议对照论文阅读。 --- ## 8. 常见问题 - **GPU 加速**:代码会自动检测 CUDA,有 GPU 就用 GPU。Windows 上如需 GPU 版 PyTorch, 参考 PyTorch 官网安装命令替换 `torch`。 - **数据泄漏**:预处理器只在训练集上拟合,验证/测试集只做 `transform`,不要 `fit`。 - **复现性**:所有随机种子都通过 `set_seed` 固定。 - **类别不平衡**:covertype 本身就不均衡(Lodgepole Pine 占近一半,Cottonwood/Willow 仅约 0.5%), 真实卫星数据里"掉落"可能更少。可考虑给 `CrossEntropyLoss` 加 `class_weight`, 或改用宏 F1 / 加权准确率作为调参目标(当前默认用验证集准确率)。