phpwind-captcha-ocr / docs /zh /TRAINING.md
FlanChanXwO's picture
docs: focus model card on PHPWind captcha OCR
3739346 verified
|
Raw
History Blame Contribute Delete
2.93 kB

训练与微调

数据范围

训练或微调时,只使用来自自有或已获明确授权评估的 PHPWind 部署的验证码图片。请保留 数据来源、授权情况及版本信息,以便正确解释训练和评估结果。

环境

pip install torch onnx onnxscript pillow numpy opencv-python

从零训练

1. 准备数据

标签格式 labels.json

{
  "captcha_001.png": {"label": "4821"},
  "captcha_002.png": {"label": "9037"}
}

图片目录:150x60 左右的 RGB 验证码 PNG,文件名与标签键一致。

2. 训练

python scripts/train_fixed.py \
  <labels.json> <图片目录> <输出.onnx> \
  0.08      # val 比例
  500       # epochs
  1         # 增强开关 (1=开)
  rgb       # 输入 RGB (关键: 不要用灰度)

示例:

python scripts/train_fixed.py \
  data/1000_labels.json data/1000_raw \
  models/my_model.onnx \
  0.08 500 1 rgb

产物:

  • <输出>.onnx — 最终 ONNX 模型
  • <输出>.onnx.pt — 最优 epoch 的 PyTorch 权重 (best val)

3. 推理验证

import numpy as np, onnxruntime as ort
from PIL import Image
sess = ort.InferenceSession("my_model.onnx", providers=["CPUExecutionProvider"])
im = Image.open("captcha.png").convert("RGB").resize((160,64), Image.BILINEAR)
x = np.asarray(im, dtype=np.float32).transpose(2,0,1)[None] / 255.0
logits = sess.run(None, {"input": x})[0]
code = "".join(str(int(logits[0,p].argmax())) for p in range(4))

微调

从 checkpoint 续训(train_fixed.py 检测到 <输出>.onnx.pt 存在会自动加载权重):

cp models/captcha_1000_raw.onnx.pt models/finetuned.onnx.pt
python scripts/train_fixed.py <新标签.json> <新图目录> models/finetuned.onnx 0.08 200 1 rgb
  • 只标少量新样本(50-200 张)即可适配小幅变化
  • 生成器变化大时建议新旧数据混合训练,避免灾难性遗忘
  • 保持同样的预处理(RGB 160x64 /255,不去噪)和增强配置

参数说明

参数 默认 说明
val_frac 0.1 验证集比例
epochs 400 总训练轮数
aug 1 增强开关
rgb - rgb 启用 3 通道输入(推荐)

关键经验

  1. 必须用 RGB,不要灰度 — 验证码数字是彩色的,灰度丢信息。
  2. 不要图像去噪 — 形态学开运算砍掉细笔画,val 从 88.6% 掉到 79.8%。数据量足够时模型自己学会过滤干扰线。
  3. 位置保留架构,不要 Global Average Pooling — GAP 丢空间位置导致 val 归零;按列分组池化(20列→4位置)后立即泛化。
  4. 人类标注 >> 视觉模型自动标注 — 自动标注 ~35% 噪声会把模型带崩到 0% 命中;手工 100% 干净标签才能学到真实分布。
  5. 增强不要加高斯噪声 — 验证码本身有干扰线,再加随机噪声会让训练样本面目全非。