ENCODERS & DECODERS

vectorencoder

image

Encodes dense vector data as Sparse Distributed Representations (SDRs).

See also: https://creatingintelligence.org/#sdr-encoders

Details and properties

  • Encoder plugin for the input component.
  • Encodes dense, real-valued vectors to SDRs.
  • Maps similar vectors to similar SDRs.
  • Projects vectors into the hyperdimensional space given by hyperparameters [N, P] through multiplication with a sparse binary matrix followed by kWTA.


Property Default Description
sparsity 1/sqrt(D) projection matrix sparsity (D is the input dimension)

Vector-to-SDR encoding

The following circuit encodes dense vectors as SDRs.

{ "hyperparameters": {"default": [1000, 10]},
  "dataflow": [
    {"component": "input", "plugin": "vectorencoder", "send": [1]},
    {"component": "output", "receive": [1]}
  ]}

image

Source code

def vectorencoder(config):
    hyperparameters = config.get("hyperparameters", [0, 0])
    n, p = hyperparameters[0], hyperparameters[1]
    key = (n, p)

    if key not in circuit_vectorencoder_matrices:
        circuit_vectorencoder_matrices[key] = {}

    R = circuit_vectorencoder_matrices[key]

    if config.get("component") == "output":
        raise ValueError("vectorencoder cannot be used as a decoder.")

    def f(lst):
        if not isinstance(lst, list):
            lst = list(lst)
        d = len(lst)
        if p <= 0 or d == 0:
            return []

        sparsity = config.get("sparsity", float(1.0 / math.sqrt(d)))

        if d not in R:
            num_ones = round(n * d * sparsity)
            flat_indices = rng.choice(n * d, size=num_ones, replace=False)
            rows = flat_indices // d
            cols = flat_indices % d
            vals = np.ones(num_ones)

            R[d] = sp.csr_matrix((vals, (rows, cols)), shape=(n, d))

        matrix = R[d]
        vec = matrix.dot(np.array(lst))

        min_val, max_val = np.min(vec), np.max(vec)
        span = max_val - min_val
        scale = max(abs(min_val), abs(max_val))
        tolerance = 1e-10

        if scale == 0 or span <= tolerance * scale:
            return []

        k = min(p, len(vec))
        top_k_indices = np.argsort(vec)[-k:]
        return sorted((top_k_indices + 1).tolist())

    def clear():
        R.clear()

    return {
        "label": "VEC",
        "function": f,
        "clear": clear
    }