def generate_one_node(self, only_one=False): ''' return a list of new nodes being generated ''' # different policy for adding new hierarchical structure if self.allow_hierarchy: choice = random.choice(NEW_STRUCT_OPTS) else: choice = NEW_STRUCT_OPTS[0] if self.args.force_symmetric: choice = 'l2-symmetry' if only_one: choice = 'l1-basic' if self.args.walker_force_no_sym: choice = 'l1-basic' new_node_list = [] if choice == 'l1-basic': # adding one basic node new_node = Node( -1, model_gen.gen_test_node_attr(task=self.args.task, node_num=2, discrete_rv=self.discrete)[-1]) new_node_list.append(new_node) elif choice == 'l2-symmetry': # adding 2 symmetric nodes attr1, attr2 = [ model_gen.gen_test_node_attr(task=self.args.task, node_num=2, discrete_rv=self.discrete)[-1] for i in range(2) ] same_attr = [ 'a_size', 'b_size', 'c_size', 'geom_type', 'joint_range' ] for item in same_attr: attr2[item] = attr1[item] # set certain attributes attr2['u'] = np.pi - attr1['u'] while attr2['u'] < 0: attr2['u'] += 2 * np.pi attr2['v'] = attr1['v'] attr2['axis_x'] = attr1['axis_x'] attr2['axis_y'] = -attr1['axis_y'] # create the new node with corresponding attributes node1 = Node(-1, attr1) node2 = Node(-1, attr2) new_node_list.append(node1) new_node_list.append(node2) else: raise NotImplementedError if self.args.force_grow_at_ends: for node in new_node_list: node.attr['axis_x'] = 1 if node.attr['axis_x'] >= 0 else -1 return new_node_list
def test_model_gen(args, body_part_num): ''' singularly test for the generation of the model based on the given adj_matrix ''' for num_episode in range(30): adj_matrix = model_gen.gen_test_adj_mat(hinge_opt=7, shape=(body_part_num, body_part_num)) node_attr = model_gen.gen_test_node_attr(task=args.task, node_num=body_part_num) species = hierarchy_model.Species(args, body_num=body_part_num) if 'walker' in args.task: adj_matrix[adj_matrix > 0] = 2 xml_struct = model_gen.walker_xml_generator(adj_matrix, node_attr, filename='walker_test') elif 'fish' in args.task: xml_struct = model_gen.fish_xml_generator(adj_matrix, node_attr, filename='fish_test') xml_str = etree.tostring(xml_struct) videoh = cv2.VideoWriter( str(num_episode) + '.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 40, (width * 2, height)) run_one_ep_given_model(args, adj_matrix, xml_str, videoh, max_time_step=400) return None
def test_perturb(args, max_evo_step, body_part_num): ''' ''' # initialize adj_matrix = model_gen.gen_test_adj_mat(hinge_opt=7, shape=(body_part_num, body_part_num)) node_attr = model_gen.gen_test_node_attr(node_num=body_part_num) for num_evo in range(max_evo_step): print('Evolution @ ' + str(num_evo)) xml_struct = model_gen.xml_generator(adj_matrix, node_attr, filename='evo' + str(num_evo)) xml_str = etree.tostring(xml_struct) videoh = cv2.VideoWriter('evo' + str(num_evo) + '.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 40, (width * 2, height)) run_one_ep_given_model(args, adj_matrix, xml_str, videoh=videoh, max_time_step=30) # perturb the evolution adj_matrix, node_attr, debug_info = model_perturb.perturb_topology( adj_matrix, node_attr, np.random.randint(3)) import pdb pdb.set_trace() pass return None
def __init__(self, args, body_num=3, discrete=True, allow_hierarchy=True, filter_ratio=0.5): # filter ratio self.args = args self.p = args.node_mutate_ratio self.allow_hierarchy = args.allow_hierarchy self.discrete = args.discrete_mutate if args.optimize_creature == False: # set up the tree (if no starting species is specified) r_node = Node( 0, model_gen.gen_test_node_attr(task=args.task, node_num=2, discrete_rv=discrete)[0]) self.struct_tree = Tree(r_node) if 'walker' in self.args.task: while len(self.struct_tree.get_root().get_all_descendents()) <= \ body_num: self.perturb_add(no_selfcross=True) else: for i in range(1, body_num): if self.args.force_symmetric: node_list = self.generate_one_node() else: node_list = self.generate_one_node(only_one=True) for c_node in node_list: self.struct_tree.add_sub_tree(r_node, c_node) else: if 'fish' in args.task: self.struct_tree = Tree(species_info.get_original_fish()) elif 'walker' in args.task: self.struct_tree = Tree(species_info.get_original_walker()) elif 'cheetah' in args.task: self.struct_tree = Tree(species_info.get_original_cheetah()) elif 'hopper' in args.task: self.struct_tree = Tree(species_info.get_original_hopper()) return None
def add_one_node(adj_matrix, node_attr_list, perturb_discrete=True): N, _ = adj_matrix.shape # randomly sample a parent parent_node = int(np.random.randint(N, size=1)) debug_info = {} debug_info['old_mat'] = np.copy(adj_matrix) debug_info['parent'] = parent_node # randomly sample a connection type connection_type = 7 new_col = np.zeros(N) new_col[parent_node] = connection_type new_col = new_col.reshape(-1, 1) new_row = np.zeros(N + 1) new_row[parent_node] = connection_type # adding debug information # keep track of how the graph perturbation is changed edge_dfs = model_gen_util.dfs_order(adj_matrix) dfs_order = [0] + [int(edge.split('-')[-1]) for edge in edge_dfs] child_list = \ model_gen_util.get_child_given_parent(adj_matrix, parent_node) debug_info['old_order'] = dfs_order new_order = copy.deepcopy(dfs_order) if len(child_list) == 0: insert_idx = dfs_order.index(parent_node) + 1 else: insert_idx = dfs_order.index(child_list[-1]) + 1 new_order.insert(insert_idx, -1) debug_info['new_order'] = new_order debug_info['old_nodes'] = list(range(N)) debug_info['new_nodes'] = copy.deepcopy(debug_info['old_nodes']) debug_info['new_nodes'].append(-1) # add the new node to the graph adj_matrix = np.hstack((adj_matrix, new_col)) adj_matrix = np.vstack((adj_matrix, new_row)) # sample a new set of attributes and add it to list new_node_attr = model_gen.gen_test_node_attr( node_num=2, discrete_rv=perturb_discrete)[1] node_attr_list.append(new_node_attr) return adj_matrix, node_attr_list, debug_info
def test_model_big(args, body_part_num, max_episode=100): ''' exhaustively generate and load the xml file ''' for i_ep in range(max_episode): print('Generating %6d episode...' % (i_ep)) adj_matrix = model_gen.gen_test_adj_mat(hinge_opt=7, shape=(body_part_num, body_part_num)) node_attr = model_gen.gen_test_node_attr(node_num=body_part_num) xml_struct = model_gen.fish_xml_generator(adj_matrix, node_attr, filename='fish_big_test') xml_str = etree.tostring(xml_struct) run_one_ep_given_model(args, adj_matrix, xml_str, max_time_step=1) return None
def make_symmetric(self, task='fish', discrete=True): ''' make the symmetric node w.r.t the self node symmetric node and return the new node ''' new_attr = model_gen.gen_test_node_attr(task=task, node_num=2, discrete_rv=discrete)[-1] same_attr = ['a_size', 'b_size', 'c_size', 'geom_type', 'joint_range'] for item in same_attr: new_attr[item] = self.attr[item] # set certain attributes new_attr['u'] = np.pi - self.attr['u'] while new_attr['u'] < 0: new_attr['u'] += 2 * np.pi new_attr['v'] = self.attr['v'] new_attr['axis_x'] = -self.attr['axis_x'] new_attr['axis_y'] = self.attr['axis_y'] # create the new node new_node = Node(-1, new_attr) return new_node
node_attr['axis_y'], node_attr['joint_range'] ]) return node_param, param_size_dict if __name__ == '__main__': pass N = 5 from config.config import get_config args = get_config(evolution=True) # get the adj_mat = model_gen.gen_test_adj_mat(task=args.task, shape=(N, N)) node_attr = model_gen.gen_test_node_attr(task=args.task, node_num=N) if 'fish' in args.task: xml_struct = model_gen.fish_xml_generator(adj_mat, node_attr, options=None, filename='debug_gnn_param') elif 'walker' in args.task: xml_struct = model_gen.walker_xml_generator(adj_mat, node_attr, options=None, filename='debug_gnn_param') res = gen_gnn_param(args.task, adj_mat, node_attr) # create an environment based on the adj_mat and node_attr from env import test_model_gen import lxml.etree as etree