예제 #1
0
    def __init__(self, pop_size, particle_length, w, c1, c2, evaluator=None):
        """
        constructor

        :param pop_size: population size
        :type pop_size: int
        :param particle_length: the length/dimension of the particle
        :type particle_length: int
        :param w: inertia weight
        :type w: float
        :param c1: an array of acceleration co-efficients for pbest
        :type c1: numpy.array
        :param c2: an array of acceleration co-efficients for gbest
        :type c2: numpy.array
        :param evaluator: evaluator to calculate the fitness
        :type evaluator: Evaluator
        """
        self.pop_size = pop_size
        self.pop = np.empty(pop_size, dtype=Particle)
        self.particle_length = particle_length
        self.w = w
        self.c1 = c1
        self.c2 = c2
        self.evaluator = evaluator
        self.decoder = Decoder()

        # initialise gbest to None
        self.gbest = None
예제 #2
0
    def __init__(self, id, length, w, c1, c2, layers=None, v_max=None):
        """
        constructor

        :param id: particle ID
        :type id: int
        :param length: the length/dimension of the particle
        :type length: int
        :param w: inertia weight
        :type w: float
        :param c1: an array of acceleration co-efficients for pbest
        :type c1: numpy.array
        :param c2: an array of acceleration co-efficients for gbest
        :type c2: numpy.array
        :param layers: a dict of (layer_name, layer) pairs; keys: conv, pooling, full, disabled
        :type layers: dict
        """
        super(Particle, self).__init__(id)
        self.length = length
        self.w = w
        self.c1 = c1
        self.c2 = c2
        self.v_max = v_max
        self.layers = layers
        self.decoder = Decoder()

        # initialise pbest, v to None
        self.pbest = None
        self.v = None
        self.fitness = None
예제 #3
0
    def __init__(self, str_subnet, fields):
        """
        constructor

        :param str_subnet: subnet string, e.g. 127.0.0.1/24
        :type str_subnet: string
        :param fields: a dict of (field_name, num_of_bits) pair
        :type fields: dict
        """
        self.str_subnet = str_subnet
        self.fields = fields
        self.subnet = parse_subnet_str(str_subnet)
        self.ip_structure = IPStructure(fields)
        self.encoder = Encoder(self.ip_structure, self.subnet)
        self.decoder = Decoder()
예제 #4
0
    def __init__(self, pop_size,  agent_length, f, cr, layers, evaluator=None, max_generation=None):
        """
        constructor

        :param pop_size: population size
        :type pop_size: int
        :param agent_length: the length/dimension of the agent
        :type agent_length: int
        :param f: F value in the update equation at the mutation step
        :type f: float
        :param cr: crossover rate at the mutation step
        :type cr: float
        :param layers: a dict of (layer_name, layer) pairs; keys: conv, pooling, full, disabled
        :type layers: dict
        :param evaluator: evaluator to calculate the fitness
        :type evaluator: Evaluator
        :param max_generation: max generation
        :type max_generation: int
        """
        self.pop_size = pop_size
        self.pop = np.empty(pop_size, dtype=Agent)
        self.agent_length = agent_length
        self.f = f
        self.cr = cr
        self.layers = layers
        self.max_generation = max_generation if max_generation > 0 else POPULATION_DEFAULT_PARAMS['max_generation']
        self.evaluator = evaluator
        self.decoder = Decoder()
        self.best_agent = None
예제 #5
0
    def __init__(self, id, length, layers=None, generation=0):
        """
        constructor

        :param id: chromosome ID
        :type id: int
        :param length: the length/dimension of the chromosome
        :type length: int
        :param layers: a dict of (layer_name, layer) pairs; keys: conv, pooling, full, disabled
        :type layers: dict
        :param generation: DE generation
        :type generation: int
        """
        super(Chromosome, self).__init__(id)
        self.length = length
        self.layers = layers
        self.generation = generation
        self.decoder = Decoder()

        # initialise fitness
        self.fitness = None
예제 #6
0
    def __init__(self,
                 pop_size,
                 chromosome_length,
                 elitism_rate,
                 mutation_rate,
                 layers,
                 evaluator=None,
                 max_generation=None):
        """
        constructor

        :param pop_size: population size
        :type pop_size: int
        :param chromosome_length: the length/dimension of the chromosome
        :type chromosome_length: int
        :param elitism_rate: elitism rate
        :type elitism_rate: float
        :param mutation_rate: mutation rate. [mutation rate for interfaces in a chromosome, mutation rate for bits in an interface]
        :type mutation_rate: numpy.array
        :param layers: a dict of (layer_name, layer) pairs; keys: conv, pooling, full, disabled
        :type layers: dict
        :param evaluator: evaluator to calculate the fitness
        :type evaluator: Evaluator
        :param max_generation: max generation
        :type max_generation: int
        """
        self.pop_size = pop_size
        self.pop = np.empty(pop_size, dtype=Chromosome)
        self.chromosome_length = chromosome_length
        self.elitism_rate = elitism_rate
        self.mutation_rate = mutation_rate
        self.layers = layers
        self.max_generation = max_generation if max_generation > 0 else POPULATION_DEFAULT_PARAMS[
            'max_generation']
        self.evaluator = evaluator
        self.decoder = Decoder()
        self.best_chromosome = None
        self.roulette_proportions = None
예제 #7
0
class BaseCNNLayer:
    """
    BaseCNNLayer class
    """
    def __init__(self, str_subnet, fields):
        """
        constructor

        :param str_subnet: subnet string, e.g. 127.0.0.1/24
        :type str_subnet: string
        :param fields: a dict of (field_name, num_of_bits) pair
        :type fields: dict
        """
        self.str_subnet = str_subnet
        self.fields = fields
        self.subnet = parse_subnet_str(str_subnet)
        self.ip_structure = IPStructure(fields)
        self.encoder = Encoder(self.ip_structure, self.subnet)
        self.decoder = Decoder()

    def encode_2_interface(self, field_values):
        """
        encode filed values to an IP interface

        :param field_values: field values
        :type field_values: a dict of (field_name, field_value) pairs
        :return: the layer interface
        :rtype: Interface
        """
        interface = self.encoder.encode_2_interface(field_values)
        return interface

    def decode_2_field_values(self, interface):
        """
        decode an IP interface to field values

        :param interface: an IP interface
        :type interface: Interface
        :return: a dict of (field_name, field_value) pairs
        :rtype: dict
        """
        field_values = self.decoder.decode_2_field_values(interface)
        return field_values

    def generate_random_interface(self):
        """
        generate an IP interface with random settings

        :rtype: Interface
        :return: an IP interface
        """
        field_values = {}
        for field_name in self.fields:
            num_of_bits = self.fields[field_name]
            max_value = max_decimal_value_of_binary(num_of_bits)
            rand_value = np.random.randint(0, max_value + 1)
            field_values[field_name] = rand_value
        return self.encode_2_interface(field_values)

    def check_interface_in_type(self, interface):
        """
        check whether the interface belongs to this type

        :param interface: an IP interface
        :type interface: Interface
        :return: boolean
        :rtype: bool
        """
        return self.subnet.check_ip_in_subnet(interface.ip)
예제 #8
0
class Particle(InterfaceArray):
    """
    Particle class
    """
    def __init__(self, id, length, w, c1, c2, layers=None, v_max=None):
        """
        constructor

        :param id: particle ID
        :type id: int
        :param length: the length/dimension of the particle
        :type length: int
        :param w: inertia weight
        :type w: float
        :param c1: an array of acceleration co-efficients for pbest
        :type c1: numpy.array
        :param c2: an array of acceleration co-efficients for gbest
        :type c2: numpy.array
        :param layers: a dict of (layer_name, layer) pairs; keys: conv, pooling, full, disabled
        :type layers: dict
        """
        super(Particle, self).__init__(id)
        self.length = length
        self.w = w
        self.c1 = c1
        self.c2 = c2
        self.v_max = v_max
        self.layers = layers
        self.decoder = Decoder()

        # initialise pbest, v to None
        self.pbest = None
        self.v = None
        self.fitness = None

    def update(self, gbest):
        """
        update particle

        :param gbest: global best
        :type gbest: Particle
        """
        # initialise pbest by copying itself
        if self.pbest is None:
            self.pbest = copy.deepcopy(self)
        # update position and velocity
        for i in range(self.length):
            logging.debug(
                '===start updating velocity and position of Interface-%d of Particle-%d===',
                i, self.id)
            logging.debug('interface before update: %s', str(self.x[i]))
            logging.debug('velocity before update: %s', str(self.v[i, :]))
            logging.debug('Layer-%d of the CNN before update: %s', i,
                          str(self.decoder.decode_2_field_values(self.x[i])))
            logging.debug('interface in pbest: %s', str(self.pbest.x[i]))
            logging.debug('interface in gbest: %s', str(gbest.x[i]))
            interface = self.x[i]
            gbest_interface = gbest.x[i]
            pbest_interface = self.pbest.x[i]
            for j in range(interface.ip.length):
                logging.debug(
                    '===start updating bytes-%d of Interface-%d of Particle-%d===',
                    j, i, self.id)
                # calculate the new position and velocity of one byte of the IP address
                v_ij = self.v[i, j]
                x_ij = interface.ip.ip[j]
                gbest_x_ij = gbest_interface.ip.ip[j]
                pbest_x_ij = pbest_interface.ip.ip[j]
                r1 = np.random.uniform(0, 1)
                r2 = np.random.uniform(0, 1)
                new_v_ij = self.w * v_ij + self.c1[j] * r1 * (
                    pbest_x_ij - x_ij) + self.c2[j] * r2 * (gbest_x_ij - x_ij)
                # velocity clamping
                if self.v_max is not None:
                    if new_v_ij > self.v_max[j]:
                        new_v_ij = self.v_max[j]
                new_x_ij = int(x_ij + new_v_ij)
                new_x_ij = new_x_ij if new_x_ij < 256 else new_x_ij - 256
                # update the IP and velocity of the particle
                self.x[i].update_byte(j, new_x_ij)
                self.v[i, j] = new_v_ij
                logging.debug(
                    '===finish updating bytes-%d of Interface-%d of Particle-%d===',
                    j, i, self.id)
            if self.layers is not None:
                self.x[i].update_subnet_and_structure(self.layers)
            logging.debug('interface after update: %s', str(self.x[i]))
            logging.debug('velocity after update: %s', str(self.v[i, :]))
            logging.debug('Layer-%d of the CNN after update: %s', i,
                          str(self.decoder.decode_2_field_values(self.x[i])))
            logging.debug(
                '===finish updating velocity and position of Interface-%d of Particle-%d===',
                i, self.id)

    def update_pbest(self, fitness):
        """
        update pbest

        :param fitness: fitness tuple
        :type fitness: tuple
        """
        logging.info('===start updating pbest of Particle-%d===', self.id)
        self.fitness = fitness
        # initialise the pbest with the first evaluated particle
        if self.pbest.fitness is None:
            self.pbest = copy.deepcopy(self)
            logging.info('pbest is initialised as the original particle')
        else:
            flag = self._compare_fitness(self.fitness, self.pbest.fitness)
            # particle fitness is greater than the pbest fitness
            if flag > 0:
                pbest_particle = copy.deepcopy(self)
                self.pbest = pbest_particle
                logging.info('pbest is updated by the updated particle')
        logging.info('===finish updating pbest of Particle-%d===', self.id)

    def compare_with(self, particle):
        """
        compare this particle to the input particle

        :param particle: the input particle
        :type particle: Particle
        :return: 0: equal, 1: this particle is greater, -1: this particle is less
        :rtype: int
        """
        return self._compare_fitness(self.fitness, particle.fitness)

    def _compare_fitness(self, fitness_1, fitness_2):
        """
예제 #9
0
    def __init__(self,
                 training_epoch,
                 batch_size,
                 training_data,
                 training_label,
                 validation_data,
                 validation_label,
                 max_gpu,
                 first_gpu_id,
                 class_num=10,
                 regularise=0,
                 dropout=0,
                 mean_centre=None,
                 mean_divisor=None,
                 stddev_divisor=None,
                 test_data=None,
                 test_label=None,
                 optimise=False,
                 tensorboard_path=None,
                 eval_csv_output_file=None):
        """
        constructor

        :param training_epoch: the training epoch before evaluation
        :type training_epoch: int
        :param batch_size: batch size
        :type batch_size: int
        :param training_data: training data
        :type training_data: numpy.array
        :param training_label: training label
        :type training_label: numpy.array
        :param validation_data: validation data
        :type validation_data: numpy.array
        :param validation_label: validation label
        :type validation_label: numpy.array
        :param test_data: test data
        :type test_data: numpy.array
        :param test_label: test label
        :type test_label: numpy.array
        :param class_num: class number
        :type class_num: int
        :param max_gpu: max number of gpu to be used
        :type max_gpu: int
        :param first_gpu_id: the first gpu ID. The GPUs will start from the first gpu ID
        and continue using the following GPUs until reaching the max_gpu number
        :type first_gpu_id: int
        :param tensorboard_path: tensorboard path
        :type tensorboard_path: string
        :param eval_csv_output_file: evaluation csv output file path
        :type eval_csv_output_file: string
        """
        self.training_epoch = training_epoch
        self.batch_size = batch_size
        self.training_data = training_data
        self.training_label = training_label
        self.validation_data = validation_data
        self.validation_label = validation_label
        self.test_data = test_data
        self.test_label = test_label
        self.class_num = class_num
        self.max_gpu = max_gpu
        self.first_gpu_id = first_gpu_id
        self.regularise = regularise
        self.dropout = dropout
        self.optimise = optimise
        self.tensorboarad_path = tensorboard_path
        self.eval_csv_output_file = eval_csv_output_file

        self.training_data_length = self.training_data.shape[0]
        self.validation_data_length = self.validation_data.shape[0]
        self.test_data_length = self.test_data.shape[
            0] if self.test_data is not None else 0
        self.decoder = Decoder(mean_centre=mean_centre,
                               mean_divisor=mean_divisor,
                               stddev_divisor=stddev_divisor)

        if self.tensorboarad_path is not None:
            self.train_writer = tf.summary.FileWriter(
                os.path.join(self.tensorboarad_path, 'train'))
            self.test_writer = tf.summary.FileWriter(
                os.path.join(self.tensorboarad_path, 'test'))
            self.validation_writer = tf.summary.FileWriter(
                os.path.join(self.tensorboarad_path, 'validation'))

        # set visible cuda devices
        if self.max_gpu is not None:
            for i in range(self.max_gpu):
                gpu_id = i
                if self.first_gpu_id is not None:
                    gpu_id = self.first_gpu_id + i
                print('CUDA DEVICES-{} enabled'.format(gpu_id))
                os.environ['CUDA_VISIBLE_DEVICES'] = '{}'.format(gpu_id)
예제 #10
0
class CNNEvaluator(Evaluator):
    """
    CNN evaluator
    """
    def __init__(self,
                 training_epoch,
                 batch_size,
                 training_data,
                 training_label,
                 validation_data,
                 validation_label,
                 max_gpu,
                 first_gpu_id,
                 class_num=10,
                 regularise=0,
                 dropout=0,
                 mean_centre=None,
                 mean_divisor=None,
                 stddev_divisor=None,
                 test_data=None,
                 test_label=None,
                 optimise=False,
                 tensorboard_path=None,
                 eval_csv_output_file=None):
        """
        constructor

        :param training_epoch: the training epoch before evaluation
        :type training_epoch: int
        :param batch_size: batch size
        :type batch_size: int
        :param training_data: training data
        :type training_data: numpy.array
        :param training_label: training label
        :type training_label: numpy.array
        :param validation_data: validation data
        :type validation_data: numpy.array
        :param validation_label: validation label
        :type validation_label: numpy.array
        :param test_data: test data
        :type test_data: numpy.array
        :param test_label: test label
        :type test_label: numpy.array
        :param class_num: class number
        :type class_num: int
        :param max_gpu: max number of gpu to be used
        :type max_gpu: int
        :param first_gpu_id: the first gpu ID. The GPUs will start from the first gpu ID
        and continue using the following GPUs until reaching the max_gpu number
        :type first_gpu_id: int
        :param tensorboard_path: tensorboard path
        :type tensorboard_path: string
        :param eval_csv_output_file: evaluation csv output file path
        :type eval_csv_output_file: string
        """
        self.training_epoch = training_epoch
        self.batch_size = batch_size
        self.training_data = training_data
        self.training_label = training_label
        self.validation_data = validation_data
        self.validation_label = validation_label
        self.test_data = test_data
        self.test_label = test_label
        self.class_num = class_num
        self.max_gpu = max_gpu
        self.first_gpu_id = first_gpu_id
        self.regularise = regularise
        self.dropout = dropout
        self.optimise = optimise
        self.tensorboarad_path = tensorboard_path
        self.eval_csv_output_file = eval_csv_output_file

        self.training_data_length = self.training_data.shape[0]
        self.validation_data_length = self.validation_data.shape[0]
        self.test_data_length = self.test_data.shape[
            0] if self.test_data is not None else 0
        self.decoder = Decoder(mean_centre=mean_centre,
                               mean_divisor=mean_divisor,
                               stddev_divisor=stddev_divisor)

        if self.tensorboarad_path is not None:
            self.train_writer = tf.summary.FileWriter(
                os.path.join(self.tensorboarad_path, 'train'))
            self.test_writer = tf.summary.FileWriter(
                os.path.join(self.tensorboarad_path, 'test'))
            self.validation_writer = tf.summary.FileWriter(
                os.path.join(self.tensorboarad_path, 'validation'))

        # set visible cuda devices
        if self.max_gpu is not None:
            for i in range(self.max_gpu):
                gpu_id = i
                if self.first_gpu_id is not None:
                    gpu_id = self.first_gpu_id + i
                print('CUDA DEVICES-{} enabled'.format(gpu_id))
                os.environ['CUDA_VISIBLE_DEVICES'] = '{}'.format(gpu_id)

    def eval(self, interface_array):
        """
        evaluate the interface_array

        :param interface_array: interface_array
        :type interface_array: InterfaceArray
        :return:
        """
        logging.info('===start evaluating InterfaceArray-%d===',
                     interface_array.id)
        tf.reset_default_graph()
        is_training, train_op, accuracy, cross_entropy, num_connections, merge_summary, regularization_loss, X, true_Y = self.build_graph(
            interface_array)
        with tf.Session() as sess:
            if self.tensorboarad_path is not None:
                self.train_writer.add_graph(sess.graph)
                self.validation_writer.add_graph(sess.graph)
                self.test_writer.add_graph(sess.graph)
            sess.run(tf.global_variables_initializer())
            steps_in_each_epoch = (self.training_data_length //
                                   self.batch_size)
            total_steps = int(self.training_epoch * steps_in_each_epoch)
            coord = tf.train.Coordinator()
            # threads = tf.train.start_queue_runners(sess, coord)
            try:
                threads = []
                for qr in tf.get_collection(tf.GraphKeys.QUEUE_RUNNERS):
                    threads.extend(
                        qr.create_threads(sess,
                                          coord=coord,
                                          daemon=True,
                                          start=True))
                for i in range(total_steps):
                    if coord.should_stop():
                        break
                    train_op_str, accuracy_str, loss_str, regularization_loss_str, merge_summary_str, X_str, true_Y_str, is_training_str = sess.run(
                        [
                            train_op, accuracy, cross_entropy,
                            regularization_loss, merge_summary, X, true_Y,
                            is_training
                        ], {is_training: 0})
                    self.train_writer.add_summary(
                        merge_summary_str,
                        i) if self.tensorboarad_path is not None else None
                    if i % (2 * steps_in_each_epoch) == 0:
                        training_epoch = i // steps_in_each_epoch
                        mean_validation_accu, mean_validation_loss, stddev_validation_acccu = self.test_one_epoch(
                            sess, accuracy, cross_entropy, is_training,
                            self.validation_data_length, 1, X, true_Y,
                            merge_summary, training_epoch)
                        logging.debug(
                            '{}, {}, indi:{}, Step:{}/{}, ce_loss:{}, reg_loss:{}, acc:{}, validation_ce_loss:{}, acc:{}'
                            .format(datetime.now(), i // steps_in_each_epoch,
                                    interface_array.id, i, total_steps,
                                    loss_str, regularization_loss_str,
                                    accuracy_str, mean_validation_loss,
                                    mean_validation_accu))
                        if self.optimise and self.test_data is not None:
                            mean_test_accu, mean_test_loss, _ = self.test_one_epoch(
                                sess, accuracy, cross_entropy, is_training,
                                self.test_data_length, 2, X, true_Y,
                                merge_summary, training_epoch)
                            logging.debug('test_ce_loss:{}, acc:{}'.format(
                                mean_test_loss, mean_test_accu))
                # validate the last epoch
                mean_validation_accu, mean_validation_loss, stddev_validation_acccu = self.test_one_epoch(
                    sess, accuracy, cross_entropy, is_training,
                    self.validation_data_length, 1, X, true_Y, merge_summary,
                    training_epoch)
                logging.debug('{}, validation_loss:{}, acc:{}'.format(
                    datetime.now(), mean_validation_loss,
                    mean_validation_accu))
                if self.optimise and self.test_data is not None:
                    mean_test_accu, mean_test_loss, _ = self.test_one_epoch(
                        sess, accuracy, cross_entropy, is_training,
                        self.test_data_length, 2, X, true_Y, merge_summary,
                        training_epoch)
                    logging.debug('test_ce_loss:{}, acc:{}'.format(
                        mean_test_loss, mean_test_accu))

            except Exception as e:
                print(e)
                coord.request_stop(e)
            finally:
                logging.debug('finally...')
                coord.request_stop()
                coord.join(threads)
            logging.info(
                'fitness of the interface_array: mean accuracy - %f, standard deviation of accuracy - %f, # of connections - %d',
                mean_validation_accu, stddev_validation_acccu, num_connections)
            logging.info('===finish evaluating InterfaceArray-%d===',
                         interface_array.id)
            self._eval_output(interface_array,
                              (mean_validation_accu, stddev_validation_acccu,
                               num_connections))
            return mean_validation_accu, stddev_validation_acccu, num_connections

    def test_one_epoch(self, sess, accuracy, cross_entropy, is_training,
                       data_length, training_mode, X, true_Y, merged_summary,
                       training_epoch):
        """
        test one epoch on validation data or test data
        :param sess: tensor session
        :param data_length: data length of validation or test data
        :param accuracy: accuracy variable in tensor session
        :param cross_entropy: cross_entropy variable in tensor session
        :param is_training: is_training variable in tensor session
        :param training_mode: training mode. 0:training, 1:validation, 2:test
        :return:
        """
        total_step = data_length // self.batch_size
        accuracy_list = []
        loss_list = []
        if self.tensorboarad_path is not None:
            test_valid_writer = self.validation_writer if training_mode == 1 else self.test_writer
        for _ in range(total_step):
            accuracy_str, loss_str, X_str, true_Y_str, mreged_summary_str = sess.run(
                [accuracy, cross_entropy, X, true_Y, merged_summary],
                {is_training: training_mode})
            accuracy_list.append(accuracy_str)
            loss_list.append(loss_str)
        # write the accuracy of last batch in summary
        test_valid_writer.add_summary(
            mreged_summary_str,
            training_epoch) if self.tensorboarad_path is not None else None
        mean_accu = np.mean(accuracy_list)
        mean_loss = np.mean(loss_list)
        stddev_accu = np.std(accuracy_list)
        return mean_accu, mean_loss, stddev_accu

    def build_graph(self, interface_array):
        """
        evaluate the interface_array

        :param interface_array: interface_array
        :type interface_array: InterfaceArray
        :return:
        """
        is_training = tf.placeholder(tf.int8, [])
        training_data, training_label = produce_tf_batch_data(
            self.training_data, self.training_label, self.batch_size)
        validation_data, validation_label = produce_tf_batch_data(
            self.validation_data, self.validation_label, self.batch_size)
        test_data, test_label = produce_tf_batch_data(self.test_data,
                                                      self.test_label,
                                                      self.batch_size)
        bool_is_training = tf.cond(
            tf.equal(is_training, tf.constant(0, dtype=tf.int8)),
            lambda: tf.constant(True, dtype=tf.bool),
            lambda: tf.constant(False, dtype=tf.bool))
        X, y_ = tf.cond(
            tf.equal(is_training, tf.constant(0, dtype=tf.int8)), lambda:
            (training_data, training_label), lambda: tf.cond(
                tf.equal(is_training, tf.constant(1, dtype=tf.int8)), lambda:
                (validation_data, validation_label), lambda:
                (test_data, test_label)))
        true_Y = tf.cast(y_, tf.int64)

        name_preffix = 'I_{}'.format(interface_array.id)
        output_list = []
        output_list.append(X)
        num_connections = 0

        regulariser = None
        if self.regularise is not None and self.regularise > 0:
            regulariser = slim.l2_regularizer(self.regularise)

        with slim.arg_scope([slim.conv2d, slim.fully_connected],
                            activation_fn=tf.nn.crelu,
                            normalizer_fn=slim.batch_norm,
                            weights_regularizer=regulariser,
                            normalizer_params={
                                'is_training': bool_is_training,
                                'decay': 0.99
                            }):
            i = 0
            for interface in interface_array.x:
                # conv layer
                field_values = self.decoder.decode_2_field_values(interface)
                if interface_array.layers['conv'].check_interface_in_type(
                        interface):
                    name_scope = '{}_conv_{}'.format(name_preffix, i)
                    with tf.variable_scope(name_scope):
                        filter_size, mean, stddev, feature_map_size, stride_size = self.decoder.filter_conv_fields(
                            field_values)
                        conv_H = slim.conv2d(
                            output_list[-1],
                            feature_map_size,
                            filter_size,
                            stride_size,
                            weights_initializer=self.
                            _create_weigth_initialiser(mean=mean,
                                                       stddev=stddev),
                            biases_initializer=init_ops.constant_initializer(
                                0.1, dtype=tf.float32))
                        output_list.append(conv_H)
                        # update for next usage
                        last_output_feature_map_size = feature_map_size
                        num_connections += feature_map_size * stride_size ^ 2 + feature_map_size
                # pooling layer
                elif interface_array.layers['pooling'].check_interface_in_type(
                        interface):
                    name_scope = '{}_pooling_{}'.format(name_preffix, i)
                    with tf.variable_scope(name_scope):
                        kernel_size, stride_size, kernel_type = self.decoder.filter_pooling_fields(
                            field_values)
                        if kernel_type == 0:
                            pool_H = slim.max_pool2d(output_list[-1],
                                                     kernel_size=kernel_size,
                                                     stride=stride_size,
                                                     padding='SAME')
                        else:
                            pool_H = slim.avg_pool2d(output_list[-1],
                                                     kernel_size=kernel_size,
                                                     stride=stride_size,
                                                     padding='SAME')
                        output_list.append(pool_H)
                        # pooling operation does not change the number of channel size, but channge the output size
                        last_output_feature_map_size = last_output_feature_map_size
                        num_connections += last_output_feature_map_size
                # fully-connected layer
                elif interface_array.layers['full'].check_interface_in_type(
                        interface):
                    name_scope = '{}_fully-connected_{}'.format(
                        name_preffix, i)
                    with tf.variable_scope(name_scope):
                        last_interface = interface_array.x[i - 1]
                        if not interface_array.layers[
                                'full'].check_interface_in_type(
                                    last_interface
                                ):  # use the previous setting to calculate this input dimension
                            input_data = slim.flatten(output_list[-1])
                            input_dim = input_data.get_shape()[1].value
                        else:  # current input dim should be the number of neurons in the previous hidden layer
                            input_data = output_list[-1]
                            last_filed_values = self.decoder.decode_2_field_values(
                                last_interface)
                            _, _, input_dim = last_filed_values[
                                'num_of_neurons'] + 1

                        mean, stddev, hidden_neuron_num = self.decoder.filter_full_fields(
                            field_values)
                        full_H = slim.fully_connected(
                            input_data,
                            num_outputs=hidden_neuron_num,
                            weights_initializer=self.
                            _create_weigth_initialiser(mean=mean,
                                                       stddev=stddev),
                            biases_initializer=init_ops.constant_initializer(
                                0.1, dtype=tf.float32))
                        output_list.append(self._add_dropout(full_H))
                        num_connections += input_dim * hidden_neuron_num + hidden_neuron_num
                # disabled layer
                elif interface_array.layers[
                        'disabled'].check_interface_in_type(interface):
                    name_scope = '{}_disabled_{}'.format(name_preffix, i)
                else:
                    logging.error('Invalid Interface: %s', str(interface))
                    raise Exception('invalid interface')
                i = i + 1
            # add the last layer which has the same number of neurons as the class number
            full_H = slim.fully_connected(
                output_list[-1],
                num_outputs=self.class_num,
                activation_fn=None,
                weights_initializer=self._create_weigth_initialiser(
                    mean=None, stddev=None),
                biases_initializer=init_ops.constant_initializer(
                    0.1, dtype=tf.float32))
            output_list.append(self._add_dropout(full_H))

            with tf.name_scope('loss'):
                logits = output_list[-1]
                if self.regularise is not None and self.regularise > 0:
                    regularization_loss = tf.add_n(
                        tf.losses.get_regularization_losses())
                else:
                    regularization_loss = tf.constant(0.0)
                cross_entropy = tf.reduce_mean(
                    tf.nn.sparse_softmax_cross_entropy_with_logits(
                        labels=true_Y, logits=logits))
                loss = regularization_loss + cross_entropy
            with tf.name_scope('train'):
                update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
                if update_ops:
                    updates = tf.group(*update_ops)
                    loss = control_flow_ops.with_dependencies([updates], loss)
                optimizer = tf.train.AdamOptimizer()
                train_op = slim.learning.create_train_op(loss, optimizer)
            with tf.name_scope('test'):
                accuracy = tf.reduce_mean(
                    tf.cast(tf.equal(tf.argmax(logits, 1), true_Y),
                            tf.float32))

        tf.summary.scalar('ce_loss', cross_entropy)
        tf.summary.scalar('reg_loss', regularization_loss)
        tf.summary.scalar('accuracy', accuracy)
        merge_summary = tf.summary.merge_all()

        return is_training, train_op, accuracy, cross_entropy, num_connections, merge_summary, regularization_loss, X, true_Y

    def _create_weigth_initialiser(self, mean=None, stddev=None):
        """
        create weight initialiser
        :param mean:
        :param stddev:
        :return:
        """
        if mean is None and stddev is None:
            initialiser = initializers.xavier_initializer()
        else:
            initialiser = tf.truncated_normal_initializer(mean=mean,
                                                          stddev=stddev)
        return initialiser

    def _add_dropout(self, full_H):
        """
        add dropout if needed
        :param full_H:
        :return:
        """
        if self.dropout is not None and self.dropout > 0:
            full_dropout_H = slim.dropout(full_H, self.dropout)
            logging.debug('dropout rate: {}'.format(self.dropout))
        else:
            full_dropout_H = full_H
        return full_dropout_H

    def _eval_output(self, interface_array, eval_result):
        """
        output evaluation result to csv
        :param interface_array: interface array comprised of all interfaces for the layer
        :type interface_array: InterfaceArray
        :param eval_result: evaluation result
        :type eval_result: tuple
        """
        if self.eval_csv_output_file is not None:
            fields = []
            # add the id of interface array
            fields.append(interface_array.id)
            # add all the ip addresses
            for interface in interface_array.x:
                fields.extend(interface.ip.ip.tolist())
            # add the evaluation result
            fields.extend(list(eval_result))
            with open(self.eval_csv_output_file, 'a', newline='') as f:
                writer = csv.writer(f)
                writer.writerow(fields)
            f.close()
예제 #11
0
class Population:
    """
    Population class
    """
    def __init__(self, pop_size, particle_length, w, c1, c2, evaluator=None):
        """
        constructor

        :param pop_size: population size
        :type pop_size: int
        :param particle_length: the length/dimension of the particle
        :type particle_length: int
        :param w: inertia weight
        :type w: float
        :param c1: an array of acceleration co-efficients for pbest
        :type c1: numpy.array
        :param c2: an array of acceleration co-efficients for gbest
        :type c2: numpy.array
        :param evaluator: evaluator to calculate the fitness
        :type evaluator: Evaluator
        """
        self.pop_size = pop_size
        self.pop = np.empty(pop_size, dtype=Particle)
        self.particle_length = particle_length
        self.w = w
        self.c1 = c1
        self.c2 = c2
        self.evaluator = evaluator
        self.decoder = Decoder()

        # initialise gbest to None
        self.gbest = None

    def fly_a_step(self, step):
        """
        train the PSO population for one step

        :param step: the step of the flies
        :type step: int
        """
        logging.info('===start updating population at step-%d===', step)
        i = 0
        for particle in self.pop:
            particle.update(self.gbest)
            eval_result = self.evaluator.eval(particle)
            # use minus standard deviation which is the less the better
            # use minus number of connections which is the less the better
            fitness = (eval_result[0], -eval_result[1], -eval_result[2])
            logging.info('===fitness of Particle-%d at step-%d: %s===', i,
                         step, str(fitness))
            particle.update_pbest(fitness)
            logging.info('===start updating gbest===')
            # gbest has never not been evaluated
            if self.gbest.fitness is None:
                self.gbest = copy.deepcopy(particle.pbest)
                logging.info(
                    'gbest is initialised as the first particle in the population'
                )
            # pbest is greater than gbest, update gbest
            elif particle.pbest.compare_with(self.gbest) > 0:
                self.gbest = copy.deepcopy(particle.pbest)
                logging.info('gbest is updated by Particle-%d', i)
            logging.info('===finish updating gbest===')
            i = i + 1
        logging.info('===fitness of gbest at step-%d: %s===', step,
                     str(self.gbest.fitness))
        logging.info('===finish updating population at step-%d===', step)

    def fly_2_end(self, max_steps=None):
        """
        train the PSO population until the termination criteria meet

        :param max_steps: max fly steps
        :type max_steps: int
        """
        if max_steps is None:
            max_steps = POPULATION_DEFAULT_PARAMS['max_steps']
        for i in range(max_steps):
            self.fly_a_step(i)
        logging.info('===gbest found Particle-%d===', self.gbest.id)
        for i in range(self.gbest.length):
            logging.info('Interface-%d of the particle: %s', i,
                         str(self.gbest.x[i]))
            logging.info(
                'Layer-%d of the CNN: %s', i,
                str(self.decoder.decode_2_field_values(self.gbest.x[i])))
        return self.gbest