Spaces:
Sleeping
Sleeping
Commit
路
90f5e4c
1
Parent(s):
b6c4c3a
Enable custom loss functions
Browse files- example.py +3 -1
- pysr/sr.py +36 -7
example.py
CHANGED
|
@@ -10,7 +10,9 @@ equations = pysr(X, y, niterations=5,
|
|
| 10 |
binary_operators=["plus", "mult"],
|
| 11 |
unary_operators=[
|
| 12 |
"cos", "exp", "sin", #Pre-defined library of operators (see https://pysr.readthedocs.io/en/latest/docs/operators/)
|
| 13 |
-
"inv(x) = 1/x"]
|
|
|
|
|
|
|
| 14 |
|
| 15 |
...# (you can use ctl-c to exit early)
|
| 16 |
|
|
|
|
| 10 |
binary_operators=["plus", "mult"],
|
| 11 |
unary_operators=[
|
| 12 |
"cos", "exp", "sin", #Pre-defined library of operators (see https://pysr.readthedocs.io/en/latest/docs/operators/)
|
| 13 |
+
"inv(x) = 1/x"],
|
| 14 |
+
loss='L1DistLoss()',
|
| 15 |
+
julia_project="../SymbolicRegression.jl") # Define your own operator! (Julia syntax)
|
| 16 |
|
| 17 |
...# (you can use ctl-c to exit early)
|
| 18 |
|
pysr/sr.py
CHANGED
|
@@ -57,12 +57,13 @@ sympy_mappings = {
|
|
| 57 |
}
|
| 58 |
|
| 59 |
def pysr(X=None, y=None, weights=None,
|
|
|
|
|
|
|
| 60 |
procs=4,
|
|
|
|
| 61 |
populations=None,
|
| 62 |
niterations=100,
|
| 63 |
ncyclesperiteration=300,
|
| 64 |
-
binary_operators=["plus", "mult"],
|
| 65 |
-
unary_operators=["cos", "exp", "sin"],
|
| 66 |
alpha=0.1,
|
| 67 |
annealing=True,
|
| 68 |
fractionReplaced=0.10,
|
|
@@ -116,16 +117,42 @@ def pysr(X=None, y=None, weights=None,
|
|
| 116 |
:param y: np.ndarray, 1D array. Rows are examples.
|
| 117 |
:param weights: np.ndarray, 1D array. Each row is how to weight the
|
| 118 |
mean-square-error loss on weights.
|
|
|
|
|
|
|
|
|
|
| 119 |
:param procs: int, Number of processes (=number of populations running).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 120 |
:param populations: int, Number of populations running; by default=procs.
|
| 121 |
:param niterations: int, Number of iterations of the algorithm to run. The best
|
| 122 |
equations are printed, and migrate between populations, at the
|
| 123 |
end of each.
|
| 124 |
:param ncyclesperiteration: int, Number of total mutations to run, per 10
|
| 125 |
samples of the population, per iteration.
|
| 126 |
-
:param binary_operators: list, List of strings giving the binary operators
|
| 127 |
-
in Julia's Base, or in `operator.jl`.
|
| 128 |
-
:param unary_operators: list, Same but for operators taking a single `Float32`.
|
| 129 |
:param alpha: float, Initial temperature.
|
| 130 |
:param annealing: bool, Whether to use annealing. You should (and it is default).
|
| 131 |
:param fractionReplaced: float, How much of population to replace with migrating
|
|
@@ -262,7 +289,7 @@ def pysr(X=None, y=None, weights=None,
|
|
| 262 |
weightSimplify=weightSimplify,
|
| 263 |
constraints=constraints,
|
| 264 |
extra_sympy_mappings=extra_sympy_mappings,
|
| 265 |
-
julia_project=julia_project)
|
| 266 |
|
| 267 |
kwargs = {**_set_paths(tempdir), **kwargs}
|
| 268 |
|
|
@@ -383,7 +410,7 @@ def _make_hyperparams_julia_str(X, alpha, annealing, batchSize, batching, binary
|
|
| 383 |
parsimony, perturbationFactor, populations, procs, shouldOptimizeConstants,
|
| 384 |
unary_operators, useFrequency, use_custom_variable_names,
|
| 385 |
variable_names, warmupMaxsize, weightAddNode,
|
| 386 |
-
ncyclesperiteration, fractionReplaced, topn, verbosity,
|
| 387 |
weightDeleteNode, weightDoNothing, weightInsertNode, weightMutateConstant,
|
| 388 |
weightMutateOperator, weightRandomize, weightSimplify, weights, **kwargs):
|
| 389 |
def tuple_fix(ops):
|
|
@@ -411,11 +438,13 @@ greater=SymbolicRegression.greater
|
|
| 411 |
relu=SymbolicRegression.relu
|
| 412 |
logical_or=SymbolicRegression.logical_or
|
| 413 |
logical_and=SymbolicRegression.logical_and
|
|
|
|
| 414 |
|
| 415 |
options = SymbolicRegression.Options(binary_operators={'(' + tuple_fix(binary_operators) + ')'},
|
| 416 |
unary_operators={'(' + tuple_fix(unary_operators) + ')'},
|
| 417 |
{constraints_str}
|
| 418 |
parsimony={parsimony:f}f0,
|
|
|
|
| 419 |
alpha={alpha:f}f0,
|
| 420 |
maxsize={maxsize:d},
|
| 421 |
maxdepth={maxdepth:d},
|
|
|
|
| 57 |
}
|
| 58 |
|
| 59 |
def pysr(X=None, y=None, weights=None,
|
| 60 |
+
binary_operators=["plus", "mult"],
|
| 61 |
+
unary_operators=["cos", "exp", "sin"],
|
| 62 |
procs=4,
|
| 63 |
+
loss='L2DistLoss()',
|
| 64 |
populations=None,
|
| 65 |
niterations=100,
|
| 66 |
ncyclesperiteration=300,
|
|
|
|
|
|
|
| 67 |
alpha=0.1,
|
| 68 |
annealing=True,
|
| 69 |
fractionReplaced=0.10,
|
|
|
|
| 117 |
:param y: np.ndarray, 1D array. Rows are examples.
|
| 118 |
:param weights: np.ndarray, 1D array. Each row is how to weight the
|
| 119 |
mean-square-error loss on weights.
|
| 120 |
+
:param binary_operators: list, List of strings giving the binary operators
|
| 121 |
+
in Julia's Base.
|
| 122 |
+
:param unary_operators: list, Same but for operators taking a single scalar.
|
| 123 |
:param procs: int, Number of processes (=number of populations running).
|
| 124 |
+
:param loss: str, String of Julia code specifying the loss function.
|
| 125 |
+
Can either be a loss from LossFunctions.jl, or your own
|
| 126 |
+
loss written as a function. Examples of custom written losses
|
| 127 |
+
include: `myloss(x, y) = abs(x-y)` for non-weighted, or
|
| 128 |
+
`myloss(x, y, w) = w*abs(x-y)` for weighted.
|
| 129 |
+
Among the included losses, these are:
|
| 130 |
+
Regression:
|
| 131 |
+
- `LPDistLoss{P}()`,
|
| 132 |
+
- `L1DistLoss()`,
|
| 133 |
+
- `L2DistLoss()` (mean square),
|
| 134 |
+
- `LogitDistLoss()`,
|
| 135 |
+
- `HuberLoss(d)`,
|
| 136 |
+
- `L1EpsilonInsLoss(系)`,
|
| 137 |
+
- `L2EpsilonInsLoss(系)`,
|
| 138 |
+
- `PeriodicLoss(c)`,
|
| 139 |
+
- `QuantileLoss(蟿)`,
|
| 140 |
+
Classification:
|
| 141 |
+
- `ZeroOneLoss()`,
|
| 142 |
+
- `PerceptronLoss()`,
|
| 143 |
+
- `L1HingeLoss()`,
|
| 144 |
+
- `SmoothedL1HingeLoss(纬)`,
|
| 145 |
+
- `ModifiedHuberLoss()`,
|
| 146 |
+
- `L2MarginLoss()`,
|
| 147 |
+
- `ExpLoss()`,
|
| 148 |
+
- `SigmoidLoss()`,
|
| 149 |
+
- `DWDMarginLoss(q)`.
|
| 150 |
:param populations: int, Number of populations running; by default=procs.
|
| 151 |
:param niterations: int, Number of iterations of the algorithm to run. The best
|
| 152 |
equations are printed, and migrate between populations, at the
|
| 153 |
end of each.
|
| 154 |
:param ncyclesperiteration: int, Number of total mutations to run, per 10
|
| 155 |
samples of the population, per iteration.
|
|
|
|
|
|
|
|
|
|
| 156 |
:param alpha: float, Initial temperature.
|
| 157 |
:param annealing: bool, Whether to use annealing. You should (and it is default).
|
| 158 |
:param fractionReplaced: float, How much of population to replace with migrating
|
|
|
|
| 289 |
weightSimplify=weightSimplify,
|
| 290 |
constraints=constraints,
|
| 291 |
extra_sympy_mappings=extra_sympy_mappings,
|
| 292 |
+
julia_project=julia_project, loss=loss)
|
| 293 |
|
| 294 |
kwargs = {**_set_paths(tempdir), **kwargs}
|
| 295 |
|
|
|
|
| 410 |
parsimony, perturbationFactor, populations, procs, shouldOptimizeConstants,
|
| 411 |
unary_operators, useFrequency, use_custom_variable_names,
|
| 412 |
variable_names, warmupMaxsize, weightAddNode,
|
| 413 |
+
ncyclesperiteration, fractionReplaced, topn, verbosity, loss,
|
| 414 |
weightDeleteNode, weightDoNothing, weightInsertNode, weightMutateConstant,
|
| 415 |
weightMutateOperator, weightRandomize, weightSimplify, weights, **kwargs):
|
| 416 |
def tuple_fix(ops):
|
|
|
|
| 438 |
relu=SymbolicRegression.relu
|
| 439 |
logical_or=SymbolicRegression.logical_or
|
| 440 |
logical_and=SymbolicRegression.logical_and
|
| 441 |
+
loss = {loss}
|
| 442 |
|
| 443 |
options = SymbolicRegression.Options(binary_operators={'(' + tuple_fix(binary_operators) + ')'},
|
| 444 |
unary_operators={'(' + tuple_fix(unary_operators) + ')'},
|
| 445 |
{constraints_str}
|
| 446 |
parsimony={parsimony:f}f0,
|
| 447 |
+
loss=loss,
|
| 448 |
alpha={alpha:f}f0,
|
| 449 |
maxsize={maxsize:d},
|
| 450 |
maxdepth={maxdepth:d},
|