The input values must already be int8/uint8 representing the desired int2
values (signed range [-2, 1], or unsigned range [0, 3]). Packing is
performed along the specified axis (default is 0). Four consecutive values
along the packing axis are stored in a single output byte, from the least
significant 2-bit field to the most significant one.
This mirrors the design of pack_int4 (padding + original-length trim),
but achieves a 4x rather than 2x storage reduction, which is what makes
2-bit storage worthwhile relative to a plain uint8 tensor.
Args
arr
An int8 or uint8 tensor containing int2 values in the range
[-2, 1] (signed) or [0, 3] (unsigned).
axis
The axis along which to pack the tensor. Defaults to 0.
dtype
The data type of the input and packed tensor. Can be
"int8" or "uint8". Defaults to "int8".
Returns
tuple
A tuple (packed, packed_shape, orig_len) where packed is
the packed tensor with four int2 values per byte, packed_shape
is the shape of the packed tensor, and orig_len is the original
(unpacked) length along axis prior to any padding that was
inserted to reach a multiple of four.
Example:
import numpy as np
from keras.quantizers import pack_int2
codes = np.array([[-2, 1, 0, -1, 1]], dtype="int8")
packed, packed_shape, orig_len = pack_int2(codes, axis=1)
np.asarray(packed) # four 2-bit fields per byte; axis 1 padded to 8
array([[-58, 1]], dtype=int8)
packed_shape, orig_len
((1, 2), 5)