def main(): # Projection n_data = 100 circle_input, _ = get_circle_data(n_data) plane_input, _ = get_plane_data(n_data) projection_input = torch.hstack([circle_input, plane_input]) discr, gener = train_gan(projection_input) func = gener inputs = gener.generate_generator_input(1) jac = get_jacobian(func=func, inputs=inputs).squeeze() print("Generator output ID is ", torch.matrix_rank(jac)) proj_func = ProjectionFunction() func = lambda x: proj_func(gener(x)) jac = get_jacobian(func=func, inputs=inputs).squeeze() print("ANN output ID is ", torch.matrix_rank(jac)) evaluate( estimate_id=twonn_dimension, get_data=lambda n: get_parabolic_data(n)[1], ) plt.show()
get_twonn = lambda x: twonn_dimension(x.detach().numpy().squeeze()) ## Train GAN n_data = 1000 circle_input, _ = get_circle_data(n_data) plane_input, _ = get_plane_data(n_data) projection_input = torch.hstack([circle_input, plane_input]) Activation = torch.nn.ReLU Optimizer = torch.optim.Adam generator_kwargs = dict(activation_function=Activation) discr, gener = train_gan( projection_input, plot=False, Optimizer=Optimizer, ) ## inputs = gener.generate_generator_input(1) def func(x): activations = [] def hook(module, input, output): activations.append(output) h = torch.nn.modules.module.register_module_forward_hook(hook) gener(x) h.remove() return tuple(activations)
def run(dataset, model, runs, epochs, lr, weight_decay, early_stopping, permute_masks=None, logger=None): batch_size = 30 losses, accs, losses_wo, accs_wo = [], [], [], [] for k in range(runs): model.to(device).reset_parameters() optimizer = Adam(model.parameters(), lr=lr, weight_decay=weight_decay) best_val_perf = test_perf = 0 if torch.cuda.is_available(): torch.cuda.synchronize() data = dataset[0] # gdc = T.GDC(self_loop_weight=1, normalization_in='sym', # normalization_out='col', # diffusion_kwargs=dict(method='ppr', alpha=0.05), # sparsification_kwargs=dict(method='topk', k=128, # dim=0), exact=True) # data = gdc(data) data = data.to(device) num_nodes = data.num_nodes pivot = int(num_nodes * 0.1) cold_mask_node = list(range(k * pivot, (k + 1) * pivot)) unknown = [[]] for thing in unknown[0]: if thing in cold_mask_node: cold_mask_node.remove(thing) data.test_masked_nodes = torch.tensor(cold_mask_node) train_node = range(num_nodes) train_node = [e for e in train_node if e not in cold_mask_node] #or unknown] data = test_edges(data, cold_mask_node) data.train_masked_nodes = torch.tensor(random.sample(train_node, 140)) epoch_num = int((num_nodes - pivot) / batch_size) print("{}-fold Result".format(k)) data = train_edges(data, data.train_masked_nodes) loss_wo, acc_wo = run_(data, dataset, data.train_edge_index, train_node, writer) losses_wo.append(loss_wo) accs_wo.append(acc_wo) scheduler = StepLR(optimizer, step_size=2000, gamma=0.5) for epoch in range(2000): with torch.autograd.set_detect_anomaly(True): train_gan(dataset, data, writer) for epoch in range(5000): with torch.autograd.set_detect_anomaly(True): train_loss = train(model, optimizer, data, epoch) scheduler.step() if torch.cuda.is_available(): torch.cuda.synchronize() loss, acc = evaluate(model, data) losses.append(loss) accs.append(acc) print('Val Loss: {:.4f}, Test Accuracy: {:.3f}'.format(loss, acc)) losses, accs, losses_wo, accs_wo = tensor(losses), tensor(accs), tensor( losses_wo), tensor(accs_wo) print('w/o Mean Val Loss: {:.4f}, Mean Test Accuracy: {:.3f} ± {:.3f}'. format(losses_wo.mean().item(), accs_wo.mean().item(), accs_wo.std().item())) print('Mean Val Loss: {:.4f}, Mean Test Accuracy: {:.3f} ± {:.3f}'.format( losses.mean().item(), accs.mean().item(), accs.std().item()))
import gan if __name__ == '__main__': gan.train_gan(examples=2, epochs=10, batch_size=4, smaller=0.00008) # For now, use small fraction of set
beta1 = float(arg) elif opt in ('-r', '--reg'): reg = float(arg) elif opt in ('-n', '--num_epochs'): num_epochs = int(arg) elif opt in ('-l', '--loss'): loss = arg elif opt in ('-s', '--batch_size'): batch_size = int(arg) elif opt in ('-e', '--eval_val'): eval_val = True elif opt in ('-a', '--save_eval_img'): save_eval_img = True elif opt in ('-c', '--device'): device = arg elif opt in ('-i', '--num_eval_img'): num_eval_img = int(arg) print('Running train_gan.py with parameters: --train_data_dir=' + train_data_dir + \ ', --val_data_dir=' + val_data_dir + ', --output_dir=' + output_dir + \ ', --D_lr=' + str(D_lr) + ', --G_lr=' + str(G_lr) + \ ', --beta1=' + str(beta1) + ', --reg=' + str(reg) + ', --num_epochs=' + str(num_epochs) + \ ', --loss=' + loss + ', --batch_size=' + str(batch_size) + ', --eval_val=' + str(eval_val) + \ ', --save_eval_img=' + str(save_eval_img) + ', --device=' + device + ', --num_eval_img=' + str(num_eval_img)) train_gan(train_data_dir=train_data_dir, val_data_dir=val_data_dir, output_dir=output_dir, D_lr=D_lr, G_lr=G_lr, beta1=beta1, reg=reg, num_epochs=num_epochs, loss=loss, batch_size=batch_size, eval_val=eval_val, save_eval_img=save_eval_img, device=device, num_eval_img=num_eval_img) print('Finished training GAN!')
def run(dataset, model, runs, epochs, lr, weight_decay, early_stopping, permute_masks=None, logger=None): batch_size = 30 losses, accs , losses_wo, accs_wo= [], [], [], [] perm = torch.randperm(dataset[0].num_nodes) for k in range(runs): model.to(device).reset_parameters() optimizer = Adam(model.parameters(), lr=lr, weight_decay=weight_decay) best_val_perf = test_perf = 0 if torch.cuda.is_available(): torch.cuda.synchronize() writer = SummaryWriter('runs/{}_{}'.format(k, tt)) data = dataset[0] data = data.to(device) num_nodes = data.num_nodes if os.path.isfile('{}_{}.pkl'.format(str(dataset)[:-2], k)): data = pickle.load(open('{}_{}.pkl'.format(str(dataset)[:-2], k), 'rb')) else: pivot= int(num_nodes*0.1) cold_mask_node = perm[list(range(k*pivot, (k+1)*pivot))] data.test_masked_nodes =cold_mask_node train_node = range(num_nodes) train_node = [e for e in train_node if e not in cold_mask_node] #or unknown] data = test_edges(data, cold_mask_node) val_mask_node = random.sample(train_node, int(pivot*0.5)) data.val_masked_nodes = torch.tensor(val_mask_node) data = val_edges(data, val_mask_node) train_node = [e for e in train_node if e not in val_mask_node] #or unknown] data.train_nodes = train_node data.train_masked_nodes = torch.tensor(random.sample(train_node,int(num_nodes*0.1))) data = train_edges(data, data.train_masked_nodes) with open('{}_{}.pkl'.format(str(dataset)[:-2], k), 'wb') as f: pickle.dump(data, f) print("{}-fold Result".format(k)) train_node=data.train_nodes loss_wo, acc_wo = run_(data, dataset, data.train_edge_index, train_node,writer) losses_wo.append(loss_wo) accs_wo.append(acc_wo) scheduler = StepLR(optimizer, step_size=2000, gamma=0.5) for epoch in range(2000): with torch.autograd.set_detect_anomaly(True): train_gan(dataset, data, writer) for epoch in range(5000): with torch.autograd.set_detect_anomaly(True): train_loss =train(model, optimizer,data,epoch) scheduler.step() if torch.cuda.is_available(): torch.cuda.synchronize() loss, acc = evaluate(model, data) losses.append(loss) accs.append(acc) print('Val Loss: {:.4f}, Test Accuracy: {:.3f}'.format(loss,acc)) losses, accs, losses_wo, accs_wo = tensor(losses), tensor(accs), tensor(losses_wo), tensor(accs_wo) print('w/o Mean Val Loss: {:.4f}, Mean Test Accuracy: {:.3f} ± {:.3f}'. format(losses_wo.mean().item(), accs_wo.mean().item(), accs_wo.std().item() )) print('Mean Val Loss: {:.4f}, Mean Test Accuracy: {:.3f} ± {:.3f}'. format(losses.mean().item(), accs.mean().item(), accs.std().item() ))
def train_ddqn_and_gan( env: gym.Env, valid_actions: list, q_est: nn.Module, q_target: nn.Module, gan: nn.Module, optimizer: optim, num_frames: int, batch_size: int = 4096, gamma: float = 0.9, buffer_size: int = 100000, ): # TODO: Fix typing in file # TODO: Note: this probably isn't the right place for this function rb = ReplayBuffer(buffer_size) epsilon = 1.0 observation = env.reset() criterion = nn.MSELoss() ddqn_losses = [] generator_losses = [] discriminator_losses = [] min_loss = 100.0 id_ses = [] ood_ses = [] # Initialize trajectory tracking trajectory = Trajectory(gamma) frames_since_accuracy_check = 0 for frame in range(num_frames): frames_since_accuracy_check += 1 # Sample from environment! torchy_obs = torch.FloatTensor(observation).unsqueeze(0) if random() < epsilon: action = env.action_space.sample() max_val = q_est(torchy_obs)[0][action] else: pred = q_est(torchy_obs) max_val = pred.max() action = int(pred.argmax()) observation_prime, reward, done, info = env.step(action) trajectory.add( observation, action, observation_prime, reward, (1.0 if done else 0.0), max_val, ) if done: rb.add_trajectory(trajectory) # Measure/record accuracy stuff here if frames_since_accuracy_check > 500: frames_since_accuracy_check = 0 q_vals_t = torch.FloatTensor(trajectory.q_vals) cum_rewards_t = torch.FloatTensor(trajectory.cum_rewards) rewards_t = torch.FloatTensor(trajectory.rewards) se = (q_vals_t - cum_rewards_t).pow(2) labels = gan.discriminator(torch.FloatTensor(trajectory.obs)) id_weights = labels[:, 0] ood_weights = labels[:, 1] ood_se = torch.sum(se * ood_weights) id_se = torch.sum(se * id_weights) ood_ses.append(float(ood_se / torch.sum(ood_weights))) id_ses.append(float(id_se / torch.sum(id_weights))) trajectory.clear() observation = env.reset() else: observation = observation_prime if epsilon > 0.05: epsilon -= 0.95 / 100000 # Training time if (frame + 1) % batch_size == 0 and frame > 2 * batch_size: q_est.zero_grad() # Sample the things you need from the buffer! obs, actions, obs_p, rews, done = rb.sample(batch_size) # TRAIN THE GAN <('_'<) generator_loss, discriminator_loss = train_gan( gan, [obs], 1, train_noise=0.05 ) generator_losses.extend(generator_loss) discriminator_losses.extend(discriminator_loss) # Choose the argmax of actions from obs_prime q_vals_mat = q_est(obs_p) max_actions = torch.argmax(q_vals_mat, 1) # Find MSE between target and network q_target_pred = q_target(obs_p).gather(1, max_actions.unsqueeze(1)) target = rews.unsqueeze(1) + (1 - done.unsqueeze(1)) * gamma * q_target_pred prediction = q_est(obs)[actions] loss = criterion(target, prediction) ddqn_losses.append(float(loss)) if float(loss) < min_loss: torch.save(q_est, "best_so_far.pt") loss.backward() optimizer.step() # Update target every 25000 steps, can do moving avg later if (frame + 1) % 25000 == 0: print("Copying over at iter: ", frame, "with loss: ", loss) q_target = copy.deepcopy(q_est) for p in q_target.parameters(): p.requires_grad = False env.close() return ( ddqn_losses, generator_losses, discriminator_losses, id_ses, ood_ses, )