-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Integration with TensorBoard and other logging utilities #277
base: master
Are you sure you want to change the base?
Conversation
f46f22c
to
5973611
Compare
AbstractLogger
)
This comment was marked as resolved.
This comment was marked as resolved.
AbstractLogger
)AbstractLogger
)
AbstractLogger
)AbstractLogger
FYI Wandb works too! https://github.com/avik-pal/Wandb.jl |
a2cf220
to
de69b29
Compare
c682a6d
to
8fb1ab6
Compare
8fb1ab6
to
bb2e16b
Compare
21c212c
to
36015de
Compare
Thanks @MilesCranmer ! The tensorboard monitoring will complement the progress bar nicely for jobs longer than a few hours. Here's just some ideas on which evolution histories can be useful:
I guess we only need to log per iteration by the head worker, right? import os
import sys
import numpy as np
import scipy
import pysr
import matplotlib.pyplot as plt
def _get_lower(polygon):
"""Lower convex hull: https://stackoverflow.com/questions/76838415/lower-convex-hull"""
minx = np.argmin(polygon[:, 0])
maxx = np.argmax(polygon[:, 0]) + 1
if minx >= maxx:
lower_points = np.concatenate([polygon[minx:], polygon[:maxx]])
else:
lower_points = polygon[minx:maxx]
return lower_points
def pareto_plot(equation_file, savefig=True, lower_convex_hull=True):
"""Plot Pareto front."""
model = pysr.PySRRegressor.from_file(equation_file)
hof = model.get_hof()
hof.plot(x='complexity', y='loss', loglog=True, xlim=(1, None), ylabel='loss',
drawstyle='steps-post')
if lower_convex_hull:
points = hof[['complexity', 'loss']].to_numpy()
points = points[np.isfinite(points.sum(axis=1))] # remove inf
hull = scipy.spatial.ConvexHull(np.log(points))
lower_points = _get_lower(points[hull.vertices])
plt.plot(lower_points[:, 0], lower_points[:, 1], ls=':', label='convex hull')
plt.legend()
if savefig:
fig_file = os.path.splitext(equation_file)[0] + '.pdf'
plt.savefig(fig_file)
else:
return plt.gcf()
if __name__ == '__main__':
for equation_file in sys.argv[1:]:
pareto_plot(equation_file) I need to remove |
Theres seems to be 2 definitions of
They both trade With this score, the pareto front (on log-log scales) are naturally divided into staged. Also what do you think about using the log-log score in fitting? |
Is there a way to create plots in TensorBoard or do you need to upload the entire image? |
Yes the internal |
c871f17
to
59a373e
Compare
@eelregit I added plotting utilities. Do you want to try it out? Here's a demo: using SymbolicRegression
using Plots
using MLJBase
model = SRRegressor(; binary_operators=[+, -, *, /], niterations=500, maxsize=80)
X = rand(1000, 2) .* 10
y = X[:, 1] + X[:, 2] .^ 2.5
mach = machine(model, X, y)
fit!(mach)
plot(mach.fitresult; dpi=300, fontfamily="serif") which creates: I think the convex hull is nice but I am worried it's a bit too specific (it seems like it wouldn't be general outside of mean-squared error loss?). I always try to make things general so users can customize these things. So I'm leaning towards taking it out and simply letting people write their own plotting method (which they could pass in as a callback function). What do you think? But maybe we could still have a decent default for the Pareto front plot itself. |
@eelregit sorry for the late follow-up. Teaching was a bit of a black hole – just finished! I added a bunch of new things. Now logged:
Here's what the output looks like: And here's an example complexity distribution over time (time is represented by depth): Here are the saved plots: Finally, for posterity, here's the code I'm using: using SymbolicRegression
using Plots
using MLJBase
using TensorBoardLogger: TBLogger
X = randn(Float32, 100, 5)
y = 2 * cos.(X[:, 4]) + X[:, 1] .^ 2 .- 2
model = SRRegressor(;
binary_operators=[+, *, /, -],
# unary_operators=[cos, exp],
populations=20,
maxsize=30,
niterations=400,
parallelism=:multithreading,
logger=TBLogger("logs"),
log_every_n=(scalars=1, plots=10),
)
mach = machine(model, X, y)
fit!(mach) |
AbstractLogger
Thanks Miles! The Pareto volume is a great metric idea. Sorry for not testing things out earlier. I will do it this weekend. |
Yep! Just note that it has changed from earlier this year as PySR now uses a different method for interconnecting Python and Julia. The docs have been updated accordingly, so if you follow that you are good. |
cc @eelregit @paulomontero
@eelregit made a request for a tensorboard logging capability. Turns out this was a fantastic idea! This is super useful, and also extremely easy to integrate. Gotta love Julia.
This is a work-in-progress PR to add tensorboard logging capabilities. Actually any other logger will work which is
<:Logging.AbstractLogger
– which is in the Julia standard library. That includes Wandb as well, via Wandb.jlIt seems to work nicely thus far. Here's a code example. First, run
julia -e 'using Pkg; pkg"add TensorBoardLogger MLJBase https://github.com/MilesCranmer/SymbolicRegression.jl/tree/tb-logging"'
to install everything.Then, you can run this with (copy-paste):
which results in (you can run
Python: Launch Tensorboard
in VSCode via the Python extension) –TODO:
with_logger
part into a separate function to clean things up. Probably inSearchUtils.jl
.logging_callback
which is passed a variety of relevant variables.SimpleLogger
.logger
andlogging_callback
in bothequation_search
andSRRegressor