Closed odow closed 2 months ago
hm, interesting. Some thoughts
show
the model post-formulation or something.Counts
implementation looks less "elegant" to me (more direct/manual, less composition of abstractions), but maybe that's for the best#
for "number" is confusing to me, since it gets highlighted like a comment (for awhile I was wondering "why isn't the size
one commented?"
#
to inject counts as comments (see below), so I probably had that expectationChain(
Dropout(0.0, active=false),
Conv((3, 3), 1 => 32, relu), # 320 parameters
BatchNorm(32, relu, active=false), # 64 parameters, plus 64
MaxPool((2, 2)),
Dropout(0.0, active=false),
Conv((3, 3), 32 => 16, relu), # 4_624 parameters
Dropout(0.0, active=false),
MaxPool((2, 2)),
Dropout(0.0, active=false),
Conv((3, 3), 16 => 10, relu), # 1_450 parameters
Dropout(0.0, active=false),
var"#22#23"(),
Dropout(0.0, active=false),
Dense(90 => 10), # 910 parameters
Dense(10 => 10), # 110 parameters
Dense(10 => 10), # 110 parameters
NNlib.softmax,
) # Total: 12 trainable arrays, 7_478 parameters,
# plus 4 non-trainable, 174 parameters, summarysize 31.431 KiB.
I think
julia> problem
summary
├─ # variables : 1 (1_000 scalar elements)
├─ # constraints : 1_000 (1_000 scalar elements)
├─ # coefficients : 1000
├─ # atoms : 2001
└─ size : 265.836 KiB
minimize
└─ sum (affine; real)
└─ 1000-element real variable (id: 153…767)
subject to
├─ ≥ constraint (affine)
│ └─ + (affine; real)
would make more sense to me if you could do problem.summary
or something to get a ProblemSummary
object, and that object had those numbers and nice printing. Because to me it looks like we are saying: "this problem has a summary
with these entries, and minimize
with these children".
(In terms of implementation, I don't think a field totally makes sense, bc I don't think we want to actually cache the summary since then we have to worry about invalidation, but it could be get_summary(problem)
or something).
What if it said "summary statistics" or "problem statistics"?
what about something more distinct from the tree printing?
julia> p = minimize(nuclearnorm(y), y == A)
┌──────────────┬────────────────────────┐
│ variables │ 1 (24 scalar elements) │
│ constraints │ 1 (24 scalar elements) │
│ coefficients │ 24 │
│ atoms │ 2 │
│ size │ 704 bytes │
└──────────────┴────────────────────────┘
minimize
└─ nuclearnorm (convex; positive)
└─ 3×4 complex variable (id: 446…935)
subject to
└─ == constraint (affine)
└─ + (affine; complex)
├─ 3×4 complex variable (id: 446…935)
└─ 3×4 complex constant
status: `solve!` not called yet
(this I mocked up with a dataframe and PrettyTables.pretty_table(stdout, df; alignment=[:r, :l], show_subheader=false, show_header=false, tf=tf_unicode)
).
What about:
julia> p
Problem statistics
number of variables : 1 (4 scalar elements)
number of constraints : 5 (14 scalar elements)
number of coefficients : 36
number of atoms : 19
memory allocated : 2.727 KiB
Solution summary
Termination status : OPTIMAL
Primal status : FEASIBLE_POINT
Dual status : FEASIBLE_POINT
objective value : 9.9998
Expression graph
minimize
└─ sum (affine; real)
└─ reshape (affine; real)
└─ * (affine; real)
├─ …
└─ …
subject to
├─ ≤ constraint (affine)
│ └─ + (affine; real)
│ ├─ * (affine; real)
│ │ ├─ …
│ │ └─ …
│ └─ 4×1 Matrix{Int64}
├─ ≥ constraint (affine)
│ └─ + (affine; real)
│ ├─ 4-element real variable (id: 104…638)
│ └─ Convex.NegateAtom (constant; negative)
│ └─ …
├─ ≤ constraint (affine)
│ └─ + (affine; real)
│ ├─ 4-element real variable (id: 104…638)
│ └─ Convex.NegateAtom (constant; negative)
│ └─ …
├─ ≤ constraint (affine)
│ └─ + (affine; real)
│ ├─ index (affine; real)
│ │ └─ …
│ └─ [-5;;]
└─ ≤ constraint (affine)
└─ + (affine; real)
├─ index (affine; real)
│ └─ …
├─ index (affine; real)
│ └─ …
├─ Convex.NegateAtom (affine; real)
│ └─ …
└─ [-10;;]
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 97.94%. Comparing base (
379f7e7
) to head (1515175
). Report is 2 commits behind head on master.
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
I like it!
One tiny nitpick is that memory allocated is potentially confusing, since more memory was likely allocated on the way, but this what we’re still using.
otherwise lgtm
memory allocated is potentially confusing
:+1:
What about explicitly quantifying the size of the expression graph and the size of the MOI backend?
One issue with optimization model : XXX bytes
is that it doesn't count the memory allocated in C by the solver
Maybe we should just remove the memory stuff. The rest is useful enough, and specifying the memory is just going to mislead people.
Okay, this now yields:
julia> A = [1 2im 3 4; 4im 3im 2 1; 4 5 6 7]
3×4 Matrix{Complex{Int64}}:
1+0im 0+2im 3+0im 4+0im
0+4im 0+3im 2+0im 1+0im
4+0im 5+0im 6+0im 7+0im
julia> y = ComplexVariable(3, 4)
Variable
size: (3, 4)
sign: complex
vexity: affine
id: 120…842
julia> p = minimize(nuclearnorm(y), y == A)
Problem statistics
number of variables : 1 (24 scalar elements)
number of constraints : 1 (24 scalar elements)
number of coefficients : 24
number of atoms : 2
Solution summary
termination status : OPTIMIZE_NOT_CALLED
primal status : NO_SOLUTION
dual status : NO_SOLUTION
Expression graph
minimize
└─ nuclearnorm (convex; positive)
└─ 3×4 complex variable (id: 120…842)
subject to
└─ == constraint (affine)
└─ + (affine; complex)
├─ 3×4 complex variable (id: 120…842)
└─ 3×4 complex constant
Alternative for #643
Closes #640
Examples