Contrastive Methods¶
Contrastive methods train against a pool of cached non-optimal solutions, treated as negative examples. solve_ratio controls how often new instances are solved exactly during training. dataset seeds the pool and is required by these methods. See Solution Pool for details on the solution-pool mechanism.
The training loops on this page build on the Common Setup from Training Methods.
Noise Contrastive Estimation (NCE)¶
NCE [1] is a surrogate loss based on negative examples. It uses a small set of non-optimal solutions as negative samples to maximize the predicted-cost margin between the optimal solution and the rest.
Let \(\Gamma\) be the cached pool of feasible solutions. For a minimization problem, NCE averages the predicted-cost margin between \(\mathbf{w}^*(\mathbf{c})\) and every member of the pool,
(If \(\mathbf{w}^*(\mathbf{c}) \in \Gamma\), its term contributes zero and the sum effectively averages over the negatives.) The gradient has a closed form that requires no solver call in the backward pass,
For a fixed \(\Gamma\), this update direction stays constant per instance. solve_ratio controls how often the pool is refreshed.
- pyepo.func.NCE
alias of
noiseContrastiveEstimation
Training loop:
nce = pyepo.func.NCE(optmodel, processes=1, solve_ratio=0.05, dataset=dataset)
for epoch in range(20):
for x, c, w, z in dataloader:
cp = predmodel(x)
loss = nce(cp, w)
optimizer.zero_grad()
loss.backward()
optimizer.step()
Contrastive MAP (CMAP)¶
CMAP [1] is a special case of NCE that uses only the lowest predicted-cost negative sample.
CMAP keeps only the most-violating member of the pool, the one with the smallest predicted-cost objective, yielding a max-margin contrast against the true optimum. For a minimization problem,
If \(\mathbf{w}^*(\mathbf{c}) \in \Gamma\), that entry contributes a zero margin, so the loss is non-negative and vanishes precisely when the predicted costs already make \(\mathbf{w}^*(\mathbf{c})\) the minimizer over \(\Gamma\).
- pyepo.func.CMAP
alias of
contrastiveMAP
Training loop:
cmap = pyepo.func.CMAP(optmodel, processes=1, solve_ratio=0.05, dataset=dataset)
for epoch in range(20):
for x, c, w, z in dataloader:
cp = predmodel(x)
loss = cmap(cp, w)
optimizer.zero_grad()
loss.backward()
optimizer.step()
Footnotes