Skip to content

Commit 6ffa47d

Browse files
committed
update docs and tutorial
1 parent ce2a9b0 commit 6ffa47d

File tree

10 files changed

+207
-150
lines changed

10 files changed

+207
-150
lines changed

docs/Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
4+
InferOpt = "4846b161-c94e-4150-8dac-c7ae193c601f"
35
InferOptBenchmarks = "2fbe496a-299b-4c81-bab5-c44dfc55cf20"
6+
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
7+
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

docs/make.jl

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
11
using Documenter
22
using InferOptBenchmarks
3+
using Literate
34

45
cp(joinpath(@__DIR__, "..", "README.md"), joinpath(@__DIR__, "src", "index.md"); force=true)
56

7+
md_dir = joinpath(@__DIR__, "src")
8+
tutorial_dir = joinpath(@__DIR__, "src", "tutorials")
9+
tutorial_files = readdir(tutorial_dir)
10+
md_tutorial_files = [split(file, ".")[1] * ".md" for file in tutorial_files]
11+
12+
for file in tutorial_files
13+
filepath = joinpath(tutorial_dir, file)
14+
Literate.markdown(filepath, md_dir; documenter=true, execute=false)
15+
end
16+
617
makedocs(;
718
modules=[InferOptBenchmarks, InferOptBenchmarks.Warcraft],
819
authors="Members of JuliaDecisionFocusedLearning",
920
sitename="InferOptBenchmarks.jl",
1021
format=Documenter.HTML(),
1122
pages=[
12-
"Home" => "index.md", #
13-
"API reference" => [
14-
"interface.md",
15-
"decision_focused.md",
16-
"warcraft.md", #
17-
],
23+
"Home" => "index.md",
24+
"Tutorials" => md_tutorial_files,
25+
"API reference" =>
26+
["api/interface.md", "api/decision_focused.md", "api/warcraft.md"],
1827
],
1928
)
2029

30+
for file in md_tutorial_files
31+
filepath = joinpath(md_dir, file)
32+
rm(filepath)
33+
end
34+
2135
deploydocs(;
2236
repo="github.com/JuliaDecisionFocusedLearning/InferOptBenchmarks.jl", devbranch="main"
2337
)
File renamed without changes.
File renamed without changes.
File renamed without changes.

docs/src/tutorials/warcraft.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# # Path-finding on image maps
2+
3+
using InferOptBenchmarks
4+
using InferOpt
5+
using Flux
6+
using Plots
7+
8+
b = WarcraftBenchmark()
9+
10+
dataset = generate_dataset(b, 50)
11+
model = generate_statistical_model(b)
12+
maximizer = generate_maximizer(b)
13+
14+
train_dataset, test_dataset = dataset[1:45], dataset[46:50]
15+
X_train = train_dataset.features
16+
Y_train = train_dataset.solutions
17+
18+
perturbed_maximizer = PerturbedMultiplicative(maximizer; ε=0.2, nb_samples=100)
19+
loss = FenchelYoungLoss(perturbed_maximizer)
20+
21+
starting_gap = compute_gap(b, test_dataset, model, maximizer)
22+
23+
opt_state = Flux.setup(Adam(1e-3), model)
24+
loss_history = Float64[]
25+
for epoch in 1:50
26+
val, grads = Flux.withgradient(model) do m
27+
sum(loss(m(x), y) for (x, y) in zip(X_train, Y_train)) / length(train_dataset)
28+
end
29+
Flux.update!(opt_state, model, grads[1])
30+
push!(loss_history, val)
31+
end
32+
33+
plot(loss_history; xlabel="Epoch", ylabel="Loss", title="Training loss")
34+
35+
#
36+
37+
final_gap = compute_gap(b, test_dataset, model, maximizer)

src/Warcraft/dataset.jl

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -42,84 +42,84 @@ function create_dataset(decompressed_path::String, nb_samples::Int=10000)
4242
return InferOptDataset(; features=X, solutions=Y, costs=WG)
4343
end
4444

45-
"""
46-
$TYPEDSIGNATURES
45+
# """
46+
# $TYPEDSIGNATURES
4747

48-
Split a dataset contained in `X` into train and test datasets.
49-
The proportion of the initial dataset kept in the train set is `train_percentage`.
50-
"""
51-
function train_test_split(X::AbstractVector, train_percentage::Real=0.5)
52-
N = length(X)
53-
N_train = floor(Int, N * train_percentage)
54-
N_test = N - N_train
55-
train_ind, test_ind = 1:N_train, (N_train + 1):(N_train + N_test)
56-
X_train, X_test = X[train_ind], X[test_ind]
57-
return X_train, X_test
58-
end
48+
# Split a dataset contained in `X` into train and test datasets.
49+
# The proportion of the initial dataset kept in the train set is `train_percentage`.
50+
# """
51+
# function train_test_split(X::AbstractVector, train_percentage::Real=0.5)
52+
# N = length(X)
53+
# N_train = floor(Int, N * train_percentage)
54+
# N_test = N - N_train
55+
# train_ind, test_ind = 1:N_train, (N_train + 1):(N_train + N_test)
56+
# X_train, X_test = X[train_ind], X[test_ind]
57+
# return X_train, X_test
58+
# end
5959

60-
"""
61-
$TYPEDSIGNATURES
60+
# """
61+
# $TYPEDSIGNATURES
6262

63-
Convert `image` to the proper data format to enable plots in Julia.
64-
"""
65-
function convert_image_for_plot(image::Array{Float32,3})::Array{RGB{N0f8},2}
66-
new_img = Array{RGB{N0f8},2}(undef, size(image)[1], size(image)[2])
67-
for i in 1:size(image)[1]
68-
for j in 1:size(image)[2]
69-
new_img[i, j] = RGB{N0f8}(image[i, j, 1], image[i, j, 2], image[i, j, 3])
70-
end
71-
end
72-
return new_img
73-
end
63+
# Convert `image` to the proper data format to enable plots in Julia.
64+
# """
65+
# function convert_image_for_plot(image::Array{Float32,3})::Array{RGB{N0f8},2}
66+
# new_img = Array{RGB{N0f8},2}(undef, size(image)[1], size(image)[2])
67+
# for i in 1:size(image)[1]
68+
# for j in 1:size(image)[2]
69+
# new_img[i, j] = RGB{N0f8}(image[i, j, 1], image[i, j, 2], image[i, j, 3])
70+
# end
71+
# end
72+
# return new_img
73+
# end
7474

75-
"""
76-
$TYPEDSIGNATURES
75+
# """
76+
# $TYPEDSIGNATURES
7777

78-
Plot the image `im`, the weights `weights`, and the path `path` on the same Figure.
79-
"""
80-
function plot_image_path(x, y; y_title="Path")
81-
im = dropdims(x; dims=4)
82-
img = convert_image_for_plot(im)
83-
p1 = Plots.plot(
84-
img; aspect_ratio=:equal, framestyle=:none, size=(300, 300), title="Terrain image"
85-
)
86-
p3 = Plots.plot(
87-
Gray.(y .* 0.7);
88-
aspect_ratio=:equal,
89-
framestyle=:none,
90-
size=(300, 300),
91-
title=y_title,
92-
)
93-
return plot(p1, p3; layout=(1, 2), size=(600, 300))
94-
end
78+
# Plot the image `im`, the weights `weights`, and the path `path` on the same Figure.
79+
# """
80+
# function plot_image_path(x, y; y_title="Path")
81+
# im = dropdims(x; dims=4)
82+
# img = convert_image_for_plot(im)
83+
# p1 = Plots.plot(
84+
# img; aspect_ratio=:equal, framestyle=:none, size=(300, 300), title="Terrain image"
85+
# )
86+
# p3 = Plots.plot(
87+
# Gray.(y .* 0.7);
88+
# aspect_ratio=:equal,
89+
# framestyle=:none,
90+
# size=(300, 300),
91+
# title=y_title,
92+
# )
93+
# return plot(p1, p3; layout=(1, 2), size=(600, 300))
94+
# end
9595

96-
"""
97-
$TYPEDSIGNATURES
96+
# """
97+
# $TYPEDSIGNATURES
9898

99-
Plot the train and test losses, as well as the train and test gaps computed over epochs.
100-
"""
101-
function plot_loss_and_gap(losses::Matrix{Float64}, gaps::Matrix{Float64}; filepath=nothing)
102-
nb_epochs = length(losses)
103-
p1 = plot(
104-
collect(1:nb_epochs),
105-
losses;
106-
title="Loss",
107-
xlabel="epochs",
108-
ylabel="loss",
109-
label=["train" "test"],
110-
)
111-
p2 = plot(
112-
collect(0:nb_epochs),
113-
gaps;
114-
title="Gap",
115-
xlabel="epochs",
116-
ylabel="ratio",
117-
label=["train" "test"],
118-
)
119-
pl = plot(p1, p2; layout=(1, 2))
120-
isnothing(filepath) || Plots.savefig(pl, filepath)
121-
return pl
122-
end
99+
# Plot the train and test losses, as well as the train and test gaps computed over epochs.
100+
# """
101+
# function plot_loss_and_gap(losses::Matrix{Float64}, gaps::Matrix{Float64}; filepath=nothing)
102+
# nb_epochs = length(losses)
103+
# p1 = plot(
104+
# collect(1:nb_epochs),
105+
# losses;
106+
# title="Loss",
107+
# xlabel="epochs",
108+
# ylabel="loss",
109+
# label=["train" "test"],
110+
# )
111+
# p2 = plot(
112+
# collect(0:nb_epochs),
113+
# gaps;
114+
# title="Gap",
115+
# xlabel="epochs",
116+
# ylabel="ratio",
117+
# label=["train" "test"],
118+
# )
119+
# pl = plot(p1, p2; layout=(1, 2))
120+
# isnothing(filepath) || Plots.savefig(pl, filepath)
121+
# return pl
122+
# end
123123

124124
"""
125125
$TYPEDSIGNATURES

test/code.jl

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,38 +17,3 @@ end
1717
using Documenter
1818
Documenter.doctest(InferOptBenchmarks)
1919
end
20-
21-
# @testset verbose = true "InferOptBenchmarks" begin
22-
# @testset verbose = true "Formalities" begin
23-
# @testset "Aqua" begin
24-
# Aqua.test_all(
25-
# InferOptBenchmarks; ambiguities=false, deps_compat=(check_extras = false)
26-
# )
27-
# end
28-
# @testset "JET" begin
29-
# JET.test_package(InferOptBenchmarks; target_defined_modules=true)
30-
# end
31-
# @testset "JuliaFormatter" begin
32-
# @test JuliaFormatter.format(InferOptBenchmarks; verbose=false, overwrite=false)
33-
# end
34-
# @testset "Documenter" begin
35-
# Documenter.doctest(InferOptBenchmarks)
36-
# end
37-
# end
38-
39-
# @testset "Warcraft" begin
40-
# include("WarcraftTest/WarcraftTest.jl")
41-
# end
42-
43-
# @testset "Shortest paths" begin
44-
# include("FixedSizeShortestPathTest/FixedSizeShortestPathTest.jl")
45-
# end
46-
47-
# @testset "Portfolio Optimization" begin
48-
# include("PortfolioOptimizationTest/PortfolioOptimizationTest.jl")
49-
# end
50-
51-
# @testset "Subset Selection" begin
52-
# include("SubsetSelectionTest/SubsetSelectionTest.jl")
53-
# end
54-
# end

test/portfolio_optimization.jl

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,36 @@
1-
# @testitem "Portfolio Optimization" begin
2-
# using InferOptBenchmarks
3-
# using InferOpt
4-
# using Flux
5-
# using Zygote
6-
7-
# b = PortfolioOptimizationBenchmark()
8-
9-
# dataset = generate_dataset(b, 100)
10-
# model = generate_statistical_model(b)
11-
# maximizer = generate_maximizer(b)
12-
13-
# train_dataset, test_dataset = dataset[1:50], dataset[50:100]
14-
# X_train = train_dataset.features
15-
# Y_train = train_dataset.solutions
16-
17-
# perturbed_maximizer = PerturbedAdditive(maximizer; ε=0.1, nb_samples=100)
18-
# loss = FenchelYoungLoss(perturbed_maximizer)
19-
20-
# starting_gap = compute_gap(b, test_dataset, model, maximizer)
21-
22-
# opt_state = Flux.setup(Adam(), model)
23-
# loss_history = Float64[]
24-
# for epoch in 1:50
25-
# val, grads = Flux.withgradient(model) do m
26-
# sum(loss(m(x), y) for (x, y) in zip(X_train, Y_train)) / length(train_dataset)
27-
# end
28-
# Flux.update!(opt_state, model, grads[1])
29-
# push!(loss_history, val)
30-
# end
31-
32-
# final_gap = compute_gap(b, test_dataset, model, maximizer)
33-
34-
# @test loss_history[end] < loss_history[1]
35-
# @test final_gap < starting_gap
36-
# end
1+
@testitem "Portfolio Optimization" begin
2+
using InferOptBenchmarks
3+
using InferOpt
4+
using Flux
5+
using Zygote
6+
7+
b = PortfolioOptimizationBenchmark()
8+
9+
dataset = generate_dataset(b, 100)
10+
model = generate_statistical_model(b)
11+
maximizer = generate_maximizer(b)
12+
13+
train_dataset, test_dataset = dataset[1:50], dataset[50:100]
14+
X_train = train_dataset.features
15+
Y_train = train_dataset.solutions
16+
17+
perturbed_maximizer = PerturbedAdditive(maximizer; ε=0.1, nb_samples=1)
18+
loss = FenchelYoungLoss(perturbed_maximizer)
19+
20+
starting_gap = compute_gap(b, test_dataset, model, maximizer)
21+
22+
opt_state = Flux.setup(Adam(), model)
23+
loss_history = Float64[]
24+
for epoch in 1:50
25+
val, grads = Flux.withgradient(model) do m
26+
sum(loss(m(x), y) for (x, y) in zip(X_train, Y_train)) / length(train_dataset)
27+
end
28+
Flux.update!(opt_state, model, grads[1])
29+
push!(loss_history, val)
30+
end
31+
32+
final_gap = compute_gap(b, test_dataset, model, maximizer)
33+
34+
@test loss_history[end] < loss_history[1]
35+
@test final_gap < starting_gap / 10
36+
end

0 commit comments

Comments
 (0)