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

(WIP) Add support for logging hyperparameters #87

Closed
wants to merge 13 commits into from

Conversation

dangirsh
Copy link

See #77 .

@dangirsh
Copy link
Author

dangirsh commented Dec 16, 2020

Remaining work:

  • Test serializaiton of non-trivial inputs matches the same from Python: e.g. this test case.
  • deserialization
  • docstrings
  • anything else @PhilipVinc ?

@PhilipVinc
Copy link
Member

Yes, that seems about right.

If you could also write some documentation with an example for the Documenter.jl generated docs it would be great.

@PhilipVinc
Copy link
Member

BTW, you have a failing test case for Julia 1.0 because of an isnothing
I know it's old, but I'm trying to support Julia LTS while we can.

Comment on lines +4 to +5
EXPERIMENT_TAG = "_hparams_/experiment"
SESSION_START_INFO_TAG = "_hparams_/session_start_info"
Copy link
Member

Choose a reason for hiding this comment

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

You got those from tensorboardx.py?

EXPERIMENT_TAG = "_hparams_/experiment"
SESSION_START_INFO_TAG = "_hparams_/session_start_info"


Copy link
Member

Choose a reason for hiding this comment

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

Could you add a few comments on what are Domain types used for? I guess it's to encode the domain of a hyper parameter but still... it would make the code more clear for future maintenance


DiscreteDomainElem = Union{String, Float64, Bool}

hparams_datatype_sym(::Type{String}) = :DATA_TYPE_STRING
Copy link
Member

Choose a reason for hiding this comment

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

Sometimes SubString might be passed in. I'd support at least that one too.
Ideally, I'd say that this should be ::Type{<:AbstractString} and a conversion for exotic types should be made where appropriate 

Comment on lines +22 to +28
ProtoBuf.google.protobuf.Value(x::Number) = Value(number_value=x)
ProtoBuf.google.protobuf.Value(x::Bool) = Value(bool_value=x)
ProtoBuf.google.protobuf.Value(x::AbstractString) = Value(string_value=x)
function ProtoBuf.google.protobuf.Value(x)
@warn "Cannot create a ProtoBuf.google.protobuf.Value of type $(typeof(x)), defaulting to null."
Value(null_value=Int32(0))
end
Copy link
Member

Choose a reason for hiding this comment

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

This is all type-piracy, and it might stop working in the future when something is changed in ProtoBuf.jl.
Is there a specific reason you need this, and can not create your own Value function that you use locally?

You should not define specialised methods for types we do not own on functions we do not own.
Maybe, do not import Protobuf.google.protobuf.Value, define your own Value functions forwarding to Protobuf.google.protobuf.Value.

end


function ProtoBuf.google.protobuf.ListValue(domain::DiscreteDomain{T}) where T <: DiscreteDomainElem
Copy link
Member

Choose a reason for hiding this comment

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

As above, type piracy. Don't import ListValue and create your own function

Comment on lines +46 to +51
struct HParam
name::AbstractString
domain::HParamDomain
display_name::AbstractString
description::AbstractString
end
Copy link
Member

Choose a reason for hiding this comment

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

Since we can only serialise standard tensor board types (Float32 and C-strings) I think that this here should be a type-stable struct with String types instead of AbstractStrings and proper conversion should be done in the constructor.

Copy link
Member

Choose a reason for hiding this comment

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

Actually, it depends: is this an internal type used for logging, or the user-accessible API-type?

description::AbstractString
dataset_type::Symbol

function Metric(tag::AbstractString,
Copy link
Member

Choose a reason for hiding this comment

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

Is the inner constructor really necessary?

Comment on lines +103 to +104
hparams::AbstractVector{HParam}
metrics::AbstractVector{Metric}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
hparams::AbstractVector{HParam}
metrics::AbstractVector{Metric}
hparams::Vector{HParam}
metrics::Vector{Metric}

Comment on lines +218 to +221
# TODO: The types in the hparam domain and this dict's values are constrained.
# e.g. an hparam with a discrete domain of ["a", "b"] must have string values
# Consider ways to enforce this relationship in the type system.
data::Dict{HParam, Any}
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain this better? I don't understand the todo

Comment on lines +222 to +223
# FIXME: group_name auto generated in the Python implementation (Tensorboard)
group_name::AbstractString
Copy link
Member

Choose a reason for hiding this comment

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

Wrapper types are essentially the user-api. if this is an internal field autogenerated, then you should remove it (and auto-generate it when necessary).
if it's optional and in some cases it's useful to define it, then use a constructor to deal with the two cases.

@PhilipVinc
Copy link
Member

Hey @dangirsh , this is a friendly bump.
Are you still planning on finishing this at some point or you really don't have time for it anymore?

@dangirsh
Copy link
Author

@PhilipVinc Unfortunately, I've recently started a non-Julia project that is consuming 100% of my time. I hope this initial attempt is a helpful start.

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