Esempio n. 1
0
    def test_grayscale_node(self, squeeze_channel, tensor_data):
        device = 'cpu'
        dtype = torch.float32

        input_tensor = torch.tensor(
            [[1, 1, 1], [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]],
            device=device,
            dtype=dtype)
        expected_tensor = torch.tensor(tensor_data, device=device, dtype=dtype)

        mb0 = MemoryBlock()
        mb0.tensor = input_tensor

        gn = GrayscaleNode(squeeze_channel=squeeze_channel)
        Connector.connect(mb0, gn.inputs.input)
        gn.allocate_memory_blocks(AllocatingCreator(device))
        gn._step()

        assert same(gn.outputs.output.tensor, expected_tensor,
                    0.000001)  # allow small epsilon differences
    def test_compute_output_projection_per_sequence(self, device, seqs, expected_output_projection):
        seqs_tensor = torch.tensor(seqs, device=device, dtype=torch.int64)
        expected_output_projection_tensor = torch.tensor(expected_output_projection, device=device,
                                                         dtype=get_float(device))
        flock_size, n_frequent_seqs, seq_length = seqs_tensor.shape
        n_cluster_centers = 4
        seq_lookahead = 1

        output_projection = TPOutputProjection(flock_size, n_frequent_seqs, n_cluster_centers, seq_length,
                                               seq_lookahead, device)

        projection_outputs = torch.zeros((flock_size, n_frequent_seqs, n_cluster_centers), device=device,
                                         dtype=get_float(device))

        output_projection.compute_output_projection_per_sequence(
            seqs_tensor,
            projection_outputs
        )

        assert same(expected_output_projection_tensor, projection_outputs)
def test_sequence_transition(sequences, trans_probs, iters, device):
    """For ease of use, sequences should be in ascending order."""

    float_dtype = get_float(device)
    seq_params = DatasetSequenceMNISTNodeParams(sequences, transition_probs=trans_probs)
    seq_params.use_custom_probs = True
    node = DatasetSequenceMNISTNode(params=DatasetMNISTParams(one_hot_labels=False), seq_params=seq_params)
    node.allocate_memory_blocks(AllocatingCreator(device=device))

    actual_sequence = []
    for x in range(iters):
        node.step()
        actual_sequence.append(node.outputs.label.tensor.clone())

    actual_sequence = torch.cat(actual_sequence, dim=0)
    proportions = torch.bincount(actual_sequence).type(float_dtype) / iters
    real_proportions = proportions[proportions > 0]

    expected_proportions = normalize_probs(torch.tensor(trans_probs, dtype=float_dtype, device=device ).sum(0), dim=0)

    assert same(expected_proportions, real_proportions, eps=1e-2)
Esempio n. 4
0
def test_graph_save_load():
    graph = create_graph()
    graph2 = create_graph()

    graph.step()
    graph2.step()

    graph2.nodes[0].outputs.output.tensor.random_()
    graph2.nodes[1].outputs.output.tensor.random_()
    graph2.nodes[2].outputs.output.tensor.random_()

    with TemporaryDirectory() as folder:
        saver = Saver(folder)
        graph.save(saver)
        saver.save()

        loader = Loader(folder)
        graph2.load(loader)

    for i in range(2):
        assert same(graph.nodes[i].outputs.output.tensor, graph2.nodes[i].outputs.output.tensor)
Esempio n. 5
0
def test_join_node_inverse_0():
    # TODO (Test): Make a dim = 1 variant
    # TODO (Test): Then, refactor tests here, maybe something to match the test class above, but for the backward projection.
    creator = AllocatingCreator(device='cpu')
    dtype = creator.float32

    dim = 0

    # The result of the inverse projection should only be one tensor.
    expected_results = [
        creator.tensor([[1, 2, 3, 4], [5, 6, 7, 8]],
                       dtype=dtype,
                       device=creator.device),
        creator.tensor([[9, 10, 11, 12], [13, 14, 15, 16]],
                       dtype=dtype,
                       device=creator.device)
    ]

    input_memory_blocks = [MemoryBlock(), MemoryBlock()]
    input_memory_blocks[0].tensor = creator.zeros((2, 4))
    input_memory_blocks[1].tensor = creator.zeros((2, 4))

    output_tensor = creator.tensor(
        [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]],
        dtype=dtype,
        device=creator.device)

    join_node = JoinNode(dim, n_inputs=2)
    Connector.connect(input_memory_blocks[0], join_node.inputs[0])
    Connector.connect(input_memory_blocks[1], join_node.inputs[1])

    output_inverse_packet = InversePassOutputPacket(output_tensor,
                                                    join_node.outputs.output)

    join_node.allocate_memory_blocks(creator)
    results = join_node.recursive_inverse_projection_from_output(
        output_inverse_packet)

    for expected, result in zip(expected_results, results):
        assert same(expected, result.tensor)
def test_coefficients(learning_coefficients):
    """Test that the data with learning_coefficients equal zero will not be sampled."""

    params = NeuralNetworkFlockParams()

    params.flock_size = len(learning_coefficients)
    params.mini_batch_size = 57

    device = 'cuda'

    params.input_size, params.output_size, batch_size, flock_inputs, flock_targets = \
        prepare_inputs_and_targets(params.flock_size, device)

    neural_nets = MultilayerPerceptronFlock(params, device)

    batch_learning_coefficients = torch.tensor(learning_coefficients,
                                               device=device,
                                               dtype=get_float(device))
    batch_learning_coefficients = batch_learning_coefficients.unsqueeze(2)

    data_loaders, should_learn = neural_nets.make_data_loaders(
        flock_inputs, flock_targets, batch_learning_coefficients,
        params.mini_batch_size, params.coefficients_minimum_max)
    # Compute frequency of each datapoint
    for flock_idx, loader in enumerate(data_loaders):
        for input_batch, target_batch in loader:
            occurrences = []
            for point_idx, point in enumerate(flock_inputs[flock_idx]):
                seen = 0
                for sampled_point in input_batch:
                    if same(sampled_point, point):
                        seen += 1

                occurrences.append(seen)
                # Data-points with 0 coefficients should not be present
                if learning_coefficients[flock_idx][point_idx] == 0:
                    assert seen == 0
                else:
                    assert seen > 0
Esempio n. 7
0
def test_buffer_mask_creation():
    buffer = create_buffer(flock_size=3, buffer_size=10, last_dim=3)
    buffer.current_ptr = torch.tensor([1, 3, 6],
                                      dtype=torch.int64,
                                      device=DEVICE)
    buffer.t1.stored_data[0][1] = torch.tensor([0.1, 0.1, 0.1],
                                               dtype=buffer._float_dtype,
                                               device=DEVICE)
    buffer.t1.stored_data[1][3] = torch.tensor([0.2, 0.2, 0.2],
                                               dtype=buffer._float_dtype,
                                               device=DEVICE)

    inp = torch.tensor([[0.1, 0.1, 0.1], [0.2, 0.2, 0.2], [0.3, 0.3, 0.3]],
                       dtype=buffer._float_dtype,
                       device=DEVICE)

    ground_truth = torch.tensor([0, 0, 1], dtype=torch.uint8, device=DEVICE)

    eq_data = buffer.t1.compare_with_last_data(inp,
                                               SPFlock._detect_any_difference)

    assert same(eq_data, ground_truth)
Esempio n. 8
0
def test_context_creation(seq_lookahead):
    device = 'cuda'
    float_dtype = get_float(device)
    seq_length = 3
    seq_lookbehind = seq_length - seq_lookahead

    flock = prepare_flock_for_context(device=device,
                                      seq_length=seq_length,
                                      seq_lookahead=seq_lookahead,
                                      n_cluster_centers=3)

    nan = float("nan")

    # Randomise our important tensors
    flock.sp_flock.forward_clusters.uniform_()
    flock.tp_flock.passive_predicted_clusters_outputs.uniform_()
    flock.tp_flock.action_rewards.uniform_()
    flock.tp_flock.action_punishments.uniform_()

    flock._assemble_output_context()

    padding = torch.full((flock.params.flock_size, flock.n_cluster_centers),
                         fill_value=nan,
                         dtype=float_dtype,
                         device=device)

    expected_output_context = torch.cat([
        flock.sp_flock.forward_clusters, flock.tp_flock.action_rewards,
        flock.tp_flock.action_punishments,
        flock.tp_flock.passive_predicted_clusters_outputs[:,
                                                          seq_lookbehind, :],
        padding, padding
    ],
                                        dim=1).view(flock.params.flock_size, 2,
                                                    NUMBER_OF_CONTEXT_TYPES,
                                                    flock.n_cluster_centers)

    assert same(expected_output_context, flock.output_context)
Esempio n. 9
0
def test_one_hot(device: str):
    """Test whether the one-hot representation works correctly as well."""

    # request one-hot representation of landmarks
    one_hot_divisor = SpaceDivisor(horizontal_segments=3,
                                   vertical_segments=4,
                                   device=device)

    positions, results = get_data(device)
    no_positions = positions.shape[0]

    _, one_hot_landmarks = one_hot_divisor.get_landmarks(positions)

    for position in range(0, no_positions):
        coordinates = get_pos(position, positions)

        _, one_hot_l = one_hot_divisor.get_landmark(*coordinates)

        assert same(one_hot_l, one_hot_landmarks[position])

        val, index = one_hot_l.max(-1)

        assert index == results[position].long()
Esempio n. 10
0
def test_lambda_node():
    device = 'cpu'
    dtype = torch.float32

    input_tensor_0 = torch.tensor([0, 1, -1], device=device, dtype=dtype)
    input_tensor_1 = torch.tensor([1, 1, -1], device=device, dtype=dtype)

    expected_tensor = input_tensor_0 + input_tensor_1

    mb0, mb1 = MemoryBlock(), MemoryBlock()
    mb0.tensor, mb1.tensor = input_tensor_0, input_tensor_1

    def add_f(inputs, outputs):
        outputs[0][:] = 0
        outputs[0].add_(inputs[0])
        outputs[0].add_(inputs[1])

    ln = LambdaNode(add_f, 2, [input_tensor_0.shape])
    ln.allocate_memory_blocks(AllocatingCreator(device=device))
    Connector.connect(mb0, ln.inputs[0])
    Connector.connect(mb1, ln.inputs[1])
    ln._step()

    assert same(ln.outputs[0].tensor, expected_tensor)
Esempio n. 11
0
def test_action_monitor_node(action_in, override, override_action, device):

    float_dtype = get_float(device)

    action_in = action_in.type(float_dtype).to(device)

    node = ActionMonitorNode(descriptor)
    node.allocate_memory_blocks(AllocatingCreator(device=device))

    block = MemoryBlock()
    block.tensor = action_in

    Connector.connect(block, node.inputs.action_in)

    node._override_checked = override
    node._actions_values = override_action
    node.step()

    output = node.outputs.action_out.tensor
    expected_output = torch.tensor(override_action,
                                   dtype=float_dtype,
                                   device=device) if override else action_in

    assert same(expected_output, output)
Esempio n. 12
0
def test_integrate():

    flock_size = 10

    # Those indices which are subflocked and those that are not
    indices = torch.tensor([0, 1, 3, 6, 9], dtype=torch.int64)
    non_indices = torch.tensor([2, 4, 5, 7, 8], dtype=torch.int64)

    # Define tensors for the process
    read1 = torch.full((flock_size, 10), fill_value=2)
    read2 = torch.full((flock_size, 10), fill_value=3)

    rw1 = torch.full((flock_size, 10), fill_value=4)
    rw2 = torch.full((flock_size, 10), fill_value=5)

    # Subflock via the process
    proc = init_process(indices)
    sub_read1 = proc._read(read1)
    sub_read2 = proc._read(read2)

    sub_read_write1 = proc._read_write(rw1)
    sub_read_write2 = proc._read_write(rw2)

    # Modify the subtensored lot
    sub_read1.fill_(22)
    sub_read2.fill_(100)

    sub_read_write1.fill_(15)
    sub_read_write2.fill_(8)

    # Integrate
    proc.integrate()

    # Test that we have the same read_only values
    assert same(torch.full((flock_size, 10), fill_value=2), read1)
    assert same(torch.full((flock_size, 10), fill_value=3), read2)

    # Test that the rw tensors have changed and nont changed in the relevant places
    assert same(torch.full((5, 10), fill_value=4), rw1[non_indices])
    assert same(torch.full((5, 10), fill_value=15), rw1[indices])

    assert same(torch.full((5, 10), fill_value=5), rw2[non_indices])
    assert same(torch.full((5, 10), fill_value=8), rw2[indices])
Esempio n. 13
0
def test_update_knowledge_new_seqs():
    """
    Unlike the non-conv TP, there is only one sets of new sequences, and one set of all encountered sequences
    irrespective of the number of experts that are learning in this process.
    """

    flock_size = 2
    n_providers = 1
    max_encountered_seqs = 7
    n_frequent_seqs = 3
    seq_length = 3
    n_cluster_centers = 3
    batch_size = 3
    forgetting_limit = 3
    context_size = 4
    seq_lookahead = 1
    max_new_seqs = 3

    device = 'cpu'
    dtype = get_float(device)

    learning_proc = create_tp_flock_learn_process(
        flock_size=flock_size,
        max_encountered_seqs=max_encountered_seqs,
        n_frequent_seqs=n_frequent_seqs,
        seq_length=seq_length,
        n_cluster_centers=n_cluster_centers,
        batch_size=batch_size,
        forgetting_limit=forgetting_limit,
        context_size=context_size,
        device=device,
        seq_lookahead=seq_lookahead,
        n_providers=n_providers)

    learning_proc._all_encountered_seqs[0, 0] = torch.tensor([1, 2, 3],
                                                             device=device,
                                                             dtype=torch.int64)
    learning_proc._all_encountered_seq_occurrences[0, 0] = 3

    learning_proc._all_encountered_seqs[0, 1] = torch.tensor([2, 1, 0],
                                                             device=device,
                                                             dtype=torch.int64)
    learning_proc._all_encountered_seq_occurrences[0, 1] = 0.4

    all_enc_seqs = learning_proc._all_encountered_seqs
    all_enc_seq_occ = learning_proc._all_encountered_seq_occurrences

    all_enc_cont_occ = torch.full(
        (1, max_encountered_seqs, seq_length, n_providers, context_size),
        fill_value=-1,
        dtype=dtype,
        device=device)
    all_enc_exp_att = torch.full(
        (flock_size, max_encountered_seqs, seq_lookahead, n_cluster_centers),
        fill_value=-1.,
        dtype=dtype,
        device=device)
    all_enc_exp_suc_rates = torch.full(
        (flock_size, max_encountered_seqs, seq_lookahead, n_cluster_centers),
        fill_value=-1.,
        dtype=dtype,
        device=device)
    all_enc_rew_pun = torch.full(
        (flock_size, max_encountered_seqs, seq_lookahead, 2),
        fill_value=-1,
        dtype=dtype,
        device=device)

    most_probable_batch_seqs = torch.tensor(
        [[[0, 1, 3], [2, 1, 3], [-1, -1, -1], [3, 1, 3]]],
        device=device,
        dtype=torch.int64)
    newly_enc_seq_counts = torch.tensor([[2, 3, 0, 1]],
                                        device=device,
                                        dtype=dtype)

    learning_proc._update_knowledge_new_seqs(all_enc_seqs, all_enc_seq_occ,
                                             all_enc_cont_occ, all_enc_rew_pun,
                                             all_enc_exp_att,
                                             all_enc_exp_suc_rates,
                                             most_probable_batch_seqs,
                                             newly_enc_seq_counts)

    expected_all_enc_seqs = all_enc_seqs.clone()
    expected_all_enc_seqs[0, -max_new_seqs:] = torch.tensor(
        [[2, 1, 3], [0, 1, 3], [3, 1, 3]], dtype=torch.int64)

    expected_all_enc_seq_occ = all_enc_seq_occ.clone()
    expected_all_enc_seq_occ[0, -max_new_seqs:] = torch.tensor([3, 2, 1],
                                                               dtype=dtype)

    new_context_counts = expected_all_enc_seq_occ[:, -max_new_seqs:].view(
        1, max_new_seqs, 1, 1, 1).expand(1, max_new_seqs, seq_length,
                                         n_providers, context_size) / 2

    expected_all_enc_cont_occ = all_enc_cont_occ.clone()
    expected_all_enc_cont_occ[:, -max_new_seqs:, :, :, :] = new_context_counts

    expected_all_enc_exp_att = all_enc_exp_att.clone()
    expected_all_enc_exp_att[:,
                             -max_new_seqs:, :, :] = learning_proc._exploration_attempts_prior

    expected_all_enc_exp_suc_rates = all_enc_exp_suc_rates.clone()
    expected_all_enc_exp_suc_rates[:, -max_new_seqs:, :, :] = 0

    expected_all_enc_rew_pun = all_enc_rew_pun.clone()
    expected_all_enc_rew_pun[:-max_new_seqs:, :, :] = 0

    assert same(expected_all_enc_seqs, all_enc_seqs)
    assert same(expected_all_enc_seq_occ, all_enc_seq_occ)
    assert same(expected_all_enc_cont_occ, all_enc_cont_occ)
    assert same(expected_all_enc_exp_att, all_enc_exp_att)
    assert same(expected_all_enc_exp_suc_rates, all_enc_exp_suc_rates)
    assert same(expected_all_enc_rew_pun, all_enc_rew_pun)
Esempio n. 14
0
    def test_boost_clusters(self, cluster_boosting_durations, variance_batch,
                            cluster_batch, expected_boosting_targets):
        """Testing if it correctly computes the boosting targets."""
        flock_size = 2
        n_cluster_centers = 4
        input_size = 3
        batch_size = 4
        do_subflocking = True
        learning_period = 10
        device = 'cpu'
        float_dtype = get_float(device)
        cluster_boost_threshold = 370

        all_indices = torch.arange(flock_size,
                                   dtype=torch.int64,
                                   device=device).unsqueeze(dim=1)

        cluster_boosting_durations = torch.tensor(cluster_boosting_durations,
                                                  dtype=torch.int64,
                                                  device=device)

        variance_batch = torch.tensor(variance_batch,
                                      dtype=float_dtype,
                                      device=device)
        cluster_batch = torch.tensor(cluster_batch,
                                     dtype=float_dtype,
                                     device=device)

        prev_boosted_clusters = torch.zeros_like(cluster_boosting_durations,
                                                 dtype=torch.uint8,
                                                 device=device)
        boosting_targets = torch.zeros((2, 4),
                                       dtype=torch.int64,
                                       device=device)

        cluster_centers = torch.rand(flock_size,
                                     n_cluster_centers,
                                     input_size,
                                     dtype=float_dtype,
                                     device=device)
        cluster_center_targets = torch.zeros(
            (flock_size, n_cluster_centers, input_size),
            dtype=float_dtype,
            device=device)
        cluster_center_deltas = torch.zeros(
            (flock_size, n_cluster_centers, input_size),
            dtype=float_dtype,
            device=device)

        # Not used, but required by SPFlockLearning
        buffer = SPFlockBuffer(AllocatingCreator(device),
                               buffer_size=20,
                               n_cluster_centers=n_cluster_centers,
                               flock_size=flock_size,
                               input_size=input_size)

        process = SPFlockLearning(
            all_indices,
            do_subflocking,
            buffer,
            cluster_centers,
            cluster_center_targets,
            cluster_boosting_durations,
            boosting_targets,
            cluster_center_deltas,
            prev_boosted_clusters,
            n_cluster_centers=n_cluster_centers,
            input_size=input_size,
            cluster_boost_threshold=cluster_boost_threshold,
            max_boost_time=200,
            learning_rate=0.01,
            learning_period=learning_period,
            batch_size=batch_size,
            execution_counter=create_execution_counter(flock_size, device),
            device=device,
            boost=False)

        process._boost_clusters(cluster_batch, variance_batch,
                                cluster_boosting_durations, boosting_targets,
                                prev_boosted_clusters,
                                process.tmp_boosting_targets,
                                process._expert_row_indices,
                                process._cluster_index_matrix)

        expected_boosting_targets = torch.tensor(expected_boosting_targets,
                                                 dtype=torch.int64,
                                                 device=device)

        assert same(expected_boosting_targets, boosting_targets)
Esempio n. 15
0
 def __eq__(self, other: Any):
     return isinstance(other, ComparableTensor) and same(
         self._tensor, other._tensor)
Esempio n. 16
0
 def test_rgb_transform(self, t_input, p_min, p_max, expected_result):
     result = TensorViewProjection._rgb_transform(t_input, p_min, p_max)
     assert same(expected_result, result, eps=0.001)
Esempio n. 17
0
    def test_learning_with_boosting(self):
        flock_size = 7
        n_cluster_centers = 5
        input_size = 3
        batch_size = 10
        do_subflocking = True
        learning_rate = 0.1
        learning_period = 10
        device = 'cuda'
        float_dtype = get_float(device)

        all_indices = torch.arange(flock_size,
                                   dtype=torch.int64,
                                   device=device).unsqueeze(dim=1)

        buffer = SPFlockBuffer(AllocatingCreator(device),
                               buffer_size=20,
                               n_cluster_centers=n_cluster_centers,
                               flock_size=flock_size,
                               input_size=input_size)
        buffer.inputs.stored_data = torch.randn(
            buffer.inputs.stored_data.size(), dtype=float_dtype, device=device)

        cluster_centers = torch.rand(
            (flock_size, n_cluster_centers, input_size),
            dtype=float_dtype,
            device=device)
        cluster_center_targets = torch.zeros(
            (flock_size, n_cluster_centers, input_size),
            dtype=float_dtype,
            device=device)
        cluster_center_deltas = torch.zeros(
            (flock_size, n_cluster_centers, input_size),
            dtype=float_dtype,
            device=device)
        cluster_boosting_durations = torch.full(
            (flock_size, n_cluster_centers),
            fill_value=995,
            device=device,
            dtype=torch.int64)
        boosting_targets = torch.zeros((flock_size, n_cluster_centers),
                                       dtype=torch.int64,
                                       device=device)
        prev_boosted_clusters = torch.zeros((flock_size, n_cluster_centers),
                                            dtype=torch.uint8,
                                            device=device)

        buffer.current_ptr = torch.full((flock_size, ),
                                        fill_value=9,
                                        dtype=torch.int64,
                                        device=device)

        buffer_data = torch.zeros((flock_size, batch_size, input_size),
                                  dtype=float_dtype,
                                  device=device)

        buffer.inputs.sample_contiguous_batch(batch_size, buffer_data)
        perm_data = buffer_data

        process = SPFlockLearning(all_indices,
                                  do_subflocking,
                                  buffer,
                                  cluster_centers,
                                  cluster_center_targets,
                                  cluster_boosting_durations,
                                  boosting_targets,
                                  cluster_center_deltas,
                                  prev_boosted_clusters,
                                  n_cluster_centers=n_cluster_centers,
                                  input_size=input_size,
                                  cluster_boost_threshold=1000,
                                  max_boost_time=200,
                                  learning_rate=learning_rate,
                                  learning_period=learning_period,
                                  batch_size=batch_size,
                                  execution_counter=create_execution_counter(
                                      flock_size, device),
                                  device=device,
                                  boost=True)

        buffer_clusters, _ = process.compute_closest_cluster_centers(
            cluster_centers, buffer_data)
        perm_clusters = buffer_clusters

        all_sum_data = []
        # Go through each flock and compute the means of points belonging to each cluster center
        for exp_data, exp_clust in zip(perm_data, perm_clusters):
            sum_data = []
            for c in range(process._n_cluster_centers):
                indices = exp_clust.type(torch.ByteTensor)[:, c]
                individual_data_points = exp_data[indices, :]
                if sum(indices) == 0:
                    mean_data_points = torch.full((process._input_size, ),
                                                  fill_value=FLOAT_NAN,
                                                  dtype=float_dtype,
                                                  device=device)
                else:
                    mean_data_points = torch.mean(individual_data_points,
                                                  dim=0)
                sum_data.append(mean_data_points)
            all_sum_data.append(torch.stack(sum_data))

        ground_truth = torch.stack(all_sum_data)

        previous_cluster_centers = cluster_centers.clone()

        process.run()
        process.integrate()

        # cluster center targets correctly computed
        assert same(ground_truth, cluster_center_targets, eps=1e-6)

        # cluster centers correctly moved
        deltas = cluster_centers[
            prev_boosted_clusters] - previous_cluster_centers[
                prev_boosted_clusters]
        boosting_targets_indexes = boosting_targets.unsqueeze(dim=2).expand(
            flock_size, n_cluster_centers, input_size)
        boosting_cluster_centers = torch.gather(previous_cluster_centers,
                                                dim=1,
                                                index=boosting_targets_indexes)
        expected_deltas = boosting_cluster_centers[
            prev_boosted_clusters] - previous_cluster_centers[
                prev_boosted_clusters]
        expected_deltas *= learning_rate

        assert same(expected_deltas, deltas, eps=1e-2)

        # check that cluster boosting durations was increased correctly
        assert (
            cluster_boosting_durations[prev_boosted_clusters == 0] == 0).all()
        assert (
            cluster_boosting_durations[prev_boosted_clusters] == 1005).all()
Esempio n. 18
0
def test_batch_sampling():
    buffer = create_buffer(flock_size=7, buffer_size=1000, last_dim=5)

    buffer.t1.stored_data = torch.randn(buffer.t1.stored_data.size(),
                                        dtype=buffer._float_dtype,
                                        device=DEVICE)
    batch_size = 100

    sample = torch.zeros((7, 100, 5), dtype=buffer._float_dtype, device=DEVICE)

    # Test 1: Past is contiguous in the buffer, pointers equal
    buffer.current_ptr = torch.full((7, ),
                                    fill_value=990,
                                    dtype=torch.int64,
                                    device=DEVICE)
    buffer.t1._sample_batch(batch_size, sample)

    # Permute for batch-major format
    ground_truth_sample = buffer.t1.stored_data[:, 891:991]

    assert same(sample, ground_truth_sample)

    # Test2: Past is non-contiguous in the buffer, pointers equal
    buffer.current_ptr = torch.full((7, ),
                                    fill_value=50,
                                    dtype=torch.int64,
                                    device=DEVICE)
    buffer.t1._sample_batch(batch_size, sample)

    # Permute for batch-major format
    ground_truth_sample = torch.cat(
        [buffer.t1.stored_data[:, -49:], buffer.t1.stored_data[:, :51]], dim=1)

    assert same(sample, ground_truth_sample)

    # Test3: Past is uneven in the buffer, pointers unequal
    buffer.current_ptr = torch.tensor([50, 200, 10, 500, 70, 95, 33],
                                      dtype=torch.int64,
                                      device=DEVICE)
    ground_truth_sample = [
        torch.cat([
            buffer.t1.stored_data[0, -49:], buffer.t1.stored_data[0, :51]
        ]), buffer.t1.stored_data[1, 101:201],
        torch.cat(
            [buffer.t1.stored_data[2, -89:], buffer.t1.stored_data[2, :11]]),
        buffer.t1.stored_data[3, 401:501],
        torch.cat(
            [buffer.t1.stored_data[4, -29:], buffer.t1.stored_data[4, :71]]),
        torch.cat(
            [buffer.t1.stored_data[5, -4:], buffer.t1.stored_data[5, :96]]),
        torch.cat(
            [buffer.t1.stored_data[6, -66:], buffer.t1.stored_data[6, :34]])
    ]

    # After stacking, convert to batch-major via permute
    ground_truth_sample = torch.stack(ground_truth_sample)
    buffer.t1._sample_batch(batch_size, sample)

    assert same(sample, ground_truth_sample)

    # Test4: Test different batch-sizes - smaller
    batch_size = 1
    sample = torch.zeros((7, 1, 5), dtype=buffer._float_dtype, device=DEVICE)
    buffer.current_ptr = torch.full((7, ),
                                    fill_value=500,
                                    dtype=torch.int64,
                                    device=DEVICE)
    buffer.t1._sample_batch(batch_size, sample)

    ground_truth_sample = buffer.t1.stored_data[:, (501 - batch_size):501]

    assert same(sample, ground_truth_sample)

    # Test5: Test different batch-sizes - bigger
    batch_size = 423
    sample = torch.zeros((7, 423, 5), dtype=buffer._float_dtype, device=DEVICE)
    buffer.current_ptr = torch.full((7, ),
                                    fill_value=500,
                                    dtype=torch.int64,
                                    device=DEVICE)
    buffer.t1._sample_batch(batch_size, sample)

    ground_truth_sample = buffer.t1.stored_data[:, (501 - batch_size):501]

    assert same(sample, ground_truth_sample)
Esempio n. 19
0
def test_forward_learn_disambiguating_context():
    """Tests if context helps to disambiguate situations.

        Two experts, both seeing the same data and contexts
    """
    device = 'cuda'
    float_dtype = get_float(device)
    batch_size = 5

    params = ExpertParams()
    params.flock_size = 2
    params.n_cluster_centers = 3

    tp_params = params.temporal
    tp_params.n_providers = 1
    tp_params.incoming_context_size = 2
    tp_params.seq_length = 2
    tp_params.buffer_size = 1000
    tp_params.batch_size = batch_size
    tp_params.seq_lookahead = 1
    tp_params.n_frequent_seqs = 50
    tp_params.max_encountered_seqs = 300
    tp_params.forgetting_limit = 1
    tp_params.learning_period = 1
    tp_params.context_prior = SMALL_CONSTANT
    tp_params.exploration_probability = 0
    tp_params.follow_goals = False
    tp_params.enable_learning = True
    tp_params.max_new_seqs = 4
    tp_params.compute_backward_pass = True

    flock = ConvTPFlock(params, creator=AllocatingCreator(device))

    # experts:
    #   both receive a cycling sequence and useful context

    seqs = torch.tensor([[[1, 0, 0], [1, 0, 0]], [[0, 1, 0], [0, 1, 0]],
                         [[0, 0, 1], [0, 0, 1]], [[0, 1, 0], [0, 1, 0]]],
                        dtype=float_dtype,
                        device=device)

    contexts = torch.tensor(
        [[[[[1, 0], [0, 0], [0, 0]]], [[[1, 0], [0, 0], [0, 0]]]],
         [[[[1, 0], [0, 0], [0, 0]]], [[[1, 0], [0, 0], [0, 0]]]],
         [[[[1, 0], [0, 0], [0, 0]]], [[[1, 0], [0, 0], [0, 0]]]],
         [[[[0, 1], [0, 0], [0, 0]]], [[[0, 1], [0, 0], [0, 0]]]]],
        dtype=float_dtype,
        device=device)

    expected_actions = torch.tensor(
        [[[0, 1, 0], [0, 1, 0]], [[0, 0, 1], [0, 0, 1]],
         [[0, 1, 0], [0, 1, 0]], [[1, 0, 0], [1, 0, 0]]],
        dtype=float_dtype,
        device=device)

    expected_projections = torch.tensor(
        [[[0.6666, 0.3333, 0.], [0.6666, 0.3333, 0.]],
         [[0., 0.6666, 0.3333], [0., 0.6666, 0.3333]],
         [[0., 0.3333, 0.6666], [0., 0.3333, 0.6666]],
         [[0.3333, 0.6666, 0.], [0.3333, 0.6666, 0.]]],
        dtype=float_dtype,
        device=device)

    # need to learn at least 2 times because contexts are not extracted when sequence is new. And they are regarded
    #  as uniform context so we need even more to get to a sharp probability
    iterations = batch_size * 4
    for k in range(iterations):
        cluster_data = seqs[k % 4]
        context_data = contexts[k % 4]
        flock.forward_learn(cluster_data, context_data, input_rewards=None)

    # Run through the sequences yet again and no grab the outputs each time for flock 2
    for k in range(4):
        flock._forward(seqs[k], contexts[k], input_rewards=None, sp_mask=None)
        # Check that the predicted outputs are what we expect
        assert same(expected_actions[k], flock.action_outputs, eps=1e-1)
        # Check that the output projection is what we expect
        assert same(expected_projections[k],
                    flock.projection_outputs,
                    eps=3e-2)
Esempio n. 20
0
    def test_compute_similarity(self, device, item, sequences, expected_result):
        def t(data):
            return torch.tensor(data, device=device, dtype=get_float(device))

        result = TPOutputProjection.compute_similarity(t(item), t(sequences))
        assert same(t(expected_result), result, eps=1e-3)
Esempio n. 21
0
def test_convolutional_aspect():
    """Tests whether the convTP is actually convolutional,

    The convolutional TP should allow any expert to recognise and predict the next element in a sequence when one
    expert does. This test shows two experts two separate sequences and, then tests them using the sequence which the
    other expert trained.

    Because lookbehind is 2, before testing, the experts need to be 'primed' with the cluster immediately preceeding
    the sequence they are to be tested on.
    """

    device = 'cuda'
    float_dtype = get_float(device)
    batch_size = 10

    params = ExpertParams()
    params.flock_size = 2
    params.n_cluster_centers = 6

    tp_params = params.temporal
    tp_params.incoming_context_size = 2
    tp_params.seq_length = 3
    tp_params.buffer_size = 1000
    tp_params.batch_size = batch_size
    tp_params.seq_lookahead = 1
    tp_params.n_frequent_seqs = 50
    tp_params.max_encountered_seqs = 300
    tp_params.forgetting_limit = 1
    tp_params.learning_period = 1
    tp_params.context_prior = SMALL_CONSTANT
    tp_params.exploration_probability = 0
    tp_params.follow_goals = False
    tp_params.enable_learning = True
    tp_params.max_new_seqs = 4
    tp_params.compute_backward_pass = True

    flock = ConvTPFlock(params, creator=AllocatingCreator(device))

    training_seqs = torch.tensor([[[1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1]],
                                  [[0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0]],
                                  [[0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0]]],
                                 dtype=float_dtype,
                                 device=device)

    training_contexts = torch.tensor(
        [[[[[1, 0], [0, 0], [0, 0]]], [[[0, 1], [0, 0], [0, 0]]]],
         [[[[1, 0], [0, 0], [0, 0]]], [[[0, 1], [0, 0], [0, 0]]]],
         [[[[1, 0], [0, 0], [0, 0]]], [[[0, 1], [0, 0], [0, 0]]]],
         [[[[1, 0], [0, 0], [0, 0]]], [[[0, 1], [0, 0], [0, 0]]]]],
        dtype=float_dtype,
        device=device)

    expected_actions_1 = torch.tensor(
        [[[0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0]],
         [[0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0]],
         [[1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1]]],
        dtype=float_dtype,
        device=device)

    # Train the models
    iterations = batch_size + 10
    for k in range(iterations):
        for cluster_data, context_data in zip(training_seqs,
                                              training_contexts):
            flock.forward_learn(cluster_data, context_data, input_rewards=None)

    # Test that each expert can recall the sequences that it had learned
    for cluster_data, context_data, expected_action in zip(
            training_seqs, training_contexts, expected_actions_1):
        flock._forward(cluster_data,
                       context_data,
                       input_rewards=None,
                       sp_mask=None)
        # Check that the predicted outputs are what we expect
        assert same(expected_action, flock.action_outputs, eps=1e-1)

    # There is a probably a cool way to reshuffle the innermost values of the tensor, but for now,
    # just define what we want to test with manually.

    testing_seqs = torch.tensor([[[0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0]],
                                 [[0, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 0]],
                                 [[0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0]]],
                                dtype=float_dtype,
                                device=device)

    testing_contexts = torch.tensor(
        [[[[[0, 1], [0, 0], [0, 0]]], [[[1, 0], [0, 0], [0, 0]]]],
         [[[[0, 1], [0, 0], [0, 0]]], [[[1, 0], [0, 0], [0, 0]]]],
         [[[[0, 1], [0, 0], [0, 0]]], [[[1, 0], [0, 0], [0, 0]]]],
         [[[[0, 1], [0, 0], [0, 0]]], [[[1, 0], [0, 0], [0, 0]]]]],
        dtype=float_dtype,
        device=device)

    expected_actions = torch.tensor([[[0, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 0]],
                                     [[0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0]],
                                     [[0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0]]],
                                    dtype=float_dtype,
                                    device=device)

    # Because each expert maintains its own buffer, we need to "prime" them with a single example from the sequence we
    # want them to now recognise. This is the last part of testing seqs, so it lines up with the first example next time
    flock._forward(testing_seqs[2],
                   testing_contexts[2],
                   input_rewards=None,
                   sp_mask=None)

    # Test that each expert can recall the sequences that *the other expert* had learned
    for cluster_data, context_data, expected_action in zip(
            testing_seqs, testing_contexts, expected_actions):
        flock._forward(cluster_data,
                       context_data,
                       input_rewards=None,
                       sp_mask=None)
        # Check that the predicted outputs are what we expect
        assert same(expected_action, flock.action_outputs, eps=1e-1)
Esempio n. 22
0
def test_same():
    """Another test is together with same_list in test_list_utils."""
    assert same(torch.ones(10), torch.ones(10), 1e-5)
    assert not same(torch.ones(10), torch.zeros(10), 1e-5)
Esempio n. 23
0
 def _same(expected, result) -> bool:
     return expected.shape == result.shape and \
            same(result[0], result[1])
Esempio n. 24
0
def test_combine_flocks(flock_size, batch_size, overlap):
    """Test the mechanism for combining all the batches from each flock into 4 tensors with padding in between.

    """
    max_encountered_seqs = 7
    n_frequent_seqs = 3
    seq_length = 3
    n_cluster_centers = 3
    forgetting_limit = 3
    context_size = 4
    seq_lookahead = 1

    device = 'cpu'
    dtype = get_float(device)

    learning_proc = create_tp_flock_learn_process(
        flock_size=flock_size,
        max_encountered_seqs=max_encountered_seqs,
        n_frequent_seqs=n_frequent_seqs,
        seq_length=seq_length,
        n_cluster_centers=n_cluster_centers,
        batch_size=batch_size,
        forgetting_limit=forgetting_limit,
        context_size=context_size,
        device=device,
        seq_lookahead=seq_lookahead)

    cluster_batch = torch.rand((flock_size, batch_size, n_cluster_centers),
                               dtype=dtype,
                               device=device)
    context_batch = torch.rand((flock_size, batch_size, context_size),
                               dtype=dtype,
                               device=device)
    exploring_batch = torch.rand((flock_size, batch_size, 1),
                                 dtype=dtype,
                                 device=device)
    actions_batch = torch.rand((flock_size, batch_size, n_cluster_centers),
                               dtype=dtype,
                               device=device)
    rewards_batch = torch.rand((flock_size, batch_size, 2),
                               dtype=dtype,
                               device=device)

    learning_proc._subbatch_overlap = overlap

    comb_clusters, comb_contexts, comb_rewards, comb_exploring, comb_actions = learning_proc._combine_flocks(
        cluster_batch, context_batch, rewards_batch, exploring_batch,
        actions_batch)

    expected_comb_clusters = torch.cat(
        [cluster_batch,
         torch.zeros(flock_size, overlap, n_cluster_centers)],
        dim=1).view(1, -1, n_cluster_centers)
    expected_comb_contexts = torch.cat(
        [context_batch,
         torch.zeros(flock_size, overlap, context_size)],
        dim=1).view(1, -1, context_size)
    expected_comb_exploring = torch.cat(
        [exploring_batch, torch.zeros(flock_size, overlap, 1)],
        dim=1).view(1, -1, 1)
    expected_comb_actions = torch.cat(
        [actions_batch,
         torch.zeros(flock_size, overlap, n_cluster_centers)],
        dim=1).view(1, -1, n_cluster_centers)
    expected_comb_rewards = torch.cat(
        [rewards_batch, torch.zeros(flock_size, overlap, 2)],
        dim=1).view(1, -1, 2)

    expected_valid_seqs_indicator = torch.cat(
        [
            torch.ones((flock_size, batch_size - overlap), dtype=torch.int64),
            torch.zeros((flock_size, overlap * 2), dtype=torch.int64)
        ],
        dim=1).view(1, -1)[:, :learning_proc._max_seqs_in_batch]

    assert same(expected_comb_clusters, comb_clusters, eps=1e-3)
    assert same(expected_comb_contexts, comb_contexts, eps=1e-3)
    assert same(expected_comb_exploring, comb_exploring, eps=1e-3)
    assert same(expected_comb_actions, comb_actions, eps=1e-3)
    assert same(expected_comb_rewards, comb_rewards, eps=1e-3)

    assert same(expected_valid_seqs_indicator,
                learning_proc._combined_valid_seqs)
Esempio n. 25
0
def test_forward_passive():
    device = 'cuda'
    float_dtype = get_float(device)
    flock_size = 2
    buffer_size = 6
    context_size = 2
    n_cluster_centers = 3
    n_frequent_seqs = 3
    n_providers = 1

    buffer = create_tp_buffer(flock_size=flock_size,
                              buffer_size=buffer_size,
                              n_cluster_centers=n_cluster_centers,
                              n_frequent_seqs=n_frequent_seqs,
                              context_size=context_size,
                              n_providers=n_providers,
                              device=device)

    # region setup tensors

    nan = FLOAT_NAN
    small_const = SMALL_CONSTANT

    buffer.clusters.stored_data = torch.tensor(
        [
            [
                [0, 1, 0],
                [1, 0, 0],  # current_ptr
                [0, 1, 0],
                [1, 0, 0],
                [0, 0, 1],
                [1, 0, 0]
            ],
            [
                [0, 1, 0],
                [0, 0, 1],
                [1, 0, 0],
                [0, 0, 1],  # current_ptr
                [nan, nan, nan],
                [nan, nan, nan]
            ]
        ],
        dtype=float_dtype,
        device=device)
    normalize_probs_(buffer.clusters.stored_data, dim=2, add_constant=True)

    buffer.contexts.stored_data = torch.tensor(
        [
            [
                [[1, 1]],
                [[0.1, 0.1]],  # current_ptr
                [[0, 1]],
                [[1, 0.5]],
                [[1, 0]],
                [[0, 0]]
            ],
            [
                [[1, 1]],
                [[1, 1]],
                [[0.9, 0]],
                [[1, 0]],  # current_ptr
                [[nan, nan]],
                [[nan, nan]]
            ]
        ],
        dtype=float_dtype,
        device=device)
    move_probs_towards_50_(buffer.contexts.stored_data)

    # 2 is used just for checking that nothing else changed.
    buffer.seq_probs.stored_data.fill_(2)
    buffer.outputs.stored_data.fill_(2)

    buffer.current_ptr = torch.tensor([1, 3], dtype=torch.int64, device=device)
    buffer.total_data_written = torch.tensor([8, 3],
                                             dtype=torch.int64,
                                             device=device)

    frequent_context_likelihoods = torch.tensor(
        [[[[4.5, 2.5], [1, 2.5], [3, 2.5]], [[4, 2], [0.1, 2], [3, 2]],
          [[0, 0], [0, 0], [0, 0]]],
         [[[0, 1.5], [1, 1.5], [2.9, 1.5]], [[0, 0], [0, 0], [0, 0]],
          [[0, 0], [0, 0], [0, 0]]]],
        dtype=float_dtype,
        device=device)
    add_small_constant_(frequent_context_likelihoods, small_const)

    cluster_data = torch.tensor([[0, 0, 1], [0.5, 0.5, 0]],
                                dtype=float_dtype,
                                device=device)

    # sequences:
    # [1, 0, 2],
    # [0, 2, 0 or 1]

    context_data = torch.tensor(
        [[[[0, 1], [0, 0], [0, 0]]], [[[1, 0.5], [0, 0], [0, 0]]]],
        dtype=float_dtype,
        device=device)

    # contexts:
    # [[1.0, 1.0], [0.1, 0.1], [0.0, 1.0]],
    # [[0.9, 0.0], [1.0, 0.0], [1.0, 0.5]]

    # Pre-fill the output tensors so that we can check that they were written into
    projection_output = torch.full((flock_size, n_cluster_centers),
                                   fill_value=-2,
                                   dtype=float_dtype,
                                   device=device)
    action_output = torch.full((flock_size, n_cluster_centers),
                               fill_value=-2,
                               dtype=float_dtype,
                               device=device)

    # endregion

    process = create_tp_flock_untrained_forward_process(
        flock_size=flock_size,
        n_frequent_seqs=n_frequent_seqs,
        n_cluster_centers=n_cluster_centers,
        context_size=context_size,
        buffer=buffer,
        cluster_data=cluster_data,
        context_data=context_data,
        projection_outputs=projection_output,
        action_outputs=action_output,
        do_subflocking=True,
        device=device)

    process.run_and_integrate()

    # temporary process expected values

    # region expected_values
    expected_buffer_current_ptr = torch.tensor([2, 4],
                                               dtype=torch.int64,
                                               device=device)
    expected_buffer_total_data_written = torch.tensor([9, 4],
                                                      dtype=torch.int64,
                                                      device=device)

    expected_buffer_clusters = torch.tensor(
        [
            [
                [0, 1, 0],
                [1, 0, 0],
                [0, 0, 1],  # current_ptr
                [1, 0, 0],
                [0, 0, 1],
                [1, 0, 0]
            ],
            [
                [0, 1, 0],
                [0, 0, 1],
                [1, 0, 0],
                [0, 0, 1],
                [0.5, 0.5, 0],  # current_ptr
                [nan, nan, nan]
            ]
        ],
        dtype=float_dtype,
        device=device)
    normalize_probs_(expected_buffer_clusters, dim=2, add_constant=True)

    expected_buffer_contexts = torch.tensor(
        [
            [
                [[1, 1]],
                [[0.1, 0.1]],
                [[0, 1]],  # current_ptr
                [[1, 0.5]],
                [[1, 0]],
                [[0, 0]]
            ],
            [
                [[1, 1]],
                [[1, 1]],
                [[0.9, 0]],
                [[1, 0]],
                [[1, 0.5]],  # current_ptr
                [[nan, nan]]
            ]
        ],
        dtype=float_dtype,
        device=device)
    move_probs_towards_50_(expected_buffer_contexts)

    # There are 3 frequent sequences, so current pointer says that the first one is 100% probable.
    expected_buffer_seq_probs = torch.tensor(
        [
            [
                [2, 2, 2],
                [2, 2, 2],
                [0, 0, 0],  # current_ptr
                [2, 2, 2],
                [2, 2, 2],
                [2, 2, 2]
            ],
            [
                [2, 2, 2],
                [2, 2, 2],
                [2, 2, 2],
                [2, 2, 2],
                [0, 0, 0],  # current_ptr
                [2, 2, 2]
            ]
        ],
        dtype=float_dtype,
        device=device)

    fill_value = (1.0 / n_cluster_centers)
    # There are 3 cluster centers.
    expected_buffer_outputs = torch.tensor(
        [
            [
                [2, 2, 2],
                [2, 2, 2],
                [fill_value, fill_value, fill_value],  # current_ptr
                [2, 2, 2],
                [2, 2, 2],
                [2, 2, 2]
            ],
            [
                [2, 2, 2],
                [2, 2, 2],
                [2, 2, 2],
                [2, 2, 2],
                [fill_value, fill_value, fill_value],  # current_ptr
                [2, 2, 2]
            ]
        ],
        dtype=float_dtype,
        device=device)

    expected_projection_output = torch.full((2, 3),
                                            fill_value=fill_value,
                                            dtype=float_dtype,
                                            device=device)
    expected_action_output = torch.full((2, 3),
                                        fill_value=fill_value,
                                        dtype=float_dtype,
                                        device=device)

    # endregion

    assert same(expected_projection_output, projection_output, eps=1e-4)
    assert same(expected_action_output, action_output, eps=1e-4)
    # test also storing into buffer
    assert same(expected_buffer_current_ptr, buffer.current_ptr)
    assert same(expected_buffer_total_data_written, buffer.total_data_written)
    assert same(expected_buffer_outputs, buffer.outputs.stored_data, eps=1e-4)
    assert same(expected_buffer_seq_probs,
                buffer.seq_probs.stored_data,
                eps=1e-4)
    assert same(expected_buffer_clusters,
                buffer.clusters.stored_data,
                eps=1e-4)
    assert same(expected_buffer_contexts,
                buffer.contexts.stored_data,
                eps=1e-4)
Esempio n. 26
0
    def test_forward_and_learning(self):
        def manually_calc_cc_targets():
            buffer = flock.buffer
            buffer_data = torch.full(
                (flock.flock_size, flock.batch_size, flock.n_cluster_centers),
                dtype=float_dtype,
                fill_value=FLOAT_NAN,
                device=device)
            buffer.inputs._sample_batch(flock.batch_size, buffer_data)
            perm_data = buffer_data

            all_indices = torch.arange(flock.flock_size,
                                       dtype=torch.int64,
                                       device=flock._device)

            learn_process = flock._create_learning_process(all_indices)

            buffer_clusters, _ = learn_process.compute_closest_cluster_centers(
                flock.cluster_centers, buffer_data)
            perm_clusters = buffer_clusters

            all_sum_data = []
            # compute for each flock independently
            for exp_data, exp_clust in zip(perm_data, perm_clusters):
                sum_data = []
                for c in range(flock.n_cluster_centers):
                    indices = exp_clust.type(torch.ByteTensor)[:, c]
                    individual_data_points = exp_data[indices, :]
                    if sum(indices) == 0:
                        mean_data_points = torch.full((flock.input_size, ),
                                                      dtype=float_dtype,
                                                      fill_value=FLOAT_NAN,
                                                      device=device)
                    else:
                        mean_data_points = torch.mean(individual_data_points,
                                                      dim=0)
                    sum_data.append(mean_data_points)
                all_sum_data.append(torch.stack(sum_data))

            ground_truth = torch.stack(all_sum_data)
            return ground_truth

        def run_forward(data):
            forward_process = flock._create_forward_process(data, all_indices)
            forward_process.run_and_integrate()

        def run_learning():
            learn_process = flock._create_learning_process(all_indices)
            learn_process.run_and_integrate()

        n_cluster_centers = 2
        f_size = 3
        i_size = 2
        buff_size = 10
        ba_size = 1
        device = 'cuda'
        float_dtype = get_float(device)

        params = ExpertParams()
        params.flock_size = f_size
        params.n_cluster_centers = n_cluster_centers

        params.spatial.input_size = i_size
        params.spatial.buffer_size = buff_size
        params.spatial.batch_size = ba_size
        params.spatial.sampling_method = SamplingMethod.LAST_N

        flock = SPFlock(params, AllocatingCreator(device))
        flock.cluster_boosting_durations.fill_(0)

        all_indices = torch.arange(f_size, dtype=torch.int64,
                                   device=device).unsqueeze(dim=1)

        flock.cluster_centers = torch.tensor(
            [[[0.25, 1.1], [-0.3, 0.2]], [[1.2, 1.3], [-1, -2]],
             [[0.6, 0.2], [-1.2, -0.8]]],
            dtype=float_dtype,
            device=device)

        # First pass - no learning happens
        data1 = torch.tensor([[0.2, 1], [1.1, 1.1], [-1.2, -0.7]],
                             dtype=float_dtype,
                             device=device)
        cc1 = torch.tensor([[1., 0], [1., 0], [0, 1]],
                           dtype=float_dtype,
                           device=device)

        run_forward(data1)
        cc_res1 = flock.forward_clusters

        run_learning()

        assert same(cc1, cc_res1)

        # Second pass - learning happens for experts 1 and 2
        data2 = torch.tensor([[0.2, 1], [-1, -0.4], [0.2, 0.3]],
                             dtype=float_dtype,
                             device=device)
        cc2 = torch.tensor([[1., 0], [0, 1.], [1, 0]],
                           dtype=float_dtype,
                           device=device)

        run_forward(data2)
        cc_res2 = flock.forward_clusters

        cc_targets2 = manually_calc_cc_targets()
        cc_deltas2 = (cc_targets2 - flock.cluster_centers)
        cc_deltas2[torch.isnan(cc_deltas2)] = 0

        run_learning()

        assert same(cc2, cc_res2)
        assert same(cc_targets2, flock.cluster_center_targets)
        assert same(cc_deltas2, flock.cluster_center_deltas)

        # Third pass, all inputs are valid, but only expert 0 learns
        data3 = torch.tensor([[0.1, 1], [-1.1, -0.4], [0.3, 0.3]],
                             dtype=float_dtype,
                             device=device)
        cc3 = torch.tensor([[1., 0], [0, 1.], [1, 0]],
                           dtype=float_dtype,
                           device=device)

        run_forward(data3)
        cc_res3 = flock.forward_clusters

        cc_targets3 = manually_calc_cc_targets()
        cc_deltas3 = (cc_targets3 - flock.cluster_centers)
        cc_deltas3[torch.isnan(cc_deltas3)] = 0

        run_learning()

        assert same(cc3, cc_res3)
        assert same(cc_targets3, flock.cluster_center_targets)
        assert same(cc_deltas3, flock.cluster_center_deltas)

        # Test with NaN input...
        copy_of_buffer = flock.buffer.inputs.stored_data.clone()

        data4 = torch.tensor([[0.1, 1], [-1.1, FLOAT_NAN], [0.3, 0.3]],
                             dtype=float_dtype,
                             device=device)
        cc4 = cc3

        run_forward(data4)
        cc_res4 = flock.forward_clusters

        run_learning()

        assert same(
            cc4,
            cc_res4), "Classification should still work with NaN in the input"

        data5 = torch.tensor([[FLOAT_NAN, 1], [-1, -0.4], [0.2, 0.3]],
                             dtype=float_dtype,
                             device=device)
        cc5 = cc2

        run_forward(data5)
        cc_res5 = flock.forward_clusters

        run_learning()

        assert same(
            cc5,
            cc_res5), "Classification should still work with NaN in the input"
Esempio n. 27
0
def test_buffer_force_cpu(flock_indices):
    device = 'cuda'
    flock_size = 3
    buffer_size = 10
    last_dim = 4

    # Create the buffer
    buffer = Buffer(AllocatingCreator(device),
                    flock_size=flock_size,
                    buffer_size=buffer_size)
    buffer.t1 = buffer._create_storage("t1",
                                       (flock_size, buffer_size, last_dim),
                                       force_cpu=True)

    # Assemble the flock indices
    if flock_indices is not None:
        flock_indices = torch.tensor(flock_indices, dtype=torch.int64)
        buffer.set_flock_indices(flock_indices)
        flock_ind_len = flock_indices.numel()
    else:
        flock_ind_len = flock_size

    storing_data = torch.ones((flock_ind_len, last_dim),
                              dtype=FLOAT_TYPE_CUDA,
                              device=device)
    expected_stored_data = storing_data.to('cpu').type(FLOAT_TYPE_CPU)

    buffer.t1.store(storing_data)

    if flock_indices is not None:
        actual_stored_data = buffer.t1.stored_data[flock_indices, -1]
    else:
        actual_stored_data = buffer.t1.stored_data[:, -1]

    # Test some storing!
    assert same(expected_stored_data, actual_stored_data)

    # Test comparison
    expected_comparison = torch.zeros(flock_size,
                                      dtype=torch.uint8,
                                      device=device)
    data = buffer.t1.stored_data[:, -1].type(FLOAT_TYPE_CUDA).to(device)

    actual_comparison = buffer.t1.compare_with_last_data(
        data, SPFlock._detect_any_difference)

    assert same(expected_comparison, actual_comparison)

    # Test_sampling

    out_tensor = torch.zeros(flock_ind_len,
                             3,
                             last_dim,
                             dtype=FLOAT_TYPE_CUDA,
                             device=device)
    buffer.t1.sample_contiguous_batch(3, out_tensor)

    expected_out_tensor = torch.full((flock_ind_len, 3, last_dim),
                                     fill_value=FLOAT_NAN,
                                     dtype=FLOAT_TYPE_CUDA,
                                     device=device)
    expected_out_tensor[:, -1] = 1

    assert same(expected_out_tensor, out_tensor)
Esempio n. 28
0
    def test_forward_learn_subflocking(self, sampling_method):
        params = ExpertParams()
        params.flock_size = 2
        params.n_cluster_centers = 4

        params.spatial.input_size = 2
        params.spatial.cluster_boost_threshold = 2
        params.spatial.learning_rate = 0.1
        params.spatial.learning_period = 1
        params.spatial.batch_size = 8
        params.spatial.buffer_size = 10
        params.spatial.max_boost_time = 10
        params.spatial.sampling_method = sampling_method

        device = 'cuda'
        float_dtype = get_float(device)

        flock = ConvSPFlock(params, AllocatingCreator(device))

        # Flock1 sequence is [0, 0], [1, 0], [0, 1], [1, 1], [0, 1]
        # Flock2 sequence is [0, 0], [1, 0], [0, 1], [1, 1], [1, 1]
        data = torch.tensor(
            [[[0., 0], [0., 0]], [[1., 0], [1., 0]], [[0., 1], [0., 1]],
             [[1, 1], [1, 1]], [[0, 1], [1, 1]]],
            dtype=float_dtype,
            device=device)

        iters = 15

        for itr in range(iters):
            for k in data:
                flock.forward_learn(k)

        expected_forward_executions = torch.tensor([[iters * 5], [iters * 4]],
                                                   dtype=torch.int64,
                                                   device=device)
        expected_learning_executions = torch.tensor(
            [[iters * 5]], dtype=torch.int64, device=device) - 3
        expected_learning_executions = expected_learning_executions.expand(
            params.flock_size, 1)

        assert same(expected_forward_executions,
                    flock.execution_counter_forward)
        assert same(expected_learning_executions,
                    flock.execution_counter_learning)

        cluster_centers1 = flock.cluster_centers.to('cpu').data[0].numpy()
        cluster_centers2 = flock.cluster_centers.to('cpu').data[1].numpy()
        data = data.to('cpu').data.numpy()
        expected_cluster_centers1 = data[:4, 0]
        expected_cluster_centers2 = data[:4, 1]

        # Cluster centers have no guarantee of order - so we have to order them manually
        rounded_cluster_centers1 = np.around(cluster_centers1, decimals=2)
        rounded_cluster_centers2 = np.around(cluster_centers2, decimals=2)

        cc_indices1 = []
        cc_indices2 = []
        for cc1, cc2 in zip(rounded_cluster_centers1,
                            rounded_cluster_centers2):
            cc_indices1.append(cc1[0] * 2 + cc1[1] * 4)
            cc_indices2.append(cc2[0] * 2 + cc2[1] * 4)

        sorted_indices1 = np.argsort(cc_indices1)
        sorted_ccs1 = cluster_centers1[sorted_indices1]

        sorted_indices2 = np.argsort(cc_indices2)
        sorted_ccs2 = cluster_centers2[sorted_indices2]

        np.testing.assert_almost_equal(expected_cluster_centers1,
                                       sorted_ccs1,
                                       decimal=1)
        np.testing.assert_almost_equal(expected_cluster_centers2,
                                       sorted_ccs2,
                                       decimal=1)
Esempio n. 29
0
 def test_replace_cluster_ids_with_projections(self, source, projections, expected_result, device):
     t_source = torch.Tensor(source).long().to(device)
     t_projections = torch.Tensor(projections).float().to(device)
     t_expected = torch.Tensor(expected_result).to(device)
     t_result = replace_cluster_ids_with_projections(t_source, t_projections)
     assert same(t_expected, t_result)
Esempio n. 30
0
 def test_colorize(self, t_input, minimum, maximum, expected_result):
     result = self.instance._colorize(t_input, minimum, maximum)
     assert same(expected_result, result, eps=0.001)