deleted: best_model.pth new file: checkpoints/forward/best_tcn_model.pt new file: checkpoints/forward/training_history.csv new file: evaluation_outputs/forward/evaluation_forward_test_b0_s0.png new file: sanity_check_alignment_forward.png modified: src/__pycache__/config.cpython-310.pyc modified: src/__pycache__/config.cpython-314.pyc modified: src/__pycache__/dataset.cpython-310.pyc modified: src/__pycache__/dataset.cpython-314.pyc modified: src/__pycache__/model.cpython-310.pyc modified: src/__pycache__/model.cpython-314.pyc modified: src/config.py modified: src/dataset.py modified: src/evaluate.py modified: src/model.py new file: src/sanity_check.py modified: src/train.py renamed: src/__init__.py -> src_old/__init__.py new file: src_old/__pycache__/config.cpython-310.pyc new file: src_old/__pycache__/config.cpython-314.pyc new file: src_old/__pycache__/dataset.cpython-310.pyc new file: src_old/__pycache__/dataset.cpython-314.pyc new file: src_old/__pycache__/evaluate.cpython-314.pyc new file: src_old/__pycache__/model.cpython-310.pyc new file: src_old/__pycache__/model.cpython-314.pyc new file: src_old/__pycache__/train.cpython-310.pyc new file: src_old/__pycache__/train.cpython-314.pyc new file: src_old/config.py new file: src_old/dataset.py new file: src_old/evaluate.py new file: src_old/model.py new file: src_old/train.py deleted: test_results.png
74 lines
2.8 KiB
Python
74 lines
2.8 KiB
Python
import torch
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
from config import *
|
|
from dataset import get_dataloaders
|
|
from model import BuildingTCN
|
|
|
|
def evaluate_model():
|
|
_, _, test_loader, scaler_X, scaler_Y = get_dataloaders()
|
|
if test_loader is None:
|
|
raise ValueError("当前数据配置下没有可用的测试集。")
|
|
|
|
model = BuildingTCN(input_size=1, output_size=5, num_channels=CHANNELS,
|
|
kernel_size=KERNEL_SIZE, dropout=DROPOUT).to(DEVICE)
|
|
model.load_state_dict(torch.load('best_model.pth', map_location=DEVICE))
|
|
model.eval()
|
|
|
|
all_preds = []
|
|
all_targets = []
|
|
|
|
with torch.no_grad():
|
|
for inputs, targets, masks in test_loader:
|
|
inputs = inputs.to(DEVICE)
|
|
outputs = model(inputs)
|
|
|
|
all_preds.append(outputs.cpu().numpy())
|
|
all_targets.append(targets.numpy())
|
|
|
|
# Concatenate results
|
|
all_preds = np.concatenate(all_preds, axis=0)
|
|
all_targets = np.concatenate(all_targets, axis=0)
|
|
|
|
# Inverse transform to physical scale for metrics
|
|
all_preds_inv = scaler_Y.inverse_transform(all_preds.reshape(-1, len(OUTPUT_SENSORS))).reshape(all_preds.shape)
|
|
all_targets_inv = scaler_Y.inverse_transform(all_targets.reshape(-1, len(OUTPUT_SENSORS))).reshape(all_targets.shape)
|
|
|
|
print("\n=== Test Metrics (All Windows) ===")
|
|
for i, sens in enumerate(OUTPUT_SENSORS):
|
|
pred_i = all_preds_inv[:, :, i].reshape(-1)
|
|
target_i = all_targets_inv[:, :, i].reshape(-1)
|
|
mae = float(np.mean(np.abs(pred_i - target_i)))
|
|
pred_std = float(np.std(pred_i))
|
|
target_std = float(np.std(target_i))
|
|
amp_ratio = pred_std / (target_std + 1e-12)
|
|
pred_peak = float(np.max(np.abs(pred_i)))
|
|
target_peak = float(np.max(np.abs(target_i)))
|
|
peak_ratio = pred_peak / (target_peak + 1e-12)
|
|
corr = float(np.corrcoef(pred_i, target_i)[0, 1]) if len(pred_i) > 1 else float("nan")
|
|
|
|
print(
|
|
f"{sens}: MAE={mae:.4f}, Corr={corr:.4f}, "
|
|
f"AmpRatio(std_pred/std_true)={amp_ratio:.4f}, "
|
|
f"PeakRatio(max|pred|/max|true|)={peak_ratio:.4f}"
|
|
)
|
|
|
|
# 取一个 batch 的第一条序列进行可视化
|
|
sample_pred = all_preds_inv[0]
|
|
sample_target = all_targets_inv[0]
|
|
|
|
plt.figure(figsize=(15, 10))
|
|
for i, sens in enumerate(OUTPUT_SENSORS):
|
|
plt.subplot(5, 1, i+1)
|
|
plt.plot(sample_target[:, i], label='True', alpha=0.7)
|
|
plt.plot(sample_pred[:, i], label='Pred', alpha=0.7, linestyle='--')
|
|
plt.title(f'Sensor {sens} Z-axis Response (Test: Earthquake)')
|
|
plt.legend()
|
|
|
|
plt.tight_layout()
|
|
plt.savefig('test_results.png')
|
|
print("Evaluation done. Result saved to test_results.png")
|
|
|
|
if __name__ == '__main__':
|
|
evaluate_model()
|