• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alan-turing-institute / MLJTuning.jl / 118

3 Apr 2020 - 2:24 coverage: 85.424% (+2.0%) from 83.404%
118

Pull #30

travis-ci-com

web-flow
more doc tweaks
Pull Request #30: Implement RandomSearch

56 of 58 new or added lines in 3 files covered. (96.55%)

4 existing lines in 3 files now uncovered.

252 of 295 relevant lines covered (85.42%)

985.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.43
/src/strategies/grid.jl
1
const ParameterName=Union{Symbol,Expr}
2

3
"""
4
    Grid(goal=nothing, resolution=10, rng=Random.GLOBAL_RNG, shuffle=true)
5

6
Instantiate a Cartesian grid-based hyperparameter tuning strategy with
7
a specified number of grid points as `goal`, or using a specified
8
default `resolution` in each numeric dimension.
9

10
### Supported ranges:
11

12
A single one-dimensional range or vector of one-dimensioinal ranges
13
can be specified. Specifically, in `Grid` search, the `range` field
14
of a `TunedModel` instance can be:
15

16
- A single one-dimensional range (ie, `ParamRange` object) `r`, or pair of
17
  the form `(r, res)` where `res` specifies a resolution to override
18
  the default `resolution`.
19

20
- Any vector of objects of the above form
21

22
`ParamRange` objects are constructed using the `range` method.
23

24
Example 1:
25

26
    range(model, :hyper1, lower=1, origin=2, unit=1)
27

28
Example 2:
29

30
    [(range(model, :hyper1, lower=1, upper=10), 15),
31
      range(model, :hyper2, lower=2, upper=4),
32
      range(model, :hyper3, values=[:ball, :tree])]
33

34
Note: All the `field` values of the `ParamRange` objects (`:hyper1`,
35
`:hyper2`, `:hyper3` in the preceding example) must refer to field
36
names a of single model (the `model` specified during `TunedModel`
37
construction).
38

39

40
### Algorithm
41

42
This is a standard grid search with the following specifics: In all
43
cases all `values` of each specified `NominalRange` are exhausted. If
44
`goal` is specified, then all resolutions are ignored, and a global
45
resolution is applied to the `NumericRange` objects that maximizes the
46
number of grid points, subject to the restriction that this not exceed
47
`goal`. Otherwise the default `resolution` and any parameter-specific
48
resolutions apply.
49

50
In all cases the models generated are shuffled using `rng`, unless
51
`shuffle=false`.
52

53
See also [`TunedModel`](@ref), [`range`](@ref).
54

55
"""
56
mutable struct Grid <: TuningStrategy
57
    goal::Union{Nothing,Int}
26×
58
    resolution::Int
59
    shuffle::Bool
60
    rng::Random.AbstractRNG
61
end
62

63
# Constructor with keywords
64
Grid(; goal=nothing, resolution=10, shuffle=true,
65
     rng=Random.GLOBAL_RNG) =
19×
66
    Grid(goal, resolution, MLJBase.shuffle_and_rng(shuffle, rng)...)
67

UNCOV
68
isnumeric(::Any) = false
!
69
isnumeric(::NumericRange) = true
16×
70

71
adjusted_resolutions(::Nothing,  ranges, resolutions) = resolutions
188×
72
function adjusted_resolutions(goal, ranges, resolutions)
73
    # get the product �� of the lengths of the NominalRanges:
74
    len(::NumericRange) = 1
8×
75
    len(r::NominalRange) = length(r.values)
76
    �� = prod(len.(ranges))
77

78
    n_numeric = sum(isnumeric.(ranges))
4×
79

80
    # compute new uniform resolution:
81
    goal = goal/��
4×
82
    res = round(Int, goal^(1/n_numeric))
4×
83
    return  map(eachindex(resolutions)) do j
6×
84
        isnumeric(ranges[j]) ? res : resolutions[j]
32×
85
    end
86
end
87

88
function setup(tuning::Grid, model, user_range, verbosity)
89
    ranges, resolutions =
80×
90
        process_grid_range(user_range, tuning.resolution, verbosity)
91
    resolutions = adjusted_resolutions(tuning.goal, ranges, resolutions)
47×
92

93
    fields = map(r -> r.field, ranges)
83×
94

95
    parameter_scales = scale.(ranges)
47×
96

97
    if tuning.shuffle
47×
98
        models = grid(tuning.rng, model, ranges, resolutions)
12×
99
    else
100
        models = grid(model, ranges, resolutions)
35×
101
    end
102

103
    state = (models=models,
47×
104
             fields=fields,
105
             parameter_scales=parameter_scales)
106

107
    return state
47×
108

109
end
110

111
MLJTuning.models!(tuning::Grid,
112
                  model,
113
                  history,
114
                  state,
115
                  n_remaining,
116
                  verbosity) =
82×
117
                      state.models[_length(history) + 1:end]
118

119
function tuning_report(tuning::Grid, history, state)
120

121
    plotting = plotting_report(state.fields, state.parameter_scales, history)
82×
122

123
    # todo: remove collects?
124
    return (history=history, plotting=plotting)
41×
125

126
end
127

128
function default_n(tuning::Grid, user_range)
129
    ranges, resolutions =
88×
130
        process_grid_range(user_range, tuning.resolution, -1)
131

132
    resolutions = adjusted_resolutions(tuning.goal, ranges, resolutions)
51×
133
    len(t::Tuple{NumericRange,Integer}) = length(iterator(t[1], t[2]))
165×
134
    len(t::Tuple{NominalRange,Integer}) = t[2]
28×
135
    return prod(len.(zip(ranges, resolutions)))
51×
136

137
end
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2023 Coveralls, Inc