def genotype(self): def _parse(weights): all_step = weights.shape[0] if all_step == 1: all_ops = CLASSIFIER else: all_ops = PRIMITIVES gene = [] for i in range(all_step): W = weights[i].copy() k_best = None for k in range(len(W)): if all_step == 1 or k != all_ops.index('none'): if k_best is None or W[k] > W[k_best]: k_best = k gene.append((all_ops[k_best], i % 3)) return gene #print("self.alphas_normal", self.alphas_normal) #print("genotype, cal_alphas_normal", self.cal_alphas_normal) gene_normal = _parse( F.softmax(self.alphas_normal, dim=-1).data.cpu().numpy()) gene_normal.extend( _parse( F.softmax(self.cal_alphas_normal, dim=-1).data.cpu().numpy())) genotype = Genotype(normal=gene_normal) return genotype
def genotype(self): def _parse(weights): gene = [] n = 2 start = 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 gene.append((PRIMITIVES[k_best], j)) start = end n += 1 return gene gene_normal = _parse( F.softmax(self.alphas_normal, dim=-1).data.cpu().numpy()) gene_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
def genotype(self, skip_primitive='none'): ''' Extract the genotype, or specific connections within a cell, as encoded by the weights. # Arguments skip_primitives: hack was added by DARTS to temporarily workaround the 'strong gradient' problem identified in the sharpDARTS paper https://arxiv.org/abs/1903.09900, set skip_primitive=None to not skip any primitives. ''' gene_normal = genotype_extractor.parse_cell( F.softmax(self.alphas_normal, dim=-1).data.cpu().numpy(), primitives=self.primitives, steps=self._steps, skip_primitive=skip_primitive) gene_reduce = genotype_extractor.parse_cell( F.softmax(self.alphas_reduce, dim=-1).data.cpu().numpy(), primitives=self.primitives, steps=self._steps, skip_primitive=skip_primitive) concat = range(2 + self._steps - self._multiplier, self._steps + 2) genotype = Genotype( normal=gene_normal, normal_concat=concat, reduce=gene_reduce, reduce_concat=concat, layout='cell', ) return genotype
def parse_genotype(alphas, steps, multiplier, path=None, parse_method='threshold_sparse', op_threshold=0.85): alphas_normal, alphas_reduce = alphas gene_normal = parse(alphas_normal, PRIMITIVES, op_threshold, parse_method, steps) gene_reduce = parse(alphas_reduce, PRIMITIVES, op_threshold, parse_method, steps) concat = range(2 + steps - multiplier, steps + 2) genotype = Genotype(normal=gene_normal, normal_concat=concat, reduce=gene_reduce, reduce_concat=concat) if path is not None: if not os.path.exists(path): os.makedirs(path) print('Architecture parsing....\n', genotype) save_path = os.path.join( path, parse_method + '_' + str(op_threshold) + '.txt') with open(save_path, "w+") as f: f.write(str(genotype)) print('Save in :', save_path)
def genotype_from_id(self, genotype_id, num_nodes=None): if num_nodes is None: num_nodes = self.intermediate_nodes gene = [(self.operations[0], 0) for _ in range(num_nodes)] current_div_result = genotype_id current_node_id = num_nodes - 1 while current_div_result > 0: # print(current_div_result, current_node_id, self.num_operations) current_div_result, prec_op_id = divmod( current_div_result, ((current_node_id + 1) * self.num_operations)) prec_node_id, operation_id = divmod(prec_op_id, self.num_operations) # updating the edge for the current node slot with the new ids gene[current_node_id] = (self.operations[operation_id], prec_node_id) # updating to the next node id of the genotype slot, from bottom to top current_node_id -= 1 return Genotype(recurrent=gene, concat=range(num_nodes + 1)[-num_nodes:])
def genotype(self): def _parse(weights): gene = [] for weight in weights: w = weight.copy() argsort_w=np.argsort(w) e= argsort_w[::-1] index=e[:2] for i in index: gene.append((PRIMITIVES[i%8], i//8)) return gene rweights1 = F.softmax(self.alphas_reduce1,dim=-1).data.cpu().numpy() rweights2 = F.softmax(self.alphas_reduce2,dim=-1).data.cpu().numpy() rweights3 = F.softmax(self.alphas_reduce3,dim=-1).data.cpu().numpy() rweights4 = F.softmax(self.alphas_reduce4,dim=-1).data.cpu().numpy() nweights1 = F.softmax(self.alphas_normal1,dim=-1).data.cpu().numpy() nweights2 = F.softmax(self.alphas_normal2,dim=-1).data.cpu().numpy() nweights3 = F.softmax(self.alphas_normal3,dim=-1).data.cpu().numpy() nweights4 = F.softmax(self.alphas_normal4,dim=-1).data.cpu().numpy() gene_normal = _parse([nweights1,nweights2,nweights3,nweights4]) gene_reduce = _parse([rweights1,rweights2,rweights3,rweights4]) 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
def get_genotype(arch_names, arch_values, steps=4, multiplier=4): def _parse(stride): genotype = [] offset = 0 for i in range(steps): edges = [] edges_confident = [] for j in range(i + 2): value = arch_values[arch_names.index("arch/weight{}_{}".format( stride, offset + j))] value_sorted = value.argsort() max_index = value_sorted[-2] if value_sorted[ -1] == PRIMITIVES.index('none') else value_sorted[-1] edges.append((PRIMITIVES[max_index], j)) edges_confident.append(value[max_index]) edges_confident = np.array(edges_confident) max_edges = [ edges[np.argsort(edges_confident)[-1]], edges[np.argsort(edges_confident)[-2]] ] genotype.extend(max_edges) offset += i + 2 return genotype concat = list(range(2 + steps - multiplier, steps + 2)) gene_normal = _parse(1) gene_reduce = _parse(2) genotype = Genotype(normal=gene_normal, normal_concat=concat, reduce=gene_reduce, reduce_concat=concat) return genotype
def parse_results(results, n_nodes): concat = range(2, 2 + n_nodes) normal_gene = [] reduction_gene = [] for i in range(n_nodes): normal_node = [] reduction_node = [] for j in range(2 + i): normal_key = 'normal_n{}_p{}'.format(i + 2, j) reduction_key = 'reduce_n{}_p{}'.format(i + 2, j) normal_op = results[normal_key].cpu().numpy() reduction_op = results[reduction_key].cpu().numpy() if sum(normal_op == 1): normal_index = np.argmax(normal_op) normal_node.append((PRIMITIVES[normal_index], j)) if sum(reduction_op == 1): reduction_index = np.argmax(reduction_op) reduction_node.append((PRIMITIVES[reduction_index], j)) normal_gene.append(normal_node) reduction_gene.append(reduction_node) genotypes = Genotype(normal=normal_gene, normal_concat=concat, reduce=reduction_gene, reduce_concat=concat) return genotypes
def genotype(self): def _parse(probs): gene = [] start = 0 for i in range(STEPS): end = start + i + 1 W = probs[start:end].copy() j = sorted( range(i + 1), key=lambda x: -max(W[x][k] for k in range(len(W[x])) if k != PRIMITIVES.index('none')))[0] 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 gene.append((PRIMITIVES[k_best], j)) start = end return gene sft = True if sft: dist = F.softmax(self.weights, dim=-1) else: rel = F.relu(self.weights) dist = rel / (torch.sum(rel, dim=-1).unsqueeze_(-1) + 0.001) gene = _parse(dist.data.cpu().numpy()) genotype = Genotype(recurrent=gene, concat=range(STEPS + 1)[-CONCAT:]) return genotype
def genotype(self, alphas_normal, alphas_reduce): def _parse(weights): gene = [] index = 0 for node in range(self._steps): count = 0 for prev_node in range(node + 2): for op_id in range(self._num_ops): if weights[index][op_id] == 1: gene.append((PRIMITIVES[op_id], prev_node)) count += 1 assert count <= 2 index += 1 return gene gene_normal = _parse(alphas_normal.data.cpu().numpy()) gene_reduce = _parse(alphas_reduce.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
def genotype(self): if self.config.topo_edges == "flat": return None, False assert self.config.weight_share if self.config.op_struc == "PCC" or self.config.topo_edges == "2": return self.genotype_PCC() def _parse(weights): PRIMITIVES_pool = self.config.PRIMITIVES_pool gene = [] n = 2 start = 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_pool.index('none')))[:2] for j in edges: k_best = None for k in range(len(W[j])): if k != PRIMITIVES_pool.index('none'): if k_best is None or W[j][k] > W[j][k_best]: k_best = k gene.append((PRIMITIVES_pool[k_best], j)) start = end n += 1 return gene #alphas_normal,alphas_reduce=self.alphas_normal,self.alphas_reduce if self.config.weight_share: if self.config.op_struc == "se": if not hasattr(self, "alphas_normal"): return "", False alphas_normal, alphas_reduce = self.alphas_normal, self.alphas_reduce else: if len(self._arch_parameters) == 2: #[a,a] alphas_normal, alphas_reduce = self._arch_parameters[ 0], self._arch_parameters[1] elif len(self._arch_parameters) == 4: #[a,b,a,b] alphas_normal, alphas_reduce = self._arch_parameters[ 0], self._arch_parameters[2] else: assert False else: return "", False gene_normal = _parse( F.softmax(alphas_normal, dim=-1).data.cpu().numpy()) gene_reduce = _parse( F.softmax(alphas_reduce, dim=-1).data.cpu().numpy()) concat = self.topo_darts._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, True
def genotype(self): n = 3 start = 2 weights_beta_reduce = F.softmax(self.betas_reduce[0:2], dim=-1) weights_beta_normal = F.softmax(self.betas_normal[0:2], dim=-1) for i in range(self.num_nodes - 1): end = start + n temp_weights_beta_reduce = F.softmax(self.betas_reduce[start:end], dim=-1) temp_weights_beta_normal = F.softmax(self.betas_normal[start:end], dim=-1) start = end n += 1 weights_beta_reduce = torch.cat( [weights_beta_reduce, temp_weights_beta_reduce], dim=0) weights_beta_normal = torch.cat( [weights_beta_normal, temp_weights_beta_normal], dim=0) gene_normal = parse_pcdarts(F.softmax(self.alphas_normal, dim=-1), weights_beta_normal, self.num_nodes, 2) gene_reduce = parse_pcdarts(F.softmax(self.alphas_reduce, dim=-1), weights_beta_reduce, self.num_nodes, 2) concat = range(2, self.num_nodes + 2) genotype = Genotype(normal=gene_normal, normal_concat=concat, reduce=gene_reduce, reduce_concat=concat) return genotype
def genotype(self): def _parse(weights): gene = [] #n = 2 n = 1 start = 0 for i in range(self._steps): W = weights.copy() k_best = None for k in range(len(W[i])): if k_best is None or W[i][k] > W[i][k_best]: k_best = k gene.append((PRIMITIVES[k_best], i)) #start = end #n += 1 return gene gene_normal = _parse( F.softmax((1.05**self.epoch) * self.alphas_normal, dim=-1).data.cpu().numpy()) #concat = range(2+self._steps-self._multiplier, self._steps+2) concat = [self._steps] genotype = Genotype(normal=gene_normal, normal_concat=concat) return genotype
def genotype_child(self, normal_weights, reduce_weights): def _parse(weights): gene = [] n = 2 start = 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 != self.Primitives.index('none')))[:2] edges = sorted(range(i + 2), key=lambda x: -max(W[x][k] for k in range(len(W[x]))))[:] for j in edges: k_best = None for k in range(len(W[j])): if k_best is None or W[j][k] > W[j][k_best]: k_best = k gene.append((self.Primitives[k_best], j)) start = end n += 1 return gene gene_normal = _parse(normal_weights.detach().cpu().numpy()) gene_reduce = _parse(reduce_weights.detach().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
def genotype(alphas_normal, alphas_reduce): def _parse(weights): gene = [] n = 2 start = 0 steps = 4 for i in range(steps): end = start + n W = weights[start:end].copy() edges = sorted( range(i + 2)) # we are going to consider all input nodes 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]: ### Choose best operation // We will see... k_best = k gene.append((PRIMITIVES[k_best], j)) start = end n += 1 return gene steps = 4 multiplier = 4 concat = range(2 + steps - multiplier, steps + 2) ## <==> range(2,6) genotype = Genotype(normal=_parse(alphas_normal), normal_concat=concat, reduce=_parse(alphas_reduce), reduce_concat=concat) return genotype
def parse_network(switches_normal, switches_reduce): def _parse_switches(switches): n = 2 start = 0 gene = [] step = 4 for i in range(step): end = start + n for j in range(start, end): for k in range(len(switches[j])): if switches[j][k]: gene.append((PRIMITIVES[k], j - start)) start = end n = n + 1 return gene gene_normal = _parse_switches(switches_normal) gene_reduce = _parse_switches(switches_reduce) concat = range(2, 6) genotype = Genotype( normal=gene_normal, normal_concat=concat, reduce=gene_reduce, reduce_concat=concat ) return genotype
def geno_seeds_after_block(self, genotype_id, num_nodes): # new_nodes = [node for node in range(num_nodes + 1, self.intermediate_nodes + 1)] new_nodes = [ node for node in range(num_nodes, self.intermediate_nodes) ] print('new nodes: ', new_nodes) # taking the old genotype of the block old_geno = self.genotype_from_id(genotype_id, num_nodes=num_nodes) # initialize the new starting block new_start_nodes = [] for new_node in range(len(new_nodes)): new_start_nodes.append((self.operations[0], 0)) gene = [] gene.extend(old_geno.recurrent) gene.extend(new_start_nodes) new_geno = Genotype(recurrent=gene, concat=range(self.intermediate_nodes + 1)[-self.intermediate_nodes:]) new_geno_id = self.get_genotype_id_from_geno(new_geno) end_range = reduce((lambda x, y: x * y), new_nodes) * (self.num_operations**len(new_nodes)) gen_ids = [ gen_id for gen_id in range(new_geno_id, new_geno_id + end_range) ] print('gen ids for blocks: ', gen_ids) genotype_seeds = [self.genotype_from_id(gen_id) for gen_id in gen_ids] logger.info('genotypes seed for blocks: {}'.format(genotype_seeds)) return genotype_seeds, set(gen_ids)
def create_arm(self, arm_dir, params, combined_train=False, default=False): os.chdir(arm_dir) arm = {} if default: dirname = "default_arm" else: subdirs = next(os.walk('.'))[1] arm_num = len(subdirs) dirname = "arm" + str(arm_num) arm['seed'] = arm_num for hp in self.search_space.keys(): val = params[hp] arm[hp] = val arm['name'] = dirname if not os.path.exists(dirname): os.makedirs(dirname) arm['dir'] = arm_dir + "/" + dirname if default: arm['genotype'] = Genotype(recurrent=[('sigmoid', 0), ('relu', 1), ('relu', 1), ('identity', 1), ('tanh', 2), ('sigmoid', 5), ('tanh', 3), ('relu', 5)], concat=range(1, 9)) arm['seed'] = 0 else: for hp in self.search_space.keys(): arm[hp] = params[hp] arm['results'] = [] arm['epochs'] = 0 return arm
def arch_to_genotype(arch_normal, arch_reduce, n_nodes, cell_type, normal_concat=None, reduce_concat=None): try: primitives = eval(cell_type) except: assert False, 'not supported op type %s' % (cell_type) gene_normal = [(primitives[op], f, t) for op, f, t in arch_normal] gene_reduce = [(primitives[op], f, t) for op, f, t in arch_reduce] if normal_concat is not None: _normal_concat = normal_concat else: _normal_concat = range(2, 2 + n_nodes) if reduce_concat is not None: _reduce_concat = reduce_concat else: _reduce_concat = range(2, 2 + n_nodes) genotype = Genotype(normal=gene_normal, normal_concat=_normal_concat, reduce=gene_reduce, reduce_concat=_reduce_concat) return genotype
def parse_actions_index(actions_index): steps = 4 normal = [] reduce = [] normal_concat = set(range(2,6)) reduce_concat = set(range(2,6)) for i in range(2*steps): node1 = int(actions_index[i*5]) node2 = int(actions_index[i*5+1]) op1 = OP_NAME[actions_index[i*5+2]] op2 = OP_NAME[actions_index[i*5+3]] comb = COMB_NAME[actions_index[i*5+4]] block = (node1, node2, op1, op2, comb) if i < steps: if node1 in normal_concat: normal_concat.remove(node1) if node2 in normal_concat: normal_concat.remove(node2) normal.append(block) else: if node1 in reduce_concat: reduce_concat.remove(node1) if node2 in reduce_concat: reduce_concat.remove(node2) reduce.append(block) genotype = Genotype(normal = normal, normal_concat = normal_concat, reduce = reduce, reduce_concat = reduce_concat) return genotype
def genotype(self, layout='raw_weights'): """ layout options: raw_weights, longest_path, graph """ if layout == 'raw_weights': # TODO(ahundt) switch from raw weights to a simpler representation for genotype? gene_normal = np.array( self.arch_weights(0).data.cpu().numpy()).tolist() gene_reduce = np.array( self.arch_weights(1).data.cpu().numpy()).tolist() elif layout == 'longest_path': # TODO(ahundt) make into a list of the layer strings to be included. gene_normal = nx.algorithms.dag.dag_longest_path(self.G) gene_reduce = [] elif layout == 'graph': data = json_graph.node_link_data(self.G) gene_normal = [json.dumps(data)] gene_reduce = [] else: raise ValueError('unsupported layout: ' + str(layout)) genotype = Genotype(normal=gene_normal, normal_concat=[], reduce=gene_reduce, reduce_concat=[], layout=layout) return genotype
def construct_genotype(self, prev_node, activation): recurrent = [] concat = range(1, self.num_node + 1) for _, (node, func_id) in enumerate(zip(prev_node, activation)): name = self.get_activation(func_id) recurrent.append((name, node)) genotype = Genotype(recurrent=recurrent, concat=concat) return genotype
def genotype(self): def _parse(weights, weights2): gene = [] n = 2 start = 0 for i in range(self._steps): end = start + n W = weights[start:end].copy() W2 = weights2[start:end].copy() for j in range(n): W[j, :] = W[j, :] * W2[j] 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] # edges = sorted(range(i + 2), key=lambda x: -W2[x])[: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 gene.append((PRIMITIVES[k_best], j)) start = end n += 1 return gene n = 3 start = 2 weightsr2 = F.softmax(self.betas_reduce[0:2], dim=-1) weightsn2 = F.softmax(self.betas_normal[0:2], dim=-1) for i in range(self._steps - 1): end = start + n tw2 = F.softmax(self.betas_reduce[start:end], dim=-1) tn2 = F.softmax(self.betas_normal[start:end], dim=-1) start = end n += 1 weightsr2 = torch.cat([weightsr2, tw2], dim=0) weightsn2 = torch.cat([weightsn2, tn2], dim=0) gene_normal = _parse( F.softmax(self.alphas_normal, dim=-1).data.cpu().numpy(), weightsn2.data.cpu().numpy(), ) gene_reduce = _parse( F.softmax(self.alphas_reduce, dim=-1).data.cpu().numpy(), weightsr2.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
def genotypev2(self): gene_normal = self.multi_parsev2(self.alphas_normal) gene_reduce = self.multi_parsev2(self.alphas_reduce) 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
def genotype(self): #用来生成cell的节点之间的连接结构 def _parse(weights): gene = [] n = 2 start = 0 #self._steps:我认为是用来控制cell中的节点个数,此处=4 #i代表的是生成中间节点的第几个,i=0,表示第2个节点,...,i=3,表示第5个节点, # 因此最后将[2,3,4,5],即range(2,6)个节点进行torch.cat()操作 for i in range(self._steps): end = start + n W = weights[start:end].copy() #在这一部分就已经相应位置的alpha取了出来 '''weights.size()=[14,8],14个连线,每个线有8个操作 i=0,[start:end]=[0:2],n=3 i=1,[start:end]=[2:5],n=4 i=2,[start:end]=[5:9],n=5 i=3,[start:end]=[9:14],n=6 ''' #选出权重最大的两条边,即:第i个节点与哪两条边相连 '''range(i+2) i=0,range(2)=[0,1] i=1,range(3)=[0,1,2] i=2,range(4)=[0,1,2,3] i=3,range(5)=[0,1,2,3,4] ''' 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] #为上面选出的两条边分别确定一个权重最大的操作:j代表边的位置:即起始点的连接节点,相应的i代表对应的终点连接的节点。 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 gene.append((PRIMITIVES[k_best], j)) #PRIMITIVES[k_best]:挑选出具有最大权重的操作 #j in [0,1,2,3,4],代表的是当前节点与几号节点相连,生成的中间节点[2,3,4,5]只保留权重最大的两个操作 start = end n += 1 return gene gene_normal = _parse( F.softmax(self.alphas_normal, dim=-1).data.cpu().numpy()) gene_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
def genotype(self): def _parse(weights): gene = [] n = 2 start = 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] key=lambda x: -max(W[x][k] for k in range(len(W[x]))))[: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 gene.append((PRIMITIVES[k_best], j)) start = end n += 1 return gene def _sift_beta(betas, W): offset = 2 node3 = sorted(range(len(betas[0][0])), key=lambda x: betas[0][0][x]) node4 = sorted(range(len(betas[1][0])), key=lambda x: betas[1][0][x]) node5 = sorted(range(len(betas[2][0])), key=lambda x: betas[2][0][x]) W[offset + node3[0]][:] = 0 offset += 3 W[offset + node4[0]][:] = 0 W[offset + node4[1]][:] = 0 offset += 4 W[offset + node5[0]][:] = 0 W[offset + node5[1]][:] = 0 W[offset + node5[2]][:] = 0 return W alphas_normal = copy.deepcopy(self.alphas_normal) alphas_reduce = copy.deepcopy(self.alphas_reduce) alphas_normal = _sift_beta(self.beta_normal, alphas_normal) alphas_reduce = _sift_beta(self.beta_reduce, alphas_reduce) gene_normal = _parse( F.softmax(alphas_normal, dim=-1).data.cpu().numpy()) gene_reduce = _parse( F.softmax(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
def genotype(self, sr_max=False, print_srs=False): def _parse(weights): gene = [] n = 2 start = 0 for i in range(self._steps): end = start + n W = weights[start:end].copy() edges = sorted( range(i + 2), key=lambda x: min(W[x][k] for k in range(len(W[x]))))[:2] for j in edges: k_best = None for k in range(len(W[j])): if k_best is None or W[j][k] < W[j][k_best]: k_best = k gene.append((PRIMITIVES_SPECTRAL[k_best], j)) start = end n += 1 return gene ret_normal = [] ret_reduce = [] srs_normal = [] srs_reduce = [] concat = range(2 + self._steps - self._multiplier, self._steps + 2) for i, cell in enumerate(self.cells): cell_arch, srs = cell.extract_arch(sr_max=sr_max) if print_srs: print("cell {}".format(i)) print(srs) if cell.reduction: ret_reduce.append( Genotype_reduce(reduce=cell_arch, reduce_concat=concat)) srs_reduce.append(srs) else: ret_normal.append( Genotype_normal(normal=cell_arch, normal_concat=concat)) srs_normal.append(srs) if not sr_max: self.normal = ret_normal self.reduce = ret_reduce self.normal_mean = np.mean(srs_normal, axis=0) self.reduce_mean = np.mean(srs_reduce, axis=0) if print_srs: print("mean information") print(self.normal_mean) print(self.reduce_mean) genotypes = Genotype(normal=_parse(self.normal_mean), normal_concat=concat, reduce=_parse(self.reduce_mean), reduce_concat=concat) return ret_normal, ret_reduce, genotypes
def genotype(self): def _parse(probs): """ build the discrete representation of the cell :param probs: tensor of dim (|max_edges| x |operations| representing the prob distribution of the ops """ gene = [] start = 0 # 'i' is the index regarding the edge to the ith intermediate node for index_node in range(self.num_nodes): end = start + index_node + 1 # selecting the alpha vectors dedicated to the incoming edges of intermediate node i # for i = 2, get the vectors regarding edges: e(0,2), e(1,2) # for i = 3, get the vectors regarding edges: e(0,3), e(1,3), e(2,3) W = probs[start:end].copy() # among the vectors of the valid edges, select the vector of # the edge with the highest probable operation, this is for # the constraint that each node has only 1 incoming edge (see paper) j = sorted( range(index_node + 1), key=lambda x: -max(W[x][k] for k in range(len(W[x]))))[ 0] # if k != self.operations.index('none')))[0] # k_best = np.argmax(W[j]) 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 # appending tuple describing the edge towards the ith node, # describing the activation function and the previous node (j) gene.append((self.operations[k_best], j)) # gene.append((PRIMITIVES[k_best], j)) start = end return gene ''' softmax = torch.nn.Softmax(dim=1) gene = _parse(softmax(self.position).data.cpu().numpy()) genotype = Genotype(recurrent=gene, concat=range(self.num_nodes + 1)[-self.num_nodes:]) ''' gene = _parse(F.softmax(self.position, dim=-1).data.cpu().numpy()) genotype = Genotype(recurrent=gene, concat=range(self.num_nodes + 1)[-self.concat:]) return genotype
def get_genotype(self, force=False): if force: gene_normal = self.parse_gene_force(self.normal_candidate_flags, self.normal_selected_idxs, self.alphas_normal) else: gene_normal = self.parse_gene(self.normal_selected_idxs) n = 2 concat = range(n + self._steps - self._multiplier, self._steps + n) genotype = Genotype(normal=gene_normal, normal_concat=concat) return genotype
def eval_layer(genotype): archs = [] for i in range(len(genotype.recurrent)): recurrent = [] concat = range(1, bandit.num_node + 1) for j, (name, node) in enumerate(genotype.recurrent): if i == j: name = 'identity' recurrent.append((name, node)) new_genotype = Genotype(recurrent=recurrent, concat=concat) archs.append(new_genotype) return archs