Upload docs/en/TRAINING.md with huggingface_hub
Browse files- docs/en/TRAINING.md +86 -0
docs/en/TRAINING.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Training & Fine-tuning
|
| 2 |
+
|
| 3 |
+
## Environment
|
| 4 |
+
|
| 5 |
+
```bash
|
| 6 |
+
pip install torch onnx onnxscript pillow numpy opencv-python
|
| 7 |
+
```
|
| 8 |
+
|
| 9 |
+
## Training from scratch
|
| 10 |
+
|
| 11 |
+
### 1. Prepare data
|
| 12 |
+
|
| 13 |
+
Label format `labels.json`:
|
| 14 |
+
```json
|
| 15 |
+
{
|
| 16 |
+
"captcha_001.png": {"label": "4821"},
|
| 17 |
+
"captcha_002.png": {"label": "9037"}
|
| 18 |
+
}
|
| 19 |
+
```
|
| 20 |
+
|
| 21 |
+
Image dir: ~150x60 RGB captcha PNGs; filenames must match label keys.
|
| 22 |
+
|
| 23 |
+
### 2. Train
|
| 24 |
+
|
| 25 |
+
```bash
|
| 26 |
+
python scripts/train_fixed.py \
|
| 27 |
+
<labels.json> <image_dir> <output.onnx> \
|
| 28 |
+
0.08 # val fraction
|
| 29 |
+
500 # epochs
|
| 30 |
+
1 # augmentation on/off (1=on)
|
| 31 |
+
rgb # RGB input (important: do NOT use grayscale)
|
| 32 |
+
```
|
| 33 |
+
|
| 34 |
+
Example:
|
| 35 |
+
```bash
|
| 36 |
+
python scripts/train_fixed.py \
|
| 37 |
+
data/1000_labels.json data/1000_raw \
|
| 38 |
+
models/my_model.onnx \
|
| 39 |
+
0.08 500 1 rgb
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
Outputs:
|
| 43 |
+
- `<output>.onnx` β final ONNX model
|
| 44 |
+
- `<output>.onnx.pt` β best-epoch PyTorch weights
|
| 45 |
+
|
| 46 |
+
### 3. Verify inference
|
| 47 |
+
|
| 48 |
+
```python
|
| 49 |
+
import numpy as np, onnxruntime as ort
|
| 50 |
+
from PIL import Image
|
| 51 |
+
sess = ort.InferenceSession("my_model.onnx", providers=["CPUExecutionProvider"])
|
| 52 |
+
im = Image.open("captcha.png").convert("RGB").resize((160,64), Image.BILINEAR)
|
| 53 |
+
x = np.asarray(im, dtype=np.float32).transpose(2,0,1)[None] / 255.0
|
| 54 |
+
logits = sess.run(None, {"input": x})[0]
|
| 55 |
+
code = "".join(str(int(logits[0,p].argmax())) for p in range(4))
|
| 56 |
+
```
|
| 57 |
+
|
| 58 |
+
## Fine-tuning
|
| 59 |
+
|
| 60 |
+
`train_fixed.py` auto-loads an existing `<output>.onnx.pt` and resumes from it:
|
| 61 |
+
|
| 62 |
+
```bash
|
| 63 |
+
cp models/captcha_1000_raw.onnx.pt models/finetuned.onnx.pt
|
| 64 |
+
python scripts/train_fixed.py <new_labels.json> <new_image_dir> models/finetuned.onnx 0.08 200 1 rgb
|
| 65 |
+
```
|
| 66 |
+
|
| 67 |
+
- 50-200 new labeled samples are enough for small changes.
|
| 68 |
+
- Mix old + new data when the generator changes a lot, to avoid catastrophic forgetting.
|
| 69 |
+
- Keep the same preprocessing (RGB 160x64 /255, no denoise) and augmentation.
|
| 70 |
+
|
| 71 |
+
## Parameters
|
| 72 |
+
|
| 73 |
+
| Param | Default | Description |
|
| 74 |
+
|---|---|---|
|
| 75 |
+
| val_frac | 0.1 | validation fraction |
|
| 76 |
+
| epochs | 400 | total epochs |
|
| 77 |
+
| aug | 1 | augmentation toggle |
|
| 78 |
+
| rgb | - | pass `rgb` for 3-channel input (recommended) |
|
| 79 |
+
|
| 80 |
+
## Key lessons
|
| 81 |
+
|
| 82 |
+
1. **Use RGB, not grayscale** β the digits are colored; grayscale loses information.
|
| 83 |
+
2. **Do NOT denoise** β morphological opening removes thin strokes, dropping val from 88.6% to 79.8%. With enough data the model learns to ignore noise lines itself.
|
| 84 |
+
3. **Position-preserving architecture, never global average pooling** β GAP destroys spatial position (val β 0%); per-column grouped pooling (20 cols β 4 positions) restores generalization.
|
| 85 |
+
4. **Human labels >> auto vision labels** β auto labels with ~35% noise crashed the model to 0%; clean manual labels are essential.
|
| 86 |
+
5. **No Gaussian noise augmentation** β the captcha already has noise lines; adding more obscures the training signal.
|