API Reference¶
Auto-generated from the docstrings. See Quick Start for how the pieces fit together.
Layers¶
The sparse layers live in sparsepixels.layers. InputReduce produces the sparse representation, and the rest consume it.
InputReduce ¶
InputReduce(n=30, threshold=0.0, beta_n=0.005, beta_maskedE=1.0, learn_n=True, learn_threshold=True, tau_threshold=0.05, tau_n=1.0, **kwargs)
Bases: Layer
Reduce a dense image to its first n active pixels for sparse FPGA inference.
Keeps the first n pixels whose first channel is above threshold, in raster order, and zeroes the rest, returning the masked image together with a 0/1 keep mask that the following sparse layers use as the sparse representation.
The budget n and the threshold can be learned during training (the default) so they need not be tuned by hand; set learn_n or learn_threshold to False to keep either fixed (both False gives the plain, non-learnable selection). The selection is always exact -- the learnable versions only shape the gradient, so the layer behaves identically at inference and stays deployable. When n is learned, a penalty of weight beta_n nudges it smaller, trading a little accuracy for lower FPGA latency and resources; it starts at n and can range over [1, H*W]. An optional penalty of weight beta_maskedE discourages masking pixel intensity, giving the threshold (and n) a restoring force so a trainable threshold settles near the noise floor instead of over-masking signal. After training, read the values to deploy from the n_max_pixels and threshold properties.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n
|
initial pixel budget, and the fixed budget when learn_n is False. |
30
|
|
threshold
|
initial activity threshold on the first channel, fixed when learn_threshold is False. |
0.0
|
|
beta_n
|
weight of the budget penalty added to the loss (0 disables it). |
0.005
|
|
beta_maskedE
|
weight of the masked-intensity penalty (0 disables it). Penalizes the fraction of pixel intensity that gets masked, so masking bright (signal) pixels is costly while masking dim (noise) pixels is cheap -- an adaptive, non-vanishing restoring force against over-masking. |
1.0
|
|
learn_n
|
make the pixel budget trainable. |
True
|
|
learn_threshold
|
make the threshold trainable. |
True
|
|
tau_threshold
|
softness of the threshold surrogate used to obtain gradients. |
0.05
|
|
tau_n
|
softness of the budget-cutoff surrogate used to obtain gradients. |
1.0
|
Source code in sparsepixels/layers.py
QConv2DSparse ¶
Bases: Layer
Quantized 2D convolution that operates on the sparse (active-pixel) representation.
Wraps an HGQ QConv2D: masks the input to the active pixels, convolves, adds a separately quantized per-filter bias on the nonzero outputs, applies the activation, then re-masks the output. This is numerically the same as a dense quantized conv restricted to the active pixels, which is what the HLS sparse_conv kernel computes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*conv_args
|
positional arguments forwarded to hgq.layers.QConv2D (e.g. filters, kernel_size). |
()
|
|
**conv_kwargs
|
keyword arguments forwarded to QConv2D (padding, strides, ...). use_bias, activation and bq_conf are handled here: the bias has its own weight and quantizer (bq_conf), and the activation is applied after the bias. |
{}
|
Call args
inputs: tuple (x, keep_mask) of the feature map and its keep mask.
Source code in sparsepixels/layers.py
AveragePooling2DSparse ¶
Bases: Layer
Average pooling on the sparse representation.
Average-pools the feature map and max-pools the keep mask, so a pooled cell stays active when any of its source pixels were active. Mirrors the HLS sparse_pooling_avg kernel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*pool_args
|
positional arguments forwarded to keras AveragePooling2D (e.g. pool_size). |
()
|
|
**pool_kwargs
|
keyword arguments forwarded to the pooling layers. |
{}
|
Call args
inputs: tuple (x, keep_mask) of the feature map and its keep mask.
Source code in sparsepixels/layers.py
MaxPooling2DSparse ¶
Bases: Layer
Max pooling on the sparse representation.
Max-pools both the feature map and the keep mask. Mirrors the HLS sparse_pooling_max kernel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*pool_args
|
positional arguments forwarded to keras MaxPooling2D (e.g. pool_size). |
()
|
|
**pool_kwargs
|
keyword arguments forwarded to the pooling layer. |
{}
|
Call args
inputs: tuple (x, keep_mask) of the feature map and its keep mask.
Source code in sparsepixels/layers.py
Data study¶
Utilities in sparsepixels.utils for picking a threshold and budget before training.
active_pixels_vs_threshold ¶
active_pixels_vs_threshold(x, thresholds=None, channel=0, percentiles=(25, 50, 75), plot=True, ax=None, save_path=None)
Study how the number of active pixels per image changes with the threshold.
For each candidate threshold, counts the active pixels (x[..., channel] > threshold) in every image and reports the mean, min, max and the given percentiles across the dataset. Use it to pick a threshold and an initial budget n: at your chosen threshold, a high percentile or the max tells you how many pixels the busiest images have.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
image array of shape (N, H, W, C). |
required | |
thresholds
|
thresholds to scan; defaults to 50 points across the data range. |
None
|
|
channel
|
channel used to decide activity (default 0, matching InputReduce). |
0
|
|
percentiles
|
percentiles of the per-image active-pixel count to report. |
(25, 50, 75)
|
|
plot
|
draw the curves (otherwise only the stats are computed). |
True
|
|
ax
|
optional Axes to draw into; when given, the figure is not shown here. |
None
|
Returns a dict with a threshold array plus mean, min, max and p
Source code in sparsepixels/utils.py
plot_reduced_examples ¶
plot_reduced_examples(x, n, threshold, indices=None, n_examples=5, channel=0, figsize=None, aspect=None, cmap='viridis', save_path=None)
Show what InputReduce keeps for a given budget n and threshold on a few images.
Each row shows the original image and, at the same intensity scale, the pixels that are kept (the first n active pixels in raster order), annotated with the kept and active counts. Use it to check that a candidate n and threshold keep the informative pixels.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
image array of shape (N, H, W, C). |
required | |
n
|
pixel budget (the first n active pixels are kept). |
required | |
threshold
|
activity threshold on the given channel. |
required | |
indices
|
which images to show; defaults to the first n_examples. |
None
|
|
n_examples
|
number of images to show when indices is not given. |
5
|
|
channel
|
channel used to decide activity (default 0). |
0
|
|
figsize
|
optional (width, height). |
None
|
|
aspect
|
imshow aspect: None keeps the natural pixel ratio, "auto" stretches each image to fill its panel (useful for very wide images), or a float scales the pixel height. |
None
|
|
cmap
|
colormap for the active pixels; empty pixels (at or below 0) are drawn white. For binary images a reversed map like "viridis_r" makes the hits dark on white. |
'viridis'
|
Source code in sparsepixels/utils.py
Training & monitoring¶
SparseTrainingMonitor ¶
Bases: Callback
Record sparse-model diagnostics into the training history each epoch.
Add it to the callbacks in model.fit; it stores these in the History so plot_history can show them next to the loss and your compiled metrics:
- n_max_pixels and threshold: the learned or fixed pixel budget and threshold of the InputReduce layer (suffixed with the layer name when there is more than one).
- ebops: total EBOPS over the quantized layers, a proxy for the quantized hardware cost. This monitor applies set_sparse_ebops_factor at the start of training, so the EBOPS (and its regularizer) reflect the sparse (active-pixel) compute without any manual call.
- loss_task, loss_ebops, loss_n, loss_maskedE: the training loss split into the task loss, the EBOPS penalty, the pixel-budget penalty and the masked-intensity penalty (the last present only when its weight beta_maskedE is nonzero), each already scaled by its weight so the parts add up to the loss.
plot_history ¶
Plot the training history recorded by SparseTrainingMonitor in one figure.
Shows the total loss and each compiled metric (train, and validation when present), the loss breakdown (task, EBOPS and budget penalties, in red) and the sparse diagnostics (n_max_pixels, threshold, ebops, in green). Panels are only created for keys that are present, so it works with or without a validation set. Single-line panels annotate their first and last values, and if early_stopping restored the best weights, a dashed line marks that epoch and its value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
history
|
the History returned by model.fit, or its .history dict. |
required | |
early_stopping
|
optional EarlyStopping callback; if it restored best weights, that epoch is marked. |
None
|
|
figsize
|
optional (width, height); chosen from the number of panels if omitted. |
None
|
|
ncols
|
number of columns in the panel grid. |
3
|
Source code in sparsepixels/utils.py
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | |
plot_layer_outputs ¶
plot_layer_outputs(model, x, index=0, layers=None, cmap='viridis', aspect='auto', max_channels=16, save_path=None)
Plot every layer's output for one input image, channel by channel.
Feeds one image through the model and draws one figure per layer, with that layer's channels stacked as rows on a common intensity scale (empty pixels in white) and the active-pixel count annotated per channel. Use it to spot where the sparse signals get over-compressed, e.g. a pooling layer merging the few active pixels of a track into far fewer, and adjust the architecture accordingly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
a functional keras model. |
required | |
x
|
image array of shape (N, H, W, C) or a single image (H, W, C). |
required | |
index
|
which image of x to feed. |
0
|
|
layers
|
layer names to show; defaults to every layer with a plottable output. |
None
|
|
cmap
|
colormap for the active values; exact zeros are drawn white. |
'viridis'
|
|
aspect
|
imshow aspect for the feature-map panels ("auto" fills each panel, None keeps the natural pixel ratio, a float scales the pixel height). |
'auto'
|
|
max_channels
|
cap on the number of channels drawn per layer. |
16
|
|
save_path
|
optional path; each layer's figure is saved with the layer name appended. |
None
|
Source code in sparsepixels/utils.py
freeze_quantization ¶
Freeze the quantization (and optionally the pixel budget) at the current learned values.
Sets every quantizer sublayer non-trainable and zeroes the WRAP integer-part decay, so the bit-width configuration stays exactly fixed afterwards; optionally also freezes the InputReduce budget. Use for two-stage training: after the quantization-aware stage converges, freeze, recompile with a lower learning rate, and fine-tune. The weights then adapt to the final bit assignment instead of a moving one, and early stopping effectively monitors the pure task loss since the frozen regularizer terms are constants.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
a keras model built with the quantized (HGQ) layers. |
required | |
freeze_budget
|
also set InputReduce layers non-trainable (a learnable budget n stops moving). |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
int |
the number of layers set non-trainable. Remember to call model.compile again. |
Source code in sparsepixels/utils.py
set_sparse_ebops_factor ¶
Correct each sparse conv's EBOPS for the fact that it only computes on the active pixels.
HGQ counts a conv's EBOPS as if it ran over the whole HW feature map, which overestimates a sparse conv that only touches about n_max_pixels of them. This scales each sparse conv's EBOPS by n_max_pixels / (HW) through HGQ's own ebops_factor, so both the reported EBOPS and the EBOPS regularization loss reflect the sparse compute. SparseTrainingMonitor applies this automatically at the start of training, so you usually do not need to call it directly -- call it manually only to correct EBOPS you inspect before training, or to refresh it if a learnable budget moves a lot (it uses the current n_max_pixels, a good approximation since the budget moves slowly).
Returns a dict of {layer_name: factor} for the sparse convs that were adjusted.
Source code in sparsepixels/utils.py
Quantization diagnostics¶
print_quantization ¶
Print the per-layer quantizer bit-widths (kernel, bias, input as mean, min, max) and EBOPS.
The EBOPS column reads HGQ's per-layer value, which reflects each layer's ebops_factor, so it is sparse corrected once set_sparse_ebops_factor has been applied.
Source code in sparsepixels/utils.py
plot_quantization ¶
Violin plots of the per-layer kernel, bias and input bit-width distributions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
models
|
a model or list of models to compare (one row per model). |
required | |
figsize
|
(width, per-model height) of the figure. |
(14, 3)
|