src.tests.transf_octorf_test
Classes
- class src.tests.transf_octorf_test.TransfOctoRFTest
- Author:
Alberto M. Esmoris Pena
Test that the TransfOctoRF three-stage pipeline (RF + NN) learns linearly separable classification problems. The test generates synthetic data where each class occupies a well-separated region in feature space, trains the full pipeline (C++ Random Forest followed by Transformer or SharedMLP neural network), and verifies that the final predictions achieve near-perfect accuracy and F1.
Twenty-eight configurations are tested:
Config
Classes
NN variant
Feature setup
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z AA AC
2 4 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
SharedMLP SharedMLP Transformer Transformer Transformer Transformer Transformer Transformer Transformer Transformer SharedMLP Transformer GVA GVA (alias) Transformer SharedMLP Transformer Transformer Transformer Transformer GVA Transformer Transformer Transformer GVA GVA GVA GVA
raw synthetic, depth=1 raw synthetic, depth=1 raw synthetic, depth=1 raw synthetic, depth=1 mined geom, same for both mined geom, NN subset mined geom + RF proba/amb proba + ambiguity, depth=3 proba + amb + mined, d=3 class_names + serializ. LR scheduler (dict) store_features validation raw synthetic, depth=1 operator name alias point-wise labels point-wise labels class weights (standard) class weights + point-wise full augmentation combo depth=2 + per-depth n_h depth=2 + per-depth n_h point-wise + predictive FPS point-wise + predictive MD CW focal loss + point-wise gva_mix=’mlp’ (interv. A) output_mix=’mlp’ (interv.B) both mixers enabled both mixers, depth=2
RF and NN receive different data splits to verify that both stages learn independently on their respective inputs.
Pass criteria (per configuration):
Training loss \(< 0.05\)
Overall accuracy (OA) \(> 0.95\)
Macro F1 \(> 0.95\)
Per-class F1 \(> 0.95\) for every class
- Variables:
loss_thr (float) – Maximum acceptable training loss.
metric_thr (float) – Minimum acceptable OA and F1.
- __init__()
Initialize the TransfOctoRF separable-problem test.
- run()
Run all nine configurations.
- Returns:
True if every configuration passes, False otherwise.
- Return type:
bool
- check_config(name, n_classes, operator, n_rf=300, n_nn=200, n_f=6, K=8, separation=8.0, seed=42, nn_fnames=None, hidden_depth=1, gradient_centralization=False, learning_rate=0.005, nn_point_wise_labels=False, class_weight=None, augmentation_config=None, n_h=32, predictive_input_strategy=None, loss_function=None, focusing_parameter=2, gva_mix_strategy='add', output_mix_strategy='none')
Run one test configuration with raw synthetic features.
- Parameters:
name (str) – Configuration label.
n_classes (int) – Number of classes.
operator (str) – Operator type (‘transformer’, ‘sharedmlp’, ‘gva’).
n_rf (int) – Samples per class for the RF dataset.
n_nn (int) – Samples per class for the NN dataset.
n_f (int) – Number of features.
K (int) – Number of KNN neighbors.
separation (float) – Distance between class centers.
seed (int) – Random seed.
nn_fnames (list or None) – NN feature names (None = all).
hidden_depth (int) – Number of stacked NN blocks.
- Returns:
True if all thresholds are met.
- Return type:
bool
- check_mined_config(name, n_classes, operator, nn_fnames=None, n_pts_rf=3000, n_pts_nn=2500, K=8, separation=8.0, seed=42, hidden_depth=1, gradient_centralization=True)
Run one test configuration with C++ mined features.
Generates raw 3D point clouds (coordinates + labels) and passes them directly to the model. The model builds octree centroids and mines features internally via
mining_config.- Parameters:
name (str) – Configuration label.
n_classes (int) – Number of classes.
operator (str) – Operator type (‘transformer’, ‘sharedmlp’, ‘gva’).
nn_fnames (list or None) – NN feature names (None = all).
n_pts_rf (int) – Points per class for the RF cloud.
n_pts_nn (int) – Points per class for the NN cloud.
K (int) – Number of KNN neighbors.
separation (float) – Distance between class centers.
seed (int) – Random seed.
- Returns:
True if all thresholds are met.
- Return type:
bool
- train_and_evaluate(name, X_rf, y_rf, X_nn, y_nn, fnames, nn_fnames, operator, K, epochs=50, n_h=32, hidden_depth=1, gradient_centralization=False, learning_rate=0.005, nn_point_wise_labels=False, class_weight=None, augmentation_config=None, predictive_input_strategy=None, loss_function=None, focusing_parameter=2, gva_mix_strategy='add', output_mix_strategy='none')
Build model, train RF + NN, predict, and validate.
- Parameters:
name (str) – Configuration label.
X_rf (
np.ndarray) – RF training features (S_rf, n_f).y_rf (
np.ndarray) – RF training labels (S_rf,).X_nn (
np.ndarray) – NN training features (S_nn, n_f).y_nn (
np.ndarray) – NN training labels (S_nn,).fnames (list) – All feature names.
nn_fnames (list or None) – NN feature names (None = all).
operator (str) – Operator type (‘transformer’, ‘sharedmlp’, ‘gva’).
K (int) – Number of KNN neighbors.
epochs (int) – Training epochs for the NN.
n_h (int) – Hidden dimensionality for the NN.
hidden_depth (int) – Number of stacked NN blocks.
- Returns:
True if all thresholds are met.
- Return type:
bool
- check_class_names_and_serialization(name, n_classes, operator, n_rf=300, n_nn=200, n_f=6, K=8, separation=8.0, seed=42)
Test that
class_namessetsnum_classes_and that the model survives a pickle round-trip (getstate/setstate).- Parameters:
name – Configuration label.
- Returns:
True if all checks pass.
- Return type:
bool
- check_store_features(name, n_classes, operator, n_rf=300, n_nn=200, n_f=6, K=8, separation=8.0, seed=42)
Test that
store_featuresandstore_raw_featuresproduce features with the expected statistical properties.store_raw_features=True: features have natural scale.store_raw_features=False: features are standardized (mean ≈ 0, std ≈ 1).
- Parameters:
name – Configuration label.
- Returns:
True if all checks pass.
- Return type:
bool
- static make_separable_features(n_per_class, n_classes, n_f, separation, seed)
Generate a linearly separable feature matrix.
Each class has its centroid offset by
c * separationalong feature axis 0. Small Gaussian noise is added to all features. The first 3 features also serve as spatial coordinates (x, y, z).- Parameters:
n_per_class (int) – Samples per class.
n_classes (int) – Number of classes.
n_f (int) – Number of features.
separation (float) – Distance between class centers.
seed (int) – Random seed for reproducibility.
- Returns:
(X, y) feature matrix and labels.
- Return type:
tuple[np.ndarray, np.ndarray]
- static make_separable_pcloud(n_per_class, n_classes, separation, seed)
Generate a 3D point cloud whose classes have distinct local geometry so geometric descriptors (linearity, planarity, sphericity, …) can separate them.
Class 0: planar — thin disc in the xy-plane.
Class 1: linear — elongated along the x-axis.
Class 2: spherical — isotropic Gaussian blob.
Class 3: mixed — moderate spread in all axes with asymmetric scaling.
Each class is offset by
c * separationalong x so that height features also contribute to separability.- Parameters:
n_per_class (int) – Points per class.
n_classes (int) – Number of classes.
separation (float) – Distance between class centers.
seed (int) – Random seed.
- Returns:
(X_coords, y_labels) with shapes (N, 3), (N,).
- Return type:
tuple[np.ndarray, np.ndarray]