CAD symbol embedder: ConvNeXt-V2 Tiny, fine stem, multi-scale GeM
Embedding 256 chiều (đã L2-norm) cho truy hồi ký hiệu bản vẽ CAD trên lớp chưa thấy khi train (zero-shot, class-holdout).
Trọng số EMA của checkpoint tốt nhất: epoch 6/12, chọn theo 0.5·val mAP@R + 0.5·V1 closed R@1.
Kết quả (TTA ảnh gốc + zoom 1.05)
| split | R@1 | R@5 | mAP@R | mAP@24 | Mode B R@1 |
|---|---|---|---|---|---|
| validation | 0.9993 | 0.9997 | 0.9991 | 0.9979 | 0.9993 |
| test | 0.9968 | 0.9986 | 0.9961 | 0.9916 | 0.9975 |
Mode A = kNN trên ảnh gallery (24 ảnh/lớp). Mode B = 0.5·cos(prototype lớp) + 0.5·trung bình top-3 cos trong lớp.
| cặp khó | split | lớp | closed R@1 (Mode B) | nhầm |
|---|---|---|---|---|
| V1 | validation | 79 ANSI-4.1.1 / 80 ANSI-4.1.2 | 0.9982 | 80->79 1 |
| T1 | test | 83 ANSI-4.10.1 / 84 ANSI-4.10.2 | 0.9876 | 83->84 2, 84->83 5 |
| T2 | test | 347 NECA-5.032 / 348 NECA-5.033 / 349 NECA-5.034 | 1.0000 | none |
Tiền xử lý (bắt buộc giống lúc train)
RGB → letterbox nền trắng (255): cạnh dài resize về 112 (cubic khi phóng, area khi thu), đặt giữa canvas 128×128 → /255 → chuẩn hóa mean [0.485, 0.456, 0.406] std [0.229, 0.224, 0.225].
Dùng với ONNX
import cv2, numpy as np, onnxruntime as ort
def preprocess(path, target=128, content=112):
rgb = cv2.cvtColor(cv2.imread(path), cv2.COLOR_BGR2RGB)
h, w = rgb.shape[:2]
s = content / max(h, w)
nw, nh = (content, max(1, round(h * content / w))) if w >= h else (max(1, round(w * content / h)), content)
rgb = cv2.resize(rgb, (nw, nh), interpolation=cv2.INTER_CUBIC if s > 1 else cv2.INTER_AREA)
canvas = np.full((target, target, 3), 255, np.uint8)
top, left = (target - nh) // 2, (target - nw) // 2
canvas[top:top + nh, left:left + nw] = rgb
x = canvas.astype(np.float32) / 255.0
x = (x - np.array([0.485, 0.456, 0.406], np.float32)) / np.array([0.229, 0.224, 0.225], np.float32)
return x.transpose(2, 0, 1)[None]
from huggingface_hub import hf_hub_download
session = ort.InferenceSession(hf_hub_download('sonspeed/symbol-embedder-convnextv2-tiny-e12', 'model.onnx'))
emb = session.run(None, {'image': preprocess('symbol.jpg')})[0] # (1, 256), đã L2-norm
# độ tương đồng = tích vô hướng giữa các embedding
Huấn luyện
- Backbone
convnextv2_tiny.fcmae_ft_in22k_in1k, stem stride 2. Center prior + GeM trên stage 3/4, neck 1152→512→256. - Loss: sub-center CosFace (k=3, s=32.0, margin 0.05→0.22) + 0.5·Multi-Similarity (bỏ cặp âm cos > 0.985).
- Batch P×K = 32×4 theo family ký hiệu. AdamW, LR backbone 0.00015 / head 0.001, đóng băng backbone 2 epoch, warmup 3, cosine, AMP fp16, EMA 0.9995, 12 epoch.
- Dữ liệu: 495 lớp (train 475 / val 10 / test 10, chia theo lớp). Gallery/query chọn theo SHA-256.
File
model.safetensors: state dict EMA củaFineGrainedSymbolEmbedder(định nghĩa trong notebook train).config.json: tham số model/input.model.onnx,model.onnx.json: export ONNX và thông số tiền xử lý.eval/: báo cáo per-class, confusion, query sai của val/test.training/: checkpoint (checkpoint_last.ptcó optimizer để train tiếp),metrics.jsonl,train.log,config.yaml.
- Downloads last month
- 9
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support