v7: yolo11s+validator-pseudo fp16 (mAP50 0.83 on holdout)
Browse filesyolo11s fine-tuned on Roboflow + 70 validator-pseudo frames (top-1 peer labels, cs=0.683). fp16 ONNX 19.27MB. miner.py auto-detects fp16 input dtype.
best.onnx
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8beaa959e6efb3b0f82ac0876fe14bfe1d8d5dfaeecb39ca31d3430473bd3ed9
|
| 3 |
+
size 19271662
|
miner.py
CHANGED
|
@@ -59,8 +59,12 @@ class Miner:
|
|
| 59 |
sess_options=so,
|
| 60 |
)
|
| 61 |
self.inp = self.sess.get_inputs()[0].name
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
active = self.sess.get_providers()[0]
|
| 63 |
-
print(f"✅ ONNX beverage model loaded (provider={active})")
|
| 64 |
|
| 65 |
# Eager CUDA EP allocation: ORT lazily binds CUDA on first sess.run,
|
| 66 |
# so without this the validator's first /predict eats the cold-bind
|
|
@@ -89,8 +93,12 @@ class Miner:
|
|
| 89 |
|
| 90 |
def _infer(self, im_bgr: ndarray) -> ndarray:
|
| 91 |
lb, s = self._letterbox(im_bgr)
|
| 92 |
-
x = lb[:, :, ::-1].transpose(2, 0, 1)[None].astype(np.float32) / 255.0
|
|
|
|
| 93 |
out = self.sess.run(None, {self.inp: x})[0][0] # (4+nc, N)
|
|
|
|
|
|
|
|
|
|
| 94 |
p = out.T if out.shape[0] < out.shape[1] else out # (N, 4+nc)
|
| 95 |
boxes = p[:, :4].copy()
|
| 96 |
scores = p[:, 4:4 + self.num_classes]
|
|
|
|
| 59 |
sess_options=so,
|
| 60 |
)
|
| 61 |
self.inp = self.sess.get_inputs()[0].name
|
| 62 |
+
# ONNX может быть экспортирован в fp16 (для лимита репо ≤30MB) —
|
| 63 |
+
# кастим вход в тот же dtype, иначе INVALID_ARGUMENT на sess.run.
|
| 64 |
+
_ort_type = self.sess.get_inputs()[0].type # e.g. "tensor(float16)"
|
| 65 |
+
self.np_dtype = np.float16 if "float16" in _ort_type else np.float32
|
| 66 |
active = self.sess.get_providers()[0]
|
| 67 |
+
print(f"✅ ONNX beverage model loaded (provider={active}, dtype={self.np_dtype.__name__})")
|
| 68 |
|
| 69 |
# Eager CUDA EP allocation: ORT lazily binds CUDA on first sess.run,
|
| 70 |
# so without this the validator's first /predict eats the cold-bind
|
|
|
|
| 93 |
|
| 94 |
def _infer(self, im_bgr: ndarray) -> ndarray:
|
| 95 |
lb, s = self._letterbox(im_bgr)
|
| 96 |
+
x = (lb[:, :, ::-1].transpose(2, 0, 1)[None].astype(np.float32) / 255.0
|
| 97 |
+
).astype(self.np_dtype)
|
| 98 |
out = self.sess.run(None, {self.inp: x})[0][0] # (4+nc, N)
|
| 99 |
+
# ONNX fp16 → numpy float16 в out; для последующего NMS на CPU
|
| 100 |
+
# удобнее float32, кастим обратно
|
| 101 |
+
out = np.asarray(out, dtype=np.float32)
|
| 102 |
p = out.T if out.shape[0] < out.shape[1] else out # (N, 4+nc)
|
| 103 |
boxes = p[:, :4].copy()
|
| 104 |
scores = p[:, 4:4 + self.num_classes]
|