diff --git a/docs/src/tutorials/warcraft.jl b/docs/src/tutorials/warcraft.jl index 9b6d199..13f21ba 100644 --- a/docs/src/tutorials/warcraft.jl +++ b/docs/src/tutorials/warcraft.jl @@ -25,10 +25,10 @@ train_dataset, test_dataset = dataset[1:45], dataset[46:50] sample = test_dataset[1] # `x` correspond to the input features, i.e. the input image (3D array) in the Warcraft benchmark case: x = sample.x -# `θ` correspond to the true unknown terrain weights. We use the opposite of the true weights in order to formulate the optimization problem as a maximization problem: -θ_true = sample.θ -# `y` correspond to the optimal shortest path, encoded as a binary matrix: -y_true = sample.y +# `θ_true` correspond to the true unknown terrain weights. We use the opposite of the true weights in order to formulate the optimization problem as a maximization problem: +θ_true = sample.θ_true +# `y_true` correspond to the optimal shortest path, encoded as a binary matrix: +y_true = sample.y_true # `instance` is not used in this benchmark, therefore set to nothing: isnothing(sample.instance) @@ -50,7 +50,7 @@ maximizer = generate_maximizer(b; dijkstra=true) # In the case o fthe Warcraft benchmark, the method has an additional keyword argument to chose the algorithm to use: Dijkstra's algorithm or Bellman-Ford algorithm. y = maximizer(θ) # As we can see, currently the pipeline predicts random noise as cell weights, and therefore the maximizer returns a straight line path. -plot_data(b, DataSample(; x, θ, y)) +plot_data(b, DataSample(; x, θ_true=θ, y_true=y)) # We can evaluate the current pipeline performance using the optimality gap metric: starting_gap = compute_gap(b, test_dataset, model, maximizer) @@ -70,7 +70,7 @@ opt_state = Flux.setup(Adam(1e-3), model) loss_history = Float64[] for epoch in 1:50 val, grads = Flux.withgradient(model) do m - sum(loss(m(sample.x), sample.y) for sample in train_dataset) / length(train_dataset) + sum(loss(m(x), y_true) for (; x, y_true) in train_dataset) / length(train_dataset) end Flux.update!(opt_state, model, grads[1]) push!(loss_history, val) @@ -85,4 +85,4 @@ final_gap = compute_gap(b, test_dataset, model, maximizer) # θ = model(x) y = maximizer(θ) -plot_data(b, DataSample(; x, θ, y)) +plot_data(b, DataSample(; x, θ_true=θ, y_true=y)) diff --git a/src/FixedSizeShortestPath/FixedSizeShortestPath.jl b/src/FixedSizeShortestPath/FixedSizeShortestPath.jl index 874fbe1..7eea5a3 100644 --- a/src/FixedSizeShortestPath/FixedSizeShortestPath.jl +++ b/src/FixedSizeShortestPath/FixedSizeShortestPath.jl @@ -132,7 +132,10 @@ function Utils.generate_dataset( # Label solutions solutions = shortest_path_maximizer.(costs) - return [DataSample(; x=x, θ=θ, y=y) for (x, θ, y) in zip(features, costs, solutions)] + return [ + DataSample(; x, θ_true, y_true) for + (x, θ_true, y_true) in zip(features, costs, solutions) + ] end """ diff --git a/src/PortfolioOptimization/PortfolioOptimization.jl b/src/PortfolioOptimization/PortfolioOptimization.jl index 3fdead6..b881909 100644 --- a/src/PortfolioOptimization/PortfolioOptimization.jl +++ b/src/PortfolioOptimization/PortfolioOptimization.jl @@ -110,7 +110,10 @@ function Utils.generate_dataset( maximizer = Utils.generate_maximizer(bench) solutions = maximizer.(costs) - return [DataSample(; x=x, θ=θ, y=y) for (x, θ, y) in zip(features, costs, solutions)] + return [ + DataSample(; x, θ_true, y_true) for + (x, θ_true, y_true) in zip(features, costs, solutions) + ] end """ diff --git a/src/SubsetSelection/SubsetSelection.jl b/src/SubsetSelection/SubsetSelection.jl index 64d353d..7d05135 100644 --- a/src/SubsetSelection/SubsetSelection.jl +++ b/src/SubsetSelection/SubsetSelection.jl @@ -73,7 +73,10 @@ function Utils.generate_dataset( mapping.(features) end solutions = top_k.(costs, k) - return [DataSample(; x=x, θ=θ, y=y) for (x, θ, y) in zip(features, costs, solutions)] + return [ + DataSample(; x, θ_true, y_true) for + (x, θ_true, y_true) in zip(features, costs, solutions) + ] end """ diff --git a/src/Utils/data_sample.jl b/src/Utils/data_sample.jl index c5eb93b..33b7bb4 100644 --- a/src/Utils/data_sample.jl +++ b/src/Utils/data_sample.jl @@ -9,10 +9,10 @@ $TYPEDFIELDS @kwdef struct DataSample{F,S,C,I} "features" x::F - "costs" - θ::C = nothing - "solution" - y::S = nothing - "instance" + "target cost parameters (optional)" + θ_true::C = nothing + "target solution (optional)" + y_true::S = nothing + "instance object (optional)" instance::I = nothing end diff --git a/src/Utils/interface.jl b/src/Utils/interface.jl index a310c13..44b21fa 100644 --- a/src/Utils/interface.jl +++ b/src/Utils/interface.jl @@ -73,8 +73,8 @@ function compute_gap( for sample in dataset x = sample.x - θ̄ = sample.θ - ȳ = sample.y + θ̄ = sample.θ_true + ȳ = sample.y_true θ = statistical_model(x) y = maximizer(θ) target_obj = objective_value(bench, θ̄, ȳ) diff --git a/src/Warcraft/Warcraft.jl b/src/Warcraft/Warcraft.jl index 5a20823..b577f54 100644 --- a/src/Warcraft/Warcraft.jl +++ b/src/Warcraft/Warcraft.jl @@ -87,12 +87,14 @@ The keyword argument `θ_true` is used to set the color range of the weights plo function Utils.plot_data( ::WarcraftBenchmark, sample::DataSample; - θ_true=sample.θ, + θ_true=sample.θ_true, θ_title="Weights", y_title="Path", kwargs..., ) - (; x, y, θ) = sample + x = sample.x + y = sample.y_true + θ = sample.θ_true im = dropdims(x; dims=4) img = convert_image_for_plot(im) p1 = Plots.plot( diff --git a/src/Warcraft/utils.jl b/src/Warcraft/utils.jl index c96aaf5..b6c040a 100644 --- a/src/Warcraft/utils.jl +++ b/src/Warcraft/utils.jl @@ -40,7 +40,7 @@ function create_dataset(decompressed_path::String, nb_samples::Int) ] Y = [BitMatrix(terrain_labels[:, :, i]) for i in 1:N] WG = [-terrain_weights[:, :, i] for i in 1:N] - return [DataSample(; x, y, θ) for (x, y, θ) in zip(X, Y, WG)] + return [DataSample(; x, y_true, θ_true) for (x, y_true, θ_true) in zip(X, Y, WG)] end """ diff --git a/test/fixed_size_shortest_path.jl b/test/fixed_size_shortest_path.jl index 495655b..257e7b2 100644 --- a/test/fixed_size_shortest_path.jl +++ b/test/fixed_size_shortest_path.jl @@ -18,9 +18,7 @@ @test gap >= 0 for sample in dataset - x = sample.x - θ_true = sample.θ - y_true = sample.y + (; x, θ_true, y_true) = sample @test all(θ_true .< 0) @test size(x) == (p,) @test length(θ_true) == A diff --git a/test/portfolio_optimization.jl b/test/portfolio_optimization.jl index e57c9d3..7c983d7 100644 --- a/test/portfolio_optimization.jl +++ b/test/portfolio_optimization.jl @@ -10,9 +10,7 @@ maximizer = generate_maximizer(b) for sample in dataset - x = sample.x - θ_true = sample.θ - y_true = sample.y + (; x, θ_true, y_true) = sample @test size(x) == (p,) @test length(θ_true) == d @test length(y_true) == d @@ -24,6 +22,6 @@ y = maximizer(θ) @test length(y) == d - @test sum(y) <= 1 + @test sum(y) <= 1 + 1e-6 end end diff --git a/test/subset_selection.jl b/test/subset_selection.jl index 91db249..694f7f4 100644 --- a/test/subset_selection.jl +++ b/test/subset_selection.jl @@ -16,9 +16,7 @@ maximizer = generate_maximizer(b) for (i, sample) in enumerate(dataset) - x = sample.x - θ_true = sample.θ - y_true = sample.y + (; x, θ_true, y_true) = sample @test size(x) == (n,) @test length(θ_true) == n @test length(y_true) == n diff --git a/test/warcraft.jl b/test/warcraft.jl index 206ee80..5d52cdd 100644 --- a/test/warcraft.jl +++ b/test/warcraft.jl @@ -19,9 +19,7 @@ @test gap >= 0 for (i, sample) in enumerate(dataset) - x = sample.x - θ_true = sample.θ - y_true = sample.y + (; x, θ_true, y_true) = sample @test size(x) == (96, 96, 3, 1) @test all(θ_true .<= 0) @test isnothing(sample.instance)