def convert(self, network): """ Performs conversion. :param network: Any object that is convertible to a :class:`~peas.networks.NeuralNetwork`. """ # Cast input to a neuralnetwork if it isn't if not isinstance(network, NeuralNetwork): network = NeuralNetwork(network) # Since Stanley mentions to "fully activate" the CPPN, # I assume this means it's a feedforward net, since otherwise # there is no clear definition of "full activation". # In an FF network, activating each node once leads to a stable condition. # Check if the network has enough inputs. required_inputs = 2 * self.substrate.dimensions + 1 if self.add_deltas: required_inputs += self.substrate.dimensions if network.cm.shape[0] <= required_inputs: raise Exception( "Network does not have enough inputs. Has %d, needs %d" % (network.cm.shape[0], cm_dims + 1)) # Initialize connectivity matrix cm = np.zeros((self.substrate.num_nodes, self.substrate.num_nodes)) for (i, j ), coords, conn_id, expr_id in self.substrate.get_connection_list( self.add_deltas): expression = True if expr_id is not None: network.flush() expression = network.feed(coords, self.activation_steps)[expr_id] > 0 if expression: network.flush() weight = network.feed(coords, self.activation_steps)[conn_id] cm[j, i] = weight # Rescale the CM cm[np.abs(cm) < self.min_weight] = 0 cm -= (np.sign(cm) * self.min_weight) cm *= self.weight_range / (self.weight_range - self.min_weight) # Clip highest weights cm = np.clip(cm, -self.weight_range, self.weight_range) net = NeuralNetwork().from_matrix(cm, node_types=[self.node_type]) if self.sandwich: net.make_sandwich() if self.feedforward: net.make_feedforward() if not np.all(np.isfinite(net.cm)): raise Exception("Network contains NaN/inf weights.") return net
def convert(self, network): """ Performs conversion. :param network: Any object that is convertible to a :class:`~peas.networks.NeuralNetwork`. """ # Cast input to a neuralnetwork if it isn't if not isinstance(network, NeuralNetwork): network = NeuralNetwork(network) # Since Stanley mentions to "fully activate" the CPPN, # I assume this means it's a feedforward net, since otherwise # there is no clear definition of "full activation". # In an FF network, activating each node once leads to a stable condition. # Check if the network has enough inputs. required_inputs = 2 * self.substrate.dimensions + 1 if self.add_deltas: required_inputs += self.substrate.dimensions if network.cm.shape[0] <= required_inputs: raise Exception("Network does not have enough inputs. Has %d, needs %d" % (network.cm.shape[0], cm_dims+1)) # Initialize connectivity matrix cm = np.zeros((self.substrate.num_nodes, self.substrate.num_nodes)) for (i,j), coords, conn_id, expr_id in self.substrate.get_connection_list(self.add_deltas): expression = True if expr_id is not None: network.flush() expression = network.feed(coords, self.activation_steps)[expr_id] > 0 if expression: network.flush() weight = network.feed(coords, self.activation_steps)[conn_id] cm[j, i] = weight # Rescale the CM cm[np.abs(cm) < self.min_weight] = 0 cm -= (np.sign(cm) * self.min_weight) cm *= self.weight_range / (self.weight_range - self.min_weight) # Clip highest weights cm = np.clip(cm, -self.weight_range, self.weight_range) net = NeuralNetwork().from_matrix(cm, node_types=[self.node_type]) if self.sandwich: net.make_sandwich() if self.feedforward: net.make_feedforward() if not np.all(np.isfinite(net.cm)): raise Exception("Network contains NaN/inf weights.") return net
def evaluate(self, network, draw=False, drawname='Simulation'): """ Evaluate the efficiency of the given network. Returns the distance that the bot ran """ if not isinstance(network, NeuralNetwork): network = NeuralNetwork(network) h,w = self.field_friction.shape if draw: import pygame pygame.init() screen = pygame.display.set_mode((w, h)) pygame.display.set_caption(drawname) clock = pygame.time.Clock() running = True font = pygame.font.Font(pygame.font.get_default_font(), 12) field_image = pygame.image.load(self.observationpath) # Initialize pymunk self.space = space = pymunk.Space() space.gravity = (0,0) space.damping = self.damping # Create objects robot = Robot(space, self.field_friction, self.field_observation, self.initial_pos, friction_scale=self.friction_scale, motor_torque=self.motor_torque, force_global=self.force_global) path = [(robot.body.position.int_tuple)] cells = [] if network.cm.shape[0] != (3*5 + 3*3 + 1): raise Exception("Network shape must be a 2 layer controller: 3x5 input + 3x3 hidden + 1 bias. Has %d." % network.cm.shape[0]) for step in range(self.max_steps): net_input = np.array(list(robot.sensor_response())) # The nodes used for output are somewhere in the middle of the network # so we extract them using -4 and -6 action = network.feed(net_input)[[-4,-6]] if self.flush_each_step: network.flush() robot.drive(*action) robot.apply_friction() space.step(1/50.0) new_cell_covered = False current_cell = int(robot.body.position.x // 32), int(robot.body.position.y // 32) if current_cell not in cells: cells.append(current_cell) new_cell_covered = True if len(cells) > self.coverage_memory: cells.pop(0) elif cells[-1] == current_cell: new_cell_covered = True if step % self.path_resolution == 0 and (not self.check_coverage or new_cell_covered): path.append((robot.body.position.int_tuple)) if draw: screen.fill((255, 255, 255)) screen.blit(field_image, (0,0)) txt = font.render('%d - %.0f' % (step, path_length(path)), False, (0,0,0) ) screen.blit(txt, (0,0)) # Draw path if len(path) > 1: pygame.draw.lines(screen, (0,0,255), False, path, 3) for cell in cells: pygame.draw.rect(screen, (200,200,0), (cell[0]*32, cell[1]*32, 32, 32), 2) robot.draw(screen) if pygame.event.get(pygame.QUIT): break for k in pygame.event.get(pygame.KEYDOWN): if k.key == pygame.K_SPACE: break pygame.display.flip() # clock.tick(50) if draw: pygame.quit() self.last_path = path dist = path_length(path) speed = dist / self.max_steps return {'fitness':1 + dist**2, 'dist':dist, 'speed':speed}
def evaluate(self, network, draw=False, drawname='Simulation'): """ Evaluate the efficiency of the given network. Returns the distance that the bot ran """ if not isinstance(network, NeuralNetwork): network = NeuralNetwork(network) h, w = self.field_friction.shape if draw: import pygame pygame.init() screen = pygame.display.set_mode((w, h)) pygame.display.set_caption(drawname) clock = pygame.time.Clock() running = True font = pygame.font.Font(pygame.font.get_default_font(), 12) field_image = pygame.image.load(self.observationpath) # Initialize pymunk self.space = space = pymunk.Space() space.gravity = (0, 0) space.damping = self.damping # Create objects robot = Robot(space, self.field_friction, self.field_observation, self.initial_pos, friction_scale=self.friction_scale, motor_torque=self.motor_torque, force_global=self.force_global) path = [(robot.body.position.int_tuple)] cells = [] if network.cm.shape[0] != (3 * 5 + 3 * 3 + 1): raise Exception( "Network shape must be a 2 layer controller: 3x5 input + 3x3 hidden + 1 bias. Has %d." % network.cm.shape[0]) for step in range(self.max_steps): net_input = np.array(list(robot.sensor_response())) # The nodes used for output are somewhere in the middle of the network # so we extract them using -4 and -6 action = network.feed(net_input)[[-4, -6]] if self.flush_each_step: network.flush() robot.drive(*action) robot.apply_friction() space.step(1 / 50.0) new_cell_covered = False current_cell = int(robot.body.position.x // 32), int( robot.body.position.y // 32) if current_cell not in cells: cells.append(current_cell) new_cell_covered = True if len(cells) > self.coverage_memory: cells.pop(0) elif cells[-1] == current_cell: new_cell_covered = True if step % self.path_resolution == 0 and (not self.check_coverage or new_cell_covered): path.append((robot.body.position.int_tuple)) if draw: screen.fill((255, 255, 255)) screen.blit(field_image, (0, 0)) txt = font.render('%d - %.0f' % (step, path_length(path)), False, (0, 0, 0)) screen.blit(txt, (0, 0)) # Draw path if len(path) > 1: pygame.draw.lines(screen, (0, 0, 255), False, path, 3) for cell in cells: pygame.draw.rect(screen, (200, 200, 0), (cell[0] * 32, cell[1] * 32, 32, 32), 2) robot.draw(screen) if pygame.event.get(pygame.QUIT): break for k in pygame.event.get(pygame.KEYDOWN): if k.key == pygame.K_SPACE: break pygame.display.flip() # clock.tick(50) if draw: pygame.quit() self.last_path = path dist = path_length(path) speed = dist / self.max_steps return {'fitness': 1 + dist**2, 'dist': dist, 'speed': speed}