data
ImageInput
ImageInput(scale: float = 1.0, bias: tuple[float, ...] = (), color: ColorSpace = ColorSpace.RGB)Present an input as an image, with the normalisation it expects.
An app holding a CVPixelBuffer cannot feed a multi-array without
converting the pixels itself, and getting that conversion subtly wrong
— a missed scale, the wrong channel order — produces a model that runs
and answers badly. Declaring the input as an image moves both the
conversion and the normalisation into the package.
scale and bias are applied as pixel * scale + bias, which
is where a mean-and-standard-deviation normalisation lands: a channel
normalised by (p/255 - m) / s has scale = 1/(255 * s) and
bias = -m / s.
Attributes
scalefloatMultiplier applied to every pixel, before
bias.biastuple[float, ...]One offset per channel. Empty adds nothing.
colorColorSpacePixel layout.
GRAYSCALE expects one channel, the others three.Examples
Pixels are whole numbers in [0, 255]; the scale is applied inside
the package, so the caller feeds pixels and not normalised values:
>>> import shutil, tempfile
>>> import lucid, lucid.nn as nn, lucid.coreml as cml
>>> model = nn.Sequential(
... nn.Conv2d(3, 16, 3, padding=1), nn.ReLU(),
... nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Linear(16, 10),
... ).eval()
>>> pixels = (lucid.rand(1, 3, 32, 32) * 255).round()
>>> room = tempfile.mkdtemp()
>>> package = cml.export(model, pixels, f"{room}/img.mlpackage",
... image_input=cml.ImageInput(scale=1 / 255.0))
>>> package.predict(pixels).shape
(1, 10)
>>> package.verify(model, pixels) < 1e-4 # the eager side is scaled to match
True
>>> package.close()
>>> shutil.rmtree(room)Used by 3
Constructors
1dunder
__init__
→None__init__(scale: float = 1.0, bias: tuple[float, ...] = (), color: ColorSpace = ColorSpace.RGB)