| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 18 天前 | ||
| 18 天前 | ||
| 18 天前 | ||
| 18 天前 | ||
| 18 天前 | ||
| 18 天前 |
CNN 模型训练
训练数字识别 CNN 和二分类 CNN,输出到 models/。
| 脚本 | 用途 | 输出文件 |
|---|---|---|
| train.py | 数字分类 CNN 训练 | models/sudoku_cnn.pth + models/sudoku_cnn.pt (TorchScript) |
| train_binary.py | 二分类 CNN 训练 | models/cell_binary.pth + models/cell_binary.pt (TorchScript) |
| extract_gt_samples.py | 从反馈数据提取数字样本 | training/gt_samples.npy, training/gt_labels.npy |
完整闭环流程
┌─────────────────────────────────────────────────────────┐
│ 1. C++ Web 服务 (--enable-feedback) │
│ 用户上传图片 → AI 识别 → 用户手动校正 │
│ → POST /feedback/ 保存 (data/feedback/) │
├─────────────────────────────────────────────────────────┤
│ 2. 提取训练样本 │
│ cd training && python3 extract_gt_samples.py │
│ → gt_samples.npy + gt_labels.npy │
├─────────────────────────────────────────────────────────┤
│ 3. 训练模型 │
│ python3 train.py # 数字分类 CNN │
│ python3 train_binary.py # 二分类 CNN │
│ → models/sudoku_cnn.pt + models/cell_binary.pt │
├─────────────────────────────────────────────────────────┤
│ 4. 部署新模型 │
│ 替换 models/ 目录下的 .pt 文件 │
│ 重启 C++ 服务即可生效 │
└─────────────────────────────────────────────────────────┘
模型架构
两个 CNN 模型定义均为自包含(train.py 和 train_binary.py 中各有一份),不依赖外部 Python 包。
SudokuDigitCNN(数字分类,约 4 万参数)
输入 1×28×28
→ Conv(1→16,3×3) → BN → ReLU → MaxPool(2) # 14×14×16
→ Conv(16→32,3×3) → BN → ReLU → MaxPool(2) # 7×7×32
→ Conv(32→64,3×3) → BN → ReLU → MaxPool(2) # 3×3×64
→ Flatten → Linear(576→64) → ReLU → Dropout(0.3) → Linear(64→9)
CellBinaryCNN(二分类,约 6.5K 参数)
输入 1×40×40
→ Conv(1→8,3×3) → BN → ReLU → MaxPool(2) # 20×20×8
→ Conv(8→16,3×3) → BN → ReLU → MaxPool(2) # 10×10×16
→ Conv(16→32,3×3) → BN → ReLU → AdaptiveAvgPool2d(1) # 1×1×32
→ Flatten → Linear(32→16) → ReLU → Dropout(0.25) → Linear(16→2)
数字分类三阶段训练策略
Phase 1: MNIST 预训练(5 epochs, LR=0.001)
├── 数据:MNIST 数字 1-9,约 60K 样本
└── 目的:学习数字笔画基本特征
Phase 2: 自定义样本微调(30 epochs, LR=0.0003)
├── 数据:training/samples.npy + label.npy(手动标注)
└── 目的:适应本项目的数独字体和预处理方式
Phase 3: GT 校正数据精调(15 epochs, LR=0.0001)
├── 数据:从 feedback 中提取的真实数字样本(含增强)
└── 目的:修复特定误分类,提升泛化能力
依赖
| 脚本 | 外部依赖 |
|---|---|
| train.py | PyTorch, torchvision, OpenCV, NumPy(模型定义自包含) |
| train_binary.py | PyTorch, OpenCV, NumPy + 原项目的 sudoku.correction(透视校正) |
| extract_gt_samples.py | OpenCV, NumPy + 原项目的 sudoku.correction + sudoku.extraction |
extract_gt_samples.py 和 train_binary.py 需要从原始 Python 项目加载图像处理函数。
设置环境变量指向原项目路径:
export SUDOKU_PY_PATH=/home/ma-user/code/sudoku-py
运行训练
cd training
# 第 1 步:从反馈数据提取样本(需先收集 feedback)
python3 extract_gt_samples.py
# 第 2 步:训练数字分类 CNN
python3 train.py # 完整三阶段
python3 train.py --skip-phase3 # 跳过 GT 微调
# 第 3 步:训练二分类 CNN
python3 train_binary.py
# 第 4 步:部署
# 训练完成后 models/ 下的 .pt 文件会自动更新
# 重启 C++ 服务即可生效
自定义训练数据
添加新样本(手动标注)
如果模型对某些图片识别效果不好,可以加入新的训练样本:
import numpy as np
samples = np.load("training/samples.npy") # (N, 400) 20×20 展平
labels = np.load("training/label.npy") # (N,) 标签 1-9
# 追加新样本
new_sample = your_20x20_image.reshape(1, 400)
new_label = np.array([5])
samples = np.vstack([samples, new_sample])
labels = np.concatenate([labels, new_label])
np.save("training/samples.npy", samples)
np.save("training/label.npy", labels)
然后重新运行 python3 train.py
超参数调优
所有可调参数集中在训练脚本顶部:
# train.py
BATCH_SIZE = 64
EPOCHS_PRETRAIN = 5
EPOCHS_FINETUNE = 30
EPOCHS_GT_FINETUNE = 15
LR_PRETRAIN = 0.001
LR_FINETUNE = 0.0003
LR_GT_FINETUNE = 0.0001
- 验证准确率不涨:降低 LR
- 欠拟合:增加 EPOCHS
- 过拟合:增大 Dropout(0.3 → 0.5)