View source on GitHub
|
Pack a ternary tensor into a uint8 tensor at ~1.6 bits per value.
tf.keras.quantizers.pack_ternary(
arr, axis=0
)
The input values must be in {-1, 0, +1}. Five ternary values (trits) are
packed into a single uint8 byte using base-3 encoding, which is exact
because 3 ** 5 == 243 <= 256. This is the information-theoretic floor for
ternary weights (log2(3) ~= 1.58 bits/value) and is strictly denser than
any integer format: ~2.5x denser than int4 and ~5x denser than int8, with
no loss (the stored values are exactly the original {-1, 0, +1}).
Each trit t is shifted to an unsigned digit d = t + 1 in {0, 1, 2}.
Five consecutive digits d0..d4 along axis are then combined into one
byte as d0 + 3*d1 + 9*d2 + 27*d3 + 81*d4 (max value 242). If the axis
length is not a multiple of 5 it is padded with zero-trits, which are
removed on unpacking.
Example:
import numpy as np from keras.quantizers import pack_ternary trits = np.array([[1, -1, 0, 1, 1, -1]], dtype="int8") packed, packed_shape, orig_len = pack_ternary(trits, axis=1) np.asarray(packed) # five trits per byte in base 3; axis 1 padded to 10 array([[227, 120]], dtype=uint8) packed_shape, orig_len ((1, 2), 6)
View source on GitHub