def test_neural_net_back_forward(self): n_in, n_out = 3, 2 weights = np.array([[0, -1, 2], [-3, 4, -5]]) bias = np.arange(n_out)[:, np.newaxis] nn = NeuralNet(MeanSquaredError(), 1e-3, layers=[Linear(n_in, 2, weights, bias), ReLU()]) x = np.array([[[0], [1], [2]]]) y = np.array([[[2], [3]]]) assert y.shape[1] == n_out # |0 -1 2| |0| |0| | 3| |0| | 3| |3| # |-3 4 -5| |1| + |1| = |-6| + |1| = |-5| -> |0| # |2| pred = nn.forward(x) assert np.array_equal(pred, [[[3], [0]]]) nn.compute_loss(pred, y) dL_dx = nn.backward() # |0 -1 2| |0 + dx1| | 3 + 0 - dx2 + 2dx3| | 3 + ...| |3 - dx2 + 2dx3| # |-3 4 -5| |1 + dx2| = |-6 - 3dx1 + 4dx2 - 5dx3| = |-5 + ...| -> |0| # |2 + dx3| The second component is ReLU'ed away # MSE loss results in 2( ... ) so dL = -2dx2 + 4dx3, dL/dx = |0, -2, 4| assert np.array_equal(dL_dx, [[[0], [-2], [4]]])
def main(): parser = argparse.ArgumentParser(description="Halite II training") parser.add_argument("--model_name", help="Name of the model") parser.add_argument("--minibatch_size", type=int, help="Size of the minibatch", default=100) parser.add_argument("--steps", type=int, help="Number of steps in the training", default=100) parser.add_argument("--data", help="Data directory or zip file containing uncompressed games") parser.add_argument("--cache", help="Location of the model we should continue to train") parser.add_argument("--games_limit", type=int, help="Train on up to games_limit games", default=1000) parser.add_argument("--seed", type=int, help="Random seed to make the training deterministic") parser.add_argument("--bot_to_imitate", help="Name of the bot whose strategy we want to learn") parser.add_argument("--dump_features_location", help="Location of hdf file where the features should be stored") args = parser.parse_args() # Make deterministic if needed if args.seed is not None: np.random.seed(args.seed) nn = NeuralNet(cached_model=args.cache, seed=args.seed) if args.data.endswith('.zip'): raw_data = fetch_data_zip(args.data, args.games_limit) else: raw_data = fetch_data_dir(args.data, args.games_limit) data_input, data_output = parse(raw_data, args.bot_to_imitate, args.dump_features_location) data_size = len(data_input) training_input, training_output = data_input[:int(0.85 * data_size)], data_output[:int(0.85 * data_size)] validation_input, validation_output = data_input[int(0.85 * data_size):], data_output[int(0.85 * data_size):] training_data_size = len(training_input) # randomly permute the data permutation = np.random.permutation(training_data_size) training_input, training_output = training_input[permutation], training_output[permutation] print("Initial, cross validation loss: {}".format(nn.compute_loss(validation_input, validation_output))) curves = [] for s in range(args.steps): start = (s * args.minibatch_size) % training_data_size end = start + args.minibatch_size training_loss = nn.fit(training_input[start:end], training_output[start:end]) if s % 25 == 0 or s == args.steps - 1: validation_loss = nn.compute_loss(validation_input, validation_output) print("Step: {}, cross validation loss: {}, training_loss: {}".format(s, validation_loss, training_loss)) curves.append((s, training_loss, validation_loss)) cf = pd.DataFrame(curves, columns=['step', 'training_loss', 'cv_loss']) fig = cf.plot(x='step', y=['training_loss', 'cv_loss']).get_figure() # Save the trained model, so it can be used by the bot current_directory = os.path.dirname(os.path.abspath(__file__)) model_path = os.path.join(current_directory, os.path.pardir, "models", args.model_name + ".ckpt") print("Training finished, serializing model to {}".format(model_path)) nn.save(model_path) print("Model serialized") curve_path = os.path.join(current_directory, os.path.pardir, "models", args.model_name + "_training_plot.png") fig.savefig(curve_path)
def test_neural_net_tends_to_correct(self): n_in, n_out = 4, 2 np.random.seed(12) weights = np.random.normal(size=(n_out, n_in)) bias = np.zeros(n_out)[:, np.newaxis] nn = NeuralNet(MeanSquaredError(), 1e-2, layers=[Linear(n_in, 2, weights, bias)]) x = np.array([[[-1], [0.5], [-0.33], [0.75]]]) y = np.array([[[-0.5], [0.2]]]) for _ in range(1000): pred = nn.forward(x) loss = nn.compute_loss(pred, y) nn.backward() assert np.isclose(loss, 0)
def test_neural_net_works_with_batches(self): n_in, n_out = 2, 2 np.random.seed(12) weights = np.random.normal(size=(n_out, n_in)) bias = np.zeros(n_out)[:, np.newaxis] nn = NeuralNet(MeanSquaredError(), 1e-2, layers=[Linear(n_in, 2, weights, bias)]) # batch of 3 x = np.array([[[-1], [0.5]], [[1], [-0.2]], [[-0.33], [0.75]]]) y = x # Why does this take so much longer to converge than the previous one? for _ in range(10000): pred = nn.forward(x) loss = nn.compute_loss(pred, y) nn.backward() assert np.isclose(loss, 0) assert np.all( np.isclose(nn.layers[0].weights, [[1, 0], [0, 1]], atol=1e-3))