PySR / test /test_torch.py
tttc3
Updated tests for compatibility with refactor
c7187a6
raw
history blame
4.59 kB
import unittest
import numpy as np
import pandas as pd
from pysr import sympy2torch, PySRRegressor
import torch
import sympy
class TestTorch(unittest.TestCase):
def setUp(self):
np.random.seed(0)
def test_sympy2torch(self):
x, y, z = sympy.symbols("x y z")
cosx = 1.0 * sympy.cos(x) + y
X = torch.tensor(np.random.randn(1000, 3))
true = 1.0 * torch.cos(X[:, 0]) + X[:, 1]
torch_module = sympy2torch(cosx, [x, y, z])
self.assertTrue(
np.all(np.isclose(torch_module(X).detach().numpy(), true.detach().numpy()))
)
def test_pipeline_pandas(self):
X = pd.DataFrame(np.random.randn(100, 10))
equations = pd.DataFrame(
{
"Equation": ["1.0", "cos(x1)", "square(cos(x1))"],
"MSE": [1.0, 0.1, 1e-5],
"Complexity": [1, 2, 3],
}
)
equations["Complexity MSE Equation".split(" ")].to_csv(
"equation_file.csv.bkup", sep="|"
)
model = PySRRegressor(
model_selection="accuracy",
equation_file="equation_file.csv",
extra_sympy_mappings={},
output_torch_format=True,
)
# Because a model hasn't been fit via the `fit` method, some
# attributes will not/cannot be set. For the purpose of
# testing, these attributes will be set manually here.
model.fit(X, y=np.ones(X.shape[0]), from_equation_file=True)
model.refresh()
tformat = model.pytorch()
self.assertEqual(str(tformat), "_SingleSymPyModule(expression=cos(x1)**2)")
np.testing.assert_almost_equal(
tformat(torch.tensor(X.values)).detach().numpy(),
np.square(np.cos(X.values[:, 1])), # Selection 1st feature
decimal=4,
)
def test_pipeline(self):
X = np.random.randn(100, 10)
equations = pd.DataFrame(
{
"Equation": ["1.0", "cos(x1)", "square(cos(x1))"],
"MSE": [1.0, 0.1, 1e-5],
"Complexity": [1, 2, 3],
}
)
equations["Complexity MSE Equation".split(" ")].to_csv(
"equation_file.csv.bkup", sep="|"
)
model = PySRRegressor(
model_selection="accuracy",
equation_file="equation_file.csv",
extra_sympy_mappings={},
output_torch_format=True,
)
model.fit(X, y=np.ones(X.shape[0]), from_equation_file=True)
model.refresh()
tformat = model.pytorch()
self.assertEqual(str(tformat), "_SingleSymPyModule(expression=cos(x1)**2)")
np.testing.assert_almost_equal(
tformat(torch.tensor(X)).detach().numpy(),
np.square(np.cos(X[:, 1])), # 2nd feature
decimal=4,
)
def test_mod_mapping(self):
x, y, z = sympy.symbols("x y z")
expression = x**2 + sympy.atanh(sympy.Mod(y + 1, 2) - 1) * 3.2 * z
module = sympy2torch(expression, [x, y, z])
X = torch.rand(100, 3).float() * 10
true_out = (
X[:, 0] ** 2 + torch.atanh(torch.fmod(X[:, 1] + 1, 2) - 1) * 3.2 * X[:, 2]
)
torch_out = module(X)
np.testing.assert_array_almost_equal(
true_out.detach(), torch_out.detach(), decimal=4
)
def test_custom_operator(self):
X = np.random.randn(100, 3)
equations = pd.DataFrame(
{
"Equation": ["1.0", "mycustomoperator(x1)"],
"MSE": [1.0, 0.1],
"Complexity": [1, 2],
}
)
equations["Complexity MSE Equation".split(" ")].to_csv(
"equation_file_custom_operator.csv.bkup", sep="|"
)
model = PySRRegressor(
model_selection="accuracy",
equation_file="equation_file_custom_operator.csv",
extra_sympy_mappings={"mycustomoperator": sympy.sin},
extra_torch_mappings={"mycustomoperator": torch.sin},
output_torch_format=True,
)
model.fit(X, y=np.ones(X.shape[0]), from_equation_file=True)
model.refresh()
self.assertEqual(str(model.sympy()), "sin(x1)")
# Will automatically use the set global state from get_hof.
tformat = model.pytorch()
self.assertEqual(str(tformat), "_SingleSymPyModule(expression=sin(x1))")
np.testing.assert_almost_equal(
tformat(torch.tensor(X)).detach().numpy(),
np.sin(X[:, 1]),
decimal=4,
)