Saving and loading an OPU for inference

A common need among users is being able to apply the same pipeline in production, after training and testing the algorithm. In this use case, it is common to save the model and the transformation, and load them later for reuse. The OPU and OPUMap objects are no exception, and can be pickled and unpickled as any Python object. When loaded, they will maintain the properties they had at save time.

lightonopu

[1]:
import numpy as np
import torch
[2]:
from lightonopu import OPU
[3]:
train_data = np.random.randint(0, 2, (3000, 1000), dtype=np.uint8)
[4]:
opu = OPU(n_components=10000)
[5]:
opu.fit1d(train_data)
[6]:
train_y = opu.transform(train_data)
[7]:
train_y.context.as_dict()
[7]:
{'exposure_us': 400,
 'frametime_us': 500,
 'output_roi': ((0, 512), (2040, 64)),
 'start': datetime.datetime(2020, 10, 9, 13, 29, 31, 971721),
 'gain_dB': 0.0,
 'end': datetime.datetime(2020, 10, 9, 13, 29, 33, 626370),
 'input_roi': ((0, 0), (912, 1140)),
 'n_ones': 518723,
 'fmt_type': 'lined',
 'fmt_factor': 1039}
[8]:
import pickle
[9]:
with open("opu.pkl", "wb") as f:
    pickle.dump(opu, f)
[10]:
with open("opu.pkl", "rb") as f:
    opu = pickle.load(f)
[11]:
test_data = np.random.randint(0, 2, (3000, 1000), dtype=np.uint8)
test_y = opu.transform(test_data)
[12]:
test_y.context.as_dict()
[12]:
{'exposure_us': 400,
 'frametime_us': 500,
 'output_roi': ((0, 512), (2040, 64)),
 'start': datetime.datetime(2020, 10, 9, 13, 29, 36, 892864),
 'gain_dB': 0.0,
 'end': datetime.datetime(2020, 10, 9, 13, 29, 38, 536101),
 'input_roi': ((0, 0), (912, 1140)),
 'n_ones': 518723,
 'fmt_type': 'lined',
 'fmt_factor': 1039}

Similarly for the scikit-learn wrapper:

lightonml

[13]:
from lightonml.projections.sklearn import OPUMap
mapping = OPUMap(opu=opu, n_components=10000)
mapping.fit(train_data)
/home/iacolippo/data/miniconda3/envs/dev/lib/python3.8/site-packages/sklearn/base.py:209: FutureWarning: From version 0.24, get_params will raise an AttributeError if a parameter cannot be retrieved as an instance attribute. Previously it would return None.
  warnings.warn('From version 0.24, get_params will raise an '
[13]:
OPUMap(n_components=10000, opu=<lightonopu.opu.OPU object at 0x7f6db02c3fd0>,
       verbose_level=None)
[14]:
mapping.fitted
[14]:
True
[15]:
with open("mapping.pkl", "wb") as f:
    pickle.dump(mapping, f)
[16]:
with open("mapping.pkl", "rb") as f:
    mapping = pickle.load(f)
[17]:
mapping.fitted
[17]:
True
[18]:
mapping.close()

And for the Pytorch wrapper

[19]:
from lightonml.projections.torch import OPUMap
mapping = OPUMap(n_components=10000)
mapping.fit(torch.from_numpy(train_data))
OPU output is detached from the computational graph.
[20]:
mapping.fitted
[20]:
True
[21]:
with open("mapping.pkl", "wb") as f:
    pickle.dump(mapping, f)
[22]:
with open("mapping.pkl", "rb") as f:
    mapping = pickle.load(f)
[23]:
mapping.fitted
[23]:
True