示例#1
0
def generate_inf_cases(train,
                       seed,
                       board_size=25,
                       min_dens=0.01,
                       max_dens=0.99,
                       warm_up=5,
                       min_delta=1,
                       max_delta=5,
                       dtype=np.int,
                       return_one_but_last=False):
    rs = np.random.RandomState(seed)
    zer = np.zeros(shape=(board_size, board_size), dtype=dtype)
    while True:
        density = rs.uniform(min_dens, max_dens)
        start = rs.choice([1, 0],
                          size=(board_size, board_size),
                          p=[density, 1.0 - density])
        for _ in range(warm_up):
            start = life_step(start)

        delta = rs.randint(min_delta, max_delta + 1)
        stop = start.copy()
        one_but_last = None
        for _ in range(delta):
            one_but_last = stop
            stop = life_step(stop)

        if not (stop == zer).all():
            if return_one_but_last:
                yield delta, one_but_last, stop
            elif train:
                yield delta, start, stop
            else:
                yield delta, stop
示例#2
0
def test_sim_toad():
    toad_1 = np.array([[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 1, 1, 0], [0, 1, 1, 1, 0, 0],
                       [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]])
    toad_2 = np.array([[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0],
                       [0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0],
                       [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0]])
    assert (life_step(toad_1) == toad_2).all()
    assert (life_step(toad_2) == toad_1).all()
示例#3
0
def test_generate_train_set():
    xs = list(generate_train_set(10, 234))
    assert len(xs) == 10
    for delta, start, stop in xs:
        for i in range(delta):
            start = life_step(start)
        assert (start == stop).all()
示例#4
0
def test_sim_block():
    block = np.array([
        [0, 0, 0, 0],
        [0, 1, 1, 0],
        [0, 1, 1, 0],
        [0, 0, 0, 0],
    ])

    assert (life_step(block) == block).all()
示例#5
0
def test_step_back_all_3x3(alg_class):
    alg = alg_class(tile_graph)

    for Aorig in tqdm(generate_all(3, 3)):
        X = np.copy(Aorig)
        X = life_step(X)
        A = alg.step_back(X)

        sc = score(1, A, X)
        assert sc == 1.0
示例#6
0
    def train(self, delta, start, stop):
        X = start

        m = X.shape[0]
        n = X.shape[1]
        for s in range(delta):
            Y = life_step(X) if s < delta - 1 else stop
            for i in range(m):
                for j in range(n):
                    a_id = self.__get_tile_id(X, i, j)
                    b_id = self.__get_tile_id(Y, i, j)

                    self.trans[a_id][b_id] += 1
示例#7
0
    def preprocess():
        # Tiles - all possible titles 3x3
        T = list(generate_all(3, 3))
        assert (len(T) == 512)

        # Backward possibilities
        # dict: central bit -> list of possible prev tiles 3x3
        B = [[], []]
        for i, tile in enumerate(T):
            next_tile = life_step(tile)
            B[int(next_tile[1][1])].append(i)

        # Fun fact:
        # >>> len(B[0])
        # 372
        # >>> len(B[1])
        # 140

        # Matrix horiz[i,j] - true if tile j can be put horizontally on the right side of tile i.
        # 0 0 1     0 1 0    0 0 1 0
        # 0[1]0  +  1[0]0 =  0[1|0]0
        # 0 0 0     0 0 1    0 0 0 1
        horiz = np.zeros((len(T), len(T)), dtype=np.bool)

        # Matrix verti[i,j] - true if tile j can be put vertically under tile i.
        verti = np.zeros((len(T), len(T)), dtype=np.bool)

        # Diagonal relationships -- they don't seem to be needed.
        #diago_se = np.zeros((len(T), len(T)), dtype=np.bool)
        #diago_sw = np.zeros((len(T), len(T)), dtype=np.bool)
        for i, x in enumerate(T):
            for j, y in enumerate(T):
                # Check if left tile is compatible with the right tile.
                # I.e., left tile's right side is equal to right tile's left side.
                horiz[i, j] = (x[:, (1, 2)] == y[:, (0, 1)]).all()

                # Check if upper tile is compatible with the lower tile.
                # I.e., upper tile's lower side is equal to lower tile's upper side.
                verti[i, j] = (x[(1, 2), :] == y[(0, 1), :]).all()

                # Diagonal relationships -- they don't seem to be needed.
                #diago_se[i, j] = (x[(1, 2), (1, 2)] == y[(0, 1), (0, 1)]).all()
                #diago_sw[i, j] = (x[(1, 2), (0, 1)] == y[(0, 1), (1, 2)]).all()

        return T, B, horiz, verti
示例#8
0
def test_step_back_simple(alg_class):
    alg = alg_class(tile_graph)

    block = np.array([
        [0, 0, 0, 0],
        [0, 1, 1, 0],
        [0, 1, 1, 0],
        [0, 0, 0, 0],
    ])
    A = alg.step_back(block)
    B = life_step(A)
    assert (B == block).all()

    toad_1 = np.array([[0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0],
                       [0, 0, 1, 1, 1, 0], [0, 1, 1, 1, 0, 0],
                       [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]])
    toad_2 = np.array([[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0],
                       [0, 1, 0, 0, 1, 0], [0, 1, 0, 0, 1, 0],
                       [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0]])
    A = alg.step_back(toad_2)
    assert (A == toad_1).all()
示例#9
0
def score(delta, start, stop):
    X = start
    for i in range(delta):
        X = life_step(X)
    return np.count_nonzero(X == stop) / stop.size
示例#10
0
def likely_starts(delta, stop):
    # Just test a couple of "likely" starting boards and pick the best one.
    starts = [np.zeros_like(stop), stop, life_step(stop)]
    scores = [score(delta, start, stop) for start in starts]
    idx = np.argmax(scores)
    return starts[idx]
示例#11
0
def sim_density(delta, stop):
    # If stop is a still board, then return that. Otherwise, return zeros.
    n = life_step(stop)
    return stop if (stop == n).all() else np.zeros_like(stop)
示例#12
0
def train(
        gen_arch,
        fwd_arch,
        device,
        writer,
        batchSize,
        niter,
        lr,
        beta1,
        dry_run,
        outf,
        workers=1,
        start_iter=0,
        gen_path=None,
        fwd_path=None,
        ngpu=1,
        nz=100,
        epoch_samples=64*100,
        learn_forward=True,
        sigmoid=True):

    os.makedirs(outf, exist_ok=True)

    gen_path = gen_path if start_iter == 0 else os.path.join(outf, f'netG_epoch_{start_iter-1}.pth')
    fwd_path = fwd_path if start_iter == 0 else os.path.join(outf, f'netF_epoch_{start_iter-1}.pth')

    # Prediction threshold
    pred_th = 0.5 if sigmoid else 0.0

    dataset = DataGenerator(823131 + start_iter, sigmoid)
    dataloader = torch.utils.data.DataLoader(dataset, batch_size=batchSize,
                                             shuffle=False, num_workers=int(workers))

    val_size = 1024
    val_set = bitmap.generate_test_set(set_size=val_size, seed=9568382)
    deltas_val, stops_val = cnnify_batch(zip(*val_set))
    ones_val = np.ones_like(deltas_val)
    noise_val = torch.randn(val_size, nz, 1, 1, device=device)

    netG = get_generator_net(gen_arch).to(device)
    init_model(netG, gen_path)

    netF = get_forward_net(fwd_arch).to(device)
    init_model(netF, fwd_path)

    criterion = nn.BCELoss()

    fixed_noise = torch.randn(batchSize, nz, 1, 1, device=device)
    fixed_ones = np.ones((batchSize,), dtype=np.int)

    # setup optimizer
    optimizerD = optim.Adam(netF.parameters(), lr=lr, betas=(beta1, 0.999))
    optimizerG = optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))

    scores = []
    for i in range(5):
        noise = torch.randn(val_size, nz, 1, 1, device=device)
        one_step_pred_batch = (netG(torch.Tensor(stops_val).to(device), noise) > pred_th).cpu()
        model_scores = scoring.score_batch(ones_val, np.array(one_step_pred_batch, dtype=np.bool), stops_val)
        scores.append(model_scores)

    zeros = np.zeros_like(one_step_pred_batch, dtype=np.bool)
    zeros_scores = scoring.score_batch(ones_val, zeros, stops_val)
    scores.append(zeros_scores)

    best_scores = np.max(scores, axis=0)

    print(
        f'Mean error one step: model {1 - np.mean(model_scores)}, zeros {1 - np.mean(zeros_scores)}, ensemble {1 - np.mean(best_scores)}')

    #for epoch in range(opt.niter):
    epoch = start_iter
    samples_in_epoch = 0
    samples_before = start_iter * epoch_samples
    for j, data in enumerate(dataloader, 0):
        i = start_iter * epoch_samples // batchSize + j
        ############################
        # (1) Update F (forward) network -- in the original GAN, it's a "D" network (discriminator)
        # Original comment: Update D network: maximize log(D(x)) + log(1 - D(G(z)))
        ###########################
        # train with real starting board -- data set provides ground truth
        netF.zero_grad()
        start_real_cpu = data[0].to(device)
        stop_real_cpu = data[1].to(device)
        batch_size = start_real_cpu.size(0)

        output = netF(start_real_cpu)
        errD_real = criterion(output, stop_real_cpu)
        if learn_forward:
            errD_real.backward()
        D_x = (output.round().eq(stop_real_cpu)).sum().item() / output.numel()

        # train with fake -- use simulator (life_step) to generate ground truth
        # TODO: replace with fixed forward model (should be faster, in batches and on GPU)
        noise = torch.randn(batch_size, nz, 1, 1, device=device)
        fake = netG(stop_real_cpu, noise)
        fake_np = (fake > pred_th).detach().cpu().numpy()
        fake_next_np = life_step(fake_np)
        fake_next = torch.tensor(fake_next_np, dtype=torch.float32).to(device)

        output = netF(fake.detach())
        errD_fake = criterion(output, fake_next)
        if learn_forward:
            errD_fake.backward()
        D_G_z1 = (output.round().eq(fake_next)).sum().item() / output.numel()
        errD = errD_real + errD_fake
        if learn_forward:
            optimizerD.step()

        # just for reporting...
        true_stop_np = (stop_real_cpu > pred_th).detach().cpu().numpy()
        fake_scores = scoring.score_batch(fixed_ones, fake_np, true_stop_np, show_progress=False)
        fake_mae = 1 - fake_scores.mean()
        fake_density = fake_np.mean()

        ############################
        # (2) Update G network: maximize log(D(G(z)))
        ###########################
        netG.zero_grad()
        output = netF(fake)
        errG = criterion(output, stop_real_cpu)
        errG.backward()
        D_G_z2 = (output.round().eq(fake_next)).sum().item() / output.numel()
        optimizerG.step()

        samples_in_epoch += batch_size
        s = samples_before + samples_in_epoch
        writer.add_scalar('Loss/forward', errD.item(), i)
        writer.add_scalar('Loss/gen', errG.item(), i)
        writer.add_scalar('MAE/train', fake_mae.item(), i)
        print('[%d/%d][%d] Loss_F: %.4f Loss_G: %.4f fwd acc(real): %.2f fwd acc(fake): %.2f / %.2f, fake dens: %.2f, MAE: %.4f'
              % (epoch, start_iter+niter, i,
                 errD.item(), errG.item(), D_x, D_G_z1, D_G_z2, fake_density, fake_mae))
        if samples_in_epoch >= epoch_samples:
            """
            multi_step_pred_batch = predict(netG, deltas_val, stops_val, fixed_noise)
            multi_step_mean_err = 1 - np.mean(scoring.score_batch(deltas_val, np.array(multi_step_pred_batch, dtype=np.bool), stops_val))
            """

            one_step_pred_batch = (netG(torch.Tensor(stops_val).to(device), noise_val) > pred_th).detach().cpu().numpy()
            one_step_mean_err = 1 - np.mean(scoring.score_batch(ones_val, np.array(one_step_pred_batch, dtype=np.bool), stops_val))
            print(f'Mean error: one step {one_step_mean_err}')
            writer.add_scalar('MAE/val', one_step_mean_err, epoch)

            vutils.save_image(start_real_cpu,
                    '%s/real_samples.png' % outf,
                    normalize=True)
            fake = netG(stop_real_cpu, fixed_noise).detach()
            vutils.save_image(fake,
                    '%s/fake_samples_epoch_%03d.png' % (outf, epoch),
                    normalize=True)

            grid = vutils.make_grid(start_real_cpu)
            writer.add_image('real', grid, epoch)
            grid = vutils.make_grid(fake)
            writer.add_image('fake', grid, epoch)

            # do checkpointing
            torch.save(netG.state_dict(), '%s/netG_epoch_%d.pth' % (outf, epoch))
            torch.save(netF.state_dict(), '%s/netF_epoch_%d.pth' % (outf, epoch))
            epoch += 1
            samples_in_epoch = 0

        if epoch - start_iter >= niter:
            break
        if dry_run:
            break

    return one_step_mean_err