QSBench commited on
Commit
70b49b1
·
verified ·
1 Parent(s): 9c8a1ad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -27
app.py CHANGED
@@ -11,7 +11,7 @@ from sklearn.ensemble import RandomForestRegressor
11
  from sklearn.metrics import mean_absolute_error, r2_score
12
  from sklearn.model_selection import train_test_split
13
 
14
- # Setup logging
15
  logging.basicConfig(level=logging.INFO)
16
  logger = logging.getLogger(__name__)
17
 
@@ -47,12 +47,13 @@ NON_FEATURE_COLS = {
47
 
48
  _ASSET_CACHE = {}
49
 
 
50
  def fetch_remote_json(url: str) -> Optional[dict]:
51
  try:
52
  response = requests.get(url, timeout=5)
53
  return response.json() if response.status_code == 200 else None
54
  except Exception as e:
55
- logger.error(f"Error fetching metadata: {e}")
56
  return None
57
 
58
  def load_all_assets(key: str) -> Dict:
@@ -69,7 +70,7 @@ def generate_guide_markdown(assets: Dict) -> str:
69
  meta = assets.get("meta", {})
70
  params = meta.get("parameters", {})
71
  report = assets.get("report", {})
72
- if not meta: return "⚠️ *Metadata unavailable.*"
73
 
74
  families = report.get("families", {})
75
  fam_table = "| Family | Samples | Description |\n| :--- | :--- | :--- |\n"
@@ -80,14 +81,14 @@ def generate_guide_markdown(assets: Dict) -> str:
80
  ## 📖 Methodology & Release Notes: {meta.get('dataset_version', '1.0.0-demo')}
81
 
82
  ### 1. Generation Engine
83
- Generated using **QSBench v{meta.get('generator_version', '5.0')}**.
84
- - **Qubits:** {params.get('n_qubits')} | **Depth:** {params.get('depth')}
85
  - **Noise:** `{params.get('noise', 'None')}` (p={params.get('noise_prob', 0)})
86
- - **Backend:** {meta.get('backend_device', 'GPU')}
87
 
88
  ### 2. Structural Metrics
89
- * **Gate Entropy:** Distribution of gates.
90
- * **Meyer-Wallach:** Global entanglement.
 
91
 
92
  ### 3. Circuit Family Coverage
93
  {fam_table}
@@ -98,10 +99,11 @@ def update_explorer_view(ds_name: str, split_name: str):
98
  df = assets["df"]
99
  splits = df["split"].unique().tolist() if "split" in df.columns else ["train"]
100
  display_df = df[df["split"] == split_name].head(10) if "split" in df.columns else df.head(10)
101
- raw_qasm = display_df["qasm_raw"].iloc[0] if "qasm_raw" in display_df.columns else "// No data"
102
- tr_qasm = display_df["qasm_transpiled"].iloc[0] if "qasm_transpiled" in display_df.columns else "// No data"
103
 
104
- meta_summary = f"### 📋 Pack: {ds_name} | Release: {assets.get('meta', {}).get('dataset_version', 'N/A')}"
 
 
 
105
  return gr.update(choices=splits), display_df, raw_qasm, tr_qasm, meta_summary, generate_guide_markdown(assets)
106
 
107
  def sync_ml_inputs(ds_name: str):
@@ -109,30 +111,49 @@ def sync_ml_inputs(ds_name: str):
109
  df = assets["df"]
110
  numeric = df.select_dtypes(include=[np.number]).columns.tolist()
111
  valid = [c for c in numeric if c not in NON_FEATURE_COLS and not c.startswith(("error_", "sign_", "ideal_", "noisy_"))]
112
- top_picks = [f for f in ["gate_entropy", "meyer_wallach", "n_qubits", "depth"] if f in valid]
113
  return gr.update(choices=valid, value=top_picks)
114
 
115
  def train_baseline_model(ds_name: str, selected_features: List[str]):
116
  if not selected_features: return None, "### ❌ Error: Select features."
 
117
  assets = load_all_assets(ds_name)
118
  df = assets["df"]
119
  target = "ideal_expval_Z_global" if "ideal_expval_Z_global" in df.columns else df.filter(like="expval").columns[0]
 
120
  train_df = df.dropna(subset=selected_features + [target])
121
  X, y = train_df[selected_features], train_df[target]
122
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
123
  model = RandomForestRegressor(n_estimators=100, max_depth=12, n_jobs=-1, random_state=42)
124
  model.fit(X_train, y_train)
125
  preds = model.predict(X_test)
126
- fig, axes = plt.subplots(1, 3, figsize=(20, 6))
127
- axes[0].scatter(y_test, preds, alpha=0.4); axes[0].plot([y.min(), y.max()], [y.min(), y.max()], 'r--')
128
- axes[1].barh(selected_features[:10], model.feature_importances_[:10])
129
- sns.histplot(y_test - preds, kde=True, ax=axes[2])
130
- plt.tight_layout()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  return fig, f"**MAE:** {mean_absolute_error(y_test, preds):.4f}"
132
 
133
  # --- UI ---
134
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
135
- gr.Markdown("# 🌌 QSBench: Quantum Synthetic Benchmark Suite")
136
 
137
  with gr.Tabs():
138
  with gr.TabItem("🔎 Explorer"):
@@ -149,7 +170,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
149
  with gr.Row():
150
  with gr.Column(scale=1):
151
  ml_ds = gr.Dropdown(choices=list(REPO_CONFIG.keys()), value="Core (Clean)", label="Dataset")
152
- ml_feat = gr.CheckboxGroup(label="Features", choices=[])
153
  btn = gr.Button("Train Baseline", variant="primary")
154
  with gr.Column(scale=2):
155
  plot_out = gr.Plot(); txt_out = gr.Markdown()
@@ -157,17 +178,16 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
157
  with gr.TabItem("📖 Methodology & Guide"):
158
  guide_md = gr.Markdown("Loading guide...")
159
 
160
- # FOOTER WITH YOUR LINKS
161
  gr.Markdown(f"""
162
  ---
163
- ### 🔗 Project Resources & Store
164
- * **🤗 Hugging Face:** [QSBench Organization](https://huggingface.co/QSBench)
165
- * **💻 GitHub:** [QSBench Source Code](https://github.com/QSBench)
166
- * **🌐 Official Site:** [qsbench.github.io](https://qsbench.github.io)
167
-
168
- *QSBench is an open-source framework for noise-aware Quantum Machine Learning benchmarking.*
169
  """)
170
 
 
171
  ds_select.change(update_explorer_view, [ds_select, split_select], [split_select, data_table, code_raw, code_tr, metadata_box, guide_md])
172
  ml_ds.change(sync_ml_inputs, [ml_ds], [ml_feat])
173
  btn.click(train_baseline_model, [ml_ds, ml_feat], [plot_out, txt_out])
 
11
  from sklearn.metrics import mean_absolute_error, r2_score
12
  from sklearn.model_selection import train_test_split
13
 
14
+ # --- CONFIG & LOGGING ---
15
  logging.basicConfig(level=logging.INFO)
16
  logger = logging.getLogger(__name__)
17
 
 
47
 
48
  _ASSET_CACHE = {}
49
 
50
+ # --- CORE LOGIC ---
51
  def fetch_remote_json(url: str) -> Optional[dict]:
52
  try:
53
  response = requests.get(url, timeout=5)
54
  return response.json() if response.status_code == 200 else None
55
  except Exception as e:
56
+ logger.error(f"Error: {e}")
57
  return None
58
 
59
  def load_all_assets(key: str) -> Dict:
 
70
  meta = assets.get("meta", {})
71
  params = meta.get("parameters", {})
72
  report = assets.get("report", {})
73
+ if not meta: return "### ⚠️ Metadata Unreachable"
74
 
75
  families = report.get("families", {})
76
  fam_table = "| Family | Samples | Description |\n| :--- | :--- | :--- |\n"
 
81
  ## 📖 Methodology & Release Notes: {meta.get('dataset_version', '1.0.0-demo')}
82
 
83
  ### 1. Generation Engine
84
+ - **Generator:** QSBench v{meta.get('generator_version', '5.x')}
 
85
  - **Noise:** `{params.get('noise', 'None')}` (p={params.get('noise_prob', 0)})
86
+ - **Backend:** {meta.get('backend_device', 'GPU')} | {meta.get('precision_mode', 'double')}
87
 
88
  ### 2. Structural Metrics
89
+ * **Gate Entropy:** Measures circuit "chaos" and gate distribution complexity.
90
+ * **Meyer-Wallach:** Quantifies global entanglement levels.
91
+ * **Adjacency:** Graph density of the qubit interaction map.
92
 
93
  ### 3. Circuit Family Coverage
94
  {fam_table}
 
99
  df = assets["df"]
100
  splits = df["split"].unique().tolist() if "split" in df.columns else ["train"]
101
  display_df = df[df["split"] == split_name].head(10) if "split" in df.columns else df.head(10)
 
 
102
 
103
+ raw_qasm = display_df["qasm_raw"].iloc[0] if "qasm_raw" in display_df.columns else "// N/A"
104
+ tr_qasm = display_df["qasm_transpiled"].iloc[0] if "qasm_transpiled" in display_df.columns else "// N/A"
105
+
106
+ meta_summary = f"### 📋 Pack: {ds_name} | Version: {assets.get('meta', {}).get('dataset_version', 'N/A')}"
107
  return gr.update(choices=splits), display_df, raw_qasm, tr_qasm, meta_summary, generate_guide_markdown(assets)
108
 
109
  def sync_ml_inputs(ds_name: str):
 
111
  df = assets["df"]
112
  numeric = df.select_dtypes(include=[np.number]).columns.tolist()
113
  valid = [c for c in numeric if c not in NON_FEATURE_COLS and not c.startswith(("error_", "sign_", "ideal_", "noisy_"))]
114
+ top_picks = [f for f in ["gate_entropy", "meyer_wallach", "n_qubits", "depth", "total_gates"] if f in valid]
115
  return gr.update(choices=valid, value=top_picks)
116
 
117
  def train_baseline_model(ds_name: str, selected_features: List[str]):
118
  if not selected_features: return None, "### ❌ Error: Select features."
119
+
120
  assets = load_all_assets(ds_name)
121
  df = assets["df"]
122
  target = "ideal_expval_Z_global" if "ideal_expval_Z_global" in df.columns else df.filter(like="expval").columns[0]
123
+
124
  train_df = df.dropna(subset=selected_features + [target])
125
  X, y = train_df[selected_features], train_df[target]
126
  X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
127
+
128
  model = RandomForestRegressor(n_estimators=100, max_depth=12, n_jobs=-1, random_state=42)
129
  model.fit(X_train, y_train)
130
  preds = model.predict(X_test)
131
+
132
+ # Улучшенная визуализация (исправляет обрезку)
133
+ sns.set_theme(style="whitegrid", context="talk")
134
+ fig, axes = plt.subplots(1, 3, figsize=(22, 7))
135
+
136
+ # 1. Parity
137
+ axes[0].scatter(y_test, preds, alpha=0.4, color='#34495e')
138
+ axes[0].plot([y.min(), y.max()], [y.min(), y.max()], 'r--', lw=2)
139
+ axes[0].set_title(f"Accuracy (R²: {r2_score(y_test, preds):.3f})")
140
+
141
+ # 2. Importance (с поправкой на длинные названия)
142
+ imp = model.feature_importances_
143
+ idx = np.argsort(imp)[-10:]
144
+ axes[1].barh([selected_features[i] for i in idx], imp[idx], color='#1abc9c')
145
+ axes[1].set_title("Top Metrics Importance")
146
+
147
+ # 3. Residuals
148
+ sns.histplot(y_test - preds, kde=True, ax=axes[2], color='#e67e22')
149
+ axes[2].set_title("Prediction Error")
150
+
151
+ plt.tight_layout() # Автоматически подгоняет отступы
152
  return fig, f"**MAE:** {mean_absolute_error(y_test, preds):.4f}"
153
 
154
  # --- UI ---
155
+ with gr.Blocks(theme=gr.themes.Soft(), title="QSBench Hub") as demo:
156
+ gr.Markdown("# 🌌 QSBench: Quantum Analytics Hub")
157
 
158
  with gr.Tabs():
159
  with gr.TabItem("🔎 Explorer"):
 
170
  with gr.Row():
171
  with gr.Column(scale=1):
172
  ml_ds = gr.Dropdown(choices=list(REPO_CONFIG.keys()), value="Core (Clean)", label="Dataset")
173
+ ml_feat = gr.CheckboxGroup(label="Structural Metrics", choices=[])
174
  btn = gr.Button("Train Baseline", variant="primary")
175
  with gr.Column(scale=2):
176
  plot_out = gr.Plot(); txt_out = gr.Markdown()
 
178
  with gr.TabItem("📖 Methodology & Guide"):
179
  guide_md = gr.Markdown("Loading guide...")
180
 
181
+ # FOOTER
182
  gr.Markdown(f"""
183
  ---
184
+ ### 🔗 Project Resources & Links
185
+ * **🤗 Hugging Face:** [QSBench Org](https://huggingface.co/QSBench) — Dataset shards and demos.
186
+ * **💻 GitHub:** [QSBench Repository](https://github.com/QSBench) — Generator source code.
187
+ * **🌐 Project Site:** [qsbench.github.io](https://qsbench.github.io) — Documentation & Papers.
 
 
188
  """)
189
 
190
+ # Handlers
191
  ds_select.change(update_explorer_view, [ds_select, split_select], [split_select, data_table, code_raw, code_tr, metadata_box, guide_md])
192
  ml_ds.change(sync_ml_inputs, [ml_ds], [ml_feat])
193
  btn.click(train_baseline_model, [ml_ds, ml_feat], [plot_out, txt_out])