Skip to main content

HomOps Reference

Softmax

Turn logits into probabilities along one axis. Client side only.

SmClient
RunsClient only
Changes shapeNo
Changes scaleNo
Levels spent0
RotatesNo
KeysNone

What it does

Softmax applies softmax along one axis: exp(x_i) / Σ exp(x_j). The output has the same shape as the input, with the values along dim normalized to sum to 1.
Softmax involves exponentials and division, so it never runs on encrypted data; there is no encrypted softmax in the operator set. It is a client-only operator, almost always the last step of client_post: the server returns encrypted logits, the client decrypts and softmaxes them into class probabilities.

Signature

Softmax(dim)
No set_data.

Parameters

ParameterTypeDefaultDescription
dimintrequiredThe axis to normalize along (PyTorch semantics; negative indices allowed). Use the axis holding the class logits: 0 for a 1D output like (10,), -1 for batched rows.

Requirements

  • Client placement. Typically the tail of client_post, after the final linear layer. A Softmax the server would have to execute fails at compile time.

Shape effect - no

The output shape equals the input shape; only the values along dim are normalized.

Scale effect - no

Softmax runs on decrypted floating-point values; the ciphertext scale is not involved.

Level budget

Zero. Nothing encrypted happens here.

Keys

None.

Example

A digit classifier: the encrypted part ends with logits, the client turns them into probabilities:
pipeline.pyPYTHON
from lattica_build.client_ops import Softmax
from lattica_build.operators import HomLinear, HomSquare, HomReshape
from lattica_build.base_classes.hom_pipeline import HomomorphicPipeline
from lattica_build.operators.composite.sequential import SequentialHomOp

pipeline = HomomorphicPipeline(
    client_pre=[HomReshape((28 * 28, 1))],
    hom=SequentialHomOp(
        HomLinear((50, 28 * 28), bias=False, with_modswitch=False),
        HomSquare(with_modswitch=False),
        HomLinear((10, 50), bias=False, with_modswitch=False),
    ),
    client_post=[HomReshape((10,)), Softmax(0)],
    input_shape=(28, 28),
)
For batched output, normalize the last axis instead:
pipeline.pyPYTHON
client_post=[Softmax(-1)]

See also