net_file = opt['dataset'] + '/net.txt' label_file = opt['dataset'] + '/label.txt' feature_file = opt['dataset'] + '/feature.txt' train_file = opt['dataset'] + '/train.txt' dev_file = opt['dataset'] + '/dev.txt' test_file = opt['dataset'] + '/test.txt' vocab_node = loader.Vocab(net_file, [0, 1]) vocab_label = loader.Vocab(label_file, [1]) vocab_feature = loader.Vocab(feature_file, [1]) opt['num_node'] = len(vocab_node) opt['num_feature'] = len(vocab_feature) opt['num_class'] = len(vocab_label) graph = loader.Graph(file_name=net_file, entity=[vocab_node, 0, 1]) label = loader.EntityLabel(file_name=label_file, entity=[vocab_node, 0], label=[vocab_label, 1]) feature = loader.EntityFeature(file_name=feature_file, entity=[vocab_node, 0], feature=[vocab_feature, 1]) partition_num = opt['partition_num'] partition_labels = graph.partition(partition_num) graph.to_symmetric(opt['self_link_weight']) feature.to_one_hot(binary=True) adj = graph.get_sparse_adjacency(opt['cuda']) with open(train_file, 'r') as fi:
def pre_train(epoches): best = 0.0 init_q_data() results = [] for epoch in range(epoches): #loss = trainer_q.update_soft_mlp(inputs_q, target_q, idx_train) #loss = trainer_q.update_soft(inputs_q, target_q, idx_train) #import pdb; pdb.set_trace() ### create mix of feature and labels rand_index = random.randint(0,1) if rand_index == 0: ### create a new net file### if os.path.exists(net_temp_file): os.remove(net_temp_file) copyfile(net_file, net_temp_file) else: copyfile(net_file, net_temp_file) lamb = np.random.beta(opt['mixup_alpha'],opt['mixup_alpha']) inputs_q_new = inputs_q target_q_new = target_q idx_train_new = torch.tensor([], dtype= idx_train.dtype).cuda()# idx_train# [] for not adding the original idx_train in the additional train data target_new = target for j in range(2): permuted_train_idx = idx_train[torch.randperm(idx_train.shape[0])] train_x_additional = lamb*inputs_q[idx_train]+ (1-lamb)*inputs_q[permuted_train_idx] train_y_additional = lamb*target_q[idx_train]+ (1-lamb)*target_q[permuted_train_idx] idx_train_additional = np.arange(idx_train.shape[0]) idx_train_additional = torch.from_numpy(idx_train_additional) idx_train_additional = idx_train_additional.cuda() idx_train_additional = idx_train_additional + target_q_new.shape[0] inputs_q_new = torch.cat((inputs_q_new, train_x_additional),0) target_q_new = torch.cat((target_q_new, train_y_additional),0) idx_train_new = torch.cat((idx_train_new, idx_train_additional),0) ## add dummy labels to the target tensor, these dummy values will not be used so I just used '0'## #import pdb; pdb.set_trace() temp = torch.zeros(train_y_additional.shape[0], dtype = target.dtype) temp = temp.cuda() target_new = torch.cat((target_new, temp),0) #import pdb; pdb.set_trace() fi = open(net_temp_file, 'a+') start_index_for_additional_nodes = target_q.shape[0]+j*idx_train.shape[0] for i in range(idx_train.shape[0]): node_index = start_index_for_additional_nodes+i fi.write(str(node_index)+'\t'+str(idx_train[i].item())+'\t'+str(1)+'\n') fi.write(str(idx_train[i].item())+'\t'+str(node_index)+'\t'+str(1)+'\n') fi.write(str(node_index)+'\t'+str(permuted_train_idx[i].item())+'\t'+str(1)+'\n') fi.write(str(permuted_train_idx[i].item())+'\t'+str(node_index)+'\t'+str(1)+'\n') fi.close() #import pdb; pdb.set_trace() ## reload the net file in the adjacency matrix### vocab_node = loader.Vocab(net_temp_file, [0, 1]) graph = loader.Graph(file_name=net_file, entity=[vocab_node, 0, 1]) graph.to_symmetric(opt['self_link_weight']) adj_new = graph.get_sparse_adjacency(opt['cuda']) #import pdb; pdb.set_trace() trainer_q.model.adj = adj_new trainer_q.model.m1.adj = adj_new trainer_q.model.m2.adj = adj_new #trainer_q.model.m3.adj = adj #trainer_q.model.m4.adj = adj #idx_train_new = #loss = trainer_q.update_soft_mix(inputs_q, target_q, idx_train)## for mixing features loss = trainer_q.update_soft(inputs_q_new, target_q_new, idx_train_new)## for augmented nodes else: loss = trainer_q.update_soft(inputs_q, target_q, idx_train) #loss = trainer_q.update_soft_aux(inputs_q, target_q, idx_train)## for training aux networks loss_aux = loss #loss, loss_aux = trainer_q.update_soft_aux(inputs_q, target_q, idx_train, epoch, opt)## for auxiliary net with shared parameters trainer_q.model.adj = adj trainer_q.model.m1.adj = adj trainer_q.model.m2.adj = adj _, preds, accuracy_train = trainer_q.evaluate(inputs_q, target, idx_train) ## target_new : for augmented nodes _, preds, accuracy_dev = trainer_q.evaluate(inputs_q, target, idx_dev) _, preds, accuracy_test = trainer_q.evaluate(inputs_q, target, idx_test) results += [(accuracy_dev, accuracy_test)] if epoch%100 == 0: print ('epoch :{:4d},loss:{:.10f},loss:{:.10f}, train_acc:{:.3f}, dev_acc:{:.3f}, test_acc:{:.3f}'.format(epoch, loss,loss_aux, accuracy_train, accuracy_dev, accuracy_test)) if accuracy_dev > best: best = accuracy_dev state = dict([('model', copy.deepcopy(trainer_q.model.state_dict())), ('optim', copy.deepcopy(trainer_q.optimizer.state_dict()))]) #trainer_q.model.load_state_dict(state['model']) #trainer_q.optimizer.load_state_dict(state['optim']) return results
def main(opt): device = torch.device('cuda' if opt['cuda'] == True and torch.cuda.is_available() else 'cpu') #-------------------------------------------------- # Load data. #-------------------------------------------------- net_file = opt['dataset'] + '/net.txt' label_file = opt['dataset'] + '/label.txt' feature_file = opt['dataset'] + '/feature.txt' train_file = opt['dataset'] + '/train.txt' dev_file = opt['dataset'] + '/dev.txt' test_file = opt['dataset'] + '/test.txt' vocab_node = loader.Vocab(net_file, [0, 1]) vocab_label = loader.Vocab(label_file, [1]) vocab_feature = loader.Vocab(feature_file, [1]) opt['num_node'] = len(vocab_node) opt['num_feature'] = len(vocab_feature) opt['num_class'] = len(vocab_label) graph = loader.Graph(file_name=net_file, entity=[vocab_node, 0, 1]) label = loader.EntityLabel(file_name=label_file, entity=[vocab_node, 0], label=[vocab_label, 1]) feature = loader.EntityFeature(file_name=feature_file, entity=[vocab_node, 0], feature=[vocab_feature, 1]) d = graph.to_symmetric(opt['self_link_weight']) feature.to_one_hot(binary=True) adj = graph.get_sparse_adjacency(opt['cuda']) deg = torch.zeros(adj.shape[0]) for k,v in d.items(): deg[k] = v with open(train_file, 'r') as fi: idx_train = [vocab_node.stoi[line.strip()] for line in fi] with open(dev_file, 'r') as fi: idx_dev = [vocab_node.stoi[line.strip()] for line in fi] with open(test_file, 'r') as fi: idx_test = [vocab_node.stoi[line.strip()] for line in fi] inputs = torch.Tensor(feature.one_hot) target = torch.LongTensor(label.itol) idx_train = torch.LongTensor(idx_train) idx_dev = torch.LongTensor(idx_dev) idx_test = torch.LongTensor(idx_test) if opt['cuda']: inputs = inputs.cuda() target = target.cuda() idx_train = idx_train.cuda() idx_dev = idx_dev.cuda() idx_test = idx_test.cuda() #-------------------------------------------------- # Build model. #-------------------------------------------------- if opt['weight']: gnn = WGNN(opt, adj, deg, opt['time']) else: gnn = GNN(opt, adj, deg, opt['time']) trainer = Trainer(opt, gnn) print(gnn) print(opt) #-------------------------------------------------- # Train model. #-------------------------------------------------- def train(epochs): best = 0.0 results = [] prev_dev_acc = 0 cnt = 0 lr = opt['lr'] for epoch in range(0, epochs): # ----------------------- # Train Model # ----------------------- if opt['weight']: loss = trainer.updatew(inputs, target, idx_train) else: loss = trainer.update(inputs, target, idx_train) # ----------------------- # Evaluate Model # ----------------------- _, preds, accuracy_dev = trainer.evaluate(inputs, target, idx_dev) # ----------------------- # Test Model # ----------------------- _, preds, accuracy_test = trainer.evaluate(inputs, target, idx_test) print( 'Epoch: {} | Loss: {:.3f} | Dev acc: {:.3f} | Test acc: {:.3f} | Forward: {} {:.3f} | Backward: {} {:.3f}'.format( epoch, loss, accuracy_dev, accuracy_test, trainer.fm.get_value(), trainer.fm.get_average(), trainer.bm.get_value(), trainer.bm.get_average())) results += [(accuracy_dev, accuracy_test)] if accuracy_dev >= best: best = accuracy_dev state = dict([('model', copy.deepcopy(trainer.model.state_dict())), ('optim', copy.deepcopy(trainer.optimizer.state_dict()))]) trainer.model.load_state_dict(state['model']) trainer.optimizer.load_state_dict(state['optim']) return results results = train(opt['epoch']) def get_accuracy(results): best_dev, acc_test = 0.0, 0.0 for d, t in results: if d > best_dev: best_dev, acc_test = d, t return acc_test, best_dev acc_test = get_accuracy(results) print('{:.3f}'.format(acc_test[0]*100)) return acc_test
def get_augmented_network_input(model, inputs_q, target_q, target, idx_train,opt): # idx_train : this is the index of the nodes that will be mixed # pass the train node idx ( labeled nodes) or the unlabeled node idx here ### create a new net file### if os.path.exists(opt['net_temp_file']): os.remove(opt['net_temp_file']) copyfile(opt['net_file'], opt['net_temp_file']) else: copyfile(opt['net_file'], opt['net_temp_file']) lamb = np.random.beta(opt['mixup_alpha'],opt['mixup_alpha']) #import pdb; pdb.set_trace() inputs_q_new = inputs_q target_q_new = target_q idx_train_new = torch.tensor([], dtype= idx_train.dtype).cuda()# idx_train# [] for not adding the original idx_train in the additional train data target_new = target for j in range(1): permuted_train_idx = idx_train[torch.randperm(idx_train.shape[0])] train_x_additional = lamb*inputs_q[idx_train]+ (1-lamb)*inputs_q[permuted_train_idx] train_y_additional = lamb*target_q[idx_train]+ (1-lamb)*target_q[permuted_train_idx] idx_train_additional = np.arange(idx_train.shape[0]) idx_train_additional = torch.from_numpy(idx_train_additional) idx_train_additional = idx_train_additional.cuda() idx_train_additional = idx_train_additional + target_q_new.shape[0] inputs_q_new = torch.cat((inputs_q_new, train_x_additional),0) target_q_new = torch.cat((target_q_new, train_y_additional),0) idx_train_new = torch.cat((idx_train_new, idx_train_additional),0) ## add dummy labels to the target tensor, these dummy values will not be used so I just used '0'## #import pdb; pdb.set_trace() temp = torch.zeros(train_y_additional.shape[0], dtype = target.dtype) temp = temp.cuda() target_new = torch.cat((target_new, temp),0) #import pdb; pdb.set_trace() fi = open(opt['net_temp_file'], 'a+') start_index_for_additional_nodes = target_q.shape[0]+j*idx_train.shape[0] for i in range(idx_train.shape[0]): node_index = start_index_for_additional_nodes+i fi.write(str(node_index)+'\t'+str(idx_train[i].item())+'\t'+str(1)+'\n') fi.write(str(idx_train[i].item())+'\t'+str(node_index)+'\t'+str(1)+'\n') fi.write(str(node_index)+'\t'+str(permuted_train_idx[i].item())+'\t'+str(1)+'\n') fi.write(str(permuted_train_idx[i].item())+'\t'+str(node_index)+'\t'+str(1)+'\n') fi.close() ## reload the net file in the adjacency matrix### vocab_node = loader.Vocab(opt['net_temp_file'], [0, 1]) graph = loader.Graph(file_name=opt['net_temp_file'], entity=[vocab_node, 0, 1]) graph.to_symmetric(opt['self_link_weight']) adj_new = graph.get_sparse_adjacency(opt['cuda']) model.m1.adj = adj_new model.m2.adj = adj_new #trainer_q.model.adj = adj_new #trainer_q.model.m1.adj = adj_new #trainer_q.model.m2.adj = adj_new #trainer_q.model.m3.adj = adj #trainer_q.model.m4.adj = adj return inputs_q_new, target_q_new, idx_train_new