Neural Knapsack
By: Shayan Hashemi
Tags: Deep Learning, Supervised Learning, Unsupervised Learning, Knapsack Problem, Neural Networks

Neural Knapsack

In some cases of data science, it is needed to run a specific algorithm on the output of the model to get the result. Sometimes it is as simple as finding the index of the maximum output, other times, more advanced algorithms are needed. You may run the algorithm after running the inference. However, designing a model that can run the algorithm internally have some advantages. Solving the problem of knapsack using neural networks not only helps the model run the knapsack algorithm internally but also allows the model to be trained end to end.

What is the knapsack problem?

My lovely computer algorithm teacher explained the knapsack problem to me using this story. Think of a thief on a robbery. There are some items available to be robbed. Each item has its own weight and value. The thief has a knapsack with a determined capacity which indicates the maximum amount of weight that he (or she) can carry. The thief’s profit is calculated via summing over the chosen item’s values. Our goal is to maximize the profit while keeping the sum of chosen items’ weights less than the knapsack’s capacity.

According to Wikipedia:

“Given a set of items, each with a weight and a value, determine the number of each item to include in a collection so that the total weight is less than or equal to a given limit and the total value is as large as possible. It derives its name from the problem faced by someone who is constrained by a fixed-size knapsack and must fill it with the most valuable items”

In this article, we try to solve the knapsack problem using neural networks.

The data

The first step is to prepare data. We use random integers for items’ weights, items’ prices and the capacity of the knapsack. After creating the problem, we use brute force to find the optimum solution.

A generated knapsack problem:

Weights: [13, 10, 13, 7, 2]

Prices: [8, 7, 9, 6, 4]

Capacity: 27

Optimum solution: [0, 1, 1, 0, 1]

Normalizing the input is a part of every machine learning project as it helps the model to generalize better. To normalize each knapsack problem:

Divide the prices by the maximum price of the problem.

Divide the weights by the capacity.

Remove the capacity from the inputs as it is embedded in the weights now.

The normalized form of previously created knapsack problem:

Weights: [0.48, 0.37, 0.48, 0.26, 0.07]

Prices: [0.89, 0.44, 1.00, 0.67, 0.44]

Optimum solution: [0, 1, 1, 0, 1]

The dataset consists of ten thousand samples for training and two hundred for testing.

The model

The model we choose for this task is a fairly simple model. It has two inputs and an output. At first, the inputs are concatenated together. The result enters two sequential dense layers activated by sigmoid non-linearity. The output of the second dense layer is the output of the model. Implementation of the model in Keras:

The following image visualizes the architecture of the model:

Model architecture

The metrics

The knapsack problem requires metrics other than the binary classification accuracy for evaluation. The first metric we introduce is called “overpricing”. As its name suggests, it evaluates the average difference between the prices of the chosen items and the optimum solution. It is implemented in Keras framework as follow:

Another vital metric is the amount of capacity used more than the knapsack’s capacity. The “space violation” is the positive difference between the sum of the chosen items’ weights and the knapsack’s capacity. It may be implemented in Keras as follow:

Supervised approach

In the supervised approach, we input weights and prices to the model and expect the optimum solution as the output. In this process the model trains using the cross-entropy loss function.

After training the model with the supervised approach, we got the following results after 512 epochs.

Model results(Train/Test):

Loss: 0.24 / 0.24

Binary accuracy: 0.89 / 0.89

Space violation: 0.04 / 0.06

Overpricing: 0.06 / 0.08

Unfortunately, there are two fundamental problems with the supervised approach:

The optimum solution is mandatory to start training.

We don’t have any control over the space violation and overpricing.

We will try to address these problems in the unsupervised approach.

Unsupervised approach

We want to train the model without computing the optimum solution. Hence, we need a new loss function. Accordingly, we subsequently define the w, p, c and o as the items’ weights, the items’ prices, the knapsack’s capacity and the model’s output. At first, we need to maximize the sum of chosen items’ prices. It may be calculated via:

Meanwhile, we want our picks not to surpass the knapsack’s capacity. This value may be formulated via:

Finally, we want to maximize the TotalPrice while minimizing SpaceViolation. This could be formulated via:

In order to have control over the SpaceViolation, we add the λ coefficient to the second term. The final loss formula is:

We can implement the new loss in Keras like this:

Using this loss function, we train the neural network in an unsupervised fashion.

Note 1: The λ parameter is named cvc in the Keras implementation of knapsack loss.

Note 2: Although we receive the optimum solution (y_true) as a function argument, we do not use it for computing the loss. We can’t either omit the argument as it is a Keras constraint to receive both predicted and expected outputs in the loss functions.

Note3: The capacity of the knapsack is equal to 1 as we normalized the data.

After training the model with the unsupervised approach, we got the following results after 512 epochs.

Model results(Train/Test):

Loss: -1.83 / -1.75

Binary accuracy: 0.89 / 0.89

Space violation: 0.05 / 0.06

Overpricing: 0.12 / 0.14

Increasing the value of cvc (λ) will cause in less space violation and overpricing. It will also reduce the binary accuracy if it is increased too much. I found that a reasonable value for it might be 5.75.

Conclusion

As discussed before, we solved the problem of knapsack using neural networks while the gradient can pass through the network. So our model could be trained end to end using any variation of the back-propagation algorithm.

This article could be used in recommender systems, especially the ones which recommends multiple items while maintaining space usage (like the banner Ads).