def _replace_range(self, genotype: Genotype) -> Genotype:
        """ Replace the range values with lists

        Python's `range` is not serializable as json objects.
        We convert the genotype's ranges to lists first.

        Args:
            genotype: the genotype to be serialized

        Returns
            genotype: with proper lists.
        """
        genotype = genotype._replace(
            normal_concat=list(genotype.normal_concat))
        genotype = genotype._replace(
            reduce_concat=list(genotype.reduce_concat))
        return genotype
Beispiel #2
0
    def _convert_serialized(self, save: list) -> Genotype:
        """ Convert json serialized form to Genotype

        Args:
            save: serialized form of the the genotype

        Returns:
            the genotype
        """
        # Serialized genotypes have a consistent structure
        normal = self._convert_to_tuple(save[0])
        normal_concat = save[1]
        reduce = self._convert_to_tuple(save[2])
        reduce_concat = save[3]
        return Genotype(normal, normal_concat, reduce, reduce_concat)
    def genotype(self):
        """
        :return:
        """
        def _parse(weights):
            """
            :param weights: [14, 8]
            :return:
            """
            gene = []
            n = 2
            start = 0
            for i in range(self.num_nodes):  # for each node
                end = start + n
                W = weights[start:end].copy()  # [2, 8], [3, 8], ...
                edges = sorted(
                    range(i + 2),  # i+2 is the number of connection for node i
                    key=lambda x: -max(W[x][k]  # by descending order
                                       for k in range(len(W[x])
                                                      )  # get strongest ops
                                       if k != PRIMITIVES.index('none'))
                )[:2]  # only has two inputs
                for j in edges:  # for every input nodes j of current node i
                    k_best = None
                    for k in range(len(
                            W[j])):  # get strongest ops for current input j->i
                        if k != PRIMITIVES.index('none'):
                            if k_best is None or W[j][k] > W[j][k_best]:
                                k_best = k
                    gene.append(
                        (PRIMITIVES[k_best], j))  # save ops and input node
                start = end
                n += 1
            return gene

        gene_normal = _parse(
            F.softmax(self.alpha_normal, dim=-1).data.cpu().numpy())
        gene_reduce = _parse(
            F.softmax(self.alpha_reduce, dim=-1).data.cpu().numpy())

        concat = range(2 + self.num_nodes - self.channel_multiplier,
                       self.num_nodes + 2)
        genotype = Genotype(normal=gene_normal,
                            normal_concat=concat,
                            reduce=gene_reduce,
                            reduce_concat=concat)

        return genotype
Beispiel #4
0
    def genotype(self):
        def _isCNNStructure(k_best):
            return k_best >= 4

        def _parse(weights):
            gene = []
            n = 2
            start = 0
            cnn_structure_count = 0
            for i in range(self._steps):
                end = start + n
                W = weights[start:end].copy()
                edges = sorted(
                    range(i + 2),
                    key=lambda x: -max(W[x][k] for k in range(len(W[x]))
                                       if k != PRIMITIVES.index('none')))[:2]
                for j in edges:
                    k_best = None
                    for k in range(len(W[j])):
                        if k != PRIMITIVES.index('none'):
                            if k_best is None or W[j][k] > W[j][k_best]:
                                k_best = k

                    if _isCNNStructure(k_best):
                        cnn_structure_count += 1
                    gene.append((PRIMITIVES[k_best], j))
                start = end
                n += 1
            return gene, cnn_structure_count

        with torch.no_grad():
            gene_normal, cnn_structure_count_normal = _parse(
                F.softmax(self.alphas_normal, dim=-1).data.cpu().numpy())
            gene_reduce, cnn_structure_count_reduce = _parse(
                F.softmax(self.alphas_reduce, dim=-1).data.cpu().numpy())

            concat = range(2 + self._steps - self._multiplier, self._steps + 2)
            genotype = Genotype(normal=gene_normal,
                                normal_concat=concat,
                                reduce=gene_reduce,
                                reduce_concat=concat)
        return genotype, cnn_structure_count_normal, cnn_structure_count_reduce
Beispiel #5
0
    def genotype(self):
        """Stores connections information for current cell."""
        def _parse(alphas):
            """Does the Paired Input selection procedure.
            2 incoming edges per node are selected and
            the best op per edge is retained.
            """
            genes = []
            for alpha in alphas:
                gene = []
                for step in range(self.num_nodes):
                    inputs = alpha['input'][step].data.cpu().numpy()
                    ops = alpha['op'][step].data.cpu().numpy()
                    top_inputs = np.argmax(inputs, axis=1)
                    top_ops = np.argmax(ops, axis=1)

                    gene.append({
                        'inputs': top_inputs,
                        'ops': top_ops,
                    })
                genes.append(gene)
            return genes

        gene_normal = _parse(self.alphas_normal)
        gene_reduce = _parse(self.alphas_reduce)
        concat = range(2, self.num_nodes + 2)
        genotypes = [
            Genotype(
                normal=gene_normal,
                normal_concat=concat,
                reduce=gene_reduce,
                reduce_concat=concat,
                alphas_normal=self.alphas_normal,
                alphas_reduce=self.alphas_reduce,
            )
        ]
        return genotypes