QSBench commited on
Commit
bf47ebc
Β·
verified Β·
1 Parent(s): 0bc99d2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +48 -23
app.py CHANGED
@@ -36,6 +36,8 @@ REPO_CONFIG = {
36
  }
37
 
38
  TARGET_COLS = ["error_Z_global", "error_X_global", "error_Y_global"]
 
 
39
 
40
  NON_FEATURE_COLS = {
41
  "sample_id", "sample_seed", "circuit_hash", "split", "circuit_qasm",
@@ -43,13 +45,10 @@ NON_FEATURE_COLS = {
43
  "noise_type", "noise_prob", "observable_bases", "observable_mode", "shots",
44
  "gpu_requested", "gpu_available", "backend_device", "precision_mode",
45
  "circuit_signature", "noise_label",
46
- "ideal_expval_Z_global", "noisy_expval_Z_global",
47
- "ideal_expval_X_global", "noisy_expval_X_global",
48
- "ideal_expval_Y_global", "noisy_expval_Y_global",
49
  "sign_ideal_Z_global", "sign_noisy_Z_global",
50
  "sign_ideal_X_global", "sign_noisy_X_global",
51
  "sign_ideal_Y_global", "sign_noisy_Y_global",
52
- *TARGET_COLS,
53
  }
54
 
55
  SOFT_EXCLUDE_PATTERNS = ["ideal_", "noisy_", "sign_ideal_", "sign_noisy_"]
@@ -59,9 +58,7 @@ _ASSET_CACHE: Dict[str, pd.DataFrame] = {}
59
  # ========================= HELPERS =========================
60
 
61
  def load_guide_content() -> str:
62
- """
63
- Read the GUIDE.md file from the root directory.
64
- """
65
  try:
66
  with open("GUIDE.md", "r", encoding="utf-8") as f:
67
  return f.read()
@@ -184,10 +181,18 @@ def default_feature_selection(features: List[str]) -> List[str]:
184
  selected = [f for f in preferred if f in features]
185
  return selected[:10] if selected else features[:10]
186
 
187
- def make_regression_figure(y_true: np.ndarray, y_pred: np.ndarray, basis: str) -> plt.Figure:
188
- """Generate diagnostic regression plots."""
189
- fig, axs = plt.subplots(1, 2, figsize=(14, 6))
190
- axs[0].scatter(y_true, y_pred, alpha=0.6, s=15)
 
 
 
 
 
 
 
 
191
  min_v, max_v = min(y_true.min(), y_pred.min()), max(y_true.max(), y_pred.max())
192
  axs[0].plot([min_v, max_v], [min_v, max_v], 'r--', lw=2)
193
  axs[0].set_xlabel("True Error")
@@ -195,14 +200,27 @@ def make_regression_figure(y_true: np.ndarray, y_pred: np.ndarray, basis: str) -
195
  axs[0].set_title(f"{basis} Error: Predicted vs True")
196
  axs[0].grid(True, alpha=0.3)
197
 
 
198
  residuals = y_true - y_pred
199
- axs[1].hist(residuals, bins=50, alpha=0.7, color="skyblue", edgecolor="black")
200
  axs[1].axvline(0, color="red", linestyle="--")
201
  axs[1].set_xlabel("Residual")
202
  axs[1].set_ylabel("Count")
203
- axs[1].set_title(f"{basis} Residual Distribution")
204
  axs[1].grid(True, alpha=0.3)
205
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  fig.tight_layout()
207
  return fig
208
 
@@ -218,7 +236,7 @@ def train_regressor(
218
  return None, "### ❌ Please select at least one feature.", None, None
219
 
220
  df = load_single_dataset()
221
- required_cols = feature_columns + TARGET_COLS
222
  train_df = df.dropna(subset=required_cols).copy()
223
 
224
  if len(train_df) < 50:
@@ -230,9 +248,15 @@ def train_regressor(
230
  seed = int(random_state)
231
  depth = int(max_depth) if max_depth and int(max_depth) > 0 else None
232
 
233
- X_train, X_test, y_train, y_test = train_test_split(
234
- X, y, test_size=test_size, random_state=seed
235
- )
 
 
 
 
 
 
236
 
237
  model = Pipeline([
238
  ("imputer", SimpleImputer(strategy="median")),
@@ -264,9 +288,10 @@ def train_regressor(
264
  f"**Y-error** β€” MAE: {mae[2]:.5f} | RMSE: {rmse[2]:.5f} | RΒ²: {r2[2]:.4f}\n"
265
  )
266
 
267
- fig_z = make_regression_figure(y_test.iloc[:, 0].values, y_pred[:, 0], "Z")
268
- fig_x = make_regression_figure(y_test.iloc[:, 1].values, y_pred[:, 1], "X")
269
- fig_y = make_regression_figure(y_test.iloc[:, 2].values, y_pred[:, 2], "Y")
 
270
 
271
  return fig_z, metrics_text, fig_x, fig_y
272
 
@@ -363,9 +388,9 @@ with gr.Blocks(title=APP_TITLE) as demo:
363
  run_btn = gr.Button("πŸš€ Train Multi-Output Regressor", variant="primary")
364
 
365
  with gr.Row():
366
- plot_z = gr.Plot(label="Z Error")
367
- plot_x = gr.Plot(label="X Error")
368
- plot_y = gr.Plot(label="Y Error")
369
  metrics = gr.Markdown()
370
 
371
  with gr.TabItem("πŸ“– Guide"):
 
36
  }
37
 
38
  TARGET_COLS = ["error_Z_global", "error_X_global", "error_Y_global"]
39
+ IDEAL_COLS = ["ideal_expval_Z_global", "ideal_expval_X_global", "ideal_expval_Y_global"]
40
+ NOISY_COLS = ["noisy_expval_Z_global", "noisy_expval_X_global", "noisy_expval_Y_global"]
41
 
42
  NON_FEATURE_COLS = {
43
  "sample_id", "sample_seed", "circuit_hash", "split", "circuit_qasm",
 
45
  "noise_type", "noise_prob", "observable_bases", "observable_mode", "shots",
46
  "gpu_requested", "gpu_available", "backend_device", "precision_mode",
47
  "circuit_signature", "noise_label",
48
+ *IDEAL_COLS, *NOISY_COLS, *TARGET_COLS,
 
 
49
  "sign_ideal_Z_global", "sign_noisy_Z_global",
50
  "sign_ideal_X_global", "sign_noisy_X_global",
51
  "sign_ideal_Y_global", "sign_noisy_Y_global",
 
52
  }
53
 
54
  SOFT_EXCLUDE_PATTERNS = ["ideal_", "noisy_", "sign_ideal_", "sign_noisy_"]
 
58
  # ========================= HELPERS =========================
59
 
60
  def load_guide_content() -> str:
61
+ """Read the GUIDE.md file from the root directory."""
 
 
62
  try:
63
  with open("GUIDE.md", "r", encoding="utf-8") as f:
64
  return f.read()
 
181
  selected = [f for f in preferred if f in features]
182
  return selected[:10] if selected else features[:10]
183
 
184
+ def make_regression_figure(
185
+ y_true: np.ndarray,
186
+ y_pred: np.ndarray,
187
+ ideal_vals: np.ndarray,
188
+ noisy_vals: np.ndarray,
189
+ basis: str
190
+ ) -> plt.Figure:
191
+ """Generate diagnostic regression plots including physics emulation."""
192
+ fig, axs = plt.subplots(1, 3, figsize=(20, 6))
193
+
194
+ # 1. Error Prediction (Predicted vs True)
195
+ axs[0].scatter(y_true, y_pred, alpha=0.6, s=15, color='#3498db')
196
  min_v, max_v = min(y_true.min(), y_pred.min()), max(y_true.max(), y_pred.max())
197
  axs[0].plot([min_v, max_v], [min_v, max_v], 'r--', lw=2)
198
  axs[0].set_xlabel("True Error")
 
200
  axs[0].set_title(f"{basis} Error: Predicted vs True")
201
  axs[0].grid(True, alpha=0.3)
202
 
203
+ # 2. Residual Distribution
204
  residuals = y_true - y_pred
205
+ axs[1].hist(residuals, bins=50, alpha=0.7, color="#2ecc71", edgecolor="black")
206
  axs[1].axvline(0, color="red", linestyle="--")
207
  axs[1].set_xlabel("Residual")
208
  axs[1].set_ylabel("Count")
209
+ axs[1].set_title(f"{basis} Error Residuals")
210
  axs[1].grid(True, alpha=0.3)
211
 
212
+ # 3. Physics Emulation (Ideal vs Noisy Expectation Values)
213
+ pred_noisy_vals = ideal_vals + y_pred
214
+
215
+ axs[2].scatter(ideal_vals, noisy_vals, alpha=0.4, s=15, label="Actual Noisy (Simulated)", color="#95a5a6")
216
+ axs[2].scatter(ideal_vals, pred_noisy_vals, alpha=0.6, s=15, label="Predicted Noisy (ML)", color="#e74c3c")
217
+ axs[2].plot([-1, 1], [-1, 1], 'k--', lw=1, alpha=0.7, label="No Noise Limit")
218
+ axs[2].set_xlabel("Ideal Expectation Value")
219
+ axs[2].set_ylabel("Noisy Expectation Value")
220
+ axs[2].set_title(f"Physics Emulation: {basis} Basis Shift")
221
+ axs[2].legend()
222
+ axs[2].grid(True, alpha=0.3)
223
+
224
  fig.tight_layout()
225
  return fig
226
 
 
236
  return None, "### ❌ Please select at least one feature.", None, None
237
 
238
  df = load_single_dataset()
239
+ required_cols = feature_columns + TARGET_COLS + IDEAL_COLS + NOISY_COLS
240
  train_df = df.dropna(subset=required_cols).copy()
241
 
242
  if len(train_df) < 50:
 
248
  seed = int(random_state)
249
  depth = int(max_depth) if max_depth and int(max_depth) > 0 else None
250
 
251
+ # Track indices to extract ideal and noisy arrays for the test set later
252
+ indices = np.arange(len(train_df))
253
+ idx_train, idx_test = train_test_split(indices, test_size=test_size, random_state=seed)
254
+
255
+ X_train, X_test = X.iloc[idx_train], X.iloc[idx_test]
256
+ y_train, y_test = y.iloc[idx_train], y.iloc[idx_test]
257
+
258
+ ideal_test = train_df[IDEAL_COLS].iloc[idx_test].values
259
+ noisy_test = train_df[NOISY_COLS].iloc[idx_test].values
260
 
261
  model = Pipeline([
262
  ("imputer", SimpleImputer(strategy="median")),
 
288
  f"**Y-error** β€” MAE: {mae[2]:.5f} | RMSE: {rmse[2]:.5f} | RΒ²: {r2[2]:.4f}\n"
289
  )
290
 
291
+ # Generate figures passing ideal and true noisy data
292
+ fig_z = make_regression_figure(y_test.iloc[:, 0].values, y_pred[:, 0], ideal_test[:, 0], noisy_test[:, 0], "Z")
293
+ fig_x = make_regression_figure(y_test.iloc[:, 1].values, y_pred[:, 1], ideal_test[:, 1], noisy_test[:, 1], "X")
294
+ fig_y = make_regression_figure(y_test.iloc[:, 2].values, y_pred[:, 2], ideal_test[:, 2], noisy_test[:, 2], "Y")
295
 
296
  return fig_z, metrics_text, fig_x, fig_y
297
 
 
388
  run_btn = gr.Button("πŸš€ Train Multi-Output Regressor", variant="primary")
389
 
390
  with gr.Row():
391
+ plot_z = gr.Plot(label="Z Error Metrics")
392
+ plot_x = gr.Plot(label="X Error Metrics")
393
+ plot_y = gr.Plot(label="Y Error Metrics")
394
  metrics = gr.Markdown()
395
 
396
  with gr.TabItem("πŸ“– Guide"):