Skip to content

Commit cd7771a

Browse files
authored
Address final CWRU fixes for Issue #8 (#11)
* Address final CWRU fixes for Issue #8 * Update threshold sweep logic and add formal validation report * Fix ruff formatting issues with imports and unused variables
1 parent 5c6d07c commit cd7771a

3 files changed

Lines changed: 58 additions & 10 deletions

File tree

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import numpy as np
2+
import tensorflow as tf
23

34
from cnsd import Dataset
45
from cnsd.diagnosis.system import CNSD
@@ -25,8 +26,11 @@ def add_awgn(signals, snr_db):
2526

2627

2728
def main():
29+
np.random.seed(42)
30+
tf.random.set_seed(42)
31+
2832
print('=' * 80)
29-
print('CNSD CROSS-DOMAIN VALIDATION (AWGN NOISE INJECTION)')
33+
print('CNSD CROSS-CONDITION ROBUSTNESS (AWGN NOISE INJECTION)')
3034
print('=' * 80)
3135

3236
# 1. Load baseline data
@@ -52,7 +56,7 @@ def main():
5256
model.fit(train_data, epochs=30)
5357
print('Training complete.\n')
5458

55-
# 3. Evaluate on noisy cross-domains
59+
# 3. Evaluate on noisy cross-conditions
5660
snr_levels = [None, 0, -5, -10]
5761

5862
for snr in snr_levels:

validate_run.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"""
1919

2020
import numpy as np
21+
import tensorflow as tf
2122

2223
from cnsd import Dataset
2324
from cnsd.causal import signal_kurtosis
@@ -79,11 +80,11 @@ def read_mat(path, label, load):
7980
dir_path = os.path.join(fault_dir, ftype, size)
8081
if not os.path.exists(dir_path):
8182
continue
82-
for f in os.listdir(dir_path):
83-
if f.endswith('.mat'):
84-
load = int(f.split('_')[-1].split('.')[0])
85-
read_mat(os.path.join(dir_path, f), label, load)
86-
83+
for root, _dirs, files in os.walk(dir_path):
84+
for f in files:
85+
if f.endswith('.mat'):
86+
load = int(f.split('_')[-1].split('.')[0])
87+
read_mat(os.path.join(root, f), label, load)
8788
return np.array(X, dtype=np.float32), np.array(y), np.array(cond)
8889

8990

@@ -126,6 +127,9 @@ def headline_accuracy_by_verdict(report, y_true):
126127

127128

128129
def main():
130+
np.random.seed(42)
131+
tf.random.set_seed(42)
132+
129133
print('=' * 68)
130134
print('CNSD VALIDATION RUN (CWRU, Protocol B)')
131135
print('=' * 68)
@@ -222,9 +226,21 @@ def main():
222226
)
223227

224228
# 7. example auditable diagnoses
225-
print('\n[examples] auditable root-cause diagnoses:')
226-
for r in report.records[:5]:
227-
print(f' [{r["status"]}] {r["root_cause"]["statement"]}')
229+
print('\n[examples] auditable root-cause diagnoses (CONFIRMED faults only):')
230+
seen_classes = set()
231+
examples = []
232+
for idx, r in enumerate(report.records):
233+
y_true = test_data.y[idx]
234+
if r['physics_verdict'] == 'CONFIRMED' and y_true > 0:
235+
if y_true not in seen_classes:
236+
examples.append(
237+
f' [Class {y_true}] [{r["status"]}] {r["root_cause"]["statement"]}'
238+
)
239+
seen_classes.add(y_true)
240+
if len(examples) >= 5:
241+
break
242+
for ex in examples:
243+
print(ex)
228244

229245
print('\n' + '=' * 68)
230246
print('VALIDATION COMPLETE - if all sections printed, the pipeline runs end-to-end.')

validation_report.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# CNSD Pipeline Validation Report (Issue #8)
2+
3+
This document serves as a professional record of the experiments, fixes, and validation runs performed to harden the CWRU baseline for the CNSD causal-neurosymbolic system.
4+
5+
## 1. Loader Bug Fix (Nested Subdirectories)
6+
The `load_cwru()` function was missing the `@3`, `@6`, and `@12` outer-race classes due to a rigid directory parsing logic. This was fixed by utilizing `os.walk` to comprehensively scan all nested subdirectories for `.mat` files.
7+
8+
**Result**: All 10 CWRU taxonomy classes are now correctly ingested.
9+
```text
10+
[train_data] Dataset 'CWRU_Train': 5806 samples, window=1024, fs=12000Hz, classes=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], conditions=[0, 1, 2], physics=yes
11+
[test_data] Dataset 'CWRU_Test': 2019 samples, window=1024, fs=12000Hz, classes=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], conditions=[3], physics=yes
12+
```
13+
14+
## 2. Root-Cause Printing Fix
15+
The root-cause print loop was previously dumping raw physics vectors and showing "No defect detected". The logic was updated to specifically filter for `CONFIRMED` faults and uniquely print the human-readable physical descriptions of each fault class exactly once.
16+
17+
**Result**: Clean, auditable, and human-readable root-cause statements.
18+
```text
19+
[examples] auditable root-cause diagnoses (CONFIRMED faults only):
20+
[Class 2] [HIGH_CONFIDENCE] Defect on the rolling element (Ball), evidenced by a peak at the BSF (135.9 Hz, strength 3.5). a defect on a rolling element striking both races as it spins.
21+
[Class 4] [HIGH_CONFIDENCE] Defect on the inner race (Inner Race), evidenced by a peak at the BPFI (156.1 Hz, strength 4.4). a defect on the rotating inner race, modulated by shaft rotation.
22+
[Class 5] [HIGH_CONFIDENCE] Defect on the inner race (Inner Race), evidenced by a peak at the BPFI (156.1 Hz, strength 3.0). a defect on the rotating inner race, modulated by shaft rotation.
23+
[Class 6] [HIGH_CONFIDENCE] Defect on the inner race (Inner Race), evidenced by a peak at the BPFI (156.1 Hz, strength 3.3). a defect on the rotating inner race, modulated by shaft rotation.
24+
[Class 7] [HIGH_CONFIDENCE] Defect on the outer race (Outer Race), evidenced by a peak at the BPFO (103.4 Hz, strength 4.6). a defect on the stationary outer race struck by each rolling element.
25+
```
26+
27+
## 3. Terminology Clarification
28+
The script `cross_domain_validation.py` was renamed to `cross_condition_robustness.py` to correctly reflect the protocol (AWGN noise injection). "Cross-domain" is reserved for multi-rig experiments (e.g., SEU/Paderborn).

0 commit comments

Comments
 (0)