davidavdav / GaussianMixtures.jl

Large scale Gaussian Mixture Models
Other
95 stars 36 forks source link

Query current logger instead of global one (should fix #92) #101

Open ForceBru opened 1 year ago

ForceBru commented 1 year ago

Problem

Currently fitting a GMM produces a lot of output:

julia> using GaussianMixtures

julia> data = [0.3*randn(200) .- 1; 0.7*randn(400) .+ 1];

julia> GMM(2, [data;;]);
[ Info: Initializing GMM, 2 Gaussians diag covariance 1 dimensions using 600 data points
K-means converged with 5 iterations (objv = 162.85171999804564)
┌ Info: K-means with 600 data points using 5 iterations
└ 150.0 data points per parameter

julia>

Part of this output can't be easily suppressed (see #92) because this code queries the global logger:

https://github.com/davidavdav/GaussianMixtures.jl/blob/9926a1171a655a089d0cadc4b6512564186d3d0f/src/train.jl#L103

For example, this makes estimating thousands of small GMMs extremely noisy, and the only solution to silence logging seems to involve changing the global logger which isn't ideal.

Possible solution

Query the current logger instead using Logging.current_logger(), which returns either the "task-local" logger or the global one if there's no local logger.

This should let users change the logger and suppress logging entirely:

julia> Logging.with_logger(Logging.NullLogger()) do; GMM(2, [data;;]) end;
# no output!
julia> 
ForceBru commented 1 year ago

Currently, I'm unable to write a unit test for this because I can't figure out how to test whether an expression doesn't produce any output: https://discourse.julialang.org/t/how-to-test-whether-evaluating-an-expression-produces-no-output-at-all/86102.

I tested it by hand (see code in "Possible solution" above), and it seems to work. That line is the only one which explicitly obtains the global logger, so everything else should "just work" with any logger.