Пример #1
0
    def kl_divergence(self, q: collections.Mapping):
        """
        Return the Kullback-Leibler divergence with probability distribution.

        This is given by the formula:

            $KL = \sum_i p_i \ln \frac {p_i} {q_i},$

        in which p_i comes from the probability object and q_i comes from the
        argument.
        """

        prob = self._data.get
        divergence = 0.0
        visited = 0

        for k, q in q.items():
            visited += 1
            p = prob(k, 0.0)
            if p:
                try:
                    divergence += p and p * log(p / q)
                except ZeroDivisionError:
                    return float('inf')

        if len(self._data) != visited:
            return float('inf')

        return divergence
Пример #2
0
def split_in_2_batches(batch: collections.Mapping, first_batch_size: int):
    """
    Split a single batch into 2 batches. The first batch will have a fixed size.

    If there is not enough sample to split the batch, return (batch, None)

    Args:
        batch: the batch to split
        first_batch_size: the batch size of the first batch. The remaining samples will be in the second batch

    Returns:
        a tuple (first batch, second batch)
    """
    batch_size = len_batch(batch)
    if batch_size <= first_batch_size:
        return batch, None

    # actually, split!
    batch_1 = type(batch)()
    batch_2 = type(batch)()

    for name, value in batch.items():
        if isinstance(value, (np.ndarray, torch.Tensor, list)):
            # split the array/list
            batch_1[name] = value[:first_batch_size]
            batch_2[name] = value[first_batch_size:]
        else:
            # for other types, simply duplicate
            batch_1[name] = value
            batch_2[name] = value

    return batch_1, batch_2
Пример #3
0
def nested_dict_contains_key(ndict: collections.Mapping, key):
    if key in ndict:
        return True
    else:
        for k, v in ndict.items():
            if isinstance(v, collections.Mapping):
                if nested_dict_contains_key(v, key):
                    return True
        return False
Пример #4
0
def flatten_dict_by_joining(
    d: collections.Mapping, parent_key: Optional[str] = "", sep: Optional[str] = "-"
) -> collections.Mapping:
    items = []
    for k, v in d.items():
        new_k = sep.join([parent_key, k]) if parent_key else k
        if isinstance(v, collections.Mapping):
            items.extend(flatten_dict_by_joining(v, new_k, sep=sep).items())
        else:
            items.append((new_k, v))
    return dict(items)
Пример #5
0
 def _check_event_handlers(self, value: collections.Mapping, level: int):
     if level > 0:
         for k, v in value.items():
             if k.startswith('_on_'):
                 assert 'name' in v, f'Missing name for the event handler \'{k}\'.'
                 assert type(
                     v['name']
                 ) == str, f'The name of event handler \'{k}\' MUST be a string.'
                 assert 'args' in v, f'Missing args for the event handler \'{k}\'.'
                 assert isinstance(
                     v, collections.Mapping
                 ), f'The args of event handler \'{k}\' MUST be an object.'
             if isinstance(v, collections.Mapping):
                 self._check_event_handlers(v, level - 1)
Пример #6
0
def list_classes_from_mapping(mappinginv: collections.Mapping,
                              default_name='unknown'):
    """
    Create a contiguous list of label names ordered from 0..N from the class mapping

    :param mappinginv: a dictionary like structure encoded as (class id, class_name)
    :param default_name: if there is no class name, use this as default
    :return: a list of class names ordered from class id = 0 to class id = N. If `mappinginv` is None,
        returns None
    """
    if mappinginv is None:
        return None
    nb_classes = max(mappinginv.keys()) + 1
    classes = [default_name] * nb_classes
    for class_id, name in mappinginv.items():
        classes[class_id] = name
    return classes
Пример #7
0
    def nested_update(self,
                      current: collections.Mapping,
                      defaults: Dict[str, Any] = ...) -> Dict[str, Any]:
        """Robust updater for nested dictionaries

        If no defaults are passed, then the instance attribute 'defaults'
        will be used.
        """
        if defaults is ...:
            defaults = self.defaults

        for key, value in current.items():
            if isinstance(value, collections.Mapping):
                result = self.nested_update(value, defaults.get(key, {}))
                defaults[key] = result
            else:
                defaults[key] = deepcopy(current[key])
        return defaults