Skip to content
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

Add a progress meter for LMM fits #539

Merged
merged 23 commits into from
Jul 13, 2021
Merged

Add a progress meter for LMM fits #539

merged 23 commits into from
Jul 13, 2021

Conversation

dmbates
Copy link
Collaborator

@dmbates dmbates commented Jul 7, 2021

  • This is just a proof of concept but it seems to work well (once I read the documentation for ProgressMeter and read our code a little more carefully).
  • Try, for example
julia> using MixedModels

julia> using MKL

julia> mrk17 = MixedModels.dataset(:mrk17_exp1);

julia> form = @formula 1000 / rt ~ 1 + F*P*Q*lQ*lT + (1+F+P+Q+lQ+lT|subj) + (1+P+Q+lQ+lT|item);

julia> contr = merge(Dict(nm => EffectsCoding() for nm in (:F, :P, :Q, :lQ, :lT)), Dict(nm => Grouping() for nm in (:subj, :item)));

julia> m = fit(MixedModel, form, mrk17; contrasts=contr);
Progress:  1316  Time: 0 Time: 0:00:07 ( 5.53 ms/it)

During the iterations the current objective is displayed below the Progress line,

  • Not entirely sure how the Time: 0 ends up in that line.

@dmbates dmbates requested a review from palday July 7, 2021 23:15
Project.toml Outdated Show resolved Hide resolved
src/linearmixedmodel.jl Outdated Show resolved Hide resolved
@palday
Copy link
Member

palday commented Jul 8, 2021

The CI failures seem to be a problem with the Windows VMs.

@palday
Copy link
Member

palday commented Jul 8, 2021

I think I had looked at making the iterations clear and print in the same spot, but then got sidetracked: timholy/ProgressMeter.jl#204

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 8, 2021

CI is failing for Julia 1.4 on Windows because it can't download packages correctly. Should we switch the CI to julia 1.6 only? (Until we are able to run tests on 1.7 and later.)

@palday
Copy link
Member

palday commented Jul 8, 2021

Since this is for the breaking 4.0 release, let's just go ahead and make support start at 1.6. Can you also update Project.toml? (And even though it's not a feature, a note to NEWS?)

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 8, 2021

Will the changes re CI on version 1.6 (and, sigh!, add a news item - I feel like a surly teenager rolling his eyes about the stupid rules his parents have) when I get back from a walk.

@palday
Copy link
Member

palday commented Jul 8, 2021

@dmbates I'll take care of it while you're out -- I have a minute while a computation runs. 😄

@codecov
Copy link

codecov bot commented Jul 8, 2021

Codecov Report

Merging #539 (491a4d1) into main (d6e0669) will increase coverage by 0.01%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #539      +/-   ##
==========================================
+ Coverage   94.28%   94.29%   +0.01%     
==========================================
  Files          26       26              
  Lines        2308     2313       +5     
==========================================
+ Hits         2176     2181       +5     
  Misses        132      132              
Impacted Files Coverage Δ
src/bootstrap.jl 97.84% <100.00%> (ø)
src/generalizedlinearmixedmodel.jl 90.20% <100.00%> (+0.10%) ⬆️
src/linearmixedmodel.jl 95.28% <100.00%> (+0.01%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d6e0669...491a4d1. Read the comment docs.

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 8, 2021

Should the default value of verbose be changed to true? I think this display is informative and may help educate users as to what is making their model fits slow. On the other hand, I don't want to clutter up users' sessions with unwanted displays.

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 8, 2021

There is a problem with using the optional argument verbose for generalized linear mixed models in that it also causes the deviance evaluation to become verbose. As a temporary fix I will add an optional progress argument separate from verbose but that is just to get things working. We can decide on a more general approach later.

@palday
Copy link
Member

palday commented Jul 8, 2021

What does verbose output look like now for a quick fit like sleepstudy?

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 8, 2021

What does verbose output look like now for a quick fit like sleepstudy?

For different machines it could be that nothing shows up or just the final summary. Perhaps we should change the optional argument name to progress throughout and explain in the documentation that this uses the facilities of the ProgressMeter package which doesn't do anything if the minimization time is much less than 1 second.

By the way, I looked in the ProgressMeter package for a NEWS.md file to check on what version is needed for which capabilities and there isn't a NEWS.md file. So there!

@palday
Copy link
Member

palday commented Jul 8, 2021

I like the idea of changing the argument name to progress.

By the way, I looked in the ProgressMeter package for a NEWS.md file to check on what version is needed for which capabilities and there isn't a NEWS.md file. So there!

😁

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 10, 2021

@palday Can you take another look, please?

@palday
Copy link
Member

palday commented Jul 11, 2021

I think it's nearly there -- what do you think of my comments for verbose vs. progress in GLMM?

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 12, 2021

I think it's nearly there -- what do you think of my comments for verbose vs. progress in GLMM?

Those look good, thanks. Both committed now.

src/linearmixedmodel.jl Outdated Show resolved Hide resolved
src/linearmixedmodel.jl Outdated Show resolved Hide resolved
@dmbates
Copy link
Collaborator Author

dmbates commented Jul 12, 2021

@palday Took a bit longer than I imagined as I needed to add a default to refit! methods as well. I chose progress::Bool=false for refit!. I also replaced a couple of occurrences of the now deprecated model_response with response in the tests.

src/linearmixedmodel.jl Outdated Show resolved Hide resolved
@palday
Copy link
Member

palday commented Jul 12, 2021

@dmbates while you were writing that comment, I was already commenting on the choice of default for refit!. I'm fine with false as the default, but true would be consistent with fit!

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 12, 2021

@dmbates while you were writing that comment, I was already commenting on the choice of default for refit!. I'm fine with false as the default, but true would be consistent with fit!

My reasoning was that for a refit! the user has already had the chance to see the progress meter for the optimization so the novelty may have worn off. I would be okay with changing the default to true for consistency with fit! but then we would need to go through all the calls to refit! in the tests to add progress=false to them. Let me know if you want me to do that.

@palday
Copy link
Member

palday commented Jul 12, 2021

I had a similar thought -- typically the user knows better what to expect with refit and model is already constructed and everything is precompiled, so that bit of overhead is gone.

We could take a middle ground that will make things easier in the future if we expose more options to the user: have a kwargs... to refit! that is splatted into the call to fit! and then the defaults are just carried over.

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 12, 2021

@palday the kwargs... approach sounds good. Would you be willing to make that change?

@palday
Copy link
Member

palday commented Jul 12, 2021

yep, will do

test/pirls.jl Outdated
Comment on lines 94 to 105
refit!(gm2r, 1 .- gm2.y; fast=true)
@test gm2r.β ≈ -gm2.β atol=1e-3

refit!(gm2r; fast=true, progress=false)
@test length(gm2r.optsum.final) == 1
@test gm2r.θ ≈ gm2.θ atol=1e-3

refit!(gm2r, 1 .- gm2.y; fast=false)
# swapping successes and failures to give us the same model
# but with opposite signs. healthy ≈ 1 - response(gm2r)
# but defining it in terms of the original values avoids some
# nasty floating point issues
healthy = @. (cbpp.hsz - cbpp.incid) / cbpp.hsz
refit!(gm2r, healthy; fast=false, progress=false)
@test length(gm2r.optsum.final) == 5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmbates going the kwargs... route made me realize that we weren't passing all the arguments here ... which then lead to the discovery that the "flipped" response was numerically pathological for fast fits. Hence the changes here.

Copy link
Member

@palday palday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As soon as the CIs pass, please merge. 😄

@dmbates
Copy link
Collaborator Author

dmbates commented Jul 13, 2021

@palday I seem to be playing "whack-a-mole" again trying to track down all the instances of fit( or refit!( in the tests and adding progress=false. The tests on Mac OSX indicate that there may be a problem with the bootstrap tests now. I feel that the parametricbootstrap function should turn off the progress meter unconditionally.

Does it seem that we are going about this the wrong way? I don't mind a bit of whack-a-mole but this seems to be going on longer than is wise.

By the way, the Mac tests seem to be slower and hence better at finding cases where the progress meter kicks in.

@palday
Copy link
Member

palday commented Jul 13, 2021

Interesting on the Mac tests ....

I agree that parametricbootstrap should unconditionally set progress=false -- it has its own progress meter anyway.

I think there's not much to be done about the whack-a-mole -- that's just what happens when you change defaults. 🤷 I have a somewhat slower computer I can also run the tests on and see if that reveals any more cases.

@palday palday merged commit b96d6c7 into main Jul 13, 2021
@palday palday deleted the db/progressmeter branch July 13, 2021 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants