mirror of
https://github.com/ruvnet/RuView.git
synced 2026-10-22 06:32:35 -05:00
feat(csi): freeze source-backed motion ablation and record rejected mean-score candidate
This commit is contained in:
1 parent
b3937732e5
commit
b7b76de1f3
3 files changed
+460
No files matched your search
@@ -0,0 +1,133 @@
|
||||
{
|
||||
"status": "complete",
|
||||
"evidence": "MEASURED",
|
||||
"promotionAuthorized": false,
|
||||
"development": {
|
||||
"accuracy": 0.42857142857142855,
|
||||
"macro_f1": 0.39720523837065186,
|
||||
"per_class_f1": [
|
||||
0.625,
|
||||
0.47619047619047616,
|
||||
0.2857142857142857,
|
||||
0.4166666666666667,
|
||||
0.3076923076923077,
|
||||
0.5263157894736842,
|
||||
0.14285714285714285
|
||||
],
|
||||
"samples": 70
|
||||
},
|
||||
"incumbent_development": {
|
||||
"accuracy": 0.44285714285714284,
|
||||
"macro_f1": 0.3839985224859174,
|
||||
"per_class_f1": [
|
||||
0.35294117647058826,
|
||||
0.6153846153846154,
|
||||
0,
|
||||
0.5882352941176471,
|
||||
0.56,
|
||||
0.5714285714285714,
|
||||
0
|
||||
],
|
||||
"samples": 70
|
||||
},
|
||||
"retention_checks": {
|
||||
"macro_f1_gain": false,
|
||||
"accuracy_nonregression": false,
|
||||
"no_additional_zero_f1_classes": true,
|
||||
"p95_under_1ms": true
|
||||
},
|
||||
"retained_as_research_candidate": false,
|
||||
"latency": {
|
||||
"candidate": {
|
||||
"p50_ms": 0.5314695,
|
||||
"p95_ms": 0.7371814999999999
|
||||
},
|
||||
"incumbent": {
|
||||
"p50_ms": 0.31542,
|
||||
"p95_ms": 0.456288
|
||||
}
|
||||
},
|
||||
"model_bytes": 496488,
|
||||
"model_sha256": "c4bef32b0b4a563381883a705679637b188f30940e92c113ff21102aa1871d36",
|
||||
"baseline_model_sha256": "8a2cafdc5e6df989a3d8fff5762e2287ac5051f0e8b1ca2868431d60274b31ca",
|
||||
"baseline_receipt_sha256": "26bad1e0d7ce7a8ad525f8218e567dd88ba3f78404027a0795b2ab0e0faeb40d",
|
||||
"source_sha256": {
|
||||
"espfi_motion.py": "53fa62558d4ec0e357e0854f728f282ca2db6449c96f1dd9a1478de98ec8dd90",
|
||||
"espfi_generalize.py": "956b3a5e918f7c263a2b9183b4a6a70c8f2157604262a4ec6cee2c324a69224f",
|
||||
"espfi_kernel.py": "ae837cb2e3fac7f052b4bd371cd496e9636e5d5dbaf3a341526a4fc5aef23478",
|
||||
"espfi_runtime.py": "8e100972b0deeb8a6586271264f335551cb5d1e9cc42a24bddf933dba064a80f"
|
||||
},
|
||||
"scope": "24 configurations selected only on two training folds; development seen once after selection; 1000 alternating paired batch1 calls include features/checks/classifier, exclude pooling and IO. Candidate is float64 with explicit map, incumbent uses seeded float32 folded runtime; storage comparison includes different encodings. No test, hardware, pose or SOTA claim.",
|
||||
"reload_max_abs_logit_error": 0,
|
||||
"selected": {
|
||||
"candidate": {
|
||||
"family": "local_spectral",
|
||||
"kind": "rff",
|
||||
"dimensions": 128,
|
||||
"gamma_multiplier": 0.1,
|
||||
"alpha": 0.01
|
||||
},
|
||||
"mean_cv_macro_f1": 0.35559936248893814,
|
||||
"scalar_count": 61999
|
||||
},
|
||||
"best_per_family": {
|
||||
"relative_combined": {
|
||||
"candidate": {
|
||||
"family": "relative_combined",
|
||||
"kind": "rff",
|
||||
"dimensions": 128,
|
||||
"gamma_multiplier": 0.1,
|
||||
"alpha": 0.01
|
||||
},
|
||||
"mean_cv_macro_f1": 0.306028118879762,
|
||||
"fold_macro_f1": [
|
||||
0.30414628178603337,
|
||||
0.30790995597349063
|
||||
]
|
||||
},
|
||||
"motion_acf": {
|
||||
"candidate": {
|
||||
"family": "motion_acf",
|
||||
"kind": "rff",
|
||||
"dimensions": 128,
|
||||
"gamma_multiplier": 0.1,
|
||||
"alpha": 0.1
|
||||
},
|
||||
"mean_cv_macro_f1": 0.33402959890262357,
|
||||
"fold_macro_f1": [
|
||||
0.33211530016861246,
|
||||
0.3359438976366347
|
||||
]
|
||||
},
|
||||
"motion_invariant": {
|
||||
"candidate": {
|
||||
"family": "motion_invariant",
|
||||
"kind": "rff",
|
||||
"dimensions": 128,
|
||||
"gamma_multiplier": 0.1,
|
||||
"alpha": 0.1
|
||||
},
|
||||
"mean_cv_macro_f1": 0.3541747172155182,
|
||||
"fold_macro_f1": [
|
||||
0.31217774871662207,
|
||||
0.39617168571441436
|
||||
]
|
||||
},
|
||||
"local_spectral": {
|
||||
"candidate": {
|
||||
"family": "local_spectral",
|
||||
"kind": "rff",
|
||||
"dimensions": 128,
|
||||
"gamma_multiplier": 0.1,
|
||||
"alpha": 0.01
|
||||
},
|
||||
"mean_cv_macro_f1": 0.35559936248893814,
|
||||
"fold_macro_f1": [
|
||||
0.26600194570119384,
|
||||
0.44519677927668244
|
||||
]
|
||||
}
|
||||
},
|
||||
"manifest_sha256": "74e0fe039acbed1b287bd11ee6b779becbb8f9b66c3c249d260ed66f5583f02a",
|
||||
"full_receipt_sha256": "98e56df2181dcae17070b80002ca67fc7a53206742903f5f2c8c353747d3d8f1"
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
"""Frozen source-only motion ablation inspired by published ACF and RuView STFT.
|
||||
|
||||
Independent feature experiment, not a reproduction of an external model.
|
||||
Only grouped training folds select a candidate; final test arrays are absent.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
import time
|
||||
import numpy as np
|
||||
from safetensors.numpy import load, save_file
|
||||
from .espfi_generalize import amplitudes, features, folds
|
||||
from .espfi_kernel import fit, predict_features
|
||||
from .espfi_runtime import BufferedKernelBundle
|
||||
from .espfi_train import digest, scores, write_json
|
||||
|
||||
WIDTHS = {'relative_combined': 468, 'motion_acf': 468,
|
||||
'motion_invariant': 45, 'local_spectral': 468}
|
||||
GRID = [dict(family=family, kind='rff', dimensions=128, gamma_multiplier=gamma, alpha=alpha)
|
||||
for family in WIDTHS for gamma in (.1, 1.) for alpha in (.01, .1, 1.)]
|
||||
CONTRACT = {'seed': 42, 'grid': GRID, 'input': 'nonnegative_amplitude_N52T190',
|
||||
'selection': 'mean training-only grouped CV macro F1, then fewer scalars, then declaration order',
|
||||
'acf_lags': [1, 2, 4, 8, 16, 32], 'difference_lags': [1, 4, 16],
|
||||
'carrier_quantiles': [.1, .25, .5, .75, .9],
|
||||
'acf': 'centered log-amplitude biased autocorrelation divided by full channel energy floored at 190e-12',
|
||||
'stft': {'window': 32, 'starts': list(range(0, 159, 16))+[158],
|
||||
'taper': 'symmetric Hann', 'bands': [[1, 5], [5, 17]],
|
||||
'pooling': '4 consecutive frame groups via array_split; channel RMS appended'},
|
||||
'frequency_units': 'normalized cycles/sample; no measured rate inferred',
|
||||
'retention_gate': {'development_macro_f1_absolute_gain': .03,
|
||||
'accuracy_nonregression': True, 'no_additional_zero_f1_classes': True,
|
||||
'paired_p95_limit_ms': 1.0},
|
||||
'promotionAuthorized': False}
|
||||
|
||||
|
||||
def motion_features(values, family):
|
||||
if family not in WIDTHS:
|
||||
raise ValueError('Unknown motion family')
|
||||
if family == 'relative_combined':
|
||||
return features(values, family)
|
||||
x = amplitudes(values)
|
||||
logged = np.log(np.maximum(x, 1e-6))
|
||||
centered = logged-logged.mean(-1, keepdims=True)
|
||||
scale = np.maximum(np.sqrt(np.mean(centered**2, axis=(1, 2), keepdims=True)), 1e-6)
|
||||
relative = centered/scale
|
||||
if family == 'local_spectral':
|
||||
rows = []
|
||||
for offset in range(0, len(x), 32):
|
||||
part = relative[offset:offset+32]
|
||||
windows = np.lib.stride_tricks.sliding_window_view(part, 32, axis=-1)
|
||||
windows = windows[..., CONTRACT['stft']['starts'], :] * np.hanning(32)
|
||||
power = np.abs(np.fft.rfft(windows, axis=-1))**2 / 32**2
|
||||
bands = np.stack((power[..., 1:5].sum(-1), power[..., 5:17].sum(-1)), axis=-1)
|
||||
local = np.stack([b.mean(axis=-2) for b in np.array_split(bands, 4, axis=-2)], axis=-2)
|
||||
rows.append(np.concatenate((local.reshape(len(part), -1),
|
||||
np.sqrt(np.mean(part**2, axis=-1))), axis=1))
|
||||
result = np.concatenate(rows)
|
||||
else:
|
||||
energy = np.maximum(np.sum(centered**2, axis=-1), 190e-12)
|
||||
acf = [np.sum(centered[..., lag:]*centered[..., :-lag], axis=-1)/energy
|
||||
for lag in CONTRACT['acf_lags']]
|
||||
changes = [np.mean(np.abs(relative[..., lag:]-relative[..., :-lag]), axis=-1)
|
||||
for lag in CONTRACT['difference_lags']]
|
||||
per_channel = np.stack(acf+changes, axis=-1)
|
||||
if family == 'motion_invariant':
|
||||
pooled = np.quantile(per_channel, CONTRACT['carrier_quantiles'], axis=1)
|
||||
result = pooled.transpose(1, 0, 2).reshape(len(x), -1)
|
||||
else:
|
||||
result = per_channel.reshape(len(x), -1)
|
||||
if result.shape != (len(x), WIDTHS[family]) or not np.isfinite(result).all():
|
||||
raise ValueError('Invalid motion features')
|
||||
return np.ascontiguousarray(result)
|
||||
|
||||
|
||||
def _read(path, limit):
|
||||
path = Path(path)
|
||||
if path.is_symlink() or not path.is_file():
|
||||
raise ValueError('Expected regular bounded artifact')
|
||||
with path.open('rb') as handle:
|
||||
data = handle.read(limit+1)
|
||||
if len(data) > limit:
|
||||
raise ValueError('Oversized artifact')
|
||||
return data
|
||||
|
||||
|
||||
class MotionBundle:
|
||||
def __init__(self, directory):
|
||||
root = Path(directory)
|
||||
status = json.loads(_read(root/'status.json', 65536))
|
||||
report = json.loads(_read(root/'metrics.json', 16*1024**2))
|
||||
if (not isinstance(status, dict) or not isinstance(report, dict)
|
||||
or status.get('status') != 'complete' or status.get('promotionAuthorized') is not False
|
||||
or report.get('status') != 'complete' or report.get('promotionAuthorized') is not False
|
||||
or report.get('contract') != CONTRACT or report.get('task') != 'public_motion_ablation'):
|
||||
raise ValueError('Invalid completed motion artifact')
|
||||
self.candidate = report['selected']['candidate']
|
||||
if self.candidate not in GRID:
|
||||
raise ValueError('Unknown candidate')
|
||||
data = _read(root/'model.safetensors', 1024**2)
|
||||
import hashlib
|
||||
if hashlib.sha256(data).hexdigest() != report.get('model_sha256'):
|
||||
raise ValueError('Model hash mismatch')
|
||||
self.state = load(data)
|
||||
width = WIDTHS[self.candidate['family']]
|
||||
expected = {'feature_mean': (width,), 'feature_scale': (width,),
|
||||
'projection': (width, 128), 'phase': (128,), 'output_mean': (128,),
|
||||
'weights': (128, 7), 'bias': (7,)}
|
||||
if (set(self.state) != set(expected) or any(self.state[k].shape != shape or
|
||||
self.state[k].dtype != np.float64 or not np.isfinite(self.state[k]).all()
|
||||
for k, shape in expected.items()) or not (self.state['feature_scale'] > 0).all()):
|
||||
raise ValueError('Invalid motion model state')
|
||||
|
||||
def predict(self, values):
|
||||
return predict_features(self.state, motion_features(values, self.candidate['family']))
|
||||
|
||||
|
||||
def _validate(parts):
|
||||
if set(parts) != {'train', 'validation'}:
|
||||
raise ValueError('Requires development-only partitions')
|
||||
for name, part in parts.items():
|
||||
ids, y = np.asarray(part['identity']), np.asarray(part['y'])
|
||||
if (y.dtype.kind not in 'iu' or y.ndim != 1 or len(y) != len(part['x'])
|
||||
or not len(y) or set(y) != set(range(7)) or ids.dtype.kind not in 'iu'
|
||||
or ids.shape != (len(y), 4) or len(np.unique(ids, axis=0)) != len(y)
|
||||
or not np.array_equal(ids[:, 2]-1, y) or not np.all((ids[:, 3] >= 1) & (ids[:, 3] <= 10))):
|
||||
raise ValueError('Invalid recording identities or labels')
|
||||
if name == 'validation' and (not np.all(ids[:, 0] == 3) or not np.all(ids[:, 1] == 7)):
|
||||
raise ValueError('Invalid development identities')
|
||||
return folds(parts['train']['identity'], parts['train']['y'])
|
||||
|
||||
|
||||
def search(parts, provenance, baseline_directory, baseline_receipt, output, max_seconds=600):
|
||||
if not 1 <= max_seconds <= 3600:
|
||||
raise ValueError('Invalid time budget')
|
||||
fold_ids = _validate(parts)
|
||||
baseline = BufferedKernelBundle(baseline_directory)
|
||||
prior = json.loads(_read(baseline_receipt, 16*1024**2))
|
||||
if (not isinstance(prior, dict) or prior.get('provenance', {}).get('manifest_sha256') != provenance.get('manifest_sha256')
|
||||
or not provenance.get('manifest_sha256') or prior.get('model_sha256') != digest(Path(baseline_directory)/'model.safetensors')):
|
||||
raise ValueError('Baseline data or model provenance mismatch')
|
||||
root = Path(output)
|
||||
root.mkdir(exist_ok=False, parents=True)
|
||||
write_json(root/'status.json', {'status': 'running', 'promotionAuthorized': False})
|
||||
write_json(root/'search_contract.json', CONTRACT)
|
||||
start = time.monotonic()
|
||||
try:
|
||||
train, dev = parts['train'], parts['validation']
|
||||
cache = {family: motion_features(train['x'], family) for family in WIDTHS}
|
||||
results, selected, rank = [], None, None
|
||||
for candidate in GRID:
|
||||
evaluations = []
|
||||
for fit_ids, eval_ids in fold_ids:
|
||||
if time.monotonic()-start > max_seconds:
|
||||
raise TimeoutError('Motion ablation budget exceeded')
|
||||
state = fit(cache[candidate['family']][fit_ids], train['y'][fit_ids], candidate)
|
||||
result = predict_features(state, cache[candidate['family']][eval_ids])
|
||||
evaluations.append(scores(train['y'][eval_ids], result.argmax(1), 7))
|
||||
row = {'candidate': candidate, 'folds': evaluations,
|
||||
'mean_cv_macro_f1': float(np.mean([v['macro_f1'] for v in evaluations])),
|
||||
'scalar_count': sum(v.size for v in state.values())}
|
||||
results.append(row)
|
||||
value = (row['mean_cv_macro_f1'], -row['scalar_count'])
|
||||
if rank is None or value > rank:
|
||||
selected, rank = row, value
|
||||
write_json(root/'selection.json', {'selected': selected, 'candidates': results, 'contract': CONTRACT})
|
||||
chosen = selected['candidate']
|
||||
state = fit(cache[chosen['family']], train['y'], chosen)
|
||||
save_file(state, str(root/'model.safetensors'))
|
||||
actual = predict_features(state, motion_features(dev['x'], chosen['family']))
|
||||
measured = scores(dev['y'], actual.argmax(1), 7)
|
||||
incumbent = scores(dev['y'], baseline.predict(dev['x']).argmax(1), 7)
|
||||
replay = load(_read(root/'model.safetensors', 1024**2))
|
||||
if not np.array_equal(actual, predict_features(replay, motion_features(dev['x'], chosen['family']))):
|
||||
raise ValueError('Reload changes logits')
|
||||
timings = {'candidate': [], 'incumbent': []}
|
||||
def predict(x):
|
||||
return predict_features(state, motion_features(x, chosen['family']))
|
||||
for i in range(20):
|
||||
sample = dev['x'][i % len(dev['x']):i % len(dev['x'])+1]
|
||||
predict(sample); baseline.predict(sample)
|
||||
for i in range(1000):
|
||||
sample = dev['x'][i % len(dev['x']):i % len(dev['x'])+1]
|
||||
calls = [('candidate', predict), ('incumbent', baseline.predict)]
|
||||
if i % 2:
|
||||
calls.reverse()
|
||||
for name, fn in calls:
|
||||
before = time.perf_counter_ns(); fn(sample)
|
||||
timings[name].append((time.perf_counter_ns()-before)/1e6)
|
||||
timing = {k: {'p50_ms': float(np.percentile(v, 50)), 'p95_ms': float(np.percentile(v, 95))} for k, v in timings.items()}
|
||||
checks = {'macro_f1_gain': measured['macro_f1'] >= incumbent['macro_f1']+.03,
|
||||
'accuracy_nonregression': measured['accuracy'] >= incumbent['accuracy'],
|
||||
'no_additional_zero_f1_classes': all(b == 0 or a > 0 for a, b in zip(measured['per_class_f1'], incumbent['per_class_f1'])),
|
||||
'p95_under_1ms': timing['candidate']['p95_ms'] < 1.0}
|
||||
report = {'status': 'complete', 'promotionAuthorized': False, 'task': 'public_motion_ablation',
|
||||
'contract': CONTRACT, 'selected': selected, 'candidates': results,
|
||||
'evidence': 'SYNTHETIC' if provenance.get('evidence') == 'SYNTHETIC' else 'MEASURED',
|
||||
'provenance': provenance, 'development': measured, 'incumbent_development': incumbent,
|
||||
'retention_checks': checks, 'retained_as_research_candidate': all(checks.values()),
|
||||
'latency': timing, 'reload_max_abs_logit_error': 0.0,
|
||||
'model_bytes': (root/'model.safetensors').stat().st_size,
|
||||
'model_sha256': digest(root/'model.safetensors'),
|
||||
'baseline_model_sha256': prior['model_sha256'], 'baseline_receipt_sha256': digest(baseline_receipt),
|
||||
'source_sha256': {name: digest(Path(__file__).with_name(name)) for name in
|
||||
('espfi_motion.py', 'espfi_generalize.py', 'espfi_kernel.py', 'espfi_runtime.py')},
|
||||
'elapsed_seconds': time.monotonic()-start,
|
||||
'scope': '24 configurations selected only on two training folds; development seen once after selection; '
|
||||
'1000 alternating paired batch1 calls include features/checks/classifier, exclude pooling and IO. '
|
||||
'Candidate is float64 with explicit map, incumbent uses seeded float32 folded runtime; '
|
||||
'storage comparison includes different encodings. No test, hardware, pose or SOTA claim.'}
|
||||
write_json(root/'metrics.json', report)
|
||||
write_json(root/'status.json', {'status': 'complete', 'promotionAuthorized': False})
|
||||
return report
|
||||
except Exception:
|
||||
write_json(root/'status.json', {'status': 'failed', 'promotionAuthorized': False})
|
||||
raise
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
for arg in ('manifest', 'baseline', 'baseline-receipt', 'output'):
|
||||
parser.add_argument('--'+arg, required=True)
|
||||
parser.add_argument('--max-seconds', type=int, default=600)
|
||||
args = parser.parse_args()
|
||||
from .espfi import load_development
|
||||
parts, provenance = load_development(args.manifest)
|
||||
report = search(parts, provenance, args.baseline, args.baseline_receipt, args.output, args.max_seconds)
|
||||
print(json.dumps({k: report[k] for k in ('selected', 'development', 'incumbent_development',
|
||||
'retention_checks', 'retained_as_research_candidate', 'latency', 'model_bytes')}, indent=2))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,95 @@
|
||||
"""Synthetic motion-ablation integrity; no sensing accuracy evidence."""
|
||||
import copy
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
import numpy as np
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
|
||||
from csi_training.espfi_motion import CONTRACT, GRID, WIDTHS, MotionBundle, motion_features, search
|
||||
from csi_training.espfi_generalize import features
|
||||
from csi_training.espfi_kernel import fit
|
||||
from csi_training.espfi_seeded import SPEC, export_seeded
|
||||
from csi_training.espfi_train import write_json
|
||||
from test_espfi_generalize import fixture
|
||||
|
||||
|
||||
class MotionTests(unittest.TestCase):
|
||||
def test_frozen_dimensions_gain_and_carrier_invariance(self):
|
||||
rng = np.random.default_rng(10)
|
||||
x = np.exp(rng.normal(size=(3, 52, 190)))
|
||||
gain = np.exp(rng.normal(size=(3, 52, 1)))
|
||||
self.assertEqual(len(GRID), 24)
|
||||
for family, width in WIDTHS.items():
|
||||
actual = motion_features(x, family)
|
||||
self.assertEqual(actual.shape, (3, width))
|
||||
np.testing.assert_allclose(actual, motion_features(x*gain, family), atol=1e-11, rtol=1e-11)
|
||||
for value in (0., 1., 1e-20, 1e100):
|
||||
self.assertTrue(np.isfinite(motion_features(np.full_like(x, value), family)).all())
|
||||
with self.assertRaises(ValueError):
|
||||
motion_features(-x, family)
|
||||
np.testing.assert_allclose(motion_features(x[:, ::-1], 'motion_invariant'),
|
||||
motion_features(x, 'motion_invariant'), atol=1e-12, rtol=1e-12)
|
||||
|
||||
def test_acf_definition_and_temporal_reversal(self):
|
||||
x = np.exp(np.random.default_rng(12).normal(size=(2, 52, 190)))
|
||||
values = motion_features(x, 'motion_acf').reshape(2, 52, 9)
|
||||
logged = np.log(x); centered = logged-logged.mean(-1, keepdims=True)
|
||||
for i, lag in enumerate(CONTRACT['acf_lags']):
|
||||
expected = (centered[..., lag:]*centered[..., :-lag]).sum(-1)/(centered**2).sum(-1)
|
||||
np.testing.assert_allclose(values[..., i], expected, atol=1e-12, rtol=1e-12)
|
||||
self.assertTrue(np.all(np.abs(values[..., :6]) <= 1+1e-12))
|
||||
np.testing.assert_allclose(values.reshape(2, -1), motion_features(x[..., ::-1], 'motion_acf'), atol=1e-12)
|
||||
|
||||
def test_stft_explicit_windows_and_tail(self):
|
||||
x = np.ones((1, 52, 190)); x[..., -1] = 20
|
||||
actual = motion_features(x, 'local_spectral')
|
||||
logged = np.log(x); relative = logged-logged.mean(-1, keepdims=True)
|
||||
relative /= np.sqrt(np.mean(relative**2))
|
||||
windows = np.stack([relative[..., i:i+32] for i in CONTRACT['stft']['starts']], axis=-2)*np.hanning(32)
|
||||
power = np.abs(np.fft.rfft(windows, axis=-1))**2/32**2
|
||||
bands = np.stack((power[..., 1:5].sum(-1), power[..., 5:17].sum(-1)), axis=-1)
|
||||
local = np.stack([b.mean(-2) for b in np.array_split(bands, 4, axis=-2)], axis=-2)
|
||||
expected = np.concatenate((local.reshape(1, -1), np.sqrt(np.mean(relative**2, axis=-1))), axis=1)
|
||||
np.testing.assert_array_equal(actual, expected)
|
||||
self.assertEqual(CONTRACT['stft']['starts'][-1]+32, 190)
|
||||
|
||||
def test_selection_provenance_reload_and_lifecycle(self):
|
||||
parts, provenance = fixture()
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
state = fit(features(parts['train']['x'], SPEC['family']), parts['train']['y'], dict(SPEC, kind='rff'))
|
||||
original = export_seeded(state, root/'baseline', precision='float32')
|
||||
receipt = root/'receipt.json'
|
||||
write_json(receipt, {'model_sha256': original['model_sha256'], 'provenance': provenance})
|
||||
a = search(parts, provenance, root/'baseline', receipt, root/'a')
|
||||
changed = copy.deepcopy(parts)
|
||||
changed['validation']['x'] *= 1.5
|
||||
changed['validation']['y'] = (changed['validation']['y']+1) % 7
|
||||
changed['validation']['identity'][:, 2] = changed['validation']['y']+1
|
||||
b = search(changed, provenance, root/'baseline', receipt, root/'b')
|
||||
self.assertEqual(a['selected'], b['selected'])
|
||||
self.assertEqual(a['model_sha256'], b['model_sha256'])
|
||||
self.assertFalse(a['promotionAuthorized'])
|
||||
self.assertEqual(a['reload_max_abs_logit_error'], 0)
|
||||
self.assertNotIn('test', a)
|
||||
loaded = MotionBundle(root/'a')
|
||||
self.assertEqual(loaded.predict(parts['validation']['x']).shape, (7, 7))
|
||||
with (root/'a/model.safetensors').open('ab') as handle:
|
||||
handle.write(b'bad')
|
||||
with self.assertRaisesRegex(ValueError, 'hash mismatch'):
|
||||
MotionBundle(root/'a')
|
||||
write_json(root/'b/status.json', {'status': 'running', 'promotionAuthorized': False})
|
||||
with self.assertRaisesRegex(ValueError, 'completed'):
|
||||
MotionBundle(root/'b')
|
||||
wrong = dict(provenance, manifest_sha256='wrong')
|
||||
with self.assertRaisesRegex(ValueError, 'provenance'):
|
||||
search(parts, wrong, root/'baseline', receipt, root/'bad')
|
||||
parts['test'] = parts['validation']
|
||||
with self.assertRaisesRegex(ValueError, 'development-only'):
|
||||
search(parts, provenance, root/'baseline', receipt, root/'test')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user