Initialize repository
This commit is contained in:
391
CLAUDE.md
Normal file
391
CLAUDE.md
Normal file
@@ -0,0 +1,391 @@
|
||||
# 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)
|
||||
|
||||
- 任务: 图像分类,判断验证码属于哪个类型
|
||||
- 架构: 轻量 CNN,3-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/
|
||||
Reference in New Issue
Block a user