Commit ·
8f748c3
1
Parent(s): 29e5ee8
Update tuned hyperparameters
Browse files- __pycache__/script.cpython-313.pyc +0 -0
- script.py +6 -6
- search_hyperparams.py +97 -0
- submission.json +0 -0
- test_local.py +58 -0
- test_local_real.py +47 -0
__pycache__/script.cpython-313.pyc
ADDED
|
Binary file (21.9 kB). View file
|
|
|
script.py
CHANGED
|
@@ -15,13 +15,13 @@ from joblib import Parallel, delayed
|
|
| 15 |
from sklearn.cluster import DBSCAN
|
| 16 |
from hoho2025 import example_solutions as hoho_example
|
| 17 |
|
| 18 |
-
VERTEX_MERGE_EPS =
|
| 19 |
EDGE_MIN_LENGTH = 0.5
|
| 20 |
-
EDGE_MIN_SUPPORT_IMAGES =
|
| 21 |
-
EDGE_MAX_ANGLE_DEG =
|
| 22 |
-
VERTEX_MAX_COLMAP_DIST =
|
| 23 |
-
VERTEX_MIN_EDGE_DEGREE =
|
| 24 |
-
VERTEX_MIN_VIEW_COUNT =
|
| 25 |
|
| 26 |
def empty_solution(sample):
|
| 27 |
'''Return a minimal valid solution, i.e. 2 vertices and 1 edge.'''
|
|
|
|
| 15 |
from sklearn.cluster import DBSCAN
|
| 16 |
from hoho2025 import example_solutions as hoho_example
|
| 17 |
|
| 18 |
+
VERTEX_MERGE_EPS = 1.0
|
| 19 |
EDGE_MIN_LENGTH = 0.5
|
| 20 |
+
EDGE_MIN_SUPPORT_IMAGES = 1
|
| 21 |
+
EDGE_MAX_ANGLE_DEG = 45.0
|
| 22 |
+
VERTEX_MAX_COLMAP_DIST = 2.0
|
| 23 |
+
VERTEX_MIN_EDGE_DEGREE = 1
|
| 24 |
+
VERTEX_MIN_VIEW_COUNT = 1
|
| 25 |
|
| 26 |
def empty_solution(sample):
|
| 27 |
'''Return a minimal valid solution, i.e. 2 vertices and 1 edge.'''
|
search_hyperparams.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import json
|
| 3 |
+
import numpy as np
|
| 4 |
+
import sys
|
| 5 |
+
import os
|
| 6 |
+
import re
|
| 7 |
+
import importlib
|
| 8 |
+
import random
|
| 9 |
+
from datasets import load_dataset
|
| 10 |
+
from hoho2025.metric_helper import hss
|
| 11 |
+
|
| 12 |
+
print("Loading dataset from Hugging Face streaming (usm3d/hoho22k_2026_trainval)...")
|
| 13 |
+
dataset = load_dataset('usm3d/hoho22k_2026_trainval', split='train', streaming=True, trust_remote_code=True)
|
| 14 |
+
# Fetch first 3 samples into memory to speed up search
|
| 15 |
+
samples = []
|
| 16 |
+
for idx, s in enumerate(dataset):
|
| 17 |
+
if idx >= 100:
|
| 18 |
+
break
|
| 19 |
+
samples.append(s)
|
| 20 |
+
|
| 21 |
+
def set_hyperparameters(eps, min_len, min_support, max_angle, max_dist, min_degree, min_view):
|
| 22 |
+
with open('script.py', 'r') as f:
|
| 23 |
+
content = f.read()
|
| 24 |
+
|
| 25 |
+
content = re.sub(r'VERTEX_MERGE_EPS = .+', f'VERTEX_MERGE_EPS = {eps}', content)
|
| 26 |
+
content = re.sub(r'EDGE_MIN_LENGTH = .+', f'EDGE_MIN_LENGTH = {min_len}', content)
|
| 27 |
+
content = re.sub(r'EDGE_MIN_SUPPORT_IMAGES = .+', f'EDGE_MIN_SUPPORT_IMAGES = {min_support}', content)
|
| 28 |
+
content = re.sub(r'EDGE_MAX_ANGLE_DEG = .+', f'EDGE_MAX_ANGLE_DEG = {max_angle}', content)
|
| 29 |
+
content = re.sub(r'VERTEX_MAX_COLMAP_DIST = .+', f'VERTEX_MAX_COLMAP_DIST = {max_dist}', content)
|
| 30 |
+
content = re.sub(r'VERTEX_MIN_EDGE_DEGREE = .+', f'VERTEX_MIN_EDGE_DEGREE = {min_degree}', content)
|
| 31 |
+
content = re.sub(r'VERTEX_MIN_VIEW_COUNT = .+', f'VERTEX_MIN_VIEW_COUNT = {min_view}', content)
|
| 32 |
+
|
| 33 |
+
with open('script.py', 'w') as f:
|
| 34 |
+
f.write(content)
|
| 35 |
+
|
| 36 |
+
import script
|
| 37 |
+
|
| 38 |
+
def evaluate():
|
| 39 |
+
importlib.reload(script)
|
| 40 |
+
scores = []
|
| 41 |
+
for sample in samples:
|
| 42 |
+
try:
|
| 43 |
+
pred_v, pred_e, _ = script.predict_wireframe_safely(sample)
|
| 44 |
+
except Exception:
|
| 45 |
+
pred_v, pred_e = np.zeros((2, 3)), [(0, 1)]
|
| 46 |
+
|
| 47 |
+
gt_v = sample.get('wf_vertices')
|
| 48 |
+
gt_e = sample.get('wf_edges')
|
| 49 |
+
res = hss(pred_v, pred_e, gt_v, gt_e)
|
| 50 |
+
scores.append(res.hss)
|
| 51 |
+
|
| 52 |
+
# Cache cleaning to prevent memory leaks over many trials
|
| 53 |
+
import gc
|
| 54 |
+
gc.collect()
|
| 55 |
+
|
| 56 |
+
return sum(scores) / len(scores) if scores else 0
|
| 57 |
+
|
| 58 |
+
best_score = -1.0
|
| 59 |
+
best_params = None
|
| 60 |
+
|
| 61 |
+
# Baseline is around 0.34
|
| 62 |
+
space = {
|
| 63 |
+
'eps': [0.1, 0.5, 1.0],
|
| 64 |
+
'min_len': [0.0, 0.2, 0.5],
|
| 65 |
+
'min_support': [1, 2],
|
| 66 |
+
'max_angle': [25.0, 45.0],
|
| 67 |
+
'max_dist': [2.0, 4.0],
|
| 68 |
+
'min_degree': [1, 2],
|
| 69 |
+
'min_view': [1, 2]
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
trials = 50
|
| 73 |
+
print(f"Running Random Search for {trials} trials...")
|
| 74 |
+
|
| 75 |
+
for i in range(trials):
|
| 76 |
+
p = {k: random.choice(v) for k, v in space.items()}
|
| 77 |
+
set_hyperparameters(
|
| 78 |
+
p['eps'], p['min_len'], p['min_support'],
|
| 79 |
+
p['max_angle'], p['max_dist'], p['min_degree'], p['min_view']
|
| 80 |
+
)
|
| 81 |
+
score = evaluate()
|
| 82 |
+
print(f"Trial {i+1} Score: {score:.4f} | Params: {p}")
|
| 83 |
+
if score > best_score:
|
| 84 |
+
best_score = score
|
| 85 |
+
best_params = p
|
| 86 |
+
|
| 87 |
+
print(f"\n--- BEST RESULT ---")
|
| 88 |
+
print(f"Best HSS Score: {best_score:.4f}")
|
| 89 |
+
print("Best Parameters:")
|
| 90 |
+
for k, v in best_params.items():
|
| 91 |
+
print(f" {k}: {v}")
|
| 92 |
+
|
| 93 |
+
# Restore best params to script.py
|
| 94 |
+
set_hyperparameters(
|
| 95 |
+
best_params['eps'], best_params['min_len'], best_params['min_support'],
|
| 96 |
+
best_params['max_angle'], best_params['max_dist'], best_params['min_degree'], best_params['min_view']
|
| 97 |
+
)
|
submission.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
test_local.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import json
|
| 3 |
+
import tarfile
|
| 4 |
+
import zipfile
|
| 5 |
+
import numpy as np
|
| 6 |
+
import sys
|
| 7 |
+
import os
|
| 8 |
+
from datasets import load_dataset
|
| 9 |
+
from hoho2025.metric_helper import hss
|
| 10 |
+
|
| 11 |
+
# Import the solution script locally
|
| 12 |
+
import script
|
| 13 |
+
|
| 14 |
+
print("Loading dataset from local parquet...")
|
| 15 |
+
dataset = load_dataset('parquet', data_files={"train": "/tmp/data/data/train-00000-of-00002.parquet"})
|
| 16 |
+
print(f"Loaded {len(dataset['train'])} examples.")
|
| 17 |
+
|
| 18 |
+
scores = []
|
| 19 |
+
|
| 20 |
+
for idx, sample in enumerate(dataset['train']):
|
| 21 |
+
if idx >= 5: # Just test first 5
|
| 22 |
+
break
|
| 23 |
+
|
| 24 |
+
order_id = sample.get('order_id', str(idx))
|
| 25 |
+
print(f"\n--- Testing order_id: {order_id} ---")
|
| 26 |
+
|
| 27 |
+
# 1. Evaluate prediction
|
| 28 |
+
# This will likely fall back to empty_solution due to missing 'gestalt'
|
| 29 |
+
pred_v, pred_e, _ = script.predict_wireframe_safely(sample)
|
| 30 |
+
|
| 31 |
+
# 2. Extract Ground Truth from ZIP
|
| 32 |
+
gt_v = None
|
| 33 |
+
gt_e = None
|
| 34 |
+
|
| 35 |
+
try:
|
| 36 |
+
with zipfile.ZipFile(io.BytesIO(sample['data']), "r") as zf:
|
| 37 |
+
if 'gt_vertices.npy' in zf.namelist():
|
| 38 |
+
gt_v = np.load(io.BytesIO(zf.read('gt_vertices.npy')))
|
| 39 |
+
if 'gt_edges.npy' in zf.namelist():
|
| 40 |
+
gt_e = np.load(io.BytesIO(zf.read('gt_edges.npy')))
|
| 41 |
+
except Exception as e:
|
| 42 |
+
print(f"Failed to read ZIP contents for GT: {e}")
|
| 43 |
+
continue
|
| 44 |
+
|
| 45 |
+
if gt_v is None or gt_e is None:
|
| 46 |
+
print("Missing ground truth for this sample.")
|
| 47 |
+
continue
|
| 48 |
+
|
| 49 |
+
# 3. Compute HSS metric Score
|
| 50 |
+
res = hss(pred_v, pred_e, gt_v, gt_e)
|
| 51 |
+
scores.append(res.hss)
|
| 52 |
+
|
| 53 |
+
print(f"Predicted Vertices: {len(pred_v)} | Predicted Edges: {len(pred_e)}")
|
| 54 |
+
print(f"GT Vertices: {len(gt_v)} | GT Edges: {len(gt_e)}")
|
| 55 |
+
print(f"HSS Score: {res.hss:.4f}")
|
| 56 |
+
|
| 57 |
+
avg_score = sum(scores) / len(scores) if scores else 0
|
| 58 |
+
print(f"\nAverage HSS Score on subset: {avg_score:.4f}")
|
test_local_real.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import io
|
| 2 |
+
import json
|
| 3 |
+
import numpy as np
|
| 4 |
+
import sys
|
| 5 |
+
import os
|
| 6 |
+
from datasets import load_dataset
|
| 7 |
+
from hoho2025.metric_helper import hss
|
| 8 |
+
|
| 9 |
+
# Import the solution script locally
|
| 10 |
+
import script
|
| 11 |
+
|
| 12 |
+
print("Loading dataset from Hugging Face streaming (usm3d/hoho22k_2026_trainval)...")
|
| 13 |
+
dataset = load_dataset('usm3d/hoho22k_2026_trainval', split='train', streaming=True, trust_remote_code=True)
|
| 14 |
+
|
| 15 |
+
scores = []
|
| 16 |
+
|
| 17 |
+
for idx, sample in enumerate(dataset):
|
| 18 |
+
if idx >= 3: # Just test first 3 (evaluating takes time for 2D parsing)
|
| 19 |
+
break
|
| 20 |
+
|
| 21 |
+
order_id = sample.get('order_id', str(idx))
|
| 22 |
+
print(f"\n--- Testing order_id: {order_id} ---")
|
| 23 |
+
|
| 24 |
+
# Run the original example solutions baseline
|
| 25 |
+
from hoho2025 import example_solutions
|
| 26 |
+
base_v, base_e = example_solutions.predict_wireframe(sample)
|
| 27 |
+
|
| 28 |
+
# Evaluate user's filtered prediction
|
| 29 |
+
pred_v, pred_e, _ = script.predict_wireframe_safely(sample)
|
| 30 |
+
|
| 31 |
+
gt_v = sample.get('wf_vertices')
|
| 32 |
+
gt_e = sample.get('wf_edges')
|
| 33 |
+
|
| 34 |
+
if gt_v is None or gt_e is None:
|
| 35 |
+
print("Missing ground truth for this sample.")
|
| 36 |
+
continue
|
| 37 |
+
|
| 38 |
+
# 3. Compute HSS metric Score
|
| 39 |
+
base_res = hss(base_v, base_e, gt_v, gt_e)
|
| 40 |
+
res = hss(pred_v, pred_e, gt_v, gt_e)
|
| 41 |
+
scores.append(res.hss)
|
| 42 |
+
|
| 43 |
+
print(f"BASELINE Predict -> Vertices: {len(base_v)} | Edges: {len(base_e)} | HSS: {base_res.hss:.4f}")
|
| 44 |
+
print(f"FILTERED Predict -> Vertices: {len(pred_v)} | Edges: {len(pred_e)} | HSS: {res.hss:.4f}")
|
| 45 |
+
|
| 46 |
+
avg_score = sum(scores) / len(scores) if scores else 0
|
| 47 |
+
print(f"\nAverage FILTERED HSS Score on subset: {avg_score:.4f}")
|