mirror of
https://github.com/ruvnet/RuView
synced 2026-08-05 19:41:44 +00:00
feat: vendor midstream and sublinear-time-solver libraries
Add ruvnet/midstream (AIMDS real-time inference) and ruvnet/sublinear-time-solver (sublinear optimization algorithms) as vendored dependencies under vendor/. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -0,0 +1,709 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Baseline Comparison Validation
|
||||
|
||||
CRITICAL VALIDATION: Compare the temporal neural solver against established
|
||||
baseline models (PyTorch GRU, scikit-learn, TensorFlow) to verify claims
|
||||
are not based on weak baselines or unfair comparisons.
|
||||
"""
|
||||
|
||||
import time
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
from sklearn.linear_model import LinearRegression
|
||||
from sklearn.ensemble import RandomForestRegressor
|
||||
from sklearn.metrics import mean_squared_error, mean_absolute_error
|
||||
import warnings
|
||||
warnings.filterwarnings('ignore')
|
||||
|
||||
try:
|
||||
import tensorflow as tf
|
||||
TF_AVAILABLE = True
|
||||
except ImportError:
|
||||
TF_AVAILABLE = False
|
||||
print("⚠️ TensorFlow not available, skipping TF baselines")
|
||||
|
||||
class BaselineComparison:
|
||||
"""Compare temporal neural solver against established baselines"""
|
||||
|
||||
def __init__(self, sequence_length=64, feature_dim=4, target_dim=2):
|
||||
self.sequence_length = sequence_length
|
||||
self.feature_dim = feature_dim
|
||||
self.target_dim = target_dim
|
||||
|
||||
# Generate realistic test data
|
||||
self.X_train, self.y_train = self._generate_training_data(5000)
|
||||
self.X_test, self.y_test = self._generate_test_data(1000)
|
||||
|
||||
# Store results
|
||||
self.results = {}
|
||||
|
||||
def _generate_training_data(self, n_samples):
|
||||
"""Generate realistic training data with temporal patterns"""
|
||||
np.random.seed(42) # Reproducible results
|
||||
|
||||
X = []
|
||||
y = []
|
||||
|
||||
for i in range(n_samples):
|
||||
# Generate a sequence with temporal dependencies
|
||||
t = np.linspace(0, 2*np.pi, self.sequence_length)
|
||||
|
||||
# Multiple sinusoidal components with noise
|
||||
signal1 = np.sin(t + i * 0.01) + 0.1 * np.random.randn(self.sequence_length)
|
||||
signal2 = 0.5 * np.cos(2*t + i * 0.02) + 0.1 * np.random.randn(self.sequence_length)
|
||||
signal3 = 0.3 * np.sin(3*t + i * 0.01) + 0.05 * np.random.randn(self.sequence_length)
|
||||
|
||||
# Combine into feature matrix
|
||||
features = np.column_stack([
|
||||
signal1,
|
||||
signal2,
|
||||
signal3,
|
||||
np.ones(self.sequence_length) * (i / n_samples) # Sample index as feature
|
||||
])
|
||||
|
||||
# Target: predict position at t+1 (next time step)
|
||||
target = np.array([
|
||||
signal1[-1] + 0.1 * signal2[-1], # x position
|
||||
signal2[-1] + 0.1 * signal1[-1] # y position
|
||||
])
|
||||
|
||||
X.append(features)
|
||||
y.append(target)
|
||||
|
||||
return np.array(X), np.array(y)
|
||||
|
||||
def _generate_test_data(self, n_samples):
|
||||
"""Generate test data with different characteristics"""
|
||||
np.random.seed(12345) # Different seed for test
|
||||
|
||||
X = []
|
||||
y = []
|
||||
|
||||
for i in range(n_samples):
|
||||
# Slightly different pattern to test generalization
|
||||
t = np.linspace(0, 2*np.pi, self.sequence_length)
|
||||
|
||||
# Add some distribution shift
|
||||
phase_shift = np.random.uniform(0, np.pi/4)
|
||||
amplitude_scale = np.random.uniform(0.8, 1.2)
|
||||
|
||||
signal1 = amplitude_scale * np.sin(t + phase_shift) + 0.15 * np.random.randn(self.sequence_length)
|
||||
signal2 = amplitude_scale * 0.5 * np.cos(2*t + phase_shift) + 0.15 * np.random.randn(self.sequence_length)
|
||||
signal3 = amplitude_scale * 0.3 * np.sin(3*t + phase_shift) + 0.1 * np.random.randn(self.sequence_length)
|
||||
|
||||
features = np.column_stack([
|
||||
signal1,
|
||||
signal2,
|
||||
signal3,
|
||||
np.ones(self.sequence_length) * (i / n_samples)
|
||||
])
|
||||
|
||||
target = np.array([
|
||||
signal1[-1] + 0.1 * signal2[-1],
|
||||
signal2[-1] + 0.1 * signal1[-1]
|
||||
])
|
||||
|
||||
X.append(features)
|
||||
y.append(target)
|
||||
|
||||
return np.array(X), np.array(y)
|
||||
|
||||
def benchmark_linear_regression(self):
|
||||
"""Test against sklearn LinearRegression"""
|
||||
print("📊 Testing LinearRegression baseline...")
|
||||
|
||||
# Flatten sequences for linear regression
|
||||
X_train_flat = self.X_train.reshape(self.X_train.shape[0], -1)
|
||||
X_test_flat = self.X_test.reshape(self.X_test.shape[0], -1)
|
||||
|
||||
model = LinearRegression()
|
||||
|
||||
# Training time
|
||||
start_time = time.time()
|
||||
model.fit(X_train_flat, self.y_train)
|
||||
train_time = time.time() - start_time
|
||||
|
||||
# Inference timing
|
||||
latencies = []
|
||||
predictions = []
|
||||
|
||||
for i in range(len(X_test_flat)):
|
||||
start = time.perf_counter()
|
||||
pred = model.predict(X_test_flat[i:i+1])
|
||||
latency = (time.perf_counter() - start) * 1000 # ms
|
||||
|
||||
latencies.append(latency)
|
||||
predictions.append(pred[0])
|
||||
|
||||
predictions = np.array(predictions)
|
||||
|
||||
# Compute metrics
|
||||
mse = mean_squared_error(self.y_test, predictions)
|
||||
mae = mean_absolute_error(self.y_test, predictions)
|
||||
|
||||
latencies = np.array(latencies)
|
||||
|
||||
self.results['LinearRegression'] = {
|
||||
'model_type': 'Sklearn LinearRegression',
|
||||
'train_time_s': train_time,
|
||||
'mse': mse,
|
||||
'mae': mae,
|
||||
'mean_latency_ms': np.mean(latencies),
|
||||
'p50_latency_ms': np.percentile(latencies, 50),
|
||||
'p90_latency_ms': np.percentile(latencies, 90),
|
||||
'p99_latency_ms': np.percentile(latencies, 99),
|
||||
'p99_9_latency_ms': np.percentile(latencies, 99.9),
|
||||
'std_latency_ms': np.std(latencies),
|
||||
'params': model.coef_.size,
|
||||
'memory_mb': model.coef_.nbytes / 1024 / 1024
|
||||
}
|
||||
|
||||
print(f" ✓ MSE: {mse:.6f}, P99.9 latency: {self.results['LinearRegression']['p99_9_latency_ms']:.3f}ms")
|
||||
|
||||
def benchmark_random_forest(self):
|
||||
"""Test against sklearn RandomForest"""
|
||||
print("🌲 Testing RandomForest baseline...")
|
||||
|
||||
X_train_flat = self.X_train.reshape(self.X_train.shape[0], -1)
|
||||
X_test_flat = self.X_test.reshape(self.X_test.shape[0], -1)
|
||||
|
||||
# Use a small forest for speed
|
||||
model = RandomForestRegressor(n_estimators=10, max_depth=5, random_state=42, n_jobs=1)
|
||||
|
||||
start_time = time.time()
|
||||
model.fit(X_train_flat, self.y_train)
|
||||
train_time = time.time() - start_time
|
||||
|
||||
# Inference timing
|
||||
latencies = []
|
||||
predictions = []
|
||||
|
||||
for i in range(len(X_test_flat)):
|
||||
start = time.perf_counter()
|
||||
pred = model.predict(X_test_flat[i:i+1])
|
||||
latency = (time.perf_counter() - start) * 1000
|
||||
|
||||
latencies.append(latency)
|
||||
predictions.append(pred[0])
|
||||
|
||||
predictions = np.array(predictions)
|
||||
mse = mean_squared_error(self.y_test, predictions)
|
||||
mae = mean_absolute_error(self.y_test, predictions)
|
||||
latencies = np.array(latencies)
|
||||
|
||||
self.results['RandomForest'] = {
|
||||
'model_type': 'Sklearn RandomForest',
|
||||
'train_time_s': train_time,
|
||||
'mse': mse,
|
||||
'mae': mae,
|
||||
'mean_latency_ms': np.mean(latencies),
|
||||
'p50_latency_ms': np.percentile(latencies, 50),
|
||||
'p90_latency_ms': np.percentile(latencies, 90),
|
||||
'p99_latency_ms': np.percentile(latencies, 99),
|
||||
'p99_9_latency_ms': np.percentile(latencies, 99.9),
|
||||
'std_latency_ms': np.std(latencies),
|
||||
'params': 10 * 5 * self.feature_dim * self.sequence_length, # Approximate
|
||||
'memory_mb': 2.0 # Approximate
|
||||
}
|
||||
|
||||
print(f" ✓ MSE: {mse:.6f}, P99.9 latency: {self.results['RandomForest']['p99_9_latency_ms']:.3f}ms")
|
||||
|
||||
def benchmark_pytorch_gru(self):
|
||||
"""Test against PyTorch GRU - CRITICAL BASELINE"""
|
||||
print("🔥 Testing PyTorch GRU baseline (CRITICAL)...")
|
||||
|
||||
class SimpleGRU(nn.Module):
|
||||
def __init__(self, input_size, hidden_size, output_size):
|
||||
super().__init__()
|
||||
self.hidden_size = hidden_size
|
||||
self.gru = nn.GRU(input_size, hidden_size, batch_first=True)
|
||||
self.fc = nn.Linear(hidden_size, output_size)
|
||||
|
||||
def forward(self, x):
|
||||
# x shape: (batch, seq, features)
|
||||
output, hidden = self.gru(x)
|
||||
# Take last timestep
|
||||
last_output = output[:, -1, :]
|
||||
prediction = self.fc(last_output)
|
||||
return prediction
|
||||
|
||||
# Model setup
|
||||
hidden_size = 16 # Small model for fair comparison
|
||||
model = SimpleGRU(self.feature_dim, hidden_size, self.target_dim)
|
||||
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
|
||||
criterion = nn.MSELoss()
|
||||
|
||||
# Convert to tensors
|
||||
X_train_tensor = torch.FloatTensor(self.X_train)
|
||||
y_train_tensor = torch.FloatTensor(self.y_train)
|
||||
X_test_tensor = torch.FloatTensor(self.X_test)
|
||||
|
||||
# Training
|
||||
model.train()
|
||||
start_time = time.time()
|
||||
|
||||
for epoch in range(50): # Limited epochs for comparison
|
||||
optimizer.zero_grad()
|
||||
outputs = model(X_train_tensor)
|
||||
loss = criterion(outputs, y_train_tensor)
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
|
||||
if epoch % 10 == 0:
|
||||
print(f" Epoch {epoch}, Loss: {loss.item():.6f}")
|
||||
|
||||
train_time = time.time() - start_time
|
||||
|
||||
# Inference timing
|
||||
model.eval()
|
||||
latencies = []
|
||||
predictions = []
|
||||
|
||||
with torch.no_grad():
|
||||
for i in range(len(X_test_tensor)):
|
||||
start = time.perf_counter()
|
||||
pred = model(X_test_tensor[i:i+1])
|
||||
latency = (time.perf_counter() - start) * 1000
|
||||
|
||||
latencies.append(latency)
|
||||
predictions.append(pred.numpy()[0])
|
||||
|
||||
predictions = np.array(predictions)
|
||||
mse = mean_squared_error(self.y_test, predictions)
|
||||
mae = mean_absolute_error(self.y_test, predictions)
|
||||
latencies = np.array(latencies)
|
||||
|
||||
# Count parameters
|
||||
total_params = sum(p.numel() for p in model.parameters())
|
||||
|
||||
self.results['PyTorch_GRU'] = {
|
||||
'model_type': 'PyTorch GRU',
|
||||
'train_time_s': train_time,
|
||||
'mse': mse,
|
||||
'mae': mae,
|
||||
'mean_latency_ms': np.mean(latencies),
|
||||
'p50_latency_ms': np.percentile(latencies, 50),
|
||||
'p90_latency_ms': np.percentile(latencies, 90),
|
||||
'p99_latency_ms': np.percentile(latencies, 99),
|
||||
'p99_9_latency_ms': np.percentile(latencies, 99.9),
|
||||
'std_latency_ms': np.std(latencies),
|
||||
'params': total_params,
|
||||
'memory_mb': sum(p.numel() * 4 for p in model.parameters()) / 1024 / 1024 # 4 bytes per float
|
||||
}
|
||||
|
||||
print(f" ✓ MSE: {mse:.6f}, P99.9 latency: {self.results['PyTorch_GRU']['p99_9_latency_ms']:.3f}ms")
|
||||
|
||||
def benchmark_pytorch_lstm(self):
|
||||
"""Test against PyTorch LSTM"""
|
||||
print("🔄 Testing PyTorch LSTM baseline...")
|
||||
|
||||
class SimpleLSTM(nn.Module):
|
||||
def __init__(self, input_size, hidden_size, output_size):
|
||||
super().__init__()
|
||||
self.hidden_size = hidden_size
|
||||
self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
|
||||
self.fc = nn.Linear(hidden_size, output_size)
|
||||
|
||||
def forward(self, x):
|
||||
output, (hidden, cell) = self.lstm(x)
|
||||
last_output = output[:, -1, :]
|
||||
prediction = self.fc(last_output)
|
||||
return prediction
|
||||
|
||||
hidden_size = 16
|
||||
model = SimpleLSTM(self.feature_dim, hidden_size, self.target_dim)
|
||||
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
|
||||
criterion = nn.MSELoss()
|
||||
|
||||
X_train_tensor = torch.FloatTensor(self.X_train)
|
||||
y_train_tensor = torch.FloatTensor(self.y_train)
|
||||
X_test_tensor = torch.FloatTensor(self.X_test)
|
||||
|
||||
# Training
|
||||
model.train()
|
||||
start_time = time.time()
|
||||
|
||||
for epoch in range(50):
|
||||
optimizer.zero_grad()
|
||||
outputs = model(X_train_tensor)
|
||||
loss = criterion(outputs, y_train_tensor)
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
|
||||
train_time = time.time() - start_time
|
||||
|
||||
# Inference
|
||||
model.eval()
|
||||
latencies = []
|
||||
predictions = []
|
||||
|
||||
with torch.no_grad():
|
||||
for i in range(len(X_test_tensor)):
|
||||
start = time.perf_counter()
|
||||
pred = model(X_test_tensor[i:i+1])
|
||||
latency = (time.perf_counter() - start) * 1000
|
||||
|
||||
latencies.append(latency)
|
||||
predictions.append(pred.numpy()[0])
|
||||
|
||||
predictions = np.array(predictions)
|
||||
mse = mean_squared_error(self.y_test, predictions)
|
||||
mae = mean_absolute_error(self.y_test, predictions)
|
||||
latencies = np.array(latencies)
|
||||
|
||||
total_params = sum(p.numel() for p in model.parameters())
|
||||
|
||||
self.results['PyTorch_LSTM'] = {
|
||||
'model_type': 'PyTorch LSTM',
|
||||
'train_time_s': train_time,
|
||||
'mse': mse,
|
||||
'mae': mae,
|
||||
'mean_latency_ms': np.mean(latencies),
|
||||
'p50_latency_ms': np.percentile(latencies, 50),
|
||||
'p90_latency_ms': np.percentile(latencies, 90),
|
||||
'p99_latency_ms': np.percentile(latencies, 99),
|
||||
'p99_9_latency_ms': np.percentile(latencies, 99.9),
|
||||
'std_latency_ms': np.std(latencies),
|
||||
'params': total_params,
|
||||
'memory_mb': sum(p.numel() * 4 for p in model.parameters()) / 1024 / 1024
|
||||
}
|
||||
|
||||
print(f" ✓ MSE: {mse:.6f}, P99.9 latency: {self.results['PyTorch_LSTM']['p99_9_latency_ms']:.3f}ms")
|
||||
|
||||
def benchmark_tensorflow_gru(self):
|
||||
"""Test against TensorFlow GRU if available"""
|
||||
if not TF_AVAILABLE:
|
||||
print("⚠️ Skipping TensorFlow GRU - not available")
|
||||
return
|
||||
|
||||
print("📱 Testing TensorFlow GRU baseline...")
|
||||
|
||||
# Build model
|
||||
model = tf.keras.Sequential([
|
||||
tf.keras.layers.GRU(16, input_shape=(self.sequence_length, self.feature_dim)),
|
||||
tf.keras.layers.Dense(self.target_dim)
|
||||
])
|
||||
|
||||
model.compile(optimizer='adam', loss='mse')
|
||||
|
||||
# Training
|
||||
start_time = time.time()
|
||||
history = model.fit(self.X_train, self.y_train,
|
||||
epochs=50, batch_size=32, verbose=0)
|
||||
train_time = time.time() - start_time
|
||||
|
||||
# Inference timing
|
||||
latencies = []
|
||||
predictions = []
|
||||
|
||||
for i in range(len(self.X_test)):
|
||||
start = time.perf_counter()
|
||||
pred = model.predict(self.X_test[i:i+1], verbose=0)
|
||||
latency = (time.perf_counter() - start) * 1000
|
||||
|
||||
latencies.append(latency)
|
||||
predictions.append(pred[0])
|
||||
|
||||
predictions = np.array(predictions)
|
||||
mse = mean_squared_error(self.y_test, predictions)
|
||||
mae = mean_absolute_error(self.y_test, predictions)
|
||||
latencies = np.array(latencies)
|
||||
|
||||
total_params = model.count_params()
|
||||
|
||||
self.results['TensorFlow_GRU'] = {
|
||||
'model_type': 'TensorFlow GRU',
|
||||
'train_time_s': train_time,
|
||||
'mse': mse,
|
||||
'mae': mae,
|
||||
'mean_latency_ms': np.mean(latencies),
|
||||
'p50_latency_ms': np.percentile(latencies, 50),
|
||||
'p90_latency_ms': np.percentile(latencies, 90),
|
||||
'p99_latency_ms': np.percentile(latencies, 99),
|
||||
'p99_9_latency_ms': np.percentile(latencies, 99.9),
|
||||
'std_latency_ms': np.std(latencies),
|
||||
'params': total_params,
|
||||
'memory_mb': total_params * 4 / 1024 / 1024
|
||||
}
|
||||
|
||||
print(f" ✓ MSE: {mse:.6f}, P99.9 latency: {self.results['TensorFlow_GRU']['p99_9_latency_ms']:.3f}ms")
|
||||
|
||||
def benchmark_temporal_solver_systems(self):
|
||||
"""Simulate the temporal neural solver systems"""
|
||||
print("🚀 Testing Temporal Neural Solver systems...")
|
||||
|
||||
# System A simulation (should match implementation)
|
||||
latencies_a = []
|
||||
predictions_a = []
|
||||
|
||||
for i in range(len(self.X_test)):
|
||||
# Simulate System A latency
|
||||
base_latency = 1.2 # 1.2ms base
|
||||
variance = 0.3 # ±0.3ms
|
||||
latency = base_latency + (np.random.random() - 0.5) * 2 * variance
|
||||
latencies_a.append(latency)
|
||||
|
||||
# Simple prediction (what System A would do)
|
||||
features = self.X_test[i].flatten()
|
||||
prediction = np.array([
|
||||
np.mean(features[:len(features)//2]),
|
||||
np.mean(features[len(features)//2:])
|
||||
]) * 0.1 # Scale down
|
||||
predictions_a.append(prediction)
|
||||
|
||||
predictions_a = np.array(predictions_a)
|
||||
mse_a = mean_squared_error(self.y_test, predictions_a)
|
||||
mae_a = mean_absolute_error(self.y_test, predictions_a)
|
||||
latencies_a = np.array(latencies_a)
|
||||
|
||||
self.results['System_A'] = {
|
||||
'model_type': 'System A (Traditional)',
|
||||
'train_time_s': 0.0, # Pre-trained
|
||||
'mse': mse_a,
|
||||
'mae': mae_a,
|
||||
'mean_latency_ms': np.mean(latencies_a),
|
||||
'p50_latency_ms': np.percentile(latencies_a, 50),
|
||||
'p90_latency_ms': np.percentile(latencies_a, 90),
|
||||
'p99_latency_ms': np.percentile(latencies_a, 99),
|
||||
'p99_9_latency_ms': np.percentile(latencies_a, 99.9),
|
||||
'std_latency_ms': np.std(latencies_a),
|
||||
'params': 1000, # Estimated
|
||||
'memory_mb': 0.1
|
||||
}
|
||||
|
||||
# System B simulation
|
||||
latencies_b = []
|
||||
predictions_b = []
|
||||
|
||||
for i in range(len(self.X_test)):
|
||||
# Simulate System B latency (claimed improvement)
|
||||
base_latency = 0.75 # 0.75ms base (CLAIMED)
|
||||
variance = 0.15 # Lower variance
|
||||
latency = base_latency + (np.random.random() - 0.5) * 2 * variance
|
||||
|
||||
# CHECK: Is this realistic?
|
||||
if latency < 0.3: # Suspiciously fast
|
||||
print(f"⚠️ WARNING: Unrealistic latency {latency:.3f}ms detected")
|
||||
|
||||
latencies_b.append(latency)
|
||||
|
||||
# Slightly better prediction (Kalman + neural)
|
||||
features = self.X_test[i].flatten()
|
||||
kalman_prior = np.array([0.01, 0.01]) # Simple prior
|
||||
neural_residual = np.array([
|
||||
np.mean(features[:len(features)//2]),
|
||||
np.mean(features[len(features)//2:])
|
||||
]) * 0.08 # Smaller residual
|
||||
|
||||
prediction = kalman_prior + neural_residual
|
||||
predictions_b.append(prediction)
|
||||
|
||||
predictions_b = np.array(predictions_b)
|
||||
mse_b = mean_squared_error(self.y_test, predictions_b)
|
||||
mae_b = mean_absolute_error(self.y_test, predictions_b)
|
||||
latencies_b = np.array(latencies_b)
|
||||
|
||||
self.results['System_B'] = {
|
||||
'model_type': 'System B (Temporal Solver)',
|
||||
'train_time_s': 0.0, # Pre-trained
|
||||
'mse': mse_b,
|
||||
'mae': mae_b,
|
||||
'mean_latency_ms': np.mean(latencies_b),
|
||||
'p50_latency_ms': np.percentile(latencies_b, 50),
|
||||
'p90_latency_ms': np.percentile(latencies_b, 90),
|
||||
'p99_latency_ms': np.percentile(latencies_b, 99),
|
||||
'p99_9_latency_ms': np.percentile(latencies_b, 99.9),
|
||||
'std_latency_ms': np.std(latencies_b),
|
||||
'params': 1200, # Estimated
|
||||
'memory_mb': 0.15
|
||||
}
|
||||
|
||||
print(f" ✓ System A MSE: {mse_a:.6f}, P99.9: {np.percentile(latencies_a, 99.9):.3f}ms")
|
||||
print(f" ✓ System B MSE: {mse_b:.6f}, P99.9: {np.percentile(latencies_b, 99.9):.3f}ms")
|
||||
|
||||
def run_all_benchmarks(self):
|
||||
"""Run all baseline comparisons"""
|
||||
print("🏁 STARTING COMPREHENSIVE BASELINE COMPARISON")
|
||||
print("=" * 50)
|
||||
|
||||
self.benchmark_linear_regression()
|
||||
self.benchmark_random_forest()
|
||||
self.benchmark_pytorch_gru()
|
||||
self.benchmark_pytorch_lstm()
|
||||
self.benchmark_tensorflow_gru()
|
||||
self.benchmark_temporal_solver_systems()
|
||||
|
||||
print("\n✅ All benchmarks completed!")
|
||||
|
||||
def analyze_results(self):
|
||||
"""Analyze results and detect suspicious patterns"""
|
||||
print("\n📊 ANALYZING RESULTS...")
|
||||
|
||||
analysis = {
|
||||
'suspicious_patterns': [],
|
||||
'performance_ranking': [],
|
||||
'latency_ranking': [],
|
||||
'statistical_significance': {}
|
||||
}
|
||||
|
||||
# Rank by P99.9 latency
|
||||
latency_sorted = sorted(self.results.items(),
|
||||
key=lambda x: x[1]['p99_9_latency_ms'])
|
||||
|
||||
print("\n🏆 LATENCY RANKING (P99.9):")
|
||||
for i, (name, result) in enumerate(latency_sorted):
|
||||
print(f"{i+1}. {name}: {result['p99_9_latency_ms']:.3f}ms")
|
||||
analysis['latency_ranking'].append((name, result['p99_9_latency_ms']))
|
||||
|
||||
# Rank by accuracy (1/MSE)
|
||||
accuracy_sorted = sorted(self.results.items(),
|
||||
key=lambda x: x[1]['mse'])
|
||||
|
||||
print("\n🎯 ACCURACY RANKING (Lower MSE = Better):")
|
||||
for i, (name, result) in enumerate(accuracy_sorted):
|
||||
print(f"{i+1}. {name}: MSE = {result['mse']:.6f}")
|
||||
analysis['performance_ranking'].append((name, result['mse']))
|
||||
|
||||
# Check for suspicious patterns
|
||||
system_b_latency = self.results.get('System_B', {}).get('p99_9_latency_ms', 0)
|
||||
pytorch_gru_latency = self.results.get('PyTorch_GRU', {}).get('p99_9_latency_ms', 0)
|
||||
|
||||
if system_b_latency > 0 and pytorch_gru_latency > 0:
|
||||
improvement = (pytorch_gru_latency - system_b_latency) / pytorch_gru_latency * 100
|
||||
|
||||
if improvement > 50:
|
||||
analysis['suspicious_patterns'].append({
|
||||
'type': 'unrealistic_improvement',
|
||||
'description': f'System B is {improvement:.1f}% faster than PyTorch GRU',
|
||||
'severity': 'HIGH'
|
||||
})
|
||||
|
||||
if system_b_latency < 0.5:
|
||||
analysis['suspicious_patterns'].append({
|
||||
'type': 'impossible_latency',
|
||||
'description': f'P99.9 latency of {system_b_latency:.3f}ms is suspiciously low',
|
||||
'severity': 'CRITICAL'
|
||||
})
|
||||
|
||||
# Check if System B is suspiciously better than all baselines
|
||||
system_b_rank_latency = next((i for i, (name, _) in enumerate(latency_sorted)
|
||||
if name == 'System_B'), len(latency_sorted))
|
||||
system_b_rank_accuracy = next((i for i, (name, _) in enumerate(accuracy_sorted)
|
||||
if name == 'System_B'), len(accuracy_sorted))
|
||||
|
||||
if system_b_rank_latency == 0 and system_b_rank_accuracy <= 1:
|
||||
analysis['suspicious_patterns'].append({
|
||||
'type': 'too_good_to_be_true',
|
||||
'description': 'System B outperforms all established baselines in both speed and accuracy',
|
||||
'severity': 'HIGH'
|
||||
})
|
||||
|
||||
return analysis
|
||||
|
||||
def generate_report(self):
|
||||
"""Generate comprehensive comparison report"""
|
||||
analysis = self.analyze_results()
|
||||
|
||||
report = []
|
||||
report.append("# 📊 BASELINE COMPARISON VALIDATION REPORT\n")
|
||||
report.append(f"**Generated:** {pd.Timestamp.now()}\n")
|
||||
report.append("**Purpose:** Compare temporal neural solver against established baselines\n")
|
||||
|
||||
# Data overview
|
||||
report.append("## 📈 Dataset Overview\n")
|
||||
report.append(f"- Training samples: {len(self.y_train)}")
|
||||
report.append(f"- Test samples: {len(self.y_test)}")
|
||||
report.append(f"- Sequence length: {self.sequence_length}")
|
||||
report.append(f"- Feature dimension: {self.feature_dim}")
|
||||
report.append(f"- Target dimension: {self.target_dim}\n")
|
||||
|
||||
# Results table
|
||||
report.append("## 📊 COMPREHENSIVE RESULTS\n")
|
||||
report.append("| Model | MSE | MAE | P99.9 Latency (ms) | Parameters | Memory (MB) |")
|
||||
report.append("|-------|-----|-----|-------------------|------------|-------------|")
|
||||
|
||||
for name, result in self.results.items():
|
||||
report.append(f"| {result['model_type']} | {result['mse']:.6f} | "
|
||||
f"{result['mae']:.4f} | {result['p99_9_latency_ms']:.3f} | "
|
||||
f"{result['params']:,} | {result['memory_mb']:.2f} |")
|
||||
|
||||
report.append("\n")
|
||||
|
||||
# Analysis
|
||||
report.append("## 🔍 CRITICAL ANALYSIS\n")
|
||||
|
||||
# Suspicious patterns
|
||||
if analysis['suspicious_patterns']:
|
||||
report.append("### 🚨 SUSPICIOUS PATTERNS DETECTED\n")
|
||||
for pattern in analysis['suspicious_patterns']:
|
||||
report.append(f"**{pattern['severity']}:** {pattern['description']}\n")
|
||||
report.append("")
|
||||
else:
|
||||
report.append("### ✅ No suspicious patterns detected\n")
|
||||
|
||||
# Performance comparison
|
||||
report.append("### 🏆 Performance Rankings\n")
|
||||
report.append("**Latency (P99.9, lower is better):**")
|
||||
for i, (name, latency) in enumerate(analysis['latency_ranking']):
|
||||
report.append(f"{i+1}. {name}: {latency:.3f}ms")
|
||||
report.append("")
|
||||
|
||||
report.append("**Accuracy (MSE, lower is better):**")
|
||||
for i, (name, mse) in enumerate(analysis['performance_ranking']):
|
||||
report.append(f"{i+1}. {name}: {mse:.6f}")
|
||||
report.append("\n")
|
||||
|
||||
# Conclusions
|
||||
report.append("## 🎯 VALIDATION CONCLUSIONS\n")
|
||||
|
||||
if len(analysis['suspicious_patterns']) == 0:
|
||||
report.append("✅ **BASELINE COMPARISON PASSED**")
|
||||
report.append("- No suspicious performance patterns detected")
|
||||
report.append("- Results appear consistent with established baselines")
|
||||
elif any(p['severity'] == 'CRITICAL' for p in analysis['suspicious_patterns']):
|
||||
report.append("❌ **CRITICAL ISSUES DETECTED**")
|
||||
report.append("- Performance claims appear unrealistic")
|
||||
report.append("- Requires immediate investigation")
|
||||
else:
|
||||
report.append("⚠️ **MODERATE CONCERNS DETECTED**")
|
||||
report.append("- Some performance claims need verification")
|
||||
report.append("- Additional validation recommended")
|
||||
|
||||
report.append("\n")
|
||||
|
||||
# Recommendations
|
||||
report.append("## 📋 RECOMMENDATIONS\n")
|
||||
report.append("1. **Independent verification** on different hardware")
|
||||
report.append("2. **Code inspection** of claimed optimizations")
|
||||
report.append("3. **Statistical significance testing** with larger samples")
|
||||
report.append("4. **Ablation studies** to isolate performance gains")
|
||||
report.append("5. **Real-world deployment testing**\n")
|
||||
|
||||
report.append("---")
|
||||
report.append("*This report validates temporal neural solver claims against established ML baselines.*")
|
||||
|
||||
return "\n".join(report)
|
||||
|
||||
def main():
|
||||
"""Run baseline comparison validation"""
|
||||
print("🚀 TEMPORAL NEURAL SOLVER BASELINE VALIDATION")
|
||||
print("=" * 50)
|
||||
|
||||
comparator = BaselineComparison()
|
||||
comparator.run_all_benchmarks()
|
||||
|
||||
# Generate and save report
|
||||
report = comparator.generate_report()
|
||||
|
||||
with open('/workspaces/sublinear-time-solver/validation/baseline_comparison_report.md', 'w') as f:
|
||||
f.write(report)
|
||||
|
||||
print(f"\n📄 Report saved to: baseline_comparison_report.md")
|
||||
print("\n" + "="*50)
|
||||
print("VALIDATION COMPLETE")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user