From e2556893df78e9869bd4827379a5232feeb0e06d Mon Sep 17 00:00:00 2001 From: Max Ramsay King <maxramsayking@gmail.com> Date: Wed, 13 Apr 2022 20:52:25 -0700 Subject: [PATCH] Had some issues with importing UCB1_JC so made it a py file, also changed some of the home.html to make the excluded transformations a checklist --- MetaAugment/CP2_Max.py | 244 +++++++++++++------------ MetaAugment/GA_results.png | Bin 43649 -> 0 bytes MetaAugment/METALEANER.py | 7 - MetaAugment/UCB1_JC.ipynb | 220 +++++++++++----------- MetaAugment/genetic_learner_results.py | 109 ----------- app.py | 46 ++++- auto_augmentation/progress.py | 6 +- auto_augmentation/templates/home.html | 63 ++++--- 8 files changed, 319 insertions(+), 376 deletions(-) delete mode 100644 MetaAugment/GA_results.png delete mode 100644 MetaAugment/METALEANER.py delete mode 100644 MetaAugment/genetic_learner_results.py diff --git a/MetaAugment/CP2_Max.py b/MetaAugment/CP2_Max.py index 792e81e1..a13fd207 100644 --- a/MetaAugment/CP2_Max.py +++ b/MetaAugment/CP2_Max.py @@ -94,75 +94,56 @@ class Learner(nn.Module): return y +# class LeNet(nn.Module): +# def __init__(self): +# super().__init__() +# self.conv1 = nn.Conv2d(1, 6, 5) +# self.relu1 = nn.ReLU() +# self.pool1 = nn.MaxPool2d(2) +# self.conv2 = nn.Conv2d(6, 16, 5) +# self.relu2 = nn.ReLU() +# self.pool2 = nn.MaxPool2d(2) +# self.fc1 = nn.Linear(256, 120) +# self.relu3 = nn.ReLU() +# self.fc2 = nn.Linear(120, 84) +# self.relu4 = nn.ReLU() +# self.fc3 = nn.Linear(84, 10) +# self.relu5 = nn.ReLU() + +# def forward(self, x): +# y = self.conv1(x) +# y = self.relu1(y) +# y = self.pool1(y) +# y = self.conv2(y) +# y = self.relu2(y) +# y = self.pool2(y) +# y = y.view(y.shape[0], -1) +# y = self.fc1(y) +# y = self.relu3(y) +# y = self.fc2(y) +# y = self.relu4(y) +# y = self.fc3(y) +# return y + + class LeNet(nn.Module): def __init__(self): super().__init__() - self.conv1 = nn.Conv2d(1, 6, 5) + self.fc1 = nn.Linear(784, 2048) self.relu1 = nn.ReLU() - self.pool1 = nn.MaxPool2d(2) - self.conv2 = nn.Conv2d(6, 16, 5) + self.fc2 = nn.Linear(2048, 10) self.relu2 = nn.ReLU() - self.pool2 = nn.MaxPool2d(2) - self.fc1 = nn.Linear(256, 120) - self.relu3 = nn.ReLU() - self.fc2 = nn.Linear(120, 84) - self.relu4 = nn.ReLU() - self.fc3 = nn.Linear(84, 10) - self.relu5 = nn.ReLU() def forward(self, x): - y = self.conv1(x) + x = x.reshape((-1, 784)) + y = self.fc1(x) y = self.relu1(y) - y = self.pool1(y) - y = self.conv2(y) - y = self.relu2(y) - y = self.pool2(y) - y = y.view(y.shape[0], -1) - y = self.fc1(y) - y = self.relu3(y) y = self.fc2(y) - y = self.relu4(y) - y = self.fc3(y) + y = self.relu2(y) return y -# code from https://github.com/ChawDoe/LeNet5-MNIST-PyTorch/blob/master/train.py -# def train_model(full_policy, child_network): -# """ -# Takes in the specific transformation index and probability -# """ - -# # transformation = generate_policy(5, ps, mags) - -# train_transform = transforms.Compose([ -# full_policy, -# transforms.ToTensor() -# ]) - -# batch_size = 32 -# n_samples = 0.005 - -# train_dataset = datasets.MNIST(root='./datasets/mnist/train', train=True, download=False, transform=train_transform) -# test_dataset = datasets.MNIST(root='./datasets/mnist/test', train=False, download=False, transform=torchvision.transforms.ToTensor()) - -# train_loader, test_loader = create_toy(train_dataset, test_dataset, batch_size, 0.01) - - -# sgd = optim.SGD(child_network.parameters(), lr=1e-1) -# cost = nn.CrossEntropyLoss() -# epoch = 20 - - -# best_acc = train_child_network(child_network, train_loader, test_loader, -# sgd, cost, max_epochs=100, print_every_epoch=False) - -# return best_acc - - - - - # ORGANISING DATA # transforms = ['RandomResizedCrop', 'RandomHorizontalFlip', 'RandomVerticalCrop', 'RandomRotation'] @@ -183,6 +164,7 @@ train_loader = torch.utils.data.DataLoader(reduced_train_dataset, batch_size=600 + class Evolutionary_learner(): def __init__(self, network, num_solutions = 10, num_generations = 5, num_parents_mating = 5, train_loader = None, child_network = None, p_bins = 11, mag_bins = 10, sub_num_pol=5, fun_num = 14, augmentation_space = None, train_dataset = None, test_dataset = None): @@ -204,28 +186,23 @@ class Evolutionary_learner(): assert num_solutions > num_parents_mating, 'Number of solutions must be larger than the number of parents mating!' self.set_up_instance() - - - def generate_policy(self, sp_num, ps, mags): - """ - - """ - policies = [] - for subpol in range(sp_num): - sub = [] - for idx in range(2): - transformation = augmentation_space[(2*subpol) + idx] - p = ps[(2*subpol) + idx] - mag = mags[(2*subpol) + idx] - sub.append((transformation, p, mag)) - policies.append(tuple(sub)) - - return policies def get_full_policy(self, x): """ - Generates the full policy (5 x 2 subpolicies) + Generates the full policy (self.num_sub_pol subpolicies). Network architecture requires + output size 5 * 2 * (self.fun_num + self.p_bins + self.mag_bins) + + Parameters + ----------- + x -> PyTorch tensor + Input data for network + + Returns + ---------- + full_policy -> [((String, float, float), (String, float, float)), ...) + Full policy consisting of tuples of subpolicies. Each subpolicy consisting of + two transformations, with a probability and magnitude float for each """ section = self.auto_aug_agent.fun_num + self.auto_aug_agent.p_bins + self.auto_aug_agent.m_bins y = self.auto_aug_agent.forward(x) @@ -244,11 +221,26 @@ class Evolutionary_learner(): full_policy.append(tuple(int_pol)) return full_policy -# + def get_policy_cov(self, x, alpha = 0.5): """ - Need p_bins = 1, num_sub_pol = 1, mag_bins = 1 + Selects policy using population and covariance matrices. For this method + we require p_bins = 1, num_sub_pol = 1, mag_bins = 1. + + Parameters + ------------ + x -> PyTorch Tensor + Input data for the AutoAugment network + + alpha -> Float + Proportion for covariance and population matrices + + Returns + ----------- + Subpolicy -> [(String, float, float), (String, float, float)] + Subpolicy consisting of two tuples of policies, each with a string associated + to a transformation, a float for a probability, and a float for a magnittude """ section = self.auto_aug_agent.fun_num + self.auto_aug_agent.p_bins + self.auto_aug_agent.m_bins @@ -284,7 +276,7 @@ class Evolutionary_learner(): mag1 = None if not self.augmentation_space[max_idx[1]][1]: mag2 = None - + for idx in range(y.shape[0]): if (torch.argmax(y_1[idx]) == max_idx[0]) and (torch.argmax(y_2[idx]) == max_idx[1]): prob1 += torch.sigmoid(y[idx, self.auto_aug_agent.fun_num]).item() @@ -313,6 +305,23 @@ class Evolutionary_learner(): def run_instance(self, return_weights = False): """ Runs the GA instance and returns the model weights as a dictionary + + Parameters + ------------ + return_weights -> Bool + Determines if the weight of the GA network should be returned + + Returns + ------------ + If return_weights: + Network weights -> Dictionary + + Else: + Solution -> Best GA instance solution + + Solution fitness -> Float + + Solution_idx -> Int """ self.ga_instance.run() solution, solution_fitness, solution_idx = self.ga_instance.best_solution() @@ -331,12 +340,25 @@ class Evolutionary_learner(): def set_up_instance(self): + """ + Initialises GA instance, as well as fitness and on_generation functions + + """ def fitness_func(solution, sol_idx): """ - Defines fitness function (accuracy of the model) + Defines the fitness function for the parent selection + + Parameters + -------------- + solution -> GA solution instance (parsed automatically) + + sol_idx -> GA solution index (parsed automatically) + + Returns + -------------- + fit_val -> float """ - print("FITNESS HERE") model_weights_dict = torchga.model_weights_as_dict(model=self.auto_aug_agent, weights_vector=solution) @@ -345,18 +367,23 @@ class Evolutionary_learner(): for idx, (test_x, label_x) in enumerate(train_loader): full_policy = self.get_policy_cov(test_x) - print("FULL POLICY: ", full_policy) - - fit_val = (test_autoaugment_policy(full_policy, self.train_dataset, self.test_dataset)[0]) #+ test_autoaugment_policy(full_policy, self.train_dataset, self.test_dataset)[0]) / 2 - - print("DONE FITNESS") + fit_val = ((test_autoaugment_policy(full_policy, self.train_dataset, self.test_dataset)[0])/ + + test_autoaugment_policy(full_policy, self.train_dataset, self.test_dataset)[0]) / 2 return fit_val def on_generation(ga_instance): """ - Just prints stuff while running + Prints information of generational fitness + + Parameters + ------------- + ga_instance -> GA instance + + Returns + ------------- + None """ print("Generation = {generation}".format(generation=ga_instance.generations_completed)) print("Fitness = {fitness}".format(fitness=ga_instance.best_solution()[1])) @@ -373,13 +400,6 @@ class Evolutionary_learner(): - - - - - - - # HEREHEREHERE0 def create_toy(train_dataset, test_dataset, batch_size, n_samples, seed=100): @@ -407,8 +427,8 @@ def create_toy(train_dataset, test_dataset, batch_size, n_samples, seed=100): def train_child_network(child_network, train_loader, test_loader, sgd, - cost, max_epochs=2000, early_stop_num = 5, logging=False, - print_every_epoch=True): + cost, max_epochs=2000, early_stop_num = 5, logging=False, + print_every_epoch=True): if torch.cuda.is_available(): device = torch.device('cuda') else: @@ -451,12 +471,10 @@ def train_child_network(child_network, train_loader, test_loader, sgd, predict_y = child_network(test_x.float()).detach() predict_ys = torch.argmax(predict_y, axis=-1) - - # label_np = test_label.numpy() - + _ = predict_ys == test_label correct += torch.sum(_, axis=-1) - # correct += torch.sum(_.numpy(), axis=-1) + _sum += _.shape[0] # update best validation accuracy if it was higher, otherwise increase early stop count @@ -511,19 +529,19 @@ __all__ = ["AutoAugmentPolicy", "AutoAugment", "RandAugment", "TrivialAugmentWid def _apply_op(img: Tensor, op_name: str, magnitude: float, - interpolation: InterpolationMode, fill: Optional[List[float]]): + interpolation: InterpolationMode, fill: Optional[List[float]]): if op_name == "ShearX": img = F.affine(img, angle=0.0, translate=[0, 0], scale=1.0, shear=[math.degrees(magnitude), 0.0], - interpolation=interpolation, fill=fill) + interpolation=interpolation, fill=fill) elif op_name == "ShearY": img = F.affine(img, angle=0.0, translate=[0, 0], scale=1.0, shear=[0.0, math.degrees(magnitude)], - interpolation=interpolation, fill=fill) + interpolation=interpolation, fill=fill) elif op_name == "TranslateX": img = F.affine(img, angle=0.0, translate=[int(magnitude), 0], scale=1.0, - interpolation=interpolation, shear=[0.0, 0.0], fill=fill) + interpolation=interpolation, shear=[0.0, 0.0], fill=fill) elif op_name == "TranslateY": img = F.affine(img, angle=0.0, translate=[0, int(magnitude)], scale=1.0, - interpolation=interpolation, shear=[0.0, 0.0], fill=fill) + interpolation=interpolation, shear=[0.0, 0.0], fill=fill) elif op_name == "Rotate": img = F.rotate(img, magnitude, interpolation=interpolation, fill=fill) elif op_name == "Brightness": @@ -728,18 +746,6 @@ class AutoAugment(torch.nn.Module): fill = [float(f) for f in fill] transform_id, probs, signs = self.get_params(len(self.subpolicies)) - # print("transform_id, probs, signs : ", transform_id, probs, signs ) - - # for i, (op_name, p, magnitude_id) in enumerate(self.subpolicies[transform_id]): - # for i, (op_name, p, magnitude_id) in enumerate(self.subpolicies): - # print("op_name, p, magnitude_id: ", op_name, p, magnitude_id) - # if probs[i] <= p: - # op_meta = self._augmentation_space(10, F.get_image_size(img)) - # magnitudes, signed = op_meta[op_name] - # magnitude = float(magnitudes[magnitude_id].item()) if magnitude_id is not None else 0.0 - # if signed and signs[i] == 0: - # magnitude *= -1.0 - # img = _apply_op(img, op_name, magnitude, interpolation=self.interpolation, fill=fill) for i, (op_name, p, magnitude) in enumerate(self.subpolicies): img = _apply_op(img, op_name, magnitude, interpolation=self.interpolation, fill=fill) @@ -771,8 +777,8 @@ class RandAugment(torch.nn.Module): """ def __init__(self, num_ops: int = 2, magnitude: int = 9, num_magnitude_bins: int = 31, - interpolation: InterpolationMode = InterpolationMode.NEAREST, - fill: Optional[List[float]] = None) -> None: + interpolation: InterpolationMode = InterpolationMode.NEAREST, + fill: Optional[List[float]] = None) -> None: super().__init__() self.num_ops = num_ops self.magnitude = magnitude @@ -853,7 +859,7 @@ class TrivialAugmentWide(torch.nn.Module): """ def __init__(self, num_magnitude_bins: int = 31, interpolation: InterpolationMode = InterpolationMode.NEAREST, - fill: Optional[List[float]] = None) -> None: + fill: Optional[List[float]] = None) -> None: super().__init__() self.num_magnitude_bins = num_magnitude_bins self.interpolation = interpolation @@ -938,4 +944,4 @@ print(f"Fitness value of the best solution = {solution_fitness}") print(f"Index of the best solution : {solution_idx}") # Fetch the parameters of the best solution. best_solution_weights = torchga.model_weights_as_dict(model=ev_learner.auto_aug_agent, - weights_vector=solution) \ No newline at end of file + weights_vector=solution) diff --git a/MetaAugment/GA_results.png b/MetaAugment/GA_results.png deleted file mode 100644 index 62449415b64500804927328ca677c4c023085436..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43649 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 FO#oZZk5d2u diff --git a/MetaAugment/METALEANER.py b/MetaAugment/METALEANER.py deleted file mode 100644 index c94246d6..00000000 --- a/MetaAugment/METALEANER.py +++ /dev/null @@ -1,7 +0,0 @@ - - - -# Neural network -# Input the dataset (same batch size, have to check if the input sizes are correc i.e. 28x28) -# Output the hyperprameters --> weights of network, kernel size, number of layers, number of kernels -# \ No newline at end of file diff --git a/MetaAugment/UCB1_JC.ipynb b/MetaAugment/UCB1_JC.ipynb index 6d872fd7..aed95670 100644 --- a/MetaAugment/UCB1_JC.ipynb +++ b/MetaAugment/UCB1_JC.ipynb @@ -1,24 +1,12 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "UCB1.ipynb", - "provenance": [], - "collapsed_sections": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - }, - "accelerator": "GPU" - }, "cells": [ { "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "U_ZJ2LqDiu_v" + }, + "outputs": [], "source": [ "import numpy as np\n", "import torch\n", @@ -33,15 +21,15 @@ "from matplotlib import pyplot as plt\n", "from numpy import save, load\n", "from tqdm import trange" - ], - "metadata": { - "id": "U_ZJ2LqDiu_v" - }, - "execution_count": 1, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "4ksS_duLFADW" + }, + "outputs": [], "source": [ "\"\"\"Define internal NN module that trains on the dataset\"\"\"\n", "class LeNet(nn.Module):\n", @@ -75,15 +63,15 @@ " y = self.fc3(y)\n", " y = self.relu5(y)\n", " return y" - ], - "metadata": { - "id": "4ksS_duLFADW" - }, - "execution_count": 2, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "LckxnUXGfxjW" + }, + "outputs": [], "source": [ "\"\"\"Define internal NN module that trains on the dataset\"\"\"\n", "class EasyNet(nn.Module):\n", @@ -101,15 +89,15 @@ " y = self.fc2(y)\n", " y = self.relu2(y)\n", " return y" - ], - "metadata": { - "id": "LckxnUXGfxjW" - }, - "execution_count": 3, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 4, + "metadata": { + "id": "enaD2xbw5hew" + }, + "outputs": [], "source": [ "\"\"\"Define internal NN module that trains on the dataset\"\"\"\n", "class SimpleNet(nn.Module):\n", @@ -123,15 +111,15 @@ " y = self.fc1(y)\n", " y = self.relu1(y)\n", " return y" - ], - "metadata": { - "id": "enaD2xbw5hew" - }, - "execution_count": 4, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 5, + "metadata": { + "id": "xujQtvVWBgMH" + }, + "outputs": [], "source": [ "\"\"\"Make toy dataset\"\"\"\n", "\n", @@ -154,15 +142,15 @@ " test_loader = torch.utils.data.DataLoader(reduced_test_dataset, batch_size=batch_size)\n", "\n", " return train_loader, test_loader" - ], - "metadata": { - "id": "xujQtvVWBgMH" - }, - "execution_count": 5, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "Iql-c88jGGWy" + }, + "outputs": [], "source": [ "\"\"\"Randomly generate 10 policies\"\"\"\n", "\"\"\"Each policy has 5 sub-policies\"\"\"\n", @@ -193,15 +181,15 @@ " policies[policy, sub_policy, transformation + 4] = np.random.randint(5,15)/10\n", "\n", " return policies" - ], - "metadata": { - "id": "Iql-c88jGGWy" - }, - "execution_count": 6, - "outputs": [] + ] }, { "cell_type": "code", + "execution_count": 7, + "metadata": { + "id": "QE2VWI8o731X" + }, + "outputs": [], "source": [ "\"\"\"Pick policy and sub-policy\"\"\"\n", "\"\"\"Each row of data should have a different sub-policy but for now, this will do\"\"\"\n", @@ -238,12 +226,7 @@ " scale = policies[policy, sub_policy][5]\n", "\n", " return degrees, shear, scale" - ], - "metadata": { - "id": "QE2VWI8o731X" - }, - "execution_count": 7, - "outputs": [] + ] }, { "cell_type": "code", @@ -392,29 +375,7 @@ }, { "cell_type": "code", - "source": [ - "batch_size = 32 # size of batch the inner NN is trained with\n", - "learning_rate = 1e-1 # fix learning rate\n", - "ds = \"MNIST\" # pick dataset (MNIST, KMNIST, FashionMNIST, CIFAR10, CIFAR100)\n", - "toy_size = 0.02 # total propeortion of training and test set we use\n", - "max_epochs = 100 # max number of epochs that is run if early stopping is not hit\n", - "early_stop_num = 10 # max number of worse validation scores before early stopping is triggered\n", - "num_policies = 5 # fix number of policies\n", - "num_sub_policies = 5 # fix number of sub-policies in a policy\n", - "iterations = 100 # total iterations, should be more than the number of policies\n", - "IsLeNet = \"SimpleNet\" # using LeNet or EasyNet or SimpleNet\n", - "\n", - "# generate random policies at start\n", - "policies = generate_policies(num_policies, num_sub_policies)\n", - "\n", - "q_values, best_q_values = run_UCB1(policies, batch_size, learning_rate, ds, toy_size, max_epochs, early_stop_num, iterations, IsLeNet)\n", - "\n", - "plt.plot(best_q_values)\n", - "\n", - "best_q_values = np.array(best_q_values)\n", - "save('best_q_values_{}_{}percent_{}.npy'.format(IsLeNet, int(toy_size*100), ds), best_q_values)\n", - "#best_q_values = load('best_q_values_{}_{}percent_{}.npy'.format(IsLeNet, int(toy_size*100), ds), allow_pickle=True)" - ], + "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -423,168 +384,207 @@ "id": "doHUtJ_tEiA6", "outputId": "3a7becf3-7b5d-4403-84d3-96e51bac8bf5" }, - "execution_count": 9, "outputs": [ { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 10%|█ | 10/100 [01:09<09:26, 6.29s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 10,\tQ-Values: [0.8, 0.71, 0.79, 0.86, 0.76], Best Policy: 0.86\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 20%|██ | 20/100 [02:18<09:03, 6.80s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 20,\tQ-Values: [0.77, 0.75, 0.81, 0.86, 0.78], Best Policy: 0.86\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 30%|███ | 30/100 [03:24<06:50, 5.87s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 30,\tQ-Values: [0.81, 0.71, 0.79, 0.8, 0.78], Best Policy: 0.81\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 40%|████ | 40/100 [04:34<06:14, 6.23s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 40,\tQ-Values: [0.8, 0.7, 0.76, 0.8, 0.78], Best Policy: 0.8\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 50%|█████ | 50/100 [05:49<06:04, 7.28s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 50,\tQ-Values: [0.79, 0.72, 0.76, 0.81, 0.74], Best Policy: 0.81\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 60%|██████ | 60/100 [06:55<04:32, 6.82s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 60,\tQ-Values: [0.79, 0.72, 0.77, 0.81, 0.76], Best Policy: 0.81\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 70%|███████ | 70/100 [08:29<04:16, 8.53s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 70,\tQ-Values: [0.78, 0.7, 0.78, 0.8, 0.76], Best Policy: 0.8\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 80%|████████ | 80/100 [09:38<02:05, 6.27s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 80,\tQ-Values: [0.79, 0.72, 0.78, 0.79, 0.77], Best Policy: 0.79\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ " 90%|█████████ | 90/100 [10:41<01:04, 6.47s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 90,\tQ-Values: [0.79, 0.71, 0.78, 0.79, 0.77], Best Policy: 0.79\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ "100%|██████████| 100/100 [11:51<00:00, 7.11s/it]" ] }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "Iteration: 100,\tQ-Values: [0.79, 0.72, 0.79, 0.79, 0.78], Best Policy: 0.79\n" ] }, { - "output_type": "stream", "name": "stderr", + "output_type": "stream", "text": [ "\n" ] }, { - "output_type": "display_data", "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD4CAYAAADiry33AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de3hc9X3n8fdXo7stW5YtG9uSscE22HG4xZCEawIhS2iC0266NUna8CwNaZ5Csilplj7NUkqS3V5Dk6eULkmzJCELpd40dRMnBAjk0phgm6stB2MbsGVsWb5gyci6zMx3/zhn5EGWpTPSyJLm93k9jx40M+dofoeBj376nu/5HXN3RESkdJWN9wBERGRsKehFREqcgl5EpMQp6EVESpyCXkSkxJWP9wAGmjVrli9cuHC8hyEiMqls2rTpgLs3DvbahAv6hQsXsnHjxvEehojIpGJmr57sNZVuRERKnIJeRKTEKehFREpcoqA3s2vM7EUz225mtw3y+gIze9zMnjGz583s2rzXzjGz9Wa2xcxeMLPqYh6AiIgMbdiTsWaWAu4GrgZagQ1mttbdW/I2+zzwkLvfY2bLgXXAQjMrB+4HftfdnzOzmUBf0Y9CREROKsmM/iJgu7vvdPde4EFg1YBtHJgWfz8deC3+/r3A8+7+HIC7H3T3zOiHLSIiSSUJ+vnA7rzHrfFz+e4APmpmrUSz+Vvi55cCbmYPm9nTZva5wd7AzG4ys41mtrG9vb2gAxARkaEVq4/+euA+d/9bM3sn8G0zWxH//EuBC4Eu4DEz2+Tuj+Xv7O73AvcCrFy5Mrh1k9c+9xrb2zoL2mflwgYuXzrotREiIm+SJOj3AM15j5vi5/LdCFwD4O7r4xOus4hm/z9z9wMAZrYOuAB4DAEgk3X+6J+fJZ11zJLt4w4LZ9byxB+/e2wHJyIlIUnQbwCWmNkiooBfDXx4wDa7gKuA+8xsGVANtAMPA58zs1qgF7gCuKtIYy8JB4/2kM46X1j1Fn73nQsT7fOF77fwwFO7xnZgIlIyhq3Ru3sauJkotLcSdddsMbM7zey6eLNbgY+b2XPAA8ANHjkMfJnol8WzwNPu/oOxOJDJan9nDwCNdcm7ThvrqujqzfBGT3qshiUiJSRRjd7d1xGdZM1/7va871uAS06y7/1ELZYyiP2d3QDMmVaVeJ/ZdVXxvj0sqppwyxWJyASjK2PHWVtHNKOfPa2wGT1Ae/zXgIjIUBT042x/HPSNU5PP6Bv7Z/TdYzImESkt+rs/9m/P7uHfn9tb0D5zplVx56oVpMoStssMYn9nNw1TKqksT/47d3Zcz9eMXkSSUNATtTh+6QdbyWSdOQlLKB3dfTy69Rg3XrqIMxqnjvi92zp6+mvuSdXXVFBeZgp6EUlEQQ9sfOUQ+zt7+Or153PdufMS7fPUy4f4L/97PbsPHxtV0Ld3dveXYpIqKzMa66r6O3ZERIaiGj3w/ef3Ul1RxlVnz068T9OMGgBaD3eN6r33d/Yk/isiX2NdlWb0IpJI8EGfzmT54ea9XHn2bKYU0Ko4Z1o1FSlj96FjI37vbNZp7yy8dAPRyVsFvYgkEXzQP/XyIQ4c7eX95yQr2eSkyox59TWjmtEf6uolXcB5gXyzp6l0IyLJBB/0//78XmorU7z7rORlm5zmGbXsPjzyGX2utXKkM/pDb/SQyQa3BpyIFCjooE9nsvxo816uWjaHmspUwfs3zahhzyhm9G1xH/zsAq6KzWmcVk3Wo7VyRESGEnTQ/3LHQQ539fH+c+aOaP/mhloOHO2lq3dka86098/oR3AydurxZRBERIYSXHvlvz7TylMvHwLg+dYjTK0q54oRruue67zZc/gYS+bUFbx/7srWQtsr8/dp14xeRIYRXNDf9chLtHV0M72mAoAbLl5IdUXhZRuAphm1ALSOMOjbOnqYXlMxovfP1fVzfxWIiJxMcEHfl8ly3bnz+OvfPnfUP6s5ntHvHmGdfn9nd0GrVubTjF5EkgquRp/OOuWpka9Nk6+xroqq8jJaR9h5s7+zZ0T1eYDqihTTqsvVSy8iwwou6DNZp7ysOIdtZsyfUcPuQyOc0Y9gnZt80TIIWsFSRIYWXND3ZbKjWm1yoOYZtSOa0bs7+zu7C1qHfiAtgyAiSQQX9NGMvnhB3zSjZkQ1+sNdffRlfFQz+tl11WqvFJFhBRf0UY2+eIfdNKOW17v66OzuK2i//aO4WCpHM3oRSSK8oM9kizqjb27IrWJZWPkmt/zBSNa5yZmtm4SLSAJBBX0262Sdotbo83vpC9HWEc/oR3kyFnR1rIgMLaigz3i0AFhFkdorIa+XvsDOm1w4j7S9Mn9flW9EZChBBX06EwV9qkjtlQANUyqpqUgVPKNv7+yhrrp8RIup5egm4SKSRFhBn80CFLVGb2Y0NxTeedPW0T2qsg3kXR2rGb2IDCGooM+t3V6sK2NzmkbQSz+aq2Jz6msqqEjpJuEiMrSggr4vLt0Uc0YPUZ2+9VAX7slvAjKadW5yysqMWVN1pykRGVpQi5rlZvTFrNFDNKPv7EnzD0/sSHyit+1Iz6iuis2ZrV56ERlGoqA3s2uArwAp4Ovu/hcDXl8AfBOoj7e5zd3XDXi9BbjD3f+mSGMvWH+Nvsilm3Ob6ykz+OuHXyxov7fMmzbq926sq2Jn+xv8aufBxPvUVVewvAjvLSKTw7BBb2Yp4G7gaqAV2GBma929JW+zzwMPufs9ZrYcWAcszHv9y8APizbqEUqPUenmokUNtNx5TUH3by0zG1XHTU5zQy2Pbt3P79z7ZEH7PfpHl7N4duFr6IvI5JNkRn8RsN3ddwKY2YPAKqIZeo4DuSnidOC13Atm9kHgZeCNYgx4NNL9pZviBj0w4puXjNZn33sWVy+fE30CCbTs7eCLP9jKwaO9LC78fugiMgklCfr5wO68x63A2wdscwfwYzO7BZgCvAfAzKYC/53or4HPnuwNzOwm4CaABQsWJBx64XIz7ooirnUz3qZUlXPxmbMSb18d/xVxrC8zVkMSkQmmWIl3PXCfuzcB1wLfNrMyol8Ad7n70aF2dvd73X2lu69sbBzZ/VuT6MtENfqxmNFPFjXxXx7dCnqRYCSZ0e8BmvMeN8XP5bsRuAbA3debWTUwi2jm/yEz+yuiE7VZM+t2978f9chHoL+PXkGvGb1IQJIE/QZgiZktIgr41cCHB2yzC7gKuM/MlgHVQLu7X5bbwMzuAI6OV8jD8Rp9MZcpnmxyJ4C7ehX0IqEYNvHcPQ3cDDwMbCXqrtliZnea2XXxZrcCHzez54AHgBu8kKuHTpF0pvhLIEw2uaA/pqAXCUaiPvq4J37dgOduz/u+BbhkmJ9xxwjGV1SZMey6mSxUoxcJT1A1jHS2+MsUTzYVqTLKy0w1epGABBb0ua6boA77BDUVKY71Zsd7GCJyigSVeGN1ZexkU12Z0oxeJCBBBf1YLVM82dRUpFSjFwlIUEGfVh89EAV9V69uKC4SisCCXjV6iFosj/WpRi8SiqASTzX6SE1Fim710YsEI6igV40+UqOTsSJBCSro+3TBFBC3VyroRYIRVNBn4iUQKgKv0VdXpLQEgkhAgkq8/huPBF+6KdOMXiQgQQa9TsZqRi8SkqCC/vh69EEd9glqKss51pdhAi4wKiJjIKjEU3tlJLeCZU9avfQiIQgr6LNZzKAs+KCPPnaVb0TCEFjQe/AdN5B38xGdkBUJQlCpl8l68D30ELVXgoJeJBRBBX1fJht8fR7ybhCu0o1IEIIK+kzWg1/+AFS6EQlNUEGfznrwK1cC1OoG4SJBCSr10irdAKrRi4QmrKDXyVjgeI1ed5kSCUNQQZ/JOhWq0R+v0at0IxKEoII+ndGMHvK6bjSjFwlCWEGfzQa/zg0cr9F3aUYvEoSgUk/tlZGq8jLMVKMXCUVQQd+XcXXdAGampYpFAhJU0GsJhONqdd9YkWAkCnozu8bMXjSz7WZ22yCvLzCzx83sGTN73syujZ+/2sw2mdkL8T+vLPYBFCKdzVKeCup320lV676xIsEoH24DM0sBdwNXA63ABjNb6+4teZt9HnjI3e8xs+XAOmAhcAD4gLu/ZmYrgIeB+UU+hsTSGaeyXEEPUeeNavQiYUiSehcB2919p7v3Ag8CqwZs48C0+PvpwGsA7v6Mu78WP78FqDGzqtEPe2R0wdRxNZUpdd2IBCJJ0M8Hduc9buXEWfkdwEfNrJVoNn/LID/nPwNPu3vPwBfM7CYz22hmG9vb2xMNfCSiC6Y0o4e4dKOgFwlCsVLveuA+d28CrgW+bWb9P9vM3gL8JfCJwXZ293vdfaW7r2xsbCzSkE7Ul8lqRh9T6UYkHEmCfg/QnPe4KX4u343AQwDuvh6oBmYBmFkT8K/A77n7jtEOeDQyWbVX5tToZKxIMJIE/QZgiZktMrNKYDWwdsA2u4CrAMxsGVHQt5tZPfAD4DZ3/4/iDXtkogumVLoBtVeKhGTY1HP3NHAzUcfMVqLumi1mdqeZXRdvdivwcTN7DngAuMHdPd5vMXC7mT0bf80ekyNJoC+rZYpzqitTHOvNjvcwROQUGLa9EsDd1xGdZM1/7va871uASwbZ74vAF0c5xqLJaFGzfqrRi4QjqDpGWssU96upSNHVmyb6w0tESllwQa8ZfaSmMkXWoTej8o1IqQsr6DNapjgnt1Rxt+r0IiUvUY2+VKi98rj8m49Mp2LUP+9fNu7mkZa2QV+7aFEDv3/ZGaN+DxEZmaCCvi/rpFSjB6L2SijeXabu/dlO9nV0M7++5k3Pt3f2sH7HQW68dBFm+ncvMh6CCnrN6I/LlW6KtQzCvo5ufuv8+fz5qhVvev7rP9/JF3+wlde7+pgxpbIo7yUihQmmYO3ucdAHc8hDqinijL6rN01nd5o506tPeO30mVMAePVQ16jfR0RGJpjUS2ejNkLN6CM1RZzR7zvSDcBp0wYL+loAXj34xqjfR0RGJpigz8RBrxp9JP9k7Gjt6zh50DfPiIJ+10HN6EXGSzBBn5vRV6h0A0BNZfTvoRhB3xYH/WClm5rKFLPrqlS6ERlHwaReOr4wSBdMRY730Y8+6PcOUbqBqHyjGb3I+Akn6HM1epVuAKitjBquijKjP9JNXXU5U6oGb+Ja0DCFVw+pRi8yXoIJ+kz/ydhgDnlIxa7Rn2w2D9GMvq2jR4uoiYyTYPro++LSjbpuIlXxTdKLcd/YfR09nDZIfT4n13mz+1AXS+bUjfr9ToX2zh4e3rJv0EXf0lmn41ia14/1crQ7TSHLwrnDsb6oHbWzO90/AUlq5cIZ/NkH3lLQPiLBBH1/142CHoCyMqO6oqwos+y2I90smT3rpK8vaMi1WE6eoP/az3dy7892DrnN1Kpy6qrLKSvwit+aylT/voXcw3jP4WPc98tX+NSVS3TxmRQkmKBXjf5ENQNuEP7Tbe283tU77H6XLp7FzKlVQPQLtP1ozzClm8l30dSv93Vy9ml13P/7bz/htZQZddXlp/xuZc/sOsxv/sMv+fn2A1x37rxT+t4yuYUT9BnV6AfKv2/strZOPvaNpxLt9+G3L+B//uZbAThwtIdM1gdtrcyZUVvB1Kpydk2ii6ZeauvkHWfMZFb8C20iOKepnhm1FTzx4n4FvRQknKDPqr1yoOq8+8a+0HoEgG/914tomlFz0n0+t+Z5tuw50v94qKtic8yMBQ21k2ZG39Hdx94j3SyePXW8h/ImqTLjsiWN/GzbAbJZp0z/LUtCwQR9rkavO0wdV1uZ6u+j37q3g6ryMi4+c+aQJYlzm+u5/8lXo7X9U2X9PfRzh5jRQ3RC9sV9ncUb/Bjavv8oAEsn4PmEK5Y2sva512jZ28GK+dPHezgySQRTx+jL6GTsQPmlm5a9HZx1Wt2wdedlc6fRk87ySlyG6b8qdogZPcCCmbXsPtxVcJfJeHipLfqFtHTOxJrRA1y+tBGIzqeIJBVM0KuP/kTVFSm6ejO4O1v3drDstGnD7rNsbjTLbdkbheG+jm4qUsbMYbpATm+YQl/G2Xvk2OgHPsa2tR2luqKMpnidnomksa6KFfOn8dMXFfSSXDCpl6vRq+vmuJqKFN19Gdo6ejjc1cfyecMH/ZLZdVSkjK17O4CotXJ2XfWw9eJcL/2uSVCn39bWyZmNUyfsX39XLG1k067DdHT3jfdQZJIIpkZ/vOtmYv7POx5q4pOxudBeNnf4oK8sL+PMxqm0vBbts6+jmznThu9MyfXS7zrYxcVnjnzMuw918cPNe3n81+10JbgGYMnsqVz71tO4ZPEsqspTid5j+/6jvOOMmSMf5Bi7Yuls7n58B//x0gHe99a5Be2bzTrffvJV/vbHL3K0Jz3ktmbGnavewkfefvpohisTQDBBrwumTpTro2+Jg/7suclOPi6fO41fbD8AREF/9mnD7zevvobyMhtx581LbZ388ZrneXb36/1jaKwb+hdM1p2HN+9jzaZW6qrL+dNrl7H6ogVD7pPruFkyAevzORcsqKeuupyfbmsvKOhbD3fxuTXP88sdB7l08SzOX1A/5Pbf+dUuntx5SEFfAoIJ+v5lik/xRS4TWXXF8Rl904waplUnu0n4srnT+O4zezh4tIe2I91cEZ8gHEqqzGiaUTOiVSz/Y/sB/uD+TVSVp/iT953N+1bMZcHMZPXznnSGX24/yJcf2cbf/HgbH3pb05AnnF9qiztuZk+8jpuc8lQZly6exZpNrTy6dfAbsg+m41iaipTxv37rray+sHnYe/g+u/v1SVFqk+GFE/RapvgENZVRjb5lbwfLE5RtcnK1/A2vHOKN3sywrZU5C2ZOYUf7UXYXEB6/2H6A//G9zZzROIVv3HBhwSdIq8pTvPvs2fSkM/zB/U+zfudBLlty8l9MuY6biTyjB7jlyiXMnFrJIEvxnFRNRYqPXbyQ5oZk/w6bG2r50eZ9IxyhTCThBL1uJXiC2ooUfRnn5QNv8IFzkl9pmavl/+TX+4HhWytzzpg1hZ9ta+eyv3q8oHFetmQWd3/kgsR/cQzmXWfNpq6qnLXPvjZ00O+POm6aJ2DHTb7l86bxxQ++dUzfY0FDLYfe6KWzu4+6Ufy7l/GXKOjN7BrgK0AK+Lq7/8WA1xcA3wTq421uc/d18Wt/AtwIZIBPufvDxRt+cv3tlSrd9MvdINw92YnYnIYplcyZVsUTcYvfUFfF5rvlysWsmD990BUhT2ZKVTlXL58z6pJbdUWK/7TiNH60eR9f+OCK/huvDLStrZPFs6fqqlOOn0DffegYy+cp6CezYYPezFLA3cDVQCuwwczWuntL3mafBx5y93vMbDmwDlgYf78aeAswD3jUzJa6+ylfmFzLFJ8oP+wKKd1A9IuhP+gTlm5mTq3iQ29rKuh9ium6c+exZlMrT7zYzjUrTht0m5fajnLxmRO34+ZU6u+UOtSVqPVWJq4k06SLgO3uvtPde4EHgVUDtnEg91/CdOC1+PtVwIPu3uPuLwPb4593yqnr5kS5m49MrSofcn2bweT/BZC0dDPeLj5zJrOmVrL2uT2Dvn7kWB/7OrpZPMHr86dKc8Px+wjI5JYk6OcDu/Met8bP5bsD+KiZtRLN5m8pYF/M7CYz22hmG9vbx+aKPy1TfKJc6WbZ3LqCSxW5vwDqaytOWgaZaMpTZbz/nHk8unU/nYNcbNS/xs0E7rg5labXVDC9pkKdNyWgWAXr64H73L0JuBb4tpkl/tnufq+7r3T3lY2Nw7fqjUS6v3SjGn1ObkZfSH0+J7dP0vr8RPGBc+fRm87y4y0ntiUeX+NGQZ+zoKFWQV8CkpyM3QM05z1uip/LdyNwDYC7rzezamBWwn1PibRKNyeoHkXQL5o1heqKssT1+YniggX1NM2o4dZ/eY7PrnnuTa+5R7/8Ci1jlbIFDbX9V07L5JUk6DcAS8xsEVFIrwY+PGCbXcBVwH1mtgyoBtqBtcD/NbMvE52MXQIku7tFkWmZ4hMtnzuN9yybzZVnzy5431SZ8fHLzuDMxslVzzYz7vqd8/j5SVZ/XD5vmjpu8jQ31PJISxuZrGuSNIkNG/Tunjazm4GHiVonv+HuW8zsTmCju68FbgW+ZmafIToxe4NHPXRbzOwhoAVIA384Hh03oBn9YKbXVvD1j1044v1vfe9ZRRzNqXPhwgYuXNgw3sOYFBY01NKbydLW0c28ev2lM1kl6qOPe+LXDXju9rzvW4BLTrLvl4AvjWKMRaFbCYoUbkFe542CfvIKJvUy2SxmmtGLFCK/l14mr2CCvi/rulhKpEBz66tJlZl66Se5YIJeJ5NECleRKmNefbVm9JNcMEGfzjgVqs+LFEy99JNfMMmXzmZJqbVSpGDNM2rZdWji3+t3MnJ3uvsy/V896bFpSgxqmWLV6EUK19xQy4GjPXT1pqmtDCYyxtwLrUf4o4ee5aV46Q2A85rr+d4fDtrAOCrBfGqZjKu1UmQE8pcrPivBbSNlaJms848/3cFdj2xj1tQqbr16aX+1YU7d2FxpHkzQ92WzOhkrMgL5LZYK+sirB9/gWIKb0+dkss72/UfZ9OphfrnjINv3H+U3zpnLlz64gvrayjEcaSSYoM9kXStXioxAsXvps1nnhT1HeHRrG5tePdy/PEkSqTLj1veexdtOn1GUsRTqaE+a2/9tM999emRLdk2pTHHegnpufvdiVp03b9j79hZLMEGvGr3IyNTXVlBXVc49T2xnzabWUf+89s4eDhztoczgrfOnF7TM9ZbXOvjiD1r47icvPmUhmfPMrsN8+sFnaT3cxSffdSbnzJ9e0P6nz5zCWafVjUtlIZygz2RVoxcZATPjU1ct4alXDhXl5519Wh2XL53Fu5bOZsaUwsoW9z/5Kp//3mZ+sf3AkPf+Hczm+K+InCPH+tjR/gY79h9lf2f3sPv3ZZz59TX88yfeOenWSgom6HXBlMjIffzyM/j45WeM9zD47ZVN/P1PtvOVR1/i0sWzEs/qXznwBtd/7Uk6u9P9z9VWpjizcSoXLpzBadNrGC4eplSV89F3nM70msl3/9xggj6ddS1RLDLJVZWn+OS7zuTP1m5h/c6DXHzmrGH36e7L8MnvPE2ZGT//3LvfdL+BU13+GS/B1DLSGc3oRUrB71zYzOy6Kr762EvDbuvufP57m/n1vg7+bvV5NDfUYmb9X6EIaEavGr1IKaiuSPGJK87kC99v4Y61W6irPnmMtXf2sGZTK5+6cjHvPqvwG+yUimCCPpN1KlIKepFS8OGLFvCdJ1/lW+tfGXbb9604jU+/Z+mYj2kiCybo+zJOdUU4f6qJlLKayhQ/+ey7xnsYk0YwU9yM+uhFJFDBBH0665SrdCMiAQom+aILpjSjF5HwBBP0umBKREIVTNCn1XUjIoEKJvnSGS1TLCJhCifo1XUjIoEKJui1Hr2IhCqYoO/TMsUiEqhgkk9dNyISqkRBb2bXmNmLZrbdzG4b5PW7zOzZ+Gubmb2e99pfmdkWM9tqZl+1cVoyLq3SjYgEati1bswsBdwNXA20AhvMbK27t+S2cffP5G1/C3B+/P3FwCXAOfHLvwCuAJ4o0vgT08lYEQlVkhn9RcB2d9/p7r3Ag8CqIba/Hngg/t6BaqASqAIqgLaT7Ddm3D0u3QRTqRIR6Zck+eYDu/Met8bPncDMTgcWAT8BcPf1wOPA3vjrYXffOsh+N5nZRjPb2N7eXtgRJJC7y3yFZvQiEqBiT3FXA2vcPQNgZouBZUAT0S+HK83ssoE7ufu97r7S3Vc2NhZ2w98k0nHQp1SjF5EAJQn6PUBz3uOm+LnBrOZ42QbgN4En3f2oux8Ffgi8cyQDHY1c0KtGLyIhShL0G4AlZrbIzCqJwnztwI3M7GxgBrA+7+ldwBVmVm5mFUQnYk8o3Yy1TCYX9KrRi0h4hk0+d08DNwMPE4X0Q+6+xczuNLPr8jZdDTzo7p733BpgB/AC8BzwnLv/e9FGn1BfNgug9koRCVKiWwm6+zpg3YDnbh/w+I5B9ssAnxjF+IoidzJWF0yJSIiCqGWk+7tugjhcEZE3CSL50pmodKMZvYiEKIygz3XdqEYvIgEKIugzWXXdiEi4gki+PpVuRCRgQQR9RhdMiUjAggh61ehFJGRhBL2ujBWRgAWRfOmsavQiEq4ggr5/mWKVbkQkQEEEfa50oxm9iIQojKBXH72IBCyI5Mto9UoRCVgQQd+XUR+9iIQriKDXMsUiErIggr5/meJUEIcrIvImQSSflikWkZCFEfRa60ZEAhZE0PcvaqbSjYgEKIjk0zLFIhKyIIJeyxSLSMiCCHotUywiIQsj6LVMsYgELIjkyy2BoMqNiIQoiKBPZ52KlGGmpBeR8AQR9Jmsq+NGRIIVRND3ZVz1eREJVhDpl8lm1XEjIsFKFPRmdo2ZvWhm283stkFev8vMno2/tpnZ63mvLTCzH5vZVjNrMbOFxRt+Mumsq4deRIJVPtwGZpYC7gauBlqBDWa21t1bctu4+2fytr8FOD/vR3wL+JK7P2JmU4FssQafVDqjGr2IhCvJjP4iYLu773T3XuBBYNUQ218PPABgZsuBcnd/BMDdj7p71yjHXLBoRh9ElUpE5ARJ0m8+sDvvcWv83AnM7HRgEfCT+KmlwOtm9l0ze8bM/jr+C2HgfjeZ2UYz29je3l7YESSgGr2IhKzY09zVwBp3z8SPy4HLgM8CFwJnADcM3Mnd73X3le6+srGxschDgj61V4pIwJIE/R6gOe9xU/zcYFYTl21ircCzcdknDXwPuGAkAx2NTMapUOlGRAKVJP02AEvMbJGZVRKF+dqBG5nZ2cAMYP2AfevNLDdNvxJoGbjvWEtrRi8iARs26OOZ+M3Aw8BW4CF332Jmd5rZdXmbrgYedHfP2zdDVLZ5zMxeAAz4WjEPIIm0avQiErBh2ysB3H0dsG7Ac7cPeHzHSfZ9BDhnhOMrioz66EUkYEEUrtNaAkFEAhZE+qWzWdXoRSRYgQS9q0YvIsEKIuhVoxeRkAUR9H0ZJ6UavYgEKoj0y2SzmtGLSLCCCHrV6EUkZGEEfUY1ehEJVxBBH90zNohDFRE5QRDplwzyGnsAAASDSURBVM5mqVDpRkQCFUbQ6w5TIhKwRGvdTAavd/Xy2/+4ftDXDnf1qkYvIsEqmaAvKzOWzJk66GtL59Rx3XmD3hRLRKTklUzQT6uu4B8+8rbxHoaIyIQTRI1eRCRkCnoRkRKnoBcRKXEKehGREqegFxEpcQp6EZESp6AXESlxCnoRkRJn7j7eY3gTM2sHXh3Fj5gFHCjScCaLEI8ZwjzuEI8ZwjzuQo/5dHdvHOyFCRf0o2VmG9195XiP41QK8ZghzOMO8ZghzOMu5jGrdCMiUuIU9CIiJa4Ug/7e8R7AOAjxmCHM4w7xmCHM4y7aMZdcjV5ERN6sFGf0IiKSR0EvIlLiSibozewaM3vRzLab2W3jPZ6xYmbNZva4mbWY2RYz+3T8fIOZPWJmL8X/nDHeYy02M0uZ2TNm9v348SIz+1X8mf+zmVWO9xiLzczqzWyNmf3azLaa2TtL/bM2s8/E/21vNrMHzKy6FD9rM/uGme03s815zw362Vrkq/HxP29mFxTyXiUR9GaWAu4G3gcsB643s+XjO6oxkwZudfflwDuAP4yP9TbgMXdfAjwWPy41nwa25j3+S+Aud18MHAZuHJdRja2vAD9y97OBc4mOv2Q/azObD3wKWOnuK4AUsJrS/KzvA64Z8NzJPtv3AUvir5uAewp5o5IIeuAiYLu773T3XuBBYNU4j2lMuPted386/r6T6H/8+UTH+814s28CHxyfEY4NM2sCfgP4evzYgCuBNfEmpXjM04HLgX8CcPded3+dEv+siW5xWmNm5UAtsJcS/Kzd/WfAoQFPn+yzXQV8yyNPAvVmNjfpe5VK0M8Hduc9bo2fK2lmthA4H/gVMMfd98Yv7QPmjNOwxsrfAZ8DsvHjmcDr7p6OH5fiZ74IaAf+T1yy+rqZTaGEP2t33wP8DbCLKOCPAJso/c8652Sf7agyrlSCPjhmNhX4f8B/c/eO/Nc86pktmb5ZM3s/sN/dN433WE6xcuAC4B53Px94gwFlmhL8rGcQzV4XAfOAKZxY3ghCMT/bUgn6PUBz3uOm+LmSZGYVRCH/HXf/bvx0W+5Pufif+8drfGPgEuA6M3uFqCx3JVHtuj7+8x5K8zNvBVrd/Vfx4zVEwV/Kn/V7gJfdvd3d+4DvEn3+pf5Z55zssx1VxpVK0G8AlsRn5iuJTt6sHecxjYm4Nv1PwFZ3/3LeS2uBj8Xffwz4t1M9trHi7n/i7k3uvpDos/2Ju38EeBz4ULxZSR0zgLvvA3ab2VnxU1cBLZTwZ01UsnmHmdXG/63njrmkP+s8J/ts1wK/F3ffvAM4klfiGZ67l8QXcC2wDdgB/Ol4j2cMj/NSoj/nngeejb+uJapZPwa8BDwKNIz3WMfo+N8FfD/+/gzgKWA78C9A1XiPbwyO9zxgY/x5fw+YUeqfNfDnwK+BzcC3gapS/KyBB4jOQ/QR/fV248k+W8CIOgt3AC8QdSUlfi8tgSAiUuJKpXQjIiInoaAXESlxCnoRkRKnoBcRKXEKehGREqegFxEpcQp6EZES9/8BkOCB+Q8kORgAAAAASUVORK5CYII=", "text/plain": [ "<Figure size 432x288 with 1 Axes>" - ], - "image/png": "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\n" + ] }, "metadata": { "needs_background": "light" - } + }, + "output_type": "display_data" } + ], + "source": [ + "batch_size = 32 # size of batch the inner NN is trained with\n", + "learning_rate = 1e-1 # fix learning rate\n", + "ds = \"MNIST\" # pick dataset (MNIST, KMNIST, FashionMNIST, CIFAR10, CIFAR100)\n", + "toy_size = 0.02 # total propeortion of training and test set we use\n", + "max_epochs = 100 # max number of epochs that is run if early stopping is not hit\n", + "early_stop_num = 10 # max number of worse validation scores before early stopping is triggered\n", + "num_policies = 5 # fix number of policies\n", + "num_sub_policies = 5 # fix number of sub-policies in a policy\n", + "iterations = 100 # total iterations, should be more than the number of policies\n", + "IsLeNet = \"SimpleNet\" # using LeNet or EasyNet or SimpleNet\n", + "\n", + "# generate random policies at start\n", + "policies = generate_policies(num_policies, num_sub_policies)\n", + "\n", + "q_values, best_q_values = run_UCB1(policies, batch_size, learning_rate, ds, toy_size, max_epochs, early_stop_num, iterations, IsLeNet)\n", + "\n", + "plt.plot(best_q_values)\n", + "\n", + "best_q_values = np.array(best_q_values)\n", + "save('best_q_values_{}_{}percent_{}.npy'.format(IsLeNet, int(toy_size*100), ds), best_q_values)\n", + "#best_q_values = load('best_q_values_{}_{}percent_{}.npy'.format(IsLeNet, int(toy_size*100), ds), allow_pickle=True)" ] } - ] -} \ No newline at end of file + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "UCB1.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/MetaAugment/genetic_learner_results.py b/MetaAugment/genetic_learner_results.py deleted file mode 100644 index 35d9de8d..00000000 --- a/MetaAugment/genetic_learner_results.py +++ /dev/null @@ -1,109 +0,0 @@ -import matplotlib.pyplot as plt -import numpy as np - - -# Fixed seed (same as benchmark) - -# Looking at last generation can make out general trends of which transformations lead to the largest accuracies - - -gen_1_acc = [0.1998, 0.1405, 0.1678, 0.9690, 0.9672, 0.9540, 0.9047, 0.9730, 0.2060, 0.9260, 0.8035, 0.9715, 0.9737, 0.14, 0.9645] - -gen_2_acc = [0.9218, 0.9753, 0.9758, 0.1088, 0.9710, 0.1655, 0.9735, 0.9655, 0.9740, 0.9377] - -gen_3_acc = [0.1445, 0.9740, 0.9643, 0.9750, 0.9492, 0.9693, 0.1262, 0.9660, 0.9760, 0.9697] - -gen_4_acc = [0.9697, 0.1238, 0.9613, 0.9737, 0.9603, 0.8620, 0.9712, 0.9617, 0.9737, 0.1855] - -gen_5_acc = [0.6445, 0.9705, 0.9668, 0.9765, 0.1142, 0.9780, 0.9700, 0.2120, 0.9555, 0.9732] - -gen_6_acc = [0.9710, 0.9665, 0.2077, 0.9535, 0.9765, 0.9712, 0.9697, 0.2145, 0.9523, 0.9718, 0.9718, 0.9718, 0.2180, 0.9622, 0.9785] - -gen_acc = [gen_1_acc, gen_2_acc, gen_3_acc, gen_4_acc, gen_5_acc, gen_6_acc] - -gen_acc_means = [] -gen_acc_stds = [] - -for val in gen_acc: - gen_acc_means.append(np.mean(val)) - gen_acc_stds.append(np.std(val)) - - - -# Vary seed - -gen_1_vary = [0.1998, 0.9707, 0.9715, 0.9657, 0.8347, 0.9655, 0.1870, 0.0983, 0.3750, 0.9765, 0.9712, 0.9705, 0.9635, 0.9718, 0.1170] - -gen_2_vary = [0.9758, 0.9607, 0.9597, 0.9753, 0.1165, 0.1503, 0.9747, 0.1725, 0.9645, 0.2290] - -gen_3_vary = [0.1357, 0.9725, 0.1708, 0.9607, 0.2132, 0.9730, 0.9743, 0.9690, 0.0850, 0.9755] - -gen_4_vary = [0.9722, 0.9760, 0.9697, 0.1155, 0.9715, 0.9688, 0.1785, 0.9745, 0.2362, 0.9765] - -gen_5_vary = [0.9705, 0.2280, 0.9745, 0.1875, 0.9735, 0.9735, 0.9720, 0.9678, 0.9770, 0.1155] - -gen_6_vary = [0.9685, 0.9730, 0.9735, 0.9760, 0.1495, 0.9707, 0.9700, 0.9747, 0.9750, 0.1155, 0.9732, 0.9745, 0.9758, 0.9768, 0.1155] - -gen_vary = [gen_1_vary, gen_2_vary, gen_3_vary, gen_4_vary, gen_5_vary, gen_6_vary] - -gen_vary_means = [] -gen_vary_stds = [] - -for val in gen_vary: - gen_vary_means.append(np.mean(val)) - gen_vary_stds.append(np.std(val)) - - - - - -# Multiple runs - -gen_1_mult = [0.1762, 0.9575, 0.1200, 0.9660, 0.9650, 0.9570, 0.9745, 0.9700, 0.15, 0.23, 0.16, 0.186, 0.9640, 0.9650] - -gen_2_mult = [0.17, 0.1515, 0.1700, 0.9625, 0.9630, 0.9732, 0.9680, 0.9633, 0.9530, 0.9640] - -gen_3_mult = [0.9750, 0.9720, 0.9655, 0.9530, 0.9623, 0.9730, 0.9748, 0.9625, 0.9716, 0.9672] - -gen_4_mult = [0.9724, 0.9755, 0.9657, 0.9718, 0.9690, 0.9735, 0.9715, 0.9300, 0.9725, 0.9695] - -gen_5_mult = [0.9560, 0.9750, 0.8750, 0.9717, 0.9731, 0.9741, 0.9747, 0.9726, 0.9729, 0.9727] - -gen_6_mult = [0.9730, 0.9740, 0.9715, 0.9755, 0.9761, 0.9700, 0.9755, 0.9750, 0.9726, 0.9748, 0.9705, 0.9745, 0.9752, 0.9740, 0.9744] - - - -gen_mult = [gen_1_mult, gen_2_mult, gen_3_mult, gen_4_mult, gen_5_mult, gen_6_mult] - -gen_mult_means = [] -gen_mult_stds = [] - -for val in gen_mult: - gen_mult_means.append(np.mean(val)) - gen_mult_stds.append(np.std(val)) - -num_gen = [i for i in range(len(gen_mult))] - - -# Baseline -baseline = [0.7990 for i in range(len(gen_mult))] - - - -# plt.errorbar(num_gen, gen_acc_means, yerr=gen_acc_stds, linestyle = 'dotted', label = 'Fixed seed GA') -# plt.errorbar(num_gen, gen_vary_means, linestyle = 'dotted', yerr=gen_vary_stds, label = 'Varying seed GA') -# plt.errorbar(num_gen, gen_mult_means, linestyle = 'dotted', yerr=gen_mult_stds, label = 'Varying seed GA 2') - -plt.plot(num_gen, gen_acc_means, linestyle = 'dotted', label = 'Fixed seed GA') -plt.plot(num_gen, gen_vary_means, linestyle = 'dotted', label = 'Varying seed GA') -plt.plot(num_gen, gen_mult_means, linestyle = 'dotted', label = 'Varying seed GA 2') - -plt.plot(num_gen, baseline, label = 'Fixed seed baseline') - - -plt.xlabel('Generation', fontsize = 16) -plt.ylabel('Validation Accuracy', fontsize = 16) - -plt.legend() - -plt.savefig('GA_results.png') \ No newline at end of file diff --git a/app.py b/app.py index e0f2a3ca..3de6b5b0 100644 --- a/app.py +++ b/app.py @@ -1,9 +1,49 @@ -from flask import Flask +# from flask import Flask +# from auto_augmentation import create_app +# import os + +# app = create_app() +# port = int(os.environ.get("PORT", 5000)) + +# if __name__ == '__main__': +# app.run(host='0.0.0.0',port=port) + + +from flask import Flask, flash, request, redirect, url_for +from werkzeug.utils import secure_filename from auto_augmentation import create_app import os - app = create_app() port = int(os.environ.get("PORT", 5000)) + +UPLOAD_FOLDER = '/datasets' + +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER +ALLOWED_EXTENSIONS = {'pdf', 'py'} + +def allowed_file(filename): + return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + +@app.route('/user_input', methods = ['GET', 'POST']) +def upload_file(): + print("HELLoasdjsadojsadojsaodjsaoij") + if request.method == 'POST': + if 'file' not in request.files: + flash('No file part') + return redirect(request.url) + file = request.files['file'] + if file.filename == '': + flash('No selected file') + return redirect(request.url) + if file and allowed_file(file.filename): + filename = secure_filename(file.filename) + file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) + return redirect(url_for('uploaded_file', filename=filename)) + return ''' + + ''' + + if __name__ == '__main__': - app.run(host='0.0.0.0',port=port) \ No newline at end of file + app.run(debug=True) \ No newline at end of file diff --git a/auto_augmentation/progress.py b/auto_augmentation/progress.py index 03d33fad..77845a02 100644 --- a/auto_augmentation/progress.py +++ b/auto_augmentation/progress.py @@ -1,5 +1,6 @@ from flask import Blueprint, request, render_template, flash, send_file import subprocess +import os import numpy as np import torch @@ -15,7 +16,10 @@ from numpy import save, load from tqdm import trange torch.manual_seed(0) # import agents and its functions -from MetaAugment import UCB1_JC + +from MetaAugment import UCB1_JC_py as UCB1_JC + + bp = Blueprint("progress", __name__) diff --git a/auto_augmentation/templates/home.html b/auto_augmentation/templates/home.html index 7e4fc067..c40f23f8 100644 --- a/auto_augmentation/templates/home.html +++ b/auto_augmentation/templates/home.html @@ -59,77 +59,86 @@ <h3>Advanced Search</h3> <!-- action(data augmentation) space --> Which data augmentation method you would like exclude? <br> - <input type="radio" id="ShearX" + <input type="checkbox" id="ShearX" name="action_space" value="ShearX"> <label for="ShearX">ShearX</label><br> - <input type="radio" id="ShearY" + <input type="checkbox" id="ShearY" name="action_space" value="ShearY"> <label for="ShearY">ShearY</label><br> - <input type="radio" id="TranslateX" + <input type="checkbox" id="TranslateX" name="action_space" value="TranslateX"> <label for="TranslateX">TranslateX</label><br> - <input type="radio" id="TranslateY" + <input type="checkbox" id="TranslateY" name="action_space" value="TranslateY"> <label for="TranslateY">TranslateY</label><br> - <input type="radio" id="Rotate" + <input type="checkbox" id="Rotate" name="Rotate" value="Rotate"> <label for="Rotate">Rotate</label><br> - <input type="radio" id="Brightness" + <input type="checkbox" id="Brightness" name="action_space" value="Brightness"> <label for="Brightness">Brightness</label><br> - <input type="radio" id="Color" + <input type="checkbox" id="Color" name="action_space" value="Color"> <label for="Color">Color</label><br> - <input type="radio" id="Contrast" + <input type="checkbox" id="Contrast" name="action_space" value="Contrast"> <label for="Contrast">Contrast</label><br> - <input type="radio" id="Sharpness" + <input type="checkbox" id="Sharpness" name="action_space" value="Sharpness"> <label for="Sharpness">Sharpness</label><br> - <input type="radio" id="Posterize" + <input type="checkbox" id="Posterize" name="action_space" value="Posterize"> <label for="Posterize">Posterize</label><br> - <input type="radio" id="Solarize" + <input type="checkbox" id="Solarize" name="action_space" value="Solarize"> <label for="Solarize">Solarize</label><br> - <input type="radio" id="AutoContrast" + <input type="checkbox" id="AutoContrast" name="action_space" value="AutoContrast"> <label for="AutoContrast">AutoContrast</label><br> - <input type="radio" id="Equalize" + <input type="checkbox" id="Equalize" name="action_space" value="Equalize"> <label for="Equalize">Equalize</label><br> - <input type="radio" id="Invert" + <input type="checkbox" id="Invert" name="action_space" value="Invert"> <label for="Invert">Invert</label><br><br><br> + <!-- <div id="exclude_augments" class="dropdown-check-list" tabindex="100"> + <span class="anchor">Select data augmentation method(s) to exclude:</span> + <ul class="items"> + <input type="checkbox" />Translate + <input type="checkbox" />Rotate + <input type="checkbox" />AutoContrast + <input type="checkbox" />Equalize + <br> + <input type="checkbox" />Solarize + <input type="checkbox" />Posterize + <input type="checkbox" />Contrast + <input type="checkbox" />Brightness + </ul> + </div> --> + + <div id="exclude_augments"> + <span class="anchor">Hyperparameter (Learning Rate):</span> + <ul class="items"> + Automatic: <input type="checkbox" /> <div></div> + Manual: <input type="number" /> + </ul> + </div> - <!-- action space --> - <!-- <label for="data_aug_method">Which data augmentation method you would like exclude?</label> - <select id="data_aug_method" name="data_aug_method"> - <option value="Translate">Translate</option> - <option value="Rotate">Rotate</option> - <option value="AutoContrast">AutoContrast</option> - <option value="Equalize">Equalize</option> - <option value="Solarize">Solarize</option> - <option value="Posterize">Posterize</option> - <option value="Contrast">Contrast</option> - <option value="Brightness">Brightness</option> - - </select><br><br> --> <input type="submit"> -- GitLab