def measure(self, protocol: Protocol) -> float:
        disentanglement_scores = []
        non_constant_positions = 0

        for j in range(self.max_message_length):
            symbols_j = [message[j] for message in protocol.values()]
            symbol_mutual_info = []
            symbol_entropy = compute_entropy(symbols_j)
            for i in range(self.num_concept_slots):
                concepts_i = [
                    flatten_derivation(derivation)[i]
                    for derivation in protocol.keys()
                ]
                mutual_info = compute_mutual_information(concepts_i, symbols_j)
                symbol_mutual_info.append(mutual_info)
            symbol_mutual_info.sort(reverse=True)

            if symbol_entropy > 0:
                disentanglement_score = (
                    symbol_mutual_info[0] -
                    symbol_mutual_info[1]) / symbol_entropy
                disentanglement_scores.append(disentanglement_score)
                non_constant_positions += 1
            if non_constant_positions > 0:
                return sum(disentanglement_scores) / non_constant_positions
            else:
                return np.nan
Пример #2
0
 def _protocol_to_tensor(
     self, protocol: Protocol
 ) -> Dict[Tuple[torch.LongTensor, torch.LongTensor], torch.LongTensor]:
     vocab = get_vocab_from_protocol(protocol)
     concept_set = set(concept for derivation in protocol.keys()
                       for concept in flatten_derivation(derivation))
     concepts = {concept: idx for idx, concept in enumerate(concept_set)}
     tensorized_protocol = {}
     for derivation, message in protocol.items():
         derivation = derivation_to_tensor(derivation, concepts)
         message = torch.LongTensor([vocab[char] for char in message])
         tensorized_protocol[derivation] = torch.nn.functional.one_hot(
             message, num_classes=len(vocab)).reshape(-1)
     return tensorized_protocol