Files
CaptchBreaker/CLAUDE.md
2026-03-10 18:47:29 +08:00

392 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md - 验证码识别多模型系统 (CaptchaBreaker)
## 项目概述
构建一个本地验证码识别系统,采用 **调度模型 + 多专家模型** 的两级架构。调度模型负责分类验证码类型,专家模型负责具体识别。所有模型轻量化设计,最终导出 ONNX 用于部署。
## 技术栈
- Python 3.10+
- uv (包管理,依赖定义在 pyproject.toml)
- PyTorch 2.x (训练)
- ONNX + ONNXRuntime (推理部署)
- Pillow (图像处理)
- FastAPI (可选,提供 HTTP 识别服务)
## 项目结构
```
captcha-breaker/
├── CLAUDE.md
├── pyproject.toml # 项目配置与依赖 (uv 管理)
├── config.py # 全局配置 (字符集、图片尺寸、路径等)
├── data/
│ ├── synthetic/ # 合成训练数据 (自动生成,不入 git)
│ │ ├── normal/ # 普通字符型
│ │ ├── math/ # 算式型
│ │ └── 3d/ # 3D立体型
│ ├── real/ # 真实验证码样本 (手动标注)
│ │ ├── normal/
│ │ ├── math/
│ │ └── 3d/
│ └── classifier/ # 调度分类器训练数据 (混合各类型)
├── generators/
│ ├── __init__.py
│ ├── base.py # 生成器基类
│ ├── normal_gen.py # 普通字符验证码生成器
│ ├── math_gen.py # 算式验证码生成器 (如 3+8=?)
│ └── threed_gen.py # 3D立体验证码生成器
├── models/
│ ├── __init__.py
│ ├── lite_crnn.py # 轻量 CRNN (用于普通字符和算式)
│ ├── classifier.py # 调度分类模型
│ └── threed_cnn.py # 3D验证码专用模型 (更深的CNN)
├── training/
│ ├── __init__.py
│ ├── train_classifier.py # 训练调度模型
│ ├── train_normal.py # 训练普通字符识别
│ ├── train_math.py # 训练算式识别
│ ├── train_3d.py # 训练3D识别
│ └── dataset.py # 通用 Dataset 类
├── inference/
│ ├── __init__.py
│ ├── pipeline.py # 核心推理流水线 (调度+识别)
│ ├── export_onnx.py # PyTorch → ONNX 导出脚本
│ └── math_eval.py # 算式计算模块
├── checkpoints/ # 训练产出的模型文件
│ ├── classifier.pth
│ ├── normal.pth
│ ├── math.pth
│ └── threed.pth
├── onnx_models/ # 导出的 ONNX 模型
│ ├── classifier.onnx
│ ├── normal.onnx
│ ├── math.onnx
│ └── threed.onnx
├── server.py # FastAPI 推理服务 (可选)
├── cli.py # 命令行入口
└── tests/
├── test_generators.py
├── test_models.py
└── test_pipeline.py
```
## 核心架构设计
### 推理流水线
```
输入图片 → 预处理 → 调度分类器 → 路由到专家模型 → 后处理 → 输出结果
┌────────┼────────┐
▼ ▼ ▼
normal math 3d
(CRNN) (CRNN) (CNN)
│ │ │
▼ ▼ ▼
"A3B8" "3+8=?"→11 "X9K2"
```
### 调度分类器 (classifier.py)
- 任务: 图像分类,判断验证码属于哪个类型
- 架构: 轻量 CNN3-4 层卷积 + 全局平均池化 + 全连接
- 输入: 灰度图 1x64x128
- 输出: softmax 概率分布,类别数 = 验证码类型数
- 要求: 准确率 99%+,推理 < 5ms
- 模型体积目标: < 500KB
```python
class CaptchaClassifier(nn.Module):
"""
轻量分类器,几层卷积即可区分不同类型验证码。
不同类型验证码视觉差异大有无运算符、3D效果等分类很容易。
"""
def __init__(self, num_types=3):
# 4层卷积 + GAP + FC
# Conv2d(1,16) -> Conv2d(16,32) -> Conv2d(32,64) -> Conv2d(64,64)
# AdaptiveAvgPool2d(1) -> Linear(64, num_types)
pass
```
### 普通字符识别专家 (lite_crnn.py - normal 模式)
- 任务: 识别彩色字符验证码 (数字+字母混合)
- 架构: CRNN + CTC
- 字符集: `0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ` (36个包含易混淆字符按本地配置训练)
- 输入: 灰度图 1x40x120
- 输出: 字符序列,通过 CTC 贪心解码
- 验证码特征: 浅色背景、彩色字符、轻微干扰线、字符有倾斜
- 模型体积目标: < 2MB
### 算式识别专家 (lite_crnn.py - math 模式)
- 任务: 识别算式验证码并计算结果
- 架构: 复用 CRNN + CTC字符集不同
- 字符集: `0123456789+-×÷=?` (数字+运算符)
- 输入: 灰度图 1x40x160 (算式通常更宽)
- 输出: 识别出算式字符串,然后交给 math_eval.py 计算
- 分两步: (1) OCR 识别 → "3+8=?" (2) 正则解析并计算 → 11
- 模型体积目标: < 2MB
```python
# math_eval.py 核心逻辑
def eval_captcha_math(expr: str) -> str:
"""
解析并计算验证码算式。
支持: 加减乘除,个位到两位数运算。
输入: "3+8=?""12×3=?""15-7=?"
输出: "11""36""8"
用正则提取数字和运算符,不要用 eval()。
"""
pass
```
### 3D立体识别专家 (threed_cnn.py)
- 任务: 识别带 3D 透视/阴影效果的验证码
- 架构: 更深的 CNN + CRNN或 ResNet-lite backbone
- 输入: 灰度图 1x60x160
- 需要更强的特征提取能力来处理透视变形和阴影
- 模型体积目标: < 5MB
## 数据生成器规范
### 基类 (base.py)
```python
class BaseCaptchaGenerator:
def generate(self, text=None) -> tuple[Image.Image, str]:
"""生成一张验证码,返回 (图片, 标签文本)"""
raise NotImplementedError
def generate_dataset(self, num_samples: int, output_dir: str):
"""批量生成,文件名格式: {label}_{index:06d}.png"""
pass
```
### 普通字符生成器 (normal_gen.py)
模拟目标风格:
- 浅色随机背景 (RGB 各通道 230-255)
- 每个字符随机颜色 (深色: 蓝/红/绿/紫/棕等)
- 字符数量: 4-5 个
- 字符有 ±15° 随机旋转
- 2-5 条浅色干扰线
- 少量噪点
- 可选轻微高斯模糊
### 算式生成器 (math_gen.py)
- 生成形如 `A op B = ?` 的算式图片
- A, B 范围: 1-30 的整数
- op: +, -, × (除法只生成能整除的)
- 确保结果为非负整数
- 标签格式: `3+8` (存储算式本身,不存结果)
- 视觉风格: 与目标算式验证码一致
### 3D生成器 (threed_gen.py)
- 使用 Pillow 的仿射变换模拟 3D 透视
- 添加阴影效果
- 字符有深度感和倾斜
- 标签: 纯字符内容
## 训练规范
### 通用训练配置
```python
# config.py 中定义
TRAIN_CONFIG = {
'classifier': {
'epochs': 30,
'batch_size': 128,
'lr': 1e-3,
'scheduler': 'cosine',
'synthetic_samples': 30000, # 每类 10000
},
'normal': {
'epochs': 50,
'batch_size': 128,
'lr': 1e-3,
'scheduler': 'cosine',
'synthetic_samples': 60000,
'loss': 'CTCLoss',
},
'math': {
'epochs': 50,
'batch_size': 128,
'lr': 1e-3,
'scheduler': 'cosine',
'synthetic_samples': 60000,
'loss': 'CTCLoss',
},
'threed': {
'epochs': 80,
'batch_size': 64,
'lr': 5e-4,
'scheduler': 'cosine',
'synthetic_samples': 80000,
'loss': 'CTCLoss',
},
}
```
### 训练脚本要求
每个训练脚本必须:
1. 检查合成数据是否已生成,没有则自动调用生成器
2. 支持混合真实数据 (如果 data/real/{type}/ 有文件)
3. 使用数据增强: RandomAffine, ColorJitter, GaussianBlur, RandomErasing
4. 输出训练日志: epoch, loss, 整体准确率, 字符级准确率
5. 保存最佳模型到 checkpoints/
6. 训练结束自动导出 ONNX 到 onnx_models/
### 数据增强策略
```python
# 训练时增强
train_augment = transforms.Compose([
transforms.Grayscale(),
transforms.Resize((H, W)),
transforms.RandomAffine(degrees=8, translate=(0.05, 0.05), scale=(0.95, 1.05)),
transforms.ColorJitter(brightness=0.3, contrast=0.3),
transforms.GaussianBlur(3, sigma=(0.1, 0.5)),
transforms.ToTensor(),
transforms.Normalize([0.5], [0.5]),
transforms.RandomErasing(p=0.15, scale=(0.01, 0.05)),
])
```
## 推理流水线 (pipeline.py)
```python
class CaptchaPipeline:
"""
核心推理流水线。
加载调度模型和所有专家模型 (ONNX 格式)。
提供统一的 solve(image) 接口。
"""
def __init__(self, models_dir='onnx_models/'):
"""
初始化加载所有 ONNX 模型。
使用 onnxruntime.InferenceSession。
"""
pass
def preprocess(self, image: Image.Image, target_size: tuple) -> np.ndarray:
"""图片预处理: resize, grayscale, normalize, 转 numpy"""
pass
def classify(self, image: Image.Image) -> str:
"""调度分类,返回类型名: 'normal' / 'math' / '3d'"""
pass
def solve(self, image) -> str:
"""
完整识别流程:
1. 分类验证码类型
2. 路由到对应专家模型
3. 后处理 (算式型需要计算结果)
4. 返回最终答案字符串
image: PIL.Image 或文件路径或 bytes
"""
pass
```
## ONNX 导出 (export_onnx.py)
```python
def export_model(model, model_name, input_shape, onnx_dir='onnx_models/'):
"""
导出单个模型为 ONNX。
- 使用 opset_version=18
- 开启 dynamic_axes 支持动态 batch
- 导出后用 onnxruntime 验证推理一致性
- 可选: onnx 模型简化 (onnxsim)
"""
pass
def export_all():
"""依次导出 classifier, normal, math, threed 四个模型"""
pass
```
## CLI 入口 (cli.py)
```bash
# 安装依赖
uv sync # 核心依赖
uv sync --extra server # 含 HTTP 服务依赖
# 生成训练数据
uv run python cli.py generate --type normal --num 60000
uv run python cli.py generate --type math --num 60000
uv run python cli.py generate --type 3d --num 80000
uv run python cli.py generate --type classifier --num 30000
# 训练模型
uv run python cli.py train --model classifier
uv run python cli.py train --model normal
uv run python cli.py train --model math
uv run python cli.py train --model 3d
uv run python cli.py train --all # 按依赖顺序全部训练
# 导出 ONNX
uv run python cli.py export --all
# 推理
uv run python cli.py predict image.png # 自动分类+识别
uv run python cli.py predict image.png --type normal # 跳过分类直接识别
uv run python cli.py predict-dir ./test_images/ # 批量识别
# 启动 HTTP 服务 (需先安装 server 可选依赖)
uv run python cli.py serve --port 8080
```
## HTTP 服务 (server.py可选)
```python
# FastAPI 服务,提供 REST API
# POST /solve - 上传图片,返回识别结果
# 请求: multipart/form-data字段名 image
# 响应: {"type": "normal", "result": "A3B8", "confidence": 0.95, "time_ms": 45}
```
## 关键约束和注意事项
1. **所有模型用 float32 训练,导出 ONNX 时不做量化**,先保证精度
2. **CTC 解码统一用贪心解码**,不需要 beam search验证码场景贪心够用
3. **字符集由 config.py 统一定义**: 当前 normal 保留易混淆字符3d 继续使用去混淆字符集
4. **算式识别分两步**: 先 OCR 识别字符串,再用规则计算,不要让模型直接输出数值
5. **生成器的随机种子**: 生成数据时设置 seed 保证可复现
6. **真实数据文件名格式**: `{label}_{任意}.png`label 部分是标注内容
7. **模型保存格式**: PyTorch checkpoint 包含 model_state_dict, chars, best_acc, epoch
8. **不使用 GPU 特有功能**,确保 CPU 也能训练和推理 (只是慢一些)
9. **类型扩展**: 新增验证码类型时,只需 (1) 加生成器 (2) 加专家模型 (3) 调度器加一个类别重新训练
10. **文档同步**: 对项目结构、配置、架构等做出变更时,必须同步更新 CLAUDE.md 中的对应内容,保持文档与代码一致
## 目标指标
| 模型 | 准确率目标 | 推理延迟 | 模型体积 |
|------|-----------|---------|---------|
| 调度分类器 | > 99% | < 5ms | < 500KB |
| 普通字符 | > 95% | < 30ms | < 2MB |
| 算式识别 | > 93% | < 30ms | < 2MB |
| 3D立体 | > 85% | < 50ms | < 5MB |
| 全流水线 | - | < 80ms | < 10MB 总计 |
## 开发顺序
1. 先实现 config.py 和 generators/
2. 实现 models/ 中所有模型定义
3. 实现 training/dataset.py 通用数据集类
4. 按顺序训练: normal → math → 3d → classifier
5. 实现 inference/pipeline.py 和 export_onnx.py
6. 实现 cli.py 统一入口
7. 可选: server.py HTTP 服务
8. 编写 tests/