def __init__(self, k=2, y_gamma=100, opu=None, postproc=None):
     super().__init__()
     self.k = k
     self.opu = opu
     self.postproc = postproc
     if opu is None:
         self.y_features = RBFSampler(gamma=y_gamma, n_components=self.k)
     else:
         self.y_features = OPUMap(n_components=k, opu=opu)
     self.U = None
class SRP(BaseEstimator, TransformerMixin):
    def __init__(self, k=2, y_gamma=100, opu=None, postproc=None):
        super().__init__()
        self.k = k
        self.opu = opu
        self.postproc = postproc
        if opu is None:
            self.y_features = RBFSampler(gamma=y_gamma, n_components=self.k)
        else:
            self.y_features = OPUMap(n_components=k, opu=opu)
        self.U = None

    def fit(self, X, y, center=True):
        if y.ndim == 1:
            y = y.reshape(-1, 1)
        psi = self.y_features.fit_transform(y).astype('float32')
        if self.postproc:
            psi = self.postproc(psi)
        if center:
            X = X - X.mean(0)
        self.U = psi.T @ X
        return self

    def transform(self, X):
        return X @ self.U.T
Esempio n. 3
0
    def forward(self, data):

        if self.precomputed is None:
            # The opu needs data to be in numpy uint8 binary format!
            data = data.numpy().astype('uint8')

            # append bias to the data
            # for the real OPU, the bias is represented by an array of ones
            # unlike for the simulated OPU, the value already needs to be squared
            bias_vector = np.ones((len(data), self.bias**2)).astype('uint8')
            data = np.hstack([data, bias_vector])

            # this part communicates with the physical device
            from lightonml.projections.sklearn import OPUMap
            from lightonopu.opu import OPU

            with OPU(n_components=self.output_features) as opu_dev:
                random_mapping = OPUMap(opu=opu_dev,
                                        n_components=self.output_features,
                                        ndims=1)
                random_mapping.opu.device.exposure_us = self.eposure_us
                random_mapping.opu.device.frametime_us = self.eposure_us + 100
                output = random_mapping.transform(data).astype('float32')
        else:
            output = self.precomputed.astype('float32')

        if self.raw_features:
            return output

        # Now we have to be careful:
        # The OPU has an unknown variance defined by physical settings
        # However, we can estimate it and normalize the projection to var=0.5
        opu_var = self.estimate_opu_variance(data, output)
        # We have OPU(x)_i = (w_i @ x)**2 + (v_i @ x)**2
        # = opu_var * (N(0,I) @ x)**2 + (N(0,I) @ x)**2
        # => We need to divide the projection by opu_var and multiply by 0.5
        output = output / opu_var * 0.5
        # => We have sampled all real entries from N(0, 0.5) like for the simulated device!

        output = output**(self.degree // 2)
        output = self.scale * output

        # We convert the data back to PyTorch format
        return torch.from_numpy(output).type(torch.FloatTensor)
    def __init__(self,
                 k=2,
                 gamma=1,
                 n_components=500,
                 metric='rbf',
                 y_gamma=100,
                 opu=None,
                 x_opu=False,
                 y_opu=False,
                 x_postproc=None,
                 y_postproc=None,
                 feature_encoder=None):
        super().__init__()
        self.k = k
        self.opu = opu
        self.gamma = gamma
        if opu is None:
            self.metric = metric
            self.x_features = RBFSampler(gamma=gamma,
                                         n_components=n_components)
            self.y_features = RBFSampler(gamma=y_gamma, n_components=self.k)
        else:
            if x_opu:
                self.x_features = make_pipeline(
                    feature_encoder,
                    OPUMap(n_components=n_components, opu=opu,
                           verbose_level=0))
            else:
                self.x_features = RBFSampler(gamma=gamma,
                                             n_components=n_components)
            if y_opu:
                # n_components should be k but since it's the same OPU object it would mess with x_features
                self.y_features = OPUMap(n_components=n_components,
                                         opu=opu,
                                         verbose_level=0)
            else:
                self.y_features = RBFSampler(gamma=y_gamma,
                                             n_components=self.k)

        self.x_postproc = x_postproc
        self.y_postproc = y_postproc
        self.U = None
        self.psi = None
        self.train_data = None
Esempio n. 5
0
class Lighton_random_features(feature_map):
    '''
    This class affords an approximation of the Gaussian kernel using random features.
    When initializing a new instance, you should pass: 
    sigma: STD of the Gaussian kernel
    input_dim, features_num: size of projection matrix
    '''
    def __init__(self, input_dim, features_num):
        self.features_num=features_num
        self.random_mapping = OPUMap(n_components=features_num)
        self.random_mapping.opu.open()
    def transform(self, A):
        A=np.uint8(A.T)
        train_random_features = self.random_mapping.transform(A)
        return train_random_features.astype('float32').T
    def close(self):
         self.random_mapping.opu.close()
Esempio n. 6
0
class Lighton_random_features(feature_map):
    '''
    This class computes optical random features with 
    the help of OPUs technology developed by LightOn company. 
    When initializing a new instance, you should pass: 
    input_dim, features_num: size of projection matrix
    '''
    def __init__(self, input_dim, features_num):
        self.features_num = features_num
        self.random_mapping = OPUMap(n_components=features_num)
        self.random_mapping.opu.open()

    def transform(self, A):
        A = np.uint8(A.T)
        train_random_features = self.random_mapping.transform(A)
        return train_random_features.astype('float32').T

    def close(self):
        self.random_mapping.opu.close()
 def __init__(self, input_dim, features_num):
     self.features_num = features_num
     self.random_mapping = OPUMap(n_components=features_num)
     self.random_mapping.opu.open()
Esempio n. 8
0
def get_random_features(X,
                        n_components,
                        opu_map=None,
                        matrix=None,
                        conv_blocks=1,
                        device="cuda:0"):
    """
    Performs the random projection of the encoded random features X using the OPU.

    Parameters
    ----------
    X: numpy 2d array or torch.tensor,
        encoded convolutional training features. Make sure that the dtype is int8 if n_components!=0.
    n_components: int,
        number of random projections.
    opu_map: OPUMap object or None,
        OPUMap object for performing the projection with the OPU. If None, it is generated automatically.
        You should pass it when you plan to do multiple projections in the same script.
    matrix: None or torch.tensor,
        Matrix to use for the random projection on GPU. If None, the OPU will be used.
    conv_blocks: int,
        number of splits for the input matrix if GPU is used.
    device: str,
        device for the random projection if the OPU is not used. Examples are "cpu" or "cuda:0".

    Returns
    -------

    proj_time: float,
        projection time for the features.
    random_features: numpy 2d array,
        random features of the training set. If n_components=0, the original train random features are returned.

    """

    if n_components == 0:
        train_time = 0.

        # The conversion to numpy is needed for compatibility with the MixingBitPlanDecoder.
        if type(X) is not np.ndarray:
            X = X.numpy()

        return train_time, X

    if matrix is not None:
        if isinstance(X, np.ndarray):
            X = torch.FloatTensor(X)

        X_blocks = X.split(conv_blocks)
        random_features, train_time = get_rand_features_GPU(X_blocks,
                                                            matrix,
                                                            device=device)

    else:
        if opu_map is None:
            opu_map = OPUMap(n_components=n_components)

        since = time()
        random_features = opu_map.transform(X)
        train_time = time() - since

    return train_time, random_features
Esempio n. 9
0
def main(args):

    if args.save_path is not None:
        folder_name = os.path.join(
            args.save_path,
            "graph_nodes_{}_clique_{}_{}".format(args.n_nodes,
                                                 args.clique_size,
                                                 args.device))
        pathlib.Path(folder_name).mkdir(parents=True, exist_ok=True)
    else:
        folder_name = None

    # Erase this, I hardcoded the number of components and the clique_size

    if args.device == "opu":
        R = None
        generation_time = 0.
        conv_blocks = 1
        opu_map = OPUMap(n_components=args.n_components)

    else:
        print("Generating random matrix of size ({} x {})".format(
            args.n_nodes, args.n_components))
        GPU_optimizer = GPU_matrix(n_samples=args.n_nodes,
                                   n_features=args.n_nodes,
                                   n_components=args.n_components,
                                   GPU_memory=args.GPU_memory)

        R, generation_time = GPU_optimizer.generate_RM()
        conv_blocks = args.n_nodes // GPU_optimizer.conv_blocks_size
        print("Generation time = {0:3.2f} s".format(generation_time))
        print("Splits size: R = {}\t conv = {}\n".format(
            GPU_optimizer.R_blocks_size, GPU_optimizer.conv_blocks_size))
        opu_map = None

    graph = Graph(n_nodes=args.n_nodes,
                  p_edges=args.p_edges,
                  clique_size=args.clique_size,
                  clique_step=args.clique_step,
                  noise_ratio=args.noise_ratio,
                  save_path=folder_name)
    graph.__info__()

    newma = NEWMA(args.n_nodes,
                  args.n_components,
                  time_window=args.time_window,
                  l_ratio=args.l_ratio,
                  eta=args.eta,
                  rescale_tau=args.rescale_tau,
                  power_iter=args.power_iter,
                  save_path=folder_name)

    with torch.no_grad():
        for t in range(1, args.t_end):
            new_edges = graph.evolve()

            if args.t_clique <= t <= args.t_clique + args.clique_step:
                graph.create_clique(progression=t - args.t_clique + 1)

            Adj_matrix = torch.FloatTensor(nx.to_numpy_array(graph.G))

            if args.device == "opu":
                Adj_matrix = Adj_matrix.bool()

            proj_time, random_features = get_random_features(
                Adj_matrix,
                args.n_components,
                opu_map=opu_map,
                matrix=R,
                conv_blocks=conv_blocks,
                device=args.device)

            newma.detect(random_features.float(), t=t)

            eigenvector = newma.compute_eigenvector(Adj_matrix.float())

            newma.update_log(t, graph.G.number_of_edges(), generation_time,
                             proj_time)
            if args.save_path is not None and t >= args.t_start:
                graph.update_plot(new_edges, eigenvector, newma, args.t_start,
                                  args.t_end, args.t_clique)
            newma.update_threshold()

    return
Esempio n. 10
0
    B = 250  # window size
    d = n_feat

    # Forget factors chosen with heuristic in the paper
    big_Lambda, small_lambda = algos.select_optimal_parameters(B)
    thres_ff = small_lambda
    # Number of random features is set automatically with this criterion
    m = int((1 / 4) / (small_lambda + big_Lambda)**2)
    m_OPU = 10 * m
    print(f'{m_OPU} random features.')

    if pyramid:
        # Pyramid sketch
        nc = 60000
        # Opening the OPU
        opu_mapping = OPUMap(n_components=nc)

        # First encoding
        encoder = BinaryThresholdEncoder(threshold_enc=10)
        minX, maxX = np.min(traj), np.max(traj)
        length_simulation = traj.shape[0]
        trajprojection = np.zeros((length_simulation, 3 * nc))

        for i in range(3):
            print(f"First sketch of the data... Step {i + 1} out of 3.")
            cut = n_atoms
            X = traj[:, cut * i:cut * (i + 1)]
            X = 255 * ((X - minX) / (maxX - minX))
            X = X.astype('uint8')
            Xencode = encoder.transform(X)
            del X
t_lopu = empty((len(d_list), len(p_list)))

for i in range(len(d_list)):
    d = d_list[i]
    print("d = " + str(d), end=".\n")
    print("Sampling x...", end=" ")
    x = torch.distributions.Binomial(1, r).sample(
        (repetitions, n, d)).type(dtype).numpy().astype('uint8')
    print("Done.")
    for j in range(len(p_list)):
        p = p_list[j]
        print("p = " + str(p), end=".\n")
        print("Building OPU object...")
        e1_lopu = time.time()
        #opu = OPU(p)
        random_mapping = OPUMap(n_components=p, ndims=1)
        e2_lopu = time.time()
        t_lopu[i, j] = e2_lopu - e1_lopu
        print("Done.")

        print("Start matmuls...")
        e1_opu = time.time()
        for repe in range(repetitions):
            _ = random_mapping.transform(x[repe, :, :])
        e2_opu = time.time()
        print("Done.")
        t_opu[i, j] = (e2_opu - e1_opu) / repetitions

print("OPU loading time:")
print(t_lopu)
print("OPU time:")