Source code for pynas.opt.evo

import random
from ..core import architecture_builder
from copy import deepcopy


[docs] def gene_mutation(children, mutation_probability): """ Apply mutation to a list of child chromosomes. Parameters: children (list): A list of child chromosomes. mutation_probability (float): The probability of a gene mutation. Returns: list: The mutated child chromosomes. """ new_children = [] for child in children: child = deepcopy(child) for gene_index in range(len(child.chromosome)): rnd = random.random() if rnd <= mutation_probability: gene = child.chromosome[gene_index] # Mutate based on the type of gene if gene[0]=='L': # Backbone layers child.chromosome[gene_index] = architecture_builder.generate_layer_code() elif gene[0]=='P': # Pooling layer gene child.chromosome[gene_index] = architecture_builder.generate_pooling_layer_code() elif gene[0]=='H': # Head gene break else: raise ValueError(f"Unrecognized gene type: {gene[0]}") child._reparse_layers() new_children.append(child) return new_children
[docs] def single_point_crossover(parents, verbose=False): """ Performs a single-point crossover between two parent chromosomes. Parameters: parents (list): The parent chromosomes as lists of genes. Returns: list: A list containing two new child chromosomes resulting from the crossover. The crossover point is randomly selected within the range of the shorter chromosome length. """ # Determine the length of the shorter parent chromosome min_length = min(len(parents[0].chromosome), len(parents[1].chromosome)) # Randomly select a crossover point, ensuring it is within the range of both chromosomes crossover_cutoff = random.randint(1, min_length - 2) if verbose: print(f"Cut off: {crossover_cutoff}") print(f"Parent 0 chromosome: {parents[0].chromosome}") print(f"Parent 1 chromosome: {parents[1].chromosome}") # Perform crossover children = parents.copy() children[0].chromosome = parents[0].chromosome[:crossover_cutoff] + parents[1].chromosome[crossover_cutoff:] children[1].chromosome = parents[1].chromosome[:crossover_cutoff] + parents[0].chromosome[crossover_cutoff:] if verbose: print("Crossed over.") print(f"Child 0 chromosome: {children[0].chromosome}") print(f"Child 1 chromosome: {children[1].chromosome}") for child in children: child._reparse_layers() return children