用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/cxcscmu/SkillLearnBench --skill run2-parallel-grid-search命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | run2_parallel_grid_search |
| description | Efficient parallel hyperparameter grid search using joblib with 847 combinations |
For Mars cloud clustering, evaluate all combinations of:
Total combinations: 7 × 11 × 11 = 847
from joblib import Parallel, delayed
import pandas as pd
import numpy as np
# Define hyperparameter ranges
min_samples_vals = list(range(3, 10))
epsilon_vals = list(range(4, 26, 2))
shape_weight_vals = list(np.round(np.arange(0.9, 2.0, 0.1), 1))
# Generate all combinations
hp_list = []
for ms in min_samples_vals:
for eps in epsilon_vals:
for sw in shape_weight_vals:
hp_list.append((ms, eps, sw))
print(f"Total combinations: {len(hp_list)}") # Should be 847
Each worker evaluates one hyperparameter combination:
def evaluate_hyperparams(min_samples, epsilon, shape_weight, citsci_df, expert_df, expert_images):
"""
Evaluate one hyperparameter combination across all expert images.
Returns: (F1_avg, delta_avg, min_samples, epsilon, shape_weight)
"""
f1_scores = []
delta_scores = []
for image_id in expert_images:
f1, delta = evaluate_image(image_id, citsci_df, expert_df,
min_samples, epsilon, shape_weight)
f1_scores.append(f1)
if not np.isnan(delta):
delta_scores.append(delta)
avg_f1 = np.mean(f1_scores) if f1_scores else 0.0
avg_delta = np.mean(delta_scores) if delta_scores else np.nan
return avg_f1, avg_delta, min_samples, epsilon, shape_weight
# Load data once, before parallelization
citsci_df = pd.read_csv('/root/data/citsci_train.csv')
expert_df = pd.read_csv('/root/data/expert_train.csv')
expert_images = sorted(expert_df['file_rad'].unique())
# Evaluate all combinations in parallel
results = Parallel(n_jobs=-1, verbose=1)(
delayed(evaluate_hyperparams)(ms, eps, sw, citsci_df, expert_df, expert_images)
for ms, eps, sw in hp_list
)
# Convert results to DataFrame
results_df = pd.DataFrame(results,
columns=['F1', 'delta', 'min_samples', 'epsilon', 'shape_weight'])
Uses all available CPU cores. For typical 22-core machines:
Prints progress:
[Parallel(n_jobs=-1)]: Done 6 tasks | elapsed: 3.0s
[Parallel(n_jobs=-1)]: Done 156 tasks | elapsed: 20.7s
[Parallel(n_jobs=-1)]: Done 847 out of 847 | elapsed: 1.7min finished
Using Unix fork (default for Loky backend):
Each worker needs:
# Load data BEFORE parallel section
citsci_df = pd.read_csv('/root/data/citsci_train.csv')
expert_df = pd.read_csv('/root/data/expert_train.csv')
expert_images = sorted(expert_df['file_rad'].unique())
# Pass as parameters (more efficient than loading in each worker)
results = Parallel(n_jobs=-1)(
delayed(evaluate_hyperparams)(ms, eps, sw,
citsci_df, expert_df, expert_images)
for ms, eps, sw in hp_list
)
results = Parallel(n_jobs=-1, verbose=10)(
delayed(fn)(args) for args in arguments
)
# verbose levels: 1=minimal, 5=moderate, 10=detailed
from tqdm import tqdm
results = Parallel(n_jobs=-1)(
delayed(fn)(args)
for args in tqdm(arguments, total=len(arguments))
)
from joblib import Parallel, delayed, parallel_backend
def progress_callback(n_tasks):
"""Called every n_tasks completed."""
print(f"Progress: {n_tasks} tasks completed")
results = Parallel(n_jobs=-1)(
delayed(fn)(args) for args in arguments
)
# All results collected after parallel section completes
results_df = pd.DataFrame(results,
columns=['F1', 'delta', 'min_samples', 'epsilon', 'shape_weight'])
# Verify completeness
assert len(results_df) == 847, "Missing results"
# Analyze
print(f"F1 range: [{results_df['F1'].min():.5f}, {results_df['F1'].max():.5f}]")
print(f"Delta range: [{results_df['delta'].min():.5f}, {results_df['delta'].max():.5f}]")
print(f"Solutions with F1 > 0.5: {(results_df['F1'] > 0.5).sum()}")
# Set timeout for long-running tasks
results = Parallel(n_jobs=-1, timeout=300)( # 5 minutes per task
delayed(evaluate_hyperparams)(ms, eps, sw, citsci_df, expert_df, expert_images)
for ms, eps, sw in hp_list
)
# If a worker crashes, task fails and exception propagates
# Typical causes:
# - Out of memory
# - Segmentation fault
# - Infinite loop (timeout helps)
# Recovery: Increase memory, reduce n_jobs, or fix underlying issue
# Parallel can batch tasks for efficiency
results = Parallel(n_jobs=-1, batch_size='auto')(
delayed(fn)(args) for args in arguments
)
from joblib import parallel_backend
# Loky backend (default, most robust)
with parallel_backend('loky', n_jobs=-1):
results = Parallel()(delayed(fn)(args) for args in arguments)
# Threading backend (for I/O-bound tasks, lower overhead)
with parallel_backend('threading', n_jobs=-1):
results = Parallel()(delayed(fn)(args) for args in arguments)
# Set random seed for reproducibility
import numpy as np
np.random.seed(42)
# Note: DBSCAN is deterministic (no randomness)
# Parallelization doesn't affect results (only speed)
For 847 DBSCAN evaluations across 369 images:
| Configuration | Time |
|---|---|
| Sequential (1 core) | ~60-90 minutes |
| Parallel (22 cores) | ~1.5-2 minutes |
| Speedup | ~40-45× |
# Test single evaluation first
result = evaluate_hyperparams(3, 4, 0.9, citsci_df, expert_df, expert_images)
print(result)
# Then enable parallelization
results = Parallel(n_jobs=-1, verbose=10)(
delayed(evaluate_hyperparams)(ms, eps, sw, citsci_df, expert_df, expert_images)
for ms, eps, sw in hp_list[:10] # Test on subset first
)
# Finally, full grid search
results = Parallel(n_jobs=-1, verbose=1)(
delayed(evaluate_hyperparams)(ms, eps, sw, citsci_df, expert_df, expert_images)
for ms, eps, sw in hp_list
)