def run(output_path, gan_path, num_gen, if_fix): os.makedirs(output_path, exist_ok=True) index2strJson = json.load(open('zelda_index2str.json', 'r')) str2index = {} for key in index2strJson: str2index[index2strJson[key]] = key device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') netG = dcgan.DCGAN_G(32, 32, 8, 64, 1, 0) netG.load_state_dict(torch.load(gan_path)) netG.to(device) with torch.no_grad(): netG.eval() for i in tqdm.tqdm(range(num_gen)): fixed_noise = torch.FloatTensor(1, 32, 1, 1).normal_(0, 1).to(device) output = netG(fixed_noise) im = output[:, :, :9, :13].cpu().numpy() numpyLvl = np.argmax(im, axis=1)[0] if if_fix: level = zelda_gan_output_to_txt(numpyLvl) new_level = fix_zelda_level(level) numpyLvl = get_integer_lvl(new_level, str2index) with open(os.path.join(output_path, '{}.json'.format(i)), 'w') as f: f.write(json.dumps(numpyLvl.tolist()))
def run(output_path, gan_experiment, cuda, gpu_id, if_fix): os.makedirs(output_path, exist_ok=True) index2strJson = json.load(open('zelda_index2str.json', 'r')) str2index = {} for key in index2strJson: str2index[index2strJson[key]] = key # now we need to setup lp function # Step 1. We translate our cplex model to matrices milp_program = Program(partial=True) cpx = milp_program.get_cplex_prob() # get the cplex problem from the docplex model cpx.cleanup(epsilon=0.0001) c, G, h, A, b, var_type = cplex_utils.cplex_to_matrices(cpx) # _, inds = sympy.Matrix(A).T.rref() # A = A[np.array(inds)] # b = b[np.array(inds)] if cuda: G = torch.from_numpy(G).float().cuda(gpu_id) h = torch.from_numpy(h).float().cuda(gpu_id) A = torch.from_numpy(A).float().cuda(gpu_id) b = torch.from_numpy(b).float().cuda(gpu_id) Q = 2e-6 * torch.eye(A.shape[1]).cuda(gpu_id) Q = Q.type_as(G).cuda(gpu_id) else: G = torch.from_numpy(G) h = torch.from_numpy(h) A = torch.from_numpy(A) b = torch.from_numpy(b) Q = 2e-6 * torch.eye(A.shape[1]) Q = Q.type_as(G) lp_function = LPFunction(QPSolvers.GUROBI, verbose=False) # netG = dcgan.DCGAN_G(32, 32, 8, 64, 1, 0) netG = dcgan.DCGAN_G(32, 32, 8, 64, 1, 0) netG_checkpoint = os.path.join(gan_experiment, 'netG_epoch_5499_999.pth') netG.load_state_dict(torch.load(netG_checkpoint)) if cuda: netG.cuda(gpu_id) num_iter = 1000 with torch.no_grad(): netG.eval() for i in tqdm.tqdm(range(num_iter)): # first we use gan to generate the level noise = torch.FloatTensor(1, 32, 1, 1).normal_(0, 1) if cuda: noise = noise.cuda(gpu_id) output = netG(noise) pred_coefs = gan_out_2_coefs(output, c.size) x = lp_function(Q, pred_coefs, G, h, A, b) output2 = mip_sol_to_gan_out(output, x) im = output2.data[:, :, :9, :13].cpu().numpy() numpyLvl = np.argmax(im, axis=1)[0] if if_fix: level = zelda_gan_output_to_txt(numpyLvl) new_level = fix_zelda_level(level) numpyLvl = get_integer_lvl(new_level, str2index) with open(os.path.join(output_path, '{}.json'.format(i)), 'w') as f: f.write(json.dumps(numpyLvl.tolist()))
ndf = int(opt.ndf) n_extra_layers = int(opt.n_extra_layers) # custom weights initialization called on netG and netD def weights_init(m): classname = m.__class__.__name__ if classname.find('Conv') != -1: m.weight.data.normal_(0.0, 0.02) elif classname.find('BatchNorm') != -1: m.weight.data.normal_(1.0, 0.02) m.bias.data.fill_(0) netG = dcgan.DCGAN_G(map_size, nz, z_dims, ngf, ngpu, n_extra_layers) netG.apply(weights_init) if opt.netG != '': # load checkpoint if needed netG.load_state_dict(torch.load(opt.netG)) # print(netG) netD = dcgan.DCGAN_D(map_size, nz, z_dims, ndf, ngpu, n_extra_layers) netD.apply(weights_init) if opt.netD != '': netD.load_state_dict(torch.load(opt.netD)) # print(netD) input = torch.FloatTensor(opt.batchSize, z_dims, map_size, map_size) noise = torch.FloatTensor(opt.batchSize, nz, 1, 1)
def run(plot_range): f_h = 2 f_w = 2 human_root = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'zelda', 'Human_Json') human_lvls = get_valid_lvls(human_root) human_patterns = count_pattern_distribution(human_lvls, f_h, f_w) human_pattern_dist = count2dist(human_patterns) kl_lst = [] average_path = [] human_path = [] duplicate_percentage = [] valid_percentage = [] valid_unique_percentage = [] average_path_ratio = [] for epoch_num in tqdm.tqdm(plot_range): gan_path = os.path.join(os.path.dirname(__file__), 'zelda_better_gan', 'netG_epoch_{}_999.pth'.format(epoch_num)) # first generate 1000 levels device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') netG = dcgan.DCGAN_G(32, 32, 8, 64, 1, 0) netG.load_state_dict(torch.load(gan_path)) netG.to(device) num_iter = 1000 with torch.no_grad(): netG.eval() noise = torch.FloatTensor(num_iter, 32, 1, 1).normal_(0, 1).to(device) output = netG(noise) im = output[:, :, :9, :13].cpu().numpy() im = np.argmax(im, axis=1).astype(int).tolist() valid_generated_lvls = [] costs = [] # first only keep valid levels for lvl in im: ret = evaluate(lvl) if ret: valid_generated_lvls.append(lvl) costs.append(ret[1]) # now it's time to compute kl divergence gan_patterns = count_pattern_distribution(valid_generated_lvls, f_h, f_w) new_gan_patterns = {} for pattern in human_patterns: if pattern in gan_patterns: new_gan_patterns[pattern] = gan_patterns[pattern] else: new_gan_patterns[pattern] = 1e-5 gan_pattern_dist = count2dist(new_gan_patterns) kl = compute_kl(human_pattern_dist, gan_pattern_dist) kl_lst.append(kl) average_cost = np.average(costs) average_path.append(average_cost) human_path.append(12.52) # computed offline average_path_ratio.append(average_cost / 12.52) valid_percentage.append(len(valid_generated_lvls) / num_iter) num_duplicated, unique_lvls = compute_duplicated_lvls( valid_generated_lvls) valid_unique_percentage.append(len(unique_lvls) / num_iter) if len(valid_generated_lvls) > 0: duplicate_percentage.append(num_duplicated / len(valid_generated_lvls)) # duplicate_percentage_x.append(epoch_num) else: duplicate_percentage.append(np.nan) fig = plt.figure() plt.plot(list(plot_range), kl_lst, label='KL Divergence') # plt.plot(list(plot_range), average_path, label='Average Path Length (GAN)') # plt.plot(list(plot_range), human_path, label='Average Path Length (Human)') plt.plot(list(plot_range), average_path_ratio, label='Average Path Length Ratio') plt.plot(list(plot_range), duplicate_percentage, label='Duplicated Levels') plt.plot(list(plot_range), valid_percentage, label='Valid Levels') plt.plot(list(plot_range), valid_unique_percentage, label='Valid and Unique Levels') # plt.axis('equal') plt.legend() plt.show()
def run(nz, ngf, ndf, batch_size, niter, lrD, lrG, beta1, cuda, ngpu, gpu_id, path_netG, path_netD, clamp_lower, clamp_upper, n_extra_layers, gan_experiment, adam, seed, lvl_data): os.makedirs(gan_experiment, exist_ok=True) random.seed(seed) torch.manual_seed(seed) cudnn.benchmark = True if torch.cuda.is_available() and not cuda: print( "WARNING: You have a CUDA device, so you should probably run with --cuda" ) map_size = 32 index2strJson = json.load( open(os.path.join(os.path.dirname(__file__), 'zelda_index2str.json'), 'r')) str2index = {} for key in index2strJson: str2index[index2strJson[key]] = key # get all levels and store them in one numpy array np_lvls = [] lvls = get_lvls(lvl_data) for lvl in lvls: numpyLvl = get_integer_lvl(lvl, str2index) np_lvls.append(numpyLvl) X = np.array(np_lvls) z_dims = len(index2strJson) num_batches = X.shape[0] / batch_size X_onehot = np.eye(z_dims, dtype='uint8')[X] X_onehot = np.rollaxis(X_onehot, 3, 1) X_train = np.zeros((X.shape[0], z_dims, map_size, map_size)) X_train[:, 1, :, :] = 1.0 X_train[:X.shape[0], :, :X.shape[1], :X.shape[2]] = X_onehot def weights_init(m): classname = m.__class__.__name__ if classname.find('Conv') != -1: m.weight.data.normal_(0.0, 0.02) elif classname.find('BatchNorm') != -1: m.weight.data.normal_(1.0, 0.02) m.bias.data.fill_(0) netG = dcgan.DCGAN_G(map_size, nz, z_dims, ngf, ngpu, n_extra_layers) netG.apply(weights_init) if path_netG != '': netG.load_state_dict(torch.load(path_netG)) netD = dcgan.DCGAN_D(map_size, nz, z_dims, ndf, ngpu, n_extra_layers) netD.apply(weights_init) if path_netD != '': netD.load_state_dict(torch.load(path_netD)) input = torch.FloatTensor(batch_size, z_dims, map_size, map_size) noise = torch.FloatTensor(batch_size, nz, 1, 1) fixed_noise = torch.FloatTensor(batch_size, nz, 1, 1).normal_(0, 1) one = torch.FloatTensor([1]) mone = one * -1 if cuda: netD.cuda(gpu_id) netG.cuda(gpu_id) input = input.cuda(gpu_id) one, mone = one.cuda(gpu_id), mone.cuda(gpu_id) noise, fixed_noise = noise.cuda(gpu_id), fixed_noise.cuda(gpu_id) # setup optimizer if adam: optimizerD = optim.Adam(netD.parameters(), lr=lrD, betas=(beta1, 0.999)) optimizerG = optim.Adam(netG.parameters(), lr=lrG, betas=(beta1, 0.999)) print("Using ADAM") else: optimizerD = optim.RMSprop(netD.parameters(), lr=lrD) optimizerG = optim.RMSprop(netG.parameters(), lr=lrG) for epoch in range(niter): X_train = X_train[torch.randperm(len(X_train))] ############################ # (1) Update D network ########################### # for p in netD.parameters(): # reset requires_grad # p.requires_grad = True # they are set to False below in netG update # for p in netG.parameters(): # p.requires_grad = False i = 0 total_errD_fake = 0 total_errD_real = 0 total_errG = 0 while i < num_batches: # len(dataloader): netD.zero_grad() # clamp parameters to a cube for p in netD.parameters(): p.data.clamp_(clamp_lower, clamp_upper) data = X_train[i * batch_size:(i + 1) * batch_size] if cuda: real_cpu = torch.FloatTensor(data).cuda(gpu_id) else: real_cpu = torch.FloatTensor(data) input.resize_as_(real_cpu).copy_(real_cpu) errD_real = netD(input) errD_real.backward(one) total_errD_real += errD_real.item() # train with fake noise.resize_(batch_size, nz, 1, 1).normal_(0, 1) fake = netG(noise) errD_fake = netD(fake.detach()) errD_fake.backward(mone) total_errD_fake += errD_fake.item() optimizerD.step() ############################ # (2) Update G network ########################### netG.zero_grad() errG = netD(fake) errG.backward(one) total_errG += errG.item() optimizerG.step() i += 1 average_errG = total_errG / num_batches average_errD_fake = total_errD_fake / num_batches average_errD_real = total_errD_real / num_batches print( '[%d/%d] Loss_G: %f Loss_D_real: %f Loss_D_fake %f' % (epoch, niter, average_errG, average_errD_real, average_errD_fake)) if epoch % 10 == 9 or epoch == niter - 1: netG.eval() with torch.no_grad(): fake = netG(fixed_noise) im = fake.cpu().numpy()[:, :, :9, :13] im = np.argmax(im, axis=1) with open( '{0}/fake_level_epoch_{1}_{2}.json'.format( gan_experiment, epoch, seed), 'w') as f: f.write(json.dumps(im[0].tolist())) torch.save( netG.state_dict(), '{0}/netG_epoch_{1}_{2}.pth'.format(gan_experiment, epoch, seed))
def run(nz, ngf, ndf, batch_size, niter, lrD, lrG, beta1, cuda, ngpu, gpu_id, path_netG, path_netD, clamp_lower, clamp_upper, n_extra_layers, gan_experiment, mipaal_experiment, adam, seed, lvl_data): # Now we need to setup lpfunction shutil.rmtree(os.path.join(mipaal_experiment, 'runs'), ignore_errors=True) writer = SummaryWriter(log_dir=os.path.join(mipaal_experiment, 'runs')) models_dir = os.path.join(mipaal_experiment, 'models') os.makedirs(models_dir, exist_ok=True) # Step 1. We translate our cplex model to matrices milp_program = Program(partial=True) cpx = milp_program.get_cplex_prob( ) # get the cplex problem from the docplex model cpx.cleanup(epsilon=0.0001) c, G, h, A, b, var_type = cplex_utils.cplex_to_matrices(cpx) # _, inds = sympy.Matrix(A).T.rref() # A = A[np.array(inds)] # b = b[np.array(inds)] # # cpx = get_mip_program() # cpx.cleanup(epsilon=0.0001) # c, G, h, A, b, var_type = cplex_utils.cplex_to_matrices(cpx) if cuda: G = torch.from_numpy(G).float().cuda(gpu_id) h = torch.from_numpy(h).float().cuda(gpu_id) A = torch.from_numpy(A).float().cuda(gpu_id) b = torch.from_numpy(b).float().cuda(gpu_id) Q = 2e-6 * torch.eye(A.shape[1]).cuda(gpu_id) Q = Q.type_as(G).cuda(gpu_id) else: G = torch.from_numpy(G) h = torch.from_numpy(h) A = torch.from_numpy(A) b = torch.from_numpy(b) Q = 2e-6 * torch.eye(A.shape[1]) Q = Q.type_as(G) if cuda: lp_function = LPFunction(QPSolvers.PDIPM_BATCHED, verbose=False) else: lp_function = LPFunction(QPSolvers.GUROBI, verbose=False) os.makedirs(gan_experiment, exist_ok=True) random.seed(seed) torch.manual_seed(seed) cudnn.benchmark = True # enable cudnn auto-tuner for finding the optimial set of algorithms. if torch.cuda.is_available() and not cuda: print( "WARNING: You have a CUDA device, so you should probably run with --cuda" ) map_size = 32 index2strJson = json.load( open(os.path.join(os.path.dirname(__file__), 'zelda_index2str.json'), 'r')) str2index = {} for key in index2strJson: str2index[index2strJson[key]] = key # get all levels and store them in one numpy array np_lvls = [] lvls = get_lvls(lvl_data) for lvl in lvls: numpyLvl = get_integer_lvl(lvl, str2index) np_lvls.append(numpyLvl) X = np.array(np_lvls) z_dims = len(index2strJson) num_batches = X.shape[0] / batch_size X_onehot = np.eye(z_dims, dtype='uint8')[X] X_onehot = np.rollaxis(X_onehot, 3, 1) X_train = np.zeros((X.shape[0], z_dims, map_size, map_size)) X_train[:, 1, :, :] = 1.0 X_train[:X.shape[0], :, :X.shape[1], :X.shape[2]] = X_onehot def weights_init(m): classname = m.__class__.__name__ if classname.find('Conv') != -1: m.weight.data.normal_(0.0, 0.02) elif classname.find('BatchNorm') != -1: m.weight.data.normal_(1.0, 0.02) m.bias.data.fill_(0) netG = dcgan.DCGAN_G(map_size, nz, z_dims, ngf, ngpu, n_extra_layers) netG.apply(weights_init) if path_netG != '': netG.load_state_dict(torch.load(path_netG)) netD = dcgan.DCGAN_D(map_size, nz, z_dims, ndf, ngpu, n_extra_layers) netD.apply(weights_init) if path_netD != '': netD.load_state_dict(torch.load(path_netD)) input = torch.FloatTensor(batch_size, z_dims, map_size, map_size) noise = torch.FloatTensor(batch_size, nz, 1, 1) fixed_noise = torch.FloatTensor(batch_size, nz, 1, 1).normal_(0, 1) one = torch.FloatTensor([1]) mone = one * -1 if cuda: netD.cuda(gpu_id) netG.cuda(gpu_id) input = input.cuda(gpu_id) one, mone = one.cuda(gpu_id), mone.cuda(gpu_id) noise, fixed_noise = noise.cuda(gpu_id), fixed_noise.cuda(gpu_id) # setup optimizer if adam: optimizerD = optim.Adam(netD.parameters(), lr=lrD, betas=(beta1, 0.999)) optimizerG = optim.Adam(netG.parameters(), lr=lrG, betas=(beta1, 0.999)) print("Using ADAM") else: optimizerD = optim.RMSprop(netD.parameters(), lr=lrD) optimizerG = optim.RMSprop(netG.parameters(), lr=lrG) for epoch in range(niter): start_time = time.time() X_train = X_train[torch.randperm( len(X_train))] # shuffle the training data ############################ # (1) Update D network ########################### i = 0 total_errD_fake = 0 total_errD_real = 0 total_errG = 0 while i < num_batches: netD.zero_grad() # clamp parameters to a cube for p in netD.parameters(): p.data.clamp_(clamp_lower, clamp_upper) data = X_train[i * batch_size:(i + 1) * batch_size] if cuda: real_cpu = torch.FloatTensor(data).cuda(gpu_id) else: real_cpu = torch.FloatTensor(data) input.resize_as_(real_cpu).copy_(real_cpu) errD_real = netD(input) errD_real.backward(one) total_errD_real += errD_real.item() # train with fake noise.resize_(batch_size, nz, 1, 1).normal_(0, 1) fake = netG(noise) pred_coefs = gan_out_2_coefs(fake, c.size, gpu_id, cuda) x = lp_function(Q, pred_coefs, G, h, A, b) fake2 = mip_sol_to_gan_out(fake, x) errD_fake = netD(fake2.detach()) errD_fake.backward(mone) total_errD_fake += errD_fake.item() # i += 1 optimizerD.step() ############################ # (2) Update G network ########################### netG.zero_grad() errG = netD(fake2) errG.backward(one) total_errG += errG.item() optimizerG.step() i += 1 average_errG = total_errG / num_batches average_errD_fake = total_errD_fake / num_batches average_errD_real = total_errD_real / num_batches end_time = time.time() print('[%d/%d] Loss_G: %f Loss_D_real: %f Loss_D_fake %f; time: [%d]' % (epoch, niter, average_errG, average_errD_real, average_errD_fake, end_time - start_time)) if epoch % 100 == 99 or epoch == niter - 1: netG.eval() with torch.no_grad(): fake = netG(fixed_noise) pred_coefs = gan_out_2_coefs(fake, c.size, gpu_id, cuda) x = lp_function(Q, pred_coefs, G, h, A, b) fake2 = mip_sol_to_gan_out(fake, x) im = fake2.data[:, :, :9, :13].cpu().numpy() im = np.argmax(im, axis=1) with open( '{0}/fake_level_epoch_{1}_{2}.json'.format( gan_experiment, epoch, seed), "w") as f: f.write(json.dumps(im[0].tolist())) torch.save( netG.state_dict(), '{0}/netG_epoch_{1}_{2}.pth'.format(gan_experiment, epoch, seed)) torch.save( netD.state_dict(), '{0}/netD_epoch_{1}_{2}.pth'.format(gan_experiment, epoch, seed))