Getting Started
Full pipeline
This example converts an MLP to a tropical rational function, computes its linear regions, and counts its stored monomials.
using TropicalNN
W, b, thresholds = random_mlp([2, 4, 2, 1])
q = tropicalize(W, b, thresholds)
regions = linear_regions(q[1]; mode = HiGHSMode())
println("Linear regions: ", length(regions))
println("Stored monomials: ", monomial_count(q[1]))Tropical arithmetic
f = Signomial([1, 2, 3], [[1 // 1, 0 // 1], [0 // 1, 1 // 1], [1 // 1, 1 // 1]])
g = Signomial([0, 4, -5], [[1 // 1, 7 // 1], [0 // 1, 1 // 1], [9 // 1, 1 // 1]])
h = f + g # Pointwise maximum.
p = f * g # Ordinary sum of the represented functions.Control expression growth
You can use quicksum and prune to accelerate computation and reduce intermediate expression size:
mode = HiGHSMode(threads = 4)
q_reduced = tropicalize(
W,
b,
thresholds;
quicksum = true,
prune = true,
elim_mode = mode,
)
pruned = prune(q_reduced[1]; mode = mode)Create a neural network
Create one layer for each affine map and each activation. NeuralNetwork applies the layers in the given order.
network = NeuralNetwork(
AffineLayer([1 0; 0 1], [0, 0]),
ActivationLayer(relu(Int), 2),
AffineLayer([1 1], [0])
)
q = tropicalize(network)
layer_maps = tropicalize_layers(network)
regions = linear_regions(network; mode = HiGHSMode())
input_dimension(network) # 2
output_dimension(network) # 1tropicalize_layers converts each layer separately. The result contains one vector of rational signomials for each layer. tropicalize composes the layer maps. It returns one vector for the complete network.
linear_regions(network; mode) uses tropicalize_layers internally and computes the regions one layer at a time, without constructing the complete tropical expression.
All layers in a network must use the same scalar type. The default type for an activation is Rational{BigInt}. If an affine layer uses a different type, give that type to the activation. For example, relu(Int) matches the integer affine layers above. maxout(Float32, 2) creates a Float32 activation that takes the maximum of two inputs.
ActivationLayer(relu(Int), 2) creates two ReLU units. Each unit receives one input. ActivationLayer(maxout(Int, 2), 3) creates three maxout units. Each unit receives a separate block of two inputs.