python/src/genetic_search.py
def _gaussian_mutation(self, individual: np.ndarray) -> np.ndarray:
        """Apply additive gaussian noise to each device parameter with a probability of self._pmutation"""
        # pylint: disable=too-many-locals

        def round_away_from_zero(v: np.float32) -> np.int64:
            if v > 0:
                return np.ceil(v)
            if v < 0:
                return np.floor(v)
            return np.int64(0)

        vectorized_round_away_from_zero = np.vectorize(round_away_from_zero, otypes=[np.int64])

        # get the indices we can modify based on self._search_params
        indices = self._variable_indices
        n = len(indices)

        # Select which device parameters to be mutated each with a probability of p
        p = self._pmutation
        mutation_mask = np.zeros(len(individual), dtype=np.bool8)
        mutation_mask[indices] = self._rng.choice([0, 1], n, p=[1 - p, p]).astype(np.bool8)

        # Sample mutations from normal distribution, then use a symmetric rounding where mutations below zero are
        # rounded down and mutations above zero are rounded up
        # This ensures that if a device parameter is chosen to be mutated it is at least changed by +/- 1
        mutations = self._rng.normal(0, self._mutation_std_deviation, len(individual))
        rounded_mutations = vectorized_round_away_from_zero(mutations)
        mutated_individual = individual + rounded_mutations * mutation_mask

        # Clip params to bounds
        r = self._range_info
        ndevices = self._ndevices
        widths = mutated_individual[:ndevices]
        lengths = mutated_individual[ndevices:-ndevices]
        fingers = mutated_individual[-ndevices:]

        widths.clip(0, len(r.widths) - 1, out=widths)
        lengths.clip(0, len(r.lengths) - 1, out=lengths)
        fingers.clip(0, len(r.fingers) - 1, out=fingers)
        return mutated_individual.astype(np.uint64)
Apply additive gaussian noise to each device parameter with a probability of self._pmutation
Apply additive gaussian noise to each device parameter with a probability of self._pmutation
Apply additive gaussian noise to each device parameter with a probability of self . _pmutation
def _gaussian_mutation(self, individual: np.ndarray) -> np.ndarray:
        def round_away_from_zero(v: np.float32) -> np.int64:
            if v > 0:
                return np.ceil(v)
            if v < 0:
                return np.floor(v)
            return np.int64(0)
        vectorized_round_away_from_zero = np.vectorize(round_away_from_zero, otypes=[np.int64])
        indices = self._variable_indices
        n = len(indices)
        p = self._pmutation
        mutation_mask = np.zeros(len(individual), dtype=np.bool8)
        mutation_mask[indices] = self._rng.choice([0, 1], n, p=[1 - p, p]).astype(np.bool8)
        mutations = self._rng.normal(0, self._mutation_std_deviation, len(individual))
        rounded_mutations = vectorized_round_away_from_zero(mutations)
        mutated_individual = individual + rounded_mutations * mutation_mask
        r = self._range_info
        ndevices = self._ndevices
        widths = mutated_individual[:ndevices]
        lengths = mutated_individual[ndevices:-ndevices]
        fingers = mutated_individual[-ndevices:]
        widths.clip(0, len(r.widths) - 1, out=widths)
        lengths.clip(0, len(r.lengths) - 1, out=lengths)
        fingers.clip(0, len(r.fingers) - 1, out=fingers)
        return mutated_individual.astype(np.uint64)
def _gaussian_mutation ( self , individual : np . ndarray ) -> np . ndarray : def round_away_from_zero ( v : np . float32 ) -> np . int64 : if v > 0 : return np . ceil ( v ) if v < 0 : return np . floor ( v ) return np . int64 ( 0 ) vectorized_round_away_from_zero = np . vectorize ( round_away_from_zero , otypes = [ np . int64 ] ) indices = self . _variable_indices n = len ( indices ) p = self . _pmutation mutation_mask = np . zeros ( len ( individual ) , dtype = np . bool8 ) mutation_mask [ indices ] = self . _rng . choice ( [ 0 , 1 ] , n , p = [ 1 - p , p ] ) . astype ( np . bool8 ) mutations = self . _rng . normal ( 0 , self . _mutation_std_deviation , len ( individual ) ) rounded_mutations = vectorized_round_away_from_zero ( mutations ) mutated_individual = individual + rounded_mutations * mutation_mask r = self . _range_info ndevices = self . _ndevices widths = mutated_individual [ : ndevices ] lengths = mutated_individual [ ndevices : - ndevices ] fingers = mutated_individual [ - ndevices : ] widths . clip ( 0 , len ( r . widths ) - 1 , out = widths ) lengths . clip ( 0 , len ( r . lengths ) - 1 , out = lengths ) fingers . clip ( 0 , len ( r . fingers ) - 1 , out = fingers ) return mutated_individual . astype ( np . uint64 )
Apply additive gaussian noise to each device parameter with a probability of self._pmutation
Apply additive gaussian noise to each device parameter with a probability of self . _pmutation
"""Apply additive gaussian noise to each device parameter with a probability of self._pmutation""" # pylint: disable=too-many-locals # get the indices we can modify based on self._search_params # Select which device parameters to be mutated each with a probability of p # Sample mutations from normal distribution, then use a symmetric rounding where mutations below zero are # rounded down and mutations above zero are rounded up # This ensures that if a device parameter is chosen to be mutated it is at least changed by +/- 1 # Clip params to bounds
self
individual
np.ndarray