-
Notifications
You must be signed in to change notification settings - Fork 8
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
Convergence logging #27
Comments
It sounds like a good addition. I think a straightforward implementation would be to add a new type like I think the surface syntax requires a separate macro; e.g., |
This sounds good to me. Convergence logging may also be interesting to TensorBoardLogger users and devs who at the moment have their own custom wrapper types and dispatch rules. @PhilipVinc do you have any thoughts? |
In ProgressMeter they use @logthreshold cur goal has the "least surprising" behavior to me, although I see the keyword |
How about |
My thought about
@pkofod if we were to have a general solution for logging optimization progress, what would you need it to do? |
See also JuliaNLSolvers/Optim.jl#442 |
We can have multiple |
On the other hand, it's a single computational process with multiple convergence criteria which apply. So I would have thought the UI should present it as a single message. In that case we should also emit the progress as a single message (or the UI will need to try to figure out how to group them). |
If they share the same parent ID, I suppose it's not too hard for the UI to figure out the relationships? Though it's appealing that we can reduce |
Hmm... I wonder if it is better to somehow combine this to table log monitor JuliaLogging/TerminalLoggers.jl#8 The idea is that each "column" can have independent threshold value, descent/ascent flag, and leave-trace-or-not flag. |
@c42f TensorBoard does not natively support logging convergence information like this, but I guess it would be a nice (and easy) addition. The way TB.jl is structured, we parse one log message at a time. It would surely makes things easier if you log just one message with all the metrics in it. |
So if you're tracking model accuracy or some other measures, the user needs to accumulate that each iteration and pass the resulting array to the logger? |
No, sorry, I simply meant that we do not have a special-cased struct ConvergenceLog
L1
L2
weirdnorm
end
with_logger(TBLogger()) begin
for i=1:100
loss = ConvergenceLog(exp(-i), exp(-2i), rand())
@info "" loss
end
end will by default create 3 plots, one for |
@PhilipVinc You need to pass "Vectorized" message type is indeed more TensorBoardLogger.jl friendly. Although TensorBoardLogger.jl needs to understand that it is an "interface type" rather than a "data type" (ref StructTypes.jl). More concretely, the message type would be something like struct Convergence
names::Vector{String}
values::Vector{Float64}
thresholds::Vector{Float64}
descending::Vector{Bool} # or maybe directions::Vector{Int8} that contains -1, 0, or 1 (0: no threshold)
id::UUID
parentid::UUID
done::Bool
step::Int
end We could make it a subtype of (Edit: |
It's probably better to add |
TensorBoard handles I agree that making it a subtype of AbstractDict might be a nice addition, because then it can be iterated easily. |
@PhilipVinc Once this is added to ProgressLogging.jl, it would be nice if TensorBoardLogger.jl depends on ProgressLogging.jl and define appropriate methods for it. I don't think it's a good idea to make it a dict subtype or iterator of |
One idea of the surface syntax is something like @logconvergence x₁/θ₁ x₂\θ₂ ... xₙ/θₙ step=i which logs Convergence(
names = ["x₁", "x₂", ..., "xₙ"],
values = [x₁, x₂, ..., xₙ],
thresholds = [θ₁, θ₂, ..., θₙ],
descending = [true, false, ..., true],
step = i,
id = ...,
parentid = ...,
done = false,
) |
Another related package is this cool looking SolverTraces.jl by @jagot (ref [ANN] SolverTraces.jl v0.1.0 - Community / Package announcements - JuliaLang). @jagot Do you think the data type |
Sure, I have something similar, but simpler: https://github.com/jagot/SolverTraces.jl/blob/master/src/tolerance.jl#L33 |
That's a good question. SolverTraces looks pretty neat above, but I'd love to be able to simultaneously log some arrays to a file or something like that. It's often interesting to look at the specific states and gradient vectors (and even Hessian approximations) to see if it appears to progress or not, and the norms are not always enough. So I'd love to be able to send summaries to one target and larger things like arrays to another target (a file probably). |
The right way forward here may possibly be to log the summary at progress level, and the larger arrays at The tricky thing is figuring out how to make stuff like "install a log filter" very much more simple, while not being tempted to take complete control of the application-level logging from your library APIs. I guess your package could define a convenience function for controlling logging which is applicable to your package in particular. For example report_convergence("somefile.txt", gradients=true, hessians=true) do
optimize_the_things(...)
end
|
Any updates on the ideas for this? I’d love to get this working for a few of my packages. |
Unfortunately, the discussion diverged as there are many nice-to-have things... I think it's important to focus on a minimal format that is:
I still think #27 (comment) is a decent sweet-spot. I don't think handling "large arrays/objects" fits in this perspective as it's hard for various monitor UIs to render/handle. Using dedicated solutions like TensorBoardLogger.jl seems to be the best solution for this. |
In some discrete search problems, there's not necessarily a measure of remaining effort, but I would like to log the effort done so far (i.e. iteration number). This is the purpose of Would the |
Feature Request
Being able to log progress without having a set number of iterations would be great. Currently
AbstractMCMC
is using ProgressLogging as a backend and they've just added convergence sampling.This is currently implemented in ProgressMeters.jl. I really like how it spits out the total time information in addition to just updating current values vs. threshold.
Example Usage
Something like this:
The text was updated successfully, but these errors were encountered: