Skip to content

Commit 9e6f3b1

Browse files
committed
fix: evaluate tau robustness on PU test set and flag limitations
1 parent aaf4f5f commit 9e6f3b1

2 files changed

Lines changed: 47 additions & 33 deletions

File tree

EXPERIMENTS.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,19 +240,25 @@ n_teeth_input: 20 | channel: 2 (planetary x-axis)
240240

241241
* **Known caveats to report honestly:** The accuracy gap is currently backwards and practically noise due to a 99.5% inconclusive rate. This is pending a strict `tau` threshold calibration sweep for gear physics, as well as confirming that GMF strength aligns with the same numerical scale as bearing physics.
242242

243-
## 4. Paderborn University (PU) Dataset - Cross-Domain Domain Shift (Speed)
243+
## 6. Paderborn University (PU) Dataset - Cross-Domain Domain Shift (Speed)
244244

245245
**Dataset**: Authentic bearing fatigue damages (FAG 6203 deep groove ball bearings).
246246
**Objective**: Eliminate data leakage by explicitly testing the model's ability to generalize across changing physical operating conditions (Domain Shift). The CNN is trained exclusively on 900 RPM data and tested exclusively on 1500 RPM data.
247-
**Physics Config**: D=28.5mm, d=6.75mm, N=8, f_s=64kHz. `tau` calibrated to 2.5 on the 1500 RPM calibration split.
247+
**Physics Config**: D=28.5mm, d=6.75mm, N=8, f_s=64kHz. Baseline CNN Accuracy: 0.704.
248248

249-
### Headline — CNN accuracy by physics verdict (Domain Shift: 900 RPM -> 1500 RPM)
250-
| Verdict | n | CNN accuracy |
251-
|---------|---|--------------|
252-
| CONFIRMED | 2340 | 0.933 |
253-
| CONFLICT | 1724 | 0.544 |
254-
| INCONCLUSIVE | 3393 | 0.504 |
255-
| **Gap (CONFIRMED - CONFLICT)** | | **+0.389** |
249+
### Test-Set Robustness Check (1500 RPM Test Split)
250+
To ensure the gap is robust and not just overfitted to a specific threshold, the test set was evaluated across multiple `tau` values:
251+
252+
| Threshold (`tau`) | CONFIRMED Acc | CONFLICT Acc | **Gap** | Inconclusive Rate |
253+
|-------------------|---------------|--------------|---------|-------------------|
254+
| 1.0 | 0.918 | 0.553 | **+0.365** | 0.1% |
255+
| 2.0 | 0.953 | 0.562 | **+0.390** | 25.9% |
256+
| 2.5 | 0.977 | 0.560 | **+0.417** | 46.3% |
257+
| 3.0 | 0.987 | 0.566 | **+0.421** | 58.5% |
256258

257259
**Notes**:
258-
This experiment perfectly proves the necessity of the causal physics engine. Because the baseline CNN was trained only on 900 RPM data, its pattern matching failed catastrophically when tested on 1500 RPM data (Baseline Accuracy crashed to 64.8%). However, the Physics Engine mathematically adjusts for RPM dynamically. It successfully caught the CNN's failures, flagging over 1,700 predictions as CONFLICTS, while isolating 2,340 verified predictions that maintained a 93.3% accuracy. The massive Accuracy Gap of **+38.9%** undeniably proves that the physics engine acts as a robust, domain-aware verification layer for unreliable neural networks.
260+
Because the baseline CNN was trained only on 900 RPM data, its pattern matching degraded when tested on 1500 RPM data (Baseline Accuracy crashed to 70.4%). The Physics Engine dynamically adjusts for RPM and isolates reliable predictions. As shown above, the gap remains strongly positive across all thresholds, peaking at +0.421.
261+
262+
**Known Limitations**:
263+
- **High Inconclusive Rate**: At the optimally calibrated threshold (`tau=2.5`), the engine flags ~46% of predictions as INCONCLUSIVE. This is a known trade-off of the strict verification process.
264+
- **Scope**: Demonstrated strong robustness on the PU speed-shift task (single dataset, single seed).

validate_pu.py

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -188,33 +188,41 @@ def headline_accuracy_by_verdict(report, y_true):
188188
best_tau = float(tau)
189189

190190
print(f'\n=> Selected optimal tau: {best_tau}')
191-
model.symbolic.tau = best_tau
192191

193-
print('\n[3] Evaluating on Test Set (1500 RPM)...')
192+
print('\n[3] Evaluating on Test Set (1500 RPM) Across Multiple Taus...')
193+
194+
# Calculate baseline CNN accuracy first (independent of tau)
195+
model.symbolic.tau = best_tau
194196
report = model.diagnose(test_data)
195-
196-
hb = headline_accuracy_by_verdict(report, y_test)
197-
198-
# Calculate baseline CNN accuracy
199197
pred = np.array([r['predicted_class'] for r in report.records])
200198
baseline_acc = float((pred == np.asarray(y_test)).mean())
201-
202199
print('\n--- FINAL TEST RESULTS (CROSS-DOMAIN PU) ---')
203200
print(f'Baseline CNN Acc: {baseline_acc:.3f}')
204-
if 'CONFIRMED' in hb:
205-
print(
206-
f'Physics-Confirmed Acc: {hb["CONFIRMED"]["cnn_accuracy"]:.3f} (n={hb["CONFIRMED"]["n"]})'
207-
)
208-
if 'CONFLICT' in hb:
209-
print(
210-
f'Physics-Conflict Acc: {hb["CONFLICT"]["cnn_accuracy"]:.3f} (n={hb["CONFLICT"]["n"]})'
211-
)
212-
if 'INCONCLUSIVE' in hb:
213-
print(
214-
f'Physics-Inconclusive Acc:{hb["INCONCLUSIVE"]["cnn_accuracy"]:.3f} (n={hb["INCONCLUSIVE"]["n"]})'
215-
)
216-
217-
if 'CONFIRMED' in hb and 'CONFLICT' in hb:
218-
gap = hb['CONFIRMED']['cnn_accuracy'] - hb['CONFLICT']['cnn_accuracy']
219-
print(f'GAP (CONF - CNFL): {gap:+.3f}')
201+
print('--------------------------------------------')
202+
203+
taus_to_test = [1.0, 2.0, 2.5, 3.0]
204+
if best_tau not in taus_to_test:
205+
taus_to_test.append(best_tau)
206+
taus_to_test = sorted(list(set(taus_to_test)))
207+
208+
for test_tau in taus_to_test:
209+
model.symbolic.tau = test_tau
210+
report = model.diagnose(test_data)
211+
hb = headline_accuracy_by_verdict(report, y_test)
212+
213+
print(f'\n[Tau = {test_tau:.1f}]')
214+
215+
if 'CONFIRMED' in hb:
216+
print(f' Physics-Confirmed Acc: {hb["CONFIRMED"]["cnn_accuracy"]:.3f} (n={hb["CONFIRMED"]["n"]})')
217+
if 'CONFLICT' in hb:
218+
print(f' Physics-Conflict Acc: {hb["CONFLICT"]["cnn_accuracy"]:.3f} (n={hb["CONFLICT"]["n"]})')
219+
220+
if 'INCONCLUSIVE' in hb:
221+
inc_n = hb["INCONCLUSIVE"]["n"]
222+
inc_pct = (inc_n / len(y_test)) * 100
223+
print(f' Physics-Inconclusive Acc:{hb["INCONCLUSIVE"]["cnn_accuracy"]:.3f} (n={inc_n}, {inc_pct:.1f}%)')
224+
225+
if 'CONFIRMED' in hb and 'CONFLICT' in hb:
226+
gap = hb['CONFIRMED']['cnn_accuracy'] - hb['CONFLICT']['cnn_accuracy']
227+
print(f' GAP (CONF - CNFL): {gap:+.3f}')
220228
print('--------------------------------------------')

0 commit comments

Comments
 (0)