Skip to content

Commit ab0c7c1

Browse files
committed
Pruebas y validaciones de los modelos Legacy
1 parent 7704b6a commit ab0c7c1

3 files changed

Lines changed: 204 additions & 0 deletions

File tree

tests/test_mlp_scaler.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""
2+
===================================================
3+
Test de QA Final: MLP Quantizado y MiniScaler
4+
Evalúa: Cuantificación INT8 Híbrida y Preprocesamiento in-place.
5+
"""
6+
7+
import os
8+
from miniml.ml_runtime import MiniNeuralNetwork, MiniScaler
9+
10+
print("1. [MLP - Sin Escalar] Entrenando red para XOR estándar...")
11+
dataset_unscaled = [
12+
[0.0, 0.0, 0],
13+
[0.0, 1.0, 1],
14+
[1.0, 0.0, 1],
15+
[1.0, 1.0, 0]
16+
]
17+
nn_unscaled = MiniNeuralNetwork(n_inputs=2, n_hidden=4, n_outputs=1, epochs=2000, learning_rate=0.1, seed=42)
18+
nn_unscaled.fit(dataset_unscaled)
19+
20+
print("2. [MLP - Con Escalar] Entrenando red con datos de gran magnitud...")
21+
# Simulamos lecturas de sensores que van de 0 a 100
22+
dataset_raw = [
23+
[0.0, 0.0, 0],
24+
[0.0, 100.0, 1],
25+
[100.0, 0.0, 1],
26+
[100.0, 100.0, 0]
27+
]
28+
29+
# Separar para ajustar el escalador
30+
X_raw = [row[:-1] for row in dataset_raw]
31+
y_raw = [row[-1] for row in dataset_raw]
32+
33+
scaler = MiniScaler(method='minmax', feature_range=(0, 1))
34+
scaler.fit(X_raw)
35+
36+
# Aplicar transformación al dataset de entrenamiento
37+
dataset_scaled = []
38+
for x, y in zip(X_raw, y_raw):
39+
dataset_scaled.append(scaler.transform(x) + [y])
40+
41+
nn_scaled = MiniNeuralNetwork(n_inputs=2, n_hidden=4, n_outputs=1, epochs=2000, learning_rate=0.1, seed=42)
42+
nn_scaled.fit(dataset_scaled)
43+
44+
print("\n3. Evaluando IA en PC (Python):")
45+
# Prueba Unscaled
46+
test_unscaled = [[0.0, 1.0], [1.0, 1.0]]
47+
preds_uns = nn_unscaled.predict(test_unscaled)
48+
print(f" [Sin Escalar] Muestra [0.0, 1.0] -> Predicción: {preds_uns[0][0]:.4f} (Esperado: ~1.0)")
49+
print(f" [Sin Escalar] Muestra [1.0, 1.0] -> Predicción: {preds_uns[1][0]:.4f} (Esperado: ~0.0)")
50+
51+
# Prueba Scaled
52+
test_raw_inputs = [[0.0, 100.0], [100.0, 100.0]]
53+
test_raw_scaled = [scaler.transform(row) for row in test_raw_inputs]
54+
preds_scl = nn_scaled.predict(test_raw_scaled)
55+
print(f" [Con Escalar] Muestra [0.0, 100.0] -> Predicción: {preds_scl[0][0]:.4f} (Esperado: ~1.0)")
56+
print(f" [Con Escalar] Muestra [100.0, 100.0] -> Predicción: {preds_scl[1][0]:.4f} (Esperado: ~0.0)")
57+
58+
print("\n4. Cuantizando Modelos (INT8/Híbrido) y Exportando a C++...")
59+
os.makedirs("exports", exist_ok=True)
60+
# La cuantización requiere haber corrido un fit() o calibrate() previo
61+
nn_unscaled.quantize()
62+
nn_scaled.quantize()
63+
64+
cpp_nn_unscaled = nn_unscaled.to_arduino_code(fn_name="predict_nn_unscaled")
65+
cpp_scaler = scaler.to_arduino_code(fn_name="preprocess_minmax")
66+
cpp_nn_scaled = nn_scaled.to_arduino_code(fn_name="predict_nn_scaled")
67+
68+
header_content = f"""#ifndef MINIML_MLP_TEST_H
69+
#define MINIML_MLP_TEST_H
70+
71+
#include <stdint.h>
72+
#include <math.h>
73+
74+
{cpp_nn_unscaled}
75+
76+
{cpp_scaler}
77+
78+
{cpp_nn_scaled}
79+
80+
#endif
81+
"""
82+
83+
with open("exports/miniml_mlp.h", "w") as f:
84+
f.write(header_content)
85+
print(" [OK] Exportación exitosa. Listo para Wokwi.")

tests/test_rf_legacy.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""
2+
===================================================
3+
Test de QA: Random Forest (MiniML Legacy)
4+
Evalúa: Generación de Árboles en PROGMEM y Votación Mayoritaria.
5+
"""
6+
7+
import os
8+
from miniml.ml_runtime import RandomForestClassifier
9+
10+
print("1. Creando Dataset Tabular IoT...")
11+
# Columnas: [Temperatura, Humedad, Vibración, CLASE]
12+
# Clase 0 = Normal, Clase 1 = Falla de Máquina
13+
dataset = [
14+
[22.0, 45.0, 0.1, 0],
15+
[23.0, 47.0, 0.2, 0],
16+
[21.5, 44.0, 0.1, 0],
17+
[45.0, 80.0, 1.5, 1],
18+
[48.0, 85.0, 1.7, 1],
19+
[50.0, 90.0, 2.0, 1]
20+
]
21+
22+
print("2. Entrenando Random Forest...")
23+
# 3 árboles son suficientes para probar la votación C++
24+
rf = RandomForestClassifier(n_trees=3, max_depth=3, seed=42)
25+
rf.fit(dataset)
26+
27+
print("\n3. Evaluando IA (Python):")
28+
X_test = [
29+
[22.5, 46.0, 0.15], # Perfil Normal (Esperado: 0)
30+
[47.0, 82.0, 1.6] # Perfil de Falla (Esperado: 1)
31+
]
32+
33+
preds = rf.predict(X_test)
34+
for i, (x, p) in enumerate(zip(X_test, preds)):
35+
print(f" Muestra {i+1} -> Predicción: {p}")
36+
37+
print("\n4. Exportando Firmware C++...")
38+
os.makedirs("exports", exist_ok=True)
39+
cpp_code = rf.to_arduino_code(fn_name="predict_rf")
40+
41+
# Envolvemos el código generado en guardas de cabecera estándar
42+
header_content = f"""#ifndef MINIML_RF_H
43+
#define MINIML_RF_H
44+
45+
#include <stdint.h>
46+
47+
{cpp_code}
48+
49+
#endif
50+
"""
51+
52+
with open("exports/miniml_rf.h", "w") as f:
53+
f.write(header_content)
54+
print(" [OK] Exportación exitosa. Listo para Wokwi.")

tests/test_svm_knn.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
===================================================
3+
Test de QA Dual: MiniSVM y K-Nearest Neighbors
4+
Evalúa: Hiperplanos lineales y Búsqueda Espacial in-place en SRAM.
5+
"""
6+
7+
import os
8+
from miniml.ml_runtime import MiniSVM, KNearestNeighbors
9+
10+
print("1. [SVM] Entrenando Support Vector Machine...")
11+
# Dataset Linealmente Separable (Clases: 1 y -1)
12+
dataset_svm = [
13+
[2.0, 2.0, 1],
14+
[3.0, 3.0, 1],
15+
[-2.0, -2.0, -1],
16+
[-3.0, -3.0, -1]
17+
]
18+
svm = MiniSVM(learning_rate=0.01, n_iters=1000)
19+
svm.fit(dataset_svm)
20+
21+
print("2. [KNN] Entrenando K-Nearest Neighbors...")
22+
# Dataset Multiclase Agrupado (Clases: 0, 1, 2)
23+
dataset_knn = [
24+
[0.0, 0.0, 0], [0.1, 0.1, 0], [0.0, 0.1, 0], # Cluster 0
25+
[5.0, 5.0, 1], [5.1, 5.1, 1], [5.0, 5.1, 1], # Cluster 1
26+
[9.0, 9.0, 2], [9.1, 9.1, 2], [9.0, 9.1, 2] # Cluster 2
27+
]
28+
knn = KNearestNeighbors(k=3, task='classification')
29+
knn.fit(dataset_knn)
30+
31+
print("\n3. Evaluando IA en PC (Python):")
32+
# Pruebas para SVM
33+
test_svm = [[2.5, 2.5], [-2.5, -2.5]]
34+
preds_svm = svm.predict(test_svm)
35+
print(f" [SVM] Muestra [ 2.5, 2.5] -> Predicción: {preds_svm[0]} (Esperado: 1)")
36+
print(f" [SVM] Muestra [-2.5, -2.5] -> Predicción: {preds_svm[1]} (Esperado: -1)")
37+
38+
# Pruebas para KNN
39+
test_knn = [[0.2, 0.2], [5.2, 5.2], [8.9, 8.9]]
40+
preds_knn = knn.predict(test_knn)
41+
print(f" [KNN] Muestra [0.2, 0.2] -> Predicción: {preds_knn[0]} (Esperado: 0)")
42+
print(f" [KNN] Muestra [5.2, 5.2] -> Predicción: {preds_knn[1]} (Esperado: 1)")
43+
print(f" [KNN] Muestra [8.9, 8.9] -> Predicción: {preds_knn[2]} (Esperado: 2)")
44+
45+
print("\n4. Exportando Firmware C++ Unificado...")
46+
os.makedirs("exports", exist_ok=True)
47+
cpp_svm = svm.to_arduino_code(fn_name="predict_svm")
48+
cpp_knn = knn.to_arduino_code(fn_name="predict_knn")
49+
50+
header_content = f"""#ifndef MINIML_LEGACY_TESTS_H
51+
#define MINIML_LEGACY_TESTS_H
52+
53+
#include <stdint.h>
54+
#include <math.h>
55+
56+
{cpp_svm}
57+
58+
{cpp_knn}
59+
60+
#endif
61+
"""
62+
63+
with open("exports/miniml_legacy.h", "w") as f:
64+
f.write(header_content)
65+
print(" [OK] Exportación exitosa. Listo para Wokwi.")

0 commit comments

Comments
 (0)