def get_average_log_delta_for(self, layer_id: int) -> float:
        """Supports getting deltas just for the layer 0"""
        assert layer_id <= len(self._group.conv_layers)

        if layer_id == len(self._group.conv_layers):
            expert = self._group.top_layer.sp_node
        else:
            expert = self._group.conv_layers[layer_id].expert_flock_nodes[0]

        if type(expert) is ExpertFlockNode or type(
                expert) is ConvExpertFlockNode:
            # turns out that the conv expert can have shape [2,2,num_cc]
            deltas = FlockNodeAccessor.get_sp_deltas(expert)
        elif type(expert) is SpatialPoolerFlockNode or type(
                expert) is ConvSpatialPoolerFlockNode:
            deltas = SpatialPoolerFlockNodeAccessor.get_sp_deltas(expert)
        else:
            logger.error("unsupported expert type!")
            return 0

        delta = average_sp_delta(deltas)

        if delta > 0:  # avoid math.domain error
            delta = math.log(delta)
        return delta
    def get_average_log_delta_for(self, layer_id: int) -> float:
        expert = self._top_layer.sp_node
        deltas = SpatialPoolerFlockNodeAccessor.get_sp_deltas(expert)
        delta = average_sp_delta(deltas)

        if delta > 0:  # avoid math.domain error
            delta = math.log(delta)
        return delta
Exemple #3
0
    def get_average_log_delta(self) -> float:
        """Supports getting deltas just for the layer 0"""
        delta = average_sp_delta(
            SpatialPoolerFlockNodeAccessor.get_sp_deltas(self.flock_node))

        if delta > 0:  # avoid math.domain error
            delta = math.log(delta)
        return delta
    def clone_sp_output_tensor_for(self, layer_id: int) -> torch.Tensor:
        flock = self._get_flock(layer_id)
        flock_size = self.get_flock_size_of(layer_id)

        if type(flock) is ExpertFlockNode or type(
                flock) is ConvExpertFlockNode:
            # turns out that the conv expert can have shape [2,2,num_cc]
            return FlockNodeAccessor.get_sp_output_tensor(flock).clone().view(
                flock_size, -1)
        if type(flock) is SpatialPoolerFlockNode or type(
                flock) is ConvSpatialPoolerFlockNode:
            return SpatialPoolerFlockNodeAccessor.get_output_tensor(
                flock).clone().view(flock_size, -1)

        logger.error(f'unsupported flock class type')
Exemple #5
0
def test_sp_flock_node_accessor_types_and_dimensions():

    device = 'cuda'  # CPU not supported by SPFlock

    upper_bound = 107
    flock_input_size = upper_bound
    flock_size = 1

    num_cc = 21

    # define params
    sp_params = MnistSpTopology.get_sp_params(num_cluster_centers=num_cc,
                                              cluster_boost_threshold=1000,
                                              learning_rate=0.1,
                                              buffer_size=2 * 30,
                                              batch_size=30,
                                              input_size=flock_input_size,
                                              flock_size=flock_size,
                                              max_boost_time=1500)

    # random_node -> unsqueeze_node, sp_flock
    random_node = RandomNumberNode(upper_bound=upper_bound)
    unsqueeze_node = UnsqueezeNode(0)
    sp_node = SpatialPoolerFlockNode(sp_params.clone())

    Connector.connect(random_node.outputs.one_hot_output,
                      unsqueeze_node.inputs.input)
    Connector.connect(unsqueeze_node.outputs.output,
                      sp_node.inputs.sp.data_input)

    # update dimensions
    creator = AllocatingCreator(device=device)
    random_node.allocate_memory_blocks(creator)
    unsqueeze_node.allocate_memory_blocks(creator)
    sp_node.allocate_memory_blocks(creator)

    # make step
    random_node.step()
    unsqueeze_node.step()
    sp_node.step()

    # collect the results
    reconstruction = SpatialPoolerFlockNodeAccessor.get_reconstruction(sp_node)
    deltas = SpatialPoolerFlockNodeAccessor.get_sp_deltas(sp_node)
    boosting_durations = SpatialPoolerFlockNodeAccessor.get_sp_boosting_durations(
        sp_node)
    output_id = SpatialPoolerFlockNodeAccessor.get_output_id(sp_node)

    # check result properties
    assert type(reconstruction) is torch.Tensor
    assert type(deltas) is torch.Tensor
    assert type(boosting_durations) is torch.Tensor
    assert type(output_id) is int

    assert reconstruction.shape == (flock_size, flock_input_size)
    assert deltas.shape == (flock_size, num_cc, flock_input_size)
    assert boosting_durations.shape == (flock_size, num_cc)
    assert 0 <= output_id < num_cc

    # test the sp metrics
    delta = average_sp_delta(deltas)
    boosting_dur = average_boosting_duration(boosting_durations)

    nbc = num_boosted_clusters(boosting_durations)

    assert type(delta) is float
    assert type(boosting_dur) is float
    assert 0 <= boosting_dur <= 1000

    assert type(nbc) is float
    assert 0 <= nbc <= 1
Exemple #6
0
 def sp_output_tensor(self) -> torch.Tensor:
     return SpatialPoolerFlockNodeAccessor.get_output_tensor(
         self.flock_node)
Exemple #7
0
 def get_average_boosting_duration(self) -> float:
     return average_boosting_duration(
         SpatialPoolerFlockNodeAccessor.get_sp_boosting_durations(
             self.flock_node))
 def get_average_delta(self) -> float:
     delta = average_sp_delta(
         SpatialPoolerFlockNodeAccessor.get_sp_deltas(self._sp))
     if delta > 0:  # avoid math.domain error
         delta = math.log(delta)
     return delta
 def get_learned_model_output_id(self) -> int:
     return SpatialPoolerFlockNodeAccessor.get_output_id(self._sp)