From cd1ebac32c3b8c1457ec57bf6b4d375015d68642 Mon Sep 17 00:00:00 2001 From: Christian Chapman-Bird Date: Mon, 20 Sep 2021 15:17:56 +0100 Subject: [PATCH] Main commit --- .gitignore | 1 + EMRI_DET/nn/model_creation.py | 53 +++ EMRI_DET/nn/model_train_test.py | 108 +++++ EMRI_DET/utilities.py | 46 ++ .../notebooks/Check_interpolators_nd.ipynb | 435 ++++++++++++++++++ .../notebooks/nd_interps_plot_dists.ipynb | 179 +++++++ .../scripts/data_generation.py | 175 +++++++ .../scripts/model_nodataloader_sepdata.py | 144 ++++++ 8 files changed, 1141 insertions(+) create mode 100644 .gitignore create mode 100644 EMRI_DET/nn/model_creation.py create mode 100644 EMRI_DET/nn/model_train_test.py create mode 100644 EMRI_DET/utilities.py create mode 100644 Projects - Mock Data/SNR Mock data function/notebooks/Check_interpolators_nd.ipynb create mode 100644 Projects - Mock Data/SNR Mock data function/notebooks/nd_interps_plot_dists.ipynb create mode 100644 Projects - Mock Data/SNR Mock data function/scripts/data_generation.py create mode 100644 Projects - Mock Data/SNR Mock data function/scripts/model_nodataloader_sepdata.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6fb395e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/_* diff --git a/EMRI_DET/nn/model_creation.py b/EMRI_DET/nn/model_creation.py new file mode 100644 index 0000000..95814fe --- /dev/null +++ b/EMRI_DET/nn/model_creation.py @@ -0,0 +1,53 @@ +import torch +import torch.nn as nn +from torch.nn.init import xavier_uniform_ +from MLtools.utilities import get_script_path + + +class LinearModel(nn.Module): + def __init__(self, in_features, out_features, neurons, n_layers, activation, name): + super().__init__() + + layers = [nn.Linear(in_features, neurons[0]), activation()] + for i in range(n_layers - 1): + layers.append(nn.Linear(neurons[i], neurons[i + 1])) + layers.append(activation()) + layers.append(nn.Linear(neurons[-1], out_features)) + + self.layers = nn.Sequential(*layers) + self.layers.apply(self.init_weights) + + self.name = name + + def forward(self, x): + return self.layers(x) + + def init_weights(self, m): + if isinstance(m, nn.Linear): + xavier_uniform_(m.weight) + + +def create_mlp(input_features, output_features, neurons, layers, activation, model_name, device=None): + if layers < 2: + raise RuntimeError('You need at least two layers for an MLP.') + if isinstance(neurons, list): + if len(neurons) != layers: + raise RuntimeError('Length of neuron vector does not equal number of hidden layers.') + else: + neurons = [neurons, ] + model = LinearModel(input_features, output_features, neurons, layers, activation, model_name) + input = [input_features, output_features, neurons, layers] + + with open(get_script_path()+'/'+model_name+'_hypers.txt', "w") as f: + f.write('\t'.join(input)) + if device is not None: + model = model.to(device) + return model + + +def load_mlp(model_name, activation): + with open(get_script_path()+'/'+model_name+'_hypers.txt',"r") as f: + pms = f.readline().split('\t') + + model = LinearModel(*pms, activation) + return model diff --git a/EMRI_DET/nn/model_train_test.py b/EMRI_DET/nn/model_train_test.py new file mode 100644 index 0000000..471798f --- /dev/null +++ b/EMRI_DET/nn/model_train_test.py @@ -0,0 +1,108 @@ +import torch +from torch import nn +from torch.nn.init import xavier_uniform +import numpy as np +import matplotlib.pyplot as plt +from EMRI_DET.MLtools.utilities import norm, norm_inputs, unnorm_inputs, unnorm, get_script_path +from EMRI_DET.MLtools.nn.model_creation import create_mlp +from sys import stdout + + +def model_train_test(data, model, device, n_epochs, n_batches, loss_function, learning_rate, verbose=False): + xtrain, ytrain, xtest, ytest = data + + name = model.name + path = get_script_path() + + np.save(path+'/'+name+'_xdata_mean_std.npy',np.array([xtrain.mean(axis=0), xtrain.std(axis=0)])) + np.save(path+'/'+name+'_ydata_mean_std.npy',np.array([ytrain.mean(), ytrain.std()])) + + xtest = torch.from_numpy(norm_inputs(xtest, xtrain)).to(device).float() + ytest = torch.from_numpy(norm(ytest, ytrain)).to(device).float() + xtrain = torch.from_numpy(norm_inputs(xtrain, xtrain)).to(device).float() + ytrain = torch.from_numpy(norm(ytrain, ytrain)).to(device).float() + + ytrainsize = len(ytrain) + ytestsize = len(ytest) + + optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate) + scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.97) # to settle into the loss 'valley' + train_losses = [] + test_losses = [] + rate = [] + # Run the training loop + + datasets = {"train": [xtrain, ytrain], "test": [xtest, ytest]} + + cutoff_LR = n_epochs - 50 + for epoch in range(n_epochs): # 5 epochs at maximum + # Print epoch + for phase in ['train','test']: + if phase == 'train': + model.train(True) + shuffled_inds = torch.randperm(ytrainsize) + + # Set current loss value + current_loss = 0.0 + + # Iterate over the DataLoader for training data + # Get and prepare inputs + inputs, targets = datasets[phase] + inputs = inputs[shuffled_inds] + targets = targets[shuffled_inds] + + targets = targets.reshape((targets.shape[0], 1)) + + for i in range(n_batches): + for param in model.parameters(): + param.grad = None + outputs = model(inputs[i * ytrainsize // n_batches:(i+1)*ytrainsize // n_batches]) + loss = torch.sqrt(loss_function(outputs, targets[i * ytrainsize // n_batches: (i+1)*ytrainsize // n_batches])) + loss.backward() + optimizer.step() + current_loss += loss.item() + + train_losses.append(current_loss / n_batches) + + else: + with torch.no_grad(): + model.train(False) + shuffled_inds = torch.randperm(ytestsize) + current_loss = 0.0 + inputs, targets = datasets[phase] + inputs = inputs[shuffled_inds] + targets = targets[shuffled_inds] + + targets = targets.reshape((targets.shape[0], 1)) + + for i in range(n_batches): + outputs = model(inputs[i * ytestsize // n_batches: (i+1)*ytestsize // n_batches]) + loss = torch.sqrt(loss_function(outputs, targets[i * ytestsize // n_batches: (i+1)*ytestsize // n_batches])) + current_loss += loss.item() + + test_losses.append(current_loss / n_batches) + + if epoch >= cutoff_LR: + scheduler.step() + rate.append(scheduler.get_last_lr()[0]) + else: + rate.append(learning_rate) + if verbose: + stdout.write(f'\rTrain loss:{train_losses[-1]} | Test loss:{test_losses[-1]} | ') + + if verbose: + print('\nTraining complete - saving.') + torch.save(model.state_dict(),path+'/'+name+'_model.pth') + + epochs = np.arange(n_epochs) + plt.semilogy(epochs, train_losses, label='Train') + plt.semilogy(epochs, test_losses, label='Test') + plt.legend() + plt.xlabel('Epochs') + plt.ylabel('Loss') + plt.title('Train and Test Loss Across Train Epochs') + plt.savefig(path+'/'+name+'_losses.png') + #plt.show() + plt.close() + + diff --git a/EMRI_DET/utilities.py b/EMRI_DET/utilities.py new file mode 100644 index 0000000..dc2e9da --- /dev/null +++ b/EMRI_DET/utilities.py @@ -0,0 +1,46 @@ +import os +import sys + + +def get_script_path(): + return os.path.dirname(os.path.realpath(sys.argv[0])) + + +def norm(dataframe, ref_dataframe=None, ref_mean=None, ref_std=None): + if ref_dataframe is not None: + df_norm = (dataframe - ref_dataframe.mean())/ref_dataframe.std() + elif ref_mean is not None and ref_std is not None: + df_norm = (dataframe - ref_mean)/ref_std + else: + raise RuntimeError("Either a reference dataset or a reference mean + std must be supplied.") + return df_norm + + +def norm_inputs(dataframe, ref_dataframe=None, ref_mean=None, ref_std=None): + if ref_dataframe is not None: + df_norm = (dataframe - ref_dataframe.mean(axis=0)) / ref_dataframe.std(axis=0) + elif ref_mean is not None and ref_std is not None: + df_norm = (dataframe - ref_mean) / ref_std + else: + raise RuntimeError("Either a reference dataset or a reference mean + std must be supplied.") + return df_norm + + +def unnorm(dataframe_norm, ref_dataframe=None, ref_mean=None, ref_std=None): + if ref_dataframe is not None: + dataframe = (dataframe_norm * ref_dataframe.std()) + ref_dataframe.mean() + elif ref_mean is not None and ref_std is not None: + dataframe = (dataframe_norm * ref_std) + ref_mean + else: + raise RuntimeError("Either a reference dataset or a reference mean + std must be supplied.") + return dataframe + + +def unnorm_inputs(dataframe_norm, ref_dataframe,ref_mean=None, ref_std=None): + if ref_dataframe is not None: + dataframe = (dataframe_norm * ref_dataframe.std(axis=0)) + ref_dataframe.mean(axis=0) + elif ref_mean is not None and ref_std is not None: + dataframe = (dataframe_norm * ref_std) + ref_mean + else: + raise RuntimeError("Either a reference dataset or a reference mean + std must be supplied.") + return dataframe diff --git a/Projects - Mock Data/SNR Mock data function/notebooks/Check_interpolators_nd.ipynb b/Projects - Mock Data/SNR Mock data function/notebooks/Check_interpolators_nd.ipynb new file mode 100644 index 0000000..589cde3 --- /dev/null +++ b/Projects - Mock Data/SNR Mock data function/notebooks/Check_interpolators_nd.ipynb @@ -0,0 +1,435 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "e186ab86", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import torch\n", + "import torch.nn as nn\n", + "from torch.nn.init import xavier_uniform_\n", + "import matplotlib.pyplot as plt\n", + "from scipy.interpolate import RegularGridInterpolator\n", + "from cupyx.scipy.ndimage import map_coordinates\n", + "import cupy as cp\n", + "import numpy as np\n", + "from data_generation import func_out" + ] + }, + { + "cell_type": "markdown", + "id": "0afef590", + "metadata": {}, + "source": [ + "# Interpolators vs. NNs: where do they meet up?\n", + "\n", + "Currently we have observed that for a dataset of $M=10^6$ points, a neural network operating with uniform samples in the prior range outperforms classic interpolation schemes operating over an $n$-dimensional grid (where $n=9$ is the number of parameters/dimensionaliy of the prior space). We expect that if we decrease $n$ and keep $M$ constant, eventually this will flip around and the interpolators will outperform the network, even if the network is retrained on this new, lower-dimension space." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "976dcc72", + "metadata": {}, + "outputs": [], + "source": [ + "def cartesian_product_recursive(arrays, out=None):\n", + " arrays = [np.asarray(x) for x in arrays]\n", + " dtype = arrays[0].dtype\n", + "\n", + " n = np.prod([x.size for x in arrays])\n", + " if out is None:\n", + " out = np.zeros([n, len(arrays)], dtype=dtype)\n", + "\n", + " m = n // arrays[0].size\n", + " out[:, 0] = np.repeat(arrays[0], m)\n", + " if arrays[1:]:\n", + " cartesian_product_recursive(arrays[1:], out=out[0:m, 1:])\n", + " for j in range(1, arrays[0].size):\n", + " out[j * m : (j + 1) * m, 1:] = out[0:m, 1:]\n", + " return out\n", + "\n", + "\n", + "\n", + "def get_data(M, n, sample_ranges):\n", + " # For a given M and n, we set a grid size to keep the number of samples ~constant.\n", + " # We output these as 'grid' set and a 'sample' set.\n", + " # Unused dimensions are taken to be constant-valued, with a value between the min and max.\n", + " \n", + " N = np.round(np.exp(np.log(M)/n)).astype(np.int64) # dimension of the grid\n", + " \n", + " ranges_kept = sample_ranges[:n,:]\n", + " fill_samps = np.mean(sample_ranges[n:,:],axis=1).tolist() # list for input\n", + " \n", + " iterators = [np.linspace(nums[0],nums[1],N) for nums in ranges_kept]\n", + "\n", + " combinations = cartesian_product_recursive(iterators)\n", + " \n", + " xgrid = np.array(combinations)\n", + " ygrid = np.zeros(xgrid.shape[0])\n", + " \n", + " for i, combo in enumerate(combinations):\n", + " ygrid[i] = func_out(*combo.tolist(),*fill_samps)\n", + " \n", + " xsamp = np.zeros((M,n))\n", + " \n", + " for i in range(n):\n", + " xsamp[:,i] = np.random.uniform(ranges_kept[i,0], ranges_kept[i,1], M)\n", + " \n", + " ysamp = np.zeros(M)\n", + " \n", + " for i,row in enumerate(xsamp):\n", + " ysamp[i] = func_out(*row.tolist(), *fill_samps)\n", + " \n", + " \n", + " xtest = np.zeros((M,n))\n", + " \n", + " for i in range(n):\n", + " xtest[:,i] = np.random.uniform(ranges_kept[i,0], ranges_kept[i,1], M)\n", + " \n", + " ytest = np.zeros(M)\n", + " \n", + " for i,row in enumerate(xtest):\n", + " ytest[i] = func_out(*row.tolist(), *fill_samps)\n", + " \n", + " return xgrid, ygrid, xsamp, ysamp, xtest, ytest, N" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "9583b6ea", + "metadata": {}, + "outputs": [], + "source": [ + "#Our prior space (params are M,q,a,e,Y,thetaS,phiS,thetaK,t)\n", + "sample_ranges=np.array([\n", + " [np.log10(8e4),np.log10(5e7)],\n", + " [np.log10(5e4),np.log10(5e7)],\n", + " [0.01,0.99],\n", + " [0.01,0.5],\n", + " [0.5,0.99],\n", + " [0,np.pi],\n", + " [0,2*np.pi],\n", + " [0,np.pi],\n", + " [0.5,4],\n", + "])\n", + "\n", + "#xg, yg, xs, ys = get_data(int(1e6),9, sample_ranges)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "15de4530", + "metadata": {}, + "outputs": [], + "source": [ + "# now we define our network model. \n", + "\n", + "class MLP(nn.Module):\n", + " def __init__(self, n_inputs):\n", + " super().__init__()\n", + " self.layers = nn.Sequential(\n", + " nn.Linear(n_inputs, 128),\n", + " nn.Tanh(),\n", + " nn.Linear(128, 64),\n", + " nn.Tanh(),\n", + " nn.Linear(64, 32),\n", + " nn.Tanh(),\n", + " nn.Linear(32, 16),\n", + " nn.Tanh(),\n", + " nn.Linear(16, 1),\n", + " )\n", + " self.layers.apply(self.init_weights)\n", + "\n", + " def forward(self, x):\n", + " return self.layers(x)\n", + "\n", + " def init_weights(self, m):\n", + " if isinstance(m, nn.Linear):\n", + " xavier_uniform_(m.weight)\n", + " \n", + "def norm(dataframe, ref_dataframe):\n", + " \"\"\"Normalise input dataframe using Z-score. First input is the dataframe to be normalised. Second input is\n", + " the referene dataframe to which everything is normalised which we need for the mean, std,\n", + " ie. df['distance_x_SNR']\"\"\"\n", + " df_norm = (dataframe - ref_dataframe.mean())/ref_dataframe.std()\n", + " return df_norm\n", + "\n", + "\n", + "def norm_inputs(dataframe, ref_dataframe):\n", + " df_norm = (dataframe - ref_dataframe.mean(axis=0))/ref_dataframe.std(axis=0)\n", + " return df_norm\n", + "\n", + "def unnorm(dataframe_norm, ref_dataframe):\n", + " \"\"\"Undo the Z-score normalisation.\n", + " Input the data which may be one column (our label output from the model, which is normalised),\n", + " Second input is the corresponding origninal data, which we need for the mean, std, ie. df['distance_x_SNR']\"\"\"\n", + " dataframe = (dataframe_norm * ref_dataframe.std()) + ref_dataframe.mean()\n", + " return dataframe\n", + "\n", + "def unnorm_inputs(dataframe_norm, ref_dataframe):\n", + " df_norm = (dataframe_norm * ref_dataframe.std(axis=0)) + ref_dataframe.mean(axis=0)\n", + " return df_norm" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d166b8d9", + "metadata": {}, + "outputs": [], + "source": [ + "# we define our network train and test functions\n", + "\n", + "def prepare_model(mlp,xtrain,ytrain,xtest,ytest):\n", + " # model training. note that xtrain,ytrain correspond to the SAMPLES, while xtest,ytest are the GRID\n", + " device = \"cuda:0\"\n", + " \n", + " this_size = xtest.shape[1]\n", + " \n", + " xtest = torch.from_numpy(norm_inputs(xtest, xtrain)).to(device).float()\n", + " ytest = torch.from_numpy(norm(ytest, ytrain)).to(device).float()\n", + "\n", + " xtrain = torch.from_numpy(norm_inputs(xtrain, xtrain)).to(device).float()\n", + " ytrain = torch.from_numpy(norm(ytrain, ytrain)).to(device).float()\n", + "\n", + " ytrainsize = len(ytrain)\n", + " ytestsize = len(ytest)\n", + "\n", + " loss_function = nn.MSELoss()\n", + "\n", + " LR = 1e-3\n", + "\n", + " optimizer = torch.optim.Adam(mlp.parameters(), lr=LR)\n", + " scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.97)\n", + " train_losses = []\n", + " test_losses = []\n", + " rate = []\n", + " # Run the training loop\n", + "\n", + " datasets = {\"train\": [xtrain, ytrain], \"test\": [xtest, ytest]}\n", + "\n", + " num_epochs = 5000\n", + " nbatch_train = 50\n", + " nbatch_test = 1\n", + " cutoff_LR = 4900\n", + " for epoch in range(num_epochs):\n", + " print(f'Starting epoch {epoch + 1}')\n", + "\n", + " for phase in ['train','test']:\n", + " if phase == 'train':\n", + " mlp.train(True)\n", + " shuffled_inds = torch.randperm(ytrainsize)\n", + "\n", + " # Set current loss value\n", + " current_loss = 0.0\n", + "\n", + " # Iterate over the DataLoader for training data\n", + " # Get and prepare inputs\n", + " inputs, targets = datasets[phase]\n", + " inputs = inputs[shuffled_inds]\n", + " targets = targets[shuffled_inds]\n", + "\n", + " targets = targets.reshape((targets.shape[0], 1))\n", + "\n", + " for i in range(nbatch_train):\n", + " for param in mlp.parameters():\n", + " param.grad = None\n", + " outputs = mlp(inputs[i * ytrainsize // nbatch_train: (i+1)*ytrainsize // nbatch_train])\n", + " loss = torch.sqrt(loss_function(outputs, targets[i * ytrainsize // nbatch_train: (i+1)*ytrainsize // nbatch_train]))\n", + " loss.backward()\n", + " optimizer.step()\n", + " current_loss += loss.item()\n", + "\n", + " train_losses.append(current_loss / nbatch_train)\n", + "\n", + " else:\n", + " with torch.no_grad():\n", + " mlp.train(False)\n", + " shuffled_inds = torch.randperm(ytestsize)\n", + " current_loss = 0.0\n", + " inputs, targets = datasets[phase]\n", + " inputs = inputs[shuffled_inds]\n", + " targets = targets[shuffled_inds]\n", + "\n", + " targets = targets.reshape((targets.shape[0], 1))\n", + "\n", + " for i in range(nbatch_test):\n", + " outputs = mlp(inputs[i * ytestsize // nbatch_test: (i+1)*ytestsize // nbatch_test])\n", + " loss = torch.sqrt(loss_function(outputs, targets[i * ytestsize // nbatch_test: (i+1)*ytestsize // nbatch_test]))\n", + " current_loss += loss.item()\n", + "\n", + " test_losses.append(current_loss / nbatch_test)\n", + "\n", + " if epoch >= cutoff_LR:\n", + " scheduler.step()\n", + " rate.append(scheduler.get_last_lr()[0])\n", + " else:\n", + " rate.append(LR)\n", + " print(f'Train loss: {train_losses[-1]}, Test loss: {test_losses[-1]}')\n", + "\n", + " torch.save(mlp.state_dict(),f'./downscale_data/{this_size}_model.pth')\n", + " \n", + " return mlp" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "f2206ce9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Grid dimension: 9\n", + "Linear + NN done\n", + "map_coords done\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "OMP: Warning #96: Cannot form a team with 44 threads, using 42 instead.\n", + "OMP: Hint Consider unsetting KMP_DEVICE_THREAD_LIMIT (KMP_ALL_THREADS), KMP_TEAMS_THREAD_LIMIT, and OMP_THREAD_LIMIT (if any are set).\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Grid dimension: 8\n", + "Linear + NN done\n", + "map_coords done\n", + "Grid dimension: 7\n", + "Linear + NN done\n", + "map_coords done\n", + "Grid dimension: 6\n", + "Linear + NN done\n", + "map_coords done\n", + "Grid dimension: 5\n", + "Linear + NN done\n", + "map_coords done\n", + "Grid dimension: 4\n", + "Linear + NN done\n", + "map_coords done\n", + "Grid dimension: 3\n", + "Linear + NN done\n", + "map_coords done\n", + "Grid dimension: 2\n", + "Linear + NN done\n", + "map_coords done\n" + ] + } + ], + "source": [ + "#for n in np.arange(9,1,-1):\n", + "for n in np.arange(9,1,-1):\n", + " print('Grid dimension: ',n)\n", + " xgrid, ygrid, xsamp, ysamp, xtest, ytest, N = get_data(int(1e6), n, sample_ranges)\n", + "\n", + " np.save(f'./downscale_data/{n}_xtest.npy',arr=xtest)\n", + " np.save(f'./downscale_data/{n}_ytest.npy',arr=ytest)\n", + " \n", + " xdata_in = ()\n", + " for i in range(xgrid.shape[1]):\n", + " xdata_in += (np.unique(xgrid[:,i]),)\n", + " yresh = (N,)\n", + " for i in range(n-1):\n", + " yresh += (N,)\n", + " y_in = ygrid.reshape(yresh)\n", + "\n", + " interp = RegularGridInterpolator(xdata_in, y_in, method='linear',bounds_error=False)\n", + " nn_interp = RegularGridInterpolator(xdata_in, y_in, method='nearest',bounds_error=False)\n", + " \n", + " new_values = interp(xtest)\n", + " new_values2 = nn_interp(xtest)\n", + " \n", + " print('Linear + NN done')\n", + " \n", + " np.save(f'./downscale_data/{n}_linear_out.npy',arr=new_values)\n", + " np.save(f'./downscale_data/{n}_nearest_out.npy',arr=new_values2)\n", + " \n", + " xtest_in = []\n", + "\n", + " norms = [listy[1] - listy[0] for listy in sample_ranges]\n", + "\n", + " for i in range(ytest.size):\n", + " sub = []\n", + " for j in range(n):\n", + " sub.append((N-1)*(xtest[i, j] - sample_ranges[j][0])/norms[j])\n", + " xtest_in.append(sub)\n", + "\n", + " xtest_in = np.asarray(xtest_in).T\n", + "\n", + " map_values = map_coordinates(cp.array(y_in), cp.array(xtest_in), prefilter=True).get()\n", + " print('map_coords done')\n", + " np.save(f'./downscale_data/{n}_map_out.npy',arr=map_values)\n", + " \n", + " device = 'cuda:0'\n", + " \n", + " mlp = MLP(n).to(device)\n", + " \n", + " #mlp = prepare_model(mlp,xsamp,np.log(ysamp),xgrid,np.log(ygrid)) # train\n", + " mlp.load_state_dict(torch.load(f'./downscale_data/{n}_model.pth'))\n", + " mlp.eval()\n", + " \n", + " xsamp = np.load(f'./downscale_data/{n}_xsamp.npy')\n", + " ysamp = np.log(np.load(f'./downscale_data/{n}_ysamp.npy'))\n", + " \n", + " test_input = torch.Tensor(xtest)\n", + " normed_input = norm_inputs(test_input, xsamp).float().to(device)\n", + "\n", + " with torch.no_grad():\n", + " out = []\n", + " for i in range(20):\n", + " output = mlp(normed_input[i * ytest.size // 20 : (i+1)*ytest.size // 20])\n", + " out.append(output.detach().cpu().numpy())\n", + "\n", + " output = np.concatenate(out)\n", + "\n", + " out_unnorm = np.exp(unnorm(output, ysamp))\n", + " out_truth = out_unnorm.flatten()\n", + " \n", + " np.save(f'./downscale_data/{n}_network_out.npy',arr=out_truth)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f4481771", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Projects - Mock Data/SNR Mock data function/notebooks/nd_interps_plot_dists.ipynb b/Projects - Mock Data/SNR Mock data function/notebooks/nd_interps_plot_dists.ipynb new file mode 100644 index 0000000..0134c47 --- /dev/null +++ b/Projects - Mock Data/SNR Mock data function/notebooks/nd_interps_plot_dists.ipynb @@ -0,0 +1,179 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "dd1f6d19", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "8aced990", + "metadata": {}, + "outputs": [], + "source": [ + "data_dir = './downscale_data/{}'\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "abc2e918", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAABJEAAAKGCAYAAAD6TQqrAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOzdeVxVdf7H8dcFFFQQxBVFAb2mSJopSjaVW1ZUoy2mtiiOGo3WWFbz03KmdGZSa9JscSwaprSNGW2SaSrMSNvMCJMatQxNDJBcUEEUkeX7+4M4gVwW2S7L+/l4+FDOOd9zPudy7tdzPue72IwxBhERERERERERkUq4ODsAERERERERERFp/JREEhERERERERGRKimJJCIiIiIiIiIiVVISSUREREREREREqqQkkoiIiIiIiIiIVElJJBERERERERERqZKSSCIi0uy8/PLL2Gw2Ro0a5exQpBnRddWwFi1ahM1mY/r06c4OpVF58cUXsdlsPProo84OpUI2mw2bzUZKSkqd7XPcuHG4urryv//9r872KSIi509JJBERJ5o+fbp1sx0aGooxpsJt77jjjnp5oFq0aBGLFi3ixIkTdbpfcZ6S66qukx1btmxh0aJFbNiwoU7329LpO9h0HD16lHXr1jF//nzGjBmDt7e3VYefOXOmWvvIzs7mD3/4A8HBwbRt25aOHTsyduxY1q9fX2XZ3NxcFi9ejJeXF/fee29tT+e8ObMO+MMf/kBRUREPPfRQgx9bRER+oSSSiEgjsX37dt56660GP+7ixYtZvHixHmClSlu2bGHx4sVKItUxfQebjldffZVJkybxxBNPsHnzZrKzs8+rfFpaGoMHD+axxx7ju+++w9XVlezsbD788ENuueUWZs+eXWn5Z555hvT0dObMmYOvr29tTqVGqlsH9OvXj379+tGqVas6O/bIkSO5/PLLeeedd/j000/rbL8iInJ+lEQSEWlEHnnkEYqKipwdhoiIOGCz2fD39+fGG2/kscceY8mSJdUua4xh4sSJ7N+/n8DAQD777DNOnjzJyZMneeKJJ3BxceH555/nxRdfdFi+sLCQZ555BoA777yzTs6nvnz33Xd899139OjRo073O3PmTACeeuqpOt2viIhUn5JIIiKNwMiRI2nbti27du3i9ddfd3Y4IiLiwD333ENqair//ve/efjhhxkx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MKdPnzbGGLN3714zbtw4A5g2bdqUSYYZY0xeXp513fbs2dO8//77pqioyBQVFZkPPvjA9OrVy0oEnvsdrCyJtGLFCrNgwQLz1VdfWedbUFBgEhMTzdVXX23ts6ioqFzZqr6Dxhjz2WefWQmdiRMnWtf6yZMnzWOPPWZsNpsBzJ///OdyZUuSSJ6enmbgwIHms88+s9YlJycbY4xZvHixlez673//a/Lz840xxXXI999/b5YtW+YwuV2fKrvealqHnDlzxlxwwQUGMH379jWffvqpMaY4SfPuu++abt26GR8fnzpPIh06dMjaLi4ursLtJk2aZABz3XXXlVmelJRkJUdLvwxwFEtV9eOpU6fMtddea9544w2Tnp5uCgsLjTHGHD9+3Dz77LPG09PTAOZf//pXuWNUtw6o6Jreu3evlYgaOXKk+e6774wxxb+XF154wbi7uxvAzJw5s8J9f/jhh1aitiR2ERFpOEoiiYg40blJpKysLOsN+cqVK8tsW1ESqaCgwHpI/Pe//+3wOD/88INp166dcXNzMwcPHiyzrjoPsCUP1qUffjIzM43NZjPBwcHmhhtuMIBJTEy01icnJxvAtG7d2nrAN8aYlJQU62H4+eefL3esU6dOmT59+hjATJ06tcy60g9st956a4XxOnrYf/DBB61E26ZNmyosW5FvvvnGSgalpaWVW19yvoD54YcfrOWPP/54g781r04SqU2bNlYCobT169dbD+d5eXll1lXnAfL77783Li4uxsfHx+zbt8/hNv/85z+tpEppJb83wDz00EMVHqMkDsD85S9/Kbc+NzfXSpye+zC6du1aKyn6v//9r1zZnTt3Wq0ioqOjHcZXneRCaWfOnLFa+WzZsqXc+up8B8eMGWMA86tf/cpha6OHHnrIShRlZWWVWVdSP/j4+FhJhXOFh4cbwCxbtuy8zq0+VXS91aYO+cc//mElWhxdn9u2bbMScnWZRCpJAgHmm2++qXC7kgTskCFDyiyPiooygOnXr1+1YqmsfqxKyXfEUcK8tkmkGTNmGChu8eUoGfbCCy9YLagc1U/GFP/fU7L/nTt3Vvu8RESkbmhMJBGRRqR9+/bW2ENLlizh1KlTVZbZsmULBw4cIDAwkBtvvNHhNkFBQVxyySUUFBSwZcuW847riiuuAOCjjz6yln3yyScYYxg1apTD9SX/HjZsGG3atLGW//vf/6aoqIhu3boxa9ascsdq27at9Rn8+9//rnB8jN///vfVir2oqIjIyEiefPJJfHx82LRpE1deeWW1ypY2cOBALrzwQoqKivjnP/9Zbv0bb7wBwIgRIwgKCrKWt2/fHoDDhw83qpn3Jk6ciN1uL7d8/Pjx2Gw28vLyqhxXxpG1a9dSVFTEDTfcQO/evR1uc9NNN+Hu7s6uXbvIyMgot97V1ZX777+/ymO1bduW++67r9xyDw8PHnjgAQDefPNNjDHWupLxXm644QYuvPDCcmVDQkKYOHEiAP/617+qjKE63N3dGTduHACfffbZeZc/duwYmzdvBuChhx5yOC7P/Pnz8fDwICcnh3fffdfhfqZNm0bXrl0driu5Th39Phqb2tQh//73v4Hi69/R9RkWFuZwLKTaKl2Xl64Pz9W2bVsAcnJyyiwv+b106tSpWserbv3oyK9//WsAtm3bVun4ROfLGGON3TVv3jzrXEubNWsWPXr0wBjjcGwmgA4dOljfgaZwvYqINDdKIomINDK/+93v6Nq1K4cPH7amc67M1q1bATh48CDdunWr8E/Jw2tqaup5xzRy5EjAcZJo5MiRVa4v7auvvgLg8ssvr3CQ2jFjxgDFD1579uwpt75NmzZcdNFFVcadn5/PrbfeyosvvkiXLl3YsmXLec2mdK5bb70VwOEMeiVJpNtuu63M8iuvvJLWrVvz1VdfMWrUKF599VWHgyw3tGHDhjlc3qpVK7p06QLA8ePHz3u/Jdfj+vXrK7wW/f39rYHeHV2Pdru9Wg/LoaGhtGvXzuG6kuvuxIkT7N+/31pecv2NHj26wv2WXH8l21bXd999xz333MOgQYNo3749Li4u1gDDTz/9NECNfvc7duzAGIPNZiv3fSrh7e3N0KFDK427smv/2muvBeCZZ55h6tSpvPfee5w8efK8Y20ItalDduzYAcBll11W4f4vv/zyugrVUjqRWXow9eo6evQoUJxAqUp16seCggKio6O55ppr8PPzw93d3bpWS45x5syZGtUBFfnhhx+sQesr+v65uLhYSbyKrmObzYa3tzfwy+ciIiINR0kkEZFGpm3btjz88MMA/PWvf61ypqiSN7Fnz57l0KFDFf45c+YMAKdPnz7vmEpaGn355ZdW+dJJosGDB+Pt7c0nn3xitbapKIl05MgRAHr06FHh8fz9/cttX1rHjh1xcan6v7CtW7darUnWr19frcRTZUoSRNu3by8zg1lSUhLffvstrq6u5WZOstvtrF69mjZt2vDJJ58wdepUevToQVBQELNnz7Yeahual5dXhes8PDwAys3oVx0l12NOTk6l12PJdeLoeuzcuXO1jlXZNVR6Xelr6Hyuv8zMzDIP/5WJiYlh0KBBrFq1iv/973+cOnUKb29vunbtSteuXa1kV3VaF56rJGZvb288PT2rjNvRdwYq/1ynTZtGZGQkxhheffVVrr32Wnx8fLj44ot55JFHzrvFx7BhwxwmEJ988snz2o8jtalDSpIOfn5+FZbt3r17bUMsp/TvrbI6uGTdub/nvLw8AFq3bl3lsaqqH3Nychg5ciSzZs1i48aN/PTTT7i6utK5c2frei1Rk+u1IqV/D9X53VV0HcMvdVRubm4dRSciItWlJJKISCN011130bNnT44fP87y5csr3bbkYfzGG2/EFI91V+mfRYsWnXc8F1xwAX5+fuTn5/P555+TlZVFUlIS/fr1o1u3bri4uHDZZZdx/Phx/ve//5GSksKPP/6Im5sbl156qcN9ljwUOVLVm/rqTrM9cOBABgwYAMDs2bNr/dY6MDDQas1RujVSSSukK6+80mrFU9qMGTPYv38/K1euZMKECXTs2JGUlBSef/55hg4dypIlS2oVV2NScj0+/fTT1boe63oa9RJVJX8qu/7O15EjR7jzzjvJz89n8uTJJCYmWq04fvrpJ3766SfmzZtXrbgqU9uYq/pcX3jhBXbu3MkjjzzCqFGjcHd3JykpiT//+c/07duXTZs2VftYR44ccZg8PLebVm3Upg5paKUTU5W1RitZd26Sy9fXFyhuWVeVqn7Pf/7zn9m6dSudOnVizZo1HDp0iNOnT3P48GF++ukn0tPTrW1rc71WprbXckkLqY4dO9ZFOCIich6URBIRaYTc3d354x//CMDKlSsrTX6UvDXevXt3vcZUetyjTz/9lKKiojIJgNJd2kpaIQ0ZMqTcG/WS1hAHDhyo8FiluzhVt1WKI76+vsTHx9OvXz927drFuHHjat09o6Q1UkniyBhDTExMmXWOdO3alXvvvZcNGzZw5MgREhISrMTfH//4R7755ptaxdVYNNT1CJU/jJduOVP6GqrO9ZeWlgYUP6BWJxnx3nvvkZOTw4ABA3j99dcZOnQorVq1KrPNoUOHqtxPRUpizs3NrbR1RknctfnOhISEsHjxYjZv3syJEyd4++23GThwIKdOnSIiIqLardNSUlLqLIl9rtrUISXdJCtrWVUf4+x07tzZOvauXbsq3K7ke1OS/C5RUrYuupetW7cOgGeffZZp06aVS3zX5lqtTOnfQ3W+fxVdx3l5eVYLpOqOESUiInVHSSQRkUbqN7/5DX369OHkyZMsW7aswu1KWsbs2bOn0oeTipQ8JFf1xrl0EslRV7Wq1pcYMmQIAF988UWF3To+/PBDANq1a0e/fv2qfS6OdOvWjQ8//JA+ffqQlJTEVVddVWUXwcpMnjwZNzc39uzZw1dffcXWrVv58ccfadOmTYUDm5/LZrMxbNgw1q1bh7+/P0VFRXz66ac1jqmhlHSRqexaKbke33777Rp1hzsfpbtXnqvkGvTx8Skz0HnJ9VcyULUjJddfybZVKXnoHTRokMNuRMYYa5+OVPUdvPjii61tKoo7KyuL7du3n1fcVWndujXXX3+9lXTIyMgo043TWWpTh1x88cUAlX7fPvnkk7oKtYyScYAqatGVnp5u1eFjx44ts67kHFJSUmodR8n1WvJZnOuDDz6osGx16oCK9O7dGx8fH6Di67ioqMia/KGi67jkM7DZbLX+/0FERM6fkkgiIo2Um5ub9db+b3/7W4WtLsaOHUuvXr2A4hlvKptNx9Fb7JJZmarqJlGSEPriiy/YuHFjmWUAQ4cOxdPTk48//th6CHCURLrppptwcXEhMzOTqKiocutPnz7NX//6V2vbuuja1L17dz788EMCAwNJTEwkPDy8xt1qOnfubD3gvfHGG1a3tuuvv97hOENnz56tcF+urq5Wi5W67F5VX6pzrURERODi4sLBgwdZunRppfurbauK06dPWwNWl5aXl8eKFSuA4lm4SrcmKpl57b333nM4HtWuXbusWaHOHd+qIiWD/O7cudPhw/WLL77Ivn37Kixf1efq6+trJSAef/xxh7P8Pf7445w5cwZPT09rkOzzUdl1Wno2scZwndamDilJ9L755psOEzJffvllpQnG2ihpqfj+++/z9ddfl1u/YsUKjDH4+fmVG3j60ksvxWazcfz48UqvpeoouV7/97//lVuXk5PDY489VmHZ6v5/4YjNZuOmm24Ciru7OkoA/v3vfyc9PR2bzWZ9V8/15ZdfAhAcHKzubCIiTqAkkohII3bbbbcxYMAAcnNzK3ywadWqFc8++yw2m41NmzZx1VVX8cUXX1gPswUFBWzfvp0FCxY4nNI6JCQEKJ6avbIE1IABA+jUqRN5eXl888039O3bt8w4HyXjHx09epT9+/db4ySdKyAggMjISAAWLFhAVFSU9WD6/fffc91117F3717atm3LH/7wh2p+UlXr1asXH374If7+/nz++edce+21NRpkHH55GIyJibFaaVTUle3hhx9m4sSJbNiwgWPHjlnLDx06xNy5c9m/fz82m82aAr7EqFGjsNls9TLdeE2VXCuffvpphS1SgoODue+++wB49NFHufvuu/nhhx+s9Tk5OWzatImpU6dyyy231Coeb29v/vjHP/L0009b3Vt++OEHJkyYwLfffouHhwcLFiwoU2by5MkMGjQIgBtuuIEPPvjA+q7Ex8dz7bXXkp+fT0hICLfffnu14rjyyiux2Wzs3LmTuXPnWg/Y2dnZ/PWvf+Xuu++u9GG3Ot/BP//5z7i4uPDVV18xZcoUqzVJTk4OS5YssVorLliwwHrQPx9XXnklc+fO5eOPPy4zWPGuXbuYPn06UDxOz8CBA89733WtNnXIbbfdht1uJzc3l2uuuYbPP/8cKG5Zs3HjRm644QYryeJIUVERR48etf6UbtWYmZlZZt25JkyYQFhYGEVFRdx4441s27YNKE7MLV++nJUrVwKwePHicgNo+/r6EhwcDPySRKmpkrrm/vvv56OPPrKu/y+//JKxY8dW2n26OnVAZR5++GHatWvHwYMHue6666yZ8/Ly8njxxReZO3cuADNnzsRutzvcR8n518cseiIiUg1GREScJiIiwgBm8uTJFW6zfv16A1h/IiIiHG73j3/8w7Ru3drazsPDw3Ts2NG4urqWKe+oXOkyvXr1MgEBAeaBBx4ot+2NN95obXvnnXeWW//YY49Z64cMGVLhOZ06dcqMGzfO2rZVq1bGx8fH+tnd3d1s2LChXLnNmzcbwAQEBFS4b2OMeemllwxgRo4cWW5dcnKy6d69uwHM2LFjTW5ubqX7ciQ7O9u0adPGitfHx8ecOXPG4bb33ntvmc+/ffv2xsvLq8yyxx57rFy5kSNHVngOVSm5rhyVLdnvSy+9VGH5gIAAA5jNmzeXWX727FnTp08fAxibzWY6d+5sAgICTEBAgElNTbW2KygoMLNnzy5zjl5eXsbHx8fYbDZr2ahRo8rsv7LfW2mPPvqoAcy0adOsa/Lca8jV1dW88cYbDssnJydb5wiYtm3bmrZt21o/9+rVy+zZs6dcucrimzdvXpnz7dChg/Xdu/rqq83ChQsr/P5W9zv4/PPPGxcXF+vzL30MwNx+++2moKCg3P4r+n2WdtFFF1n7cXFxMR06dDAeHh5lPqMPPvigwvL1oeT37Ogzq2kdYowxO3bsKLOtp6en9X2+4IILzPLlyw1grrrqqnJl9+/fX+b3XNkfR1JTU01QUFCZY7u5uVk///a3v63w81i8eLEBzB133OFwfXXrx3379plOnTqVuebatWtnANOmTRuzceNGa93+/fvLlK1uHVBReWOM+c9//lPm2vLx8TGtWrWyfh47dqzJycmpMH673W4A8+GHH1Z6niIiUj/UEklEpJG76aabqjXGyW9+8xv27NnDfffdR0hICG5ubmRlZdGxY0dGjx7Nk08+6bD7xm9+8xtefPFFhg8fjpubG6mpqRw4cMDh2+jS3dMcdVVzNEaSI23btuW9997j73//O5dffjlt27bl9OnTBAQEMGvWLP73v/8xYcKEKs+5Jux2O/Hx8XTt2pX4+HhuvPHG8+6i4+Xlxa9//Wvr55tvvhl3d3eH286bN49nnnmGCRMmcMEFF2CMIS8vj549ezJ58mQ+/vhjHn744VqdU0Np1aoV8fHxTJ06lR49enD8+HEOHDjAgQMHKCgosLZzdXXlb3/7G59++il33HEHAQEBnD17ltzcXHr16sWNN97ImjVr2LBhQ63isdlsrFu3jhUrVhAcHMzZs2fp0KED119/PVu3bmXKlCkOy9ntdr7++mseeeQRLrzwQmv5hRdeaA1yfsEFF5xXLCtWrCAqKoqLL74Yd3d3CgoKGDx4MCtXruSdd97Bzc2twrLV/Q7eddddfPnll9x22234+fmRk5ODt7c348aNY926dbz66qs17v7597//ncWLFzN69Gh69epltUbq378/99xzDzt37iw3To8z1aYOGTx4MF9//TW/+c1v6NatG/n5+XTr1o3777+fhIQEa9yfkvF76pK/vz9JSUk8/PDD9O/fn4KCAry8vBg9ejT/+te/WL16dYVlf/Ob3+Di4kJsbCxnzpypcQy9e/cmISGBO+64gy5dulBYWIiPjw+33347X375JVdddVWFZatbB1Tm17/+Nf/73/+48847CQwM5PTp07Rt25bLLruMqKgoNm7cSLt27RyWTUxMZO/evfTu3btRtdIUEWlJbMbU09ydIiIiIvVg0aJFLF68mIiICF5++WVnhyPNzNSpU3n11Vd59NFH62Q2ubp0/fXX884777Bu3boKxwxqzh544AFWrFjBkiVLeOihh5wdjohIi6SWSCIiIiIiFI+p9eabbwKUG6esMVi0aBE2m43ly5c7O5QGl5WVRXR0NJ07d+aee+5xdjgiIi2WkkgiIiIi0mLExsby8MMPs2vXLvLz84HigZ1jY2MZM2YMubm5XHLJJfzqV79ycqTlhYaGcsstt7Bt2zY++OADZ4fToJ555hmysrJ4+OGHHc6EKSIiDaPiDvoiIiIiIs3MkSNHWLp0KUuXLsXFxQUfHx+ys7OtMX0CAgJ49dVXnRxlxZYtW0ZwcDA5OTnODqVBdejQgT/96U/Mnj3b2aGIiLRoSiKJiIiISItx5ZVXsnDhQj788ENrAPO2bdtit9sZP3489957b70Mql1XgoKCGt1YTQ1BXdhERBoHDawtIiIiIiIiIiJV0phIIiIiIiIiIiJSJSWRRERERERERESkSkoiiYiIiIiIiIhIlZREEhERERERERGRKimJJCIiIiIiIiIiVVISSUREREREREREqqQkkoiIiIiIiIiIVElJJBERERERERERqZKSSCIiIiIiIiIiUiUlkUREREREREREpEpKIomIiIiIiIiISJWURBIRERERERERkSopiSQiIiIiIiIiIlVSEklERERERERERKqkJJKIiIiIiIiIiFRJSSQREREREREREamSkkgiIiIiIiIiIlIlJZFERERERERERKRKSiKJiIiIiIiIiEiVlEQSEREREREREZEqKYkkIiIiIiIiIiJVUhJJRERERERERESqpCSSiIiIiIiIiIhUSUkkERERERERERGpkpJIIiIiIiIiIiJSJSWRRERERERERESkSkoiiYiIiIiIiIhIlZREEhERERERERGRKimJJCIiIiIiIiIiVVISSUREREREREREqqQkkoiIiIiIiIiIVElJpHqWkpKCzWajoKAAgPDwcNasWePkqH7xySef0K9fv3o/zqJFi7jjjjvq/Tgi4pjqomKqi0ScS3VRMdVFIs6luqiY6iKpCSWRqpCXl8fMmTMJCAjAy8uLiy++mPfee6/G+3vvvfeIiIiowwhr5/LLL2fPnj3ODqPJUsUrDemOO+7Az8+P9u3bc8EFF/D3v/+9xvtSXdS8qC4SZ0hOTsbDw6NW157qouZFdZE0pFGjRuHh4YGnpyeenp61SrqoLmpeVBfVLyWRqlBQUEDPnj356KOPyMrK4s9//jOTJk0iJSXF2aGJAyVvE5qKphavONdDDz1ESkoK2dnZ/Oc//+EPf/gD27dvd3ZY4kBT+243tXilcbj77rsZNmyYs8OQSjS173ZTi1ec77nnniMnJ4ecnBwlXRqxpvbdbmrxNjQlkarQrl07Fi1aRGBgIC4uLlx//fUEBQVV+OBWWFjIgw8+SKdOnejduzfvvPNOmfWjRo2yWg+8/PLL/OpXv2LevHn4+PjQu3dvtm7dyssvv0zPnj3p0qVLmWaVeXl5PPjgg/Tq1YuuXbvy29/+ltzcXAC2bNmCv78/y5cvp0uXLvj5+fHSSy9ZZd99910GDBiAl5cXPXr04MknnyxTrsS3337LqFGj8PHxISQkhP/85z/WuunTp3P33Xdz3XXX4eXlRVhYGPv27bPW33vvvfTs2ZP27dszdOhQPvnkk2p9xiUxLFmyhE6dOhEYGMhrr71mrX/nnXe4+OKLad++PT179mTRokXWupKmqNHR0fTq1YsxY8YAcMstt9CtWze8vb254oor2LVrV5nzmDNnDuHh4Xh6evKrX/2Kn376ifvuu48OHTrQv39/duzYYW1/8OBBbr75Zjp37kxQUBDPPPMMAHFxcSxZsoR//vOfeHp6ctFFFwGQlZXFzJkz8fPzo0ePHvzhD3+gsLCw3O/c19e3zLmUSEhIIDQ0lPbt29O1a1fuv//+MucaFRVF9+7d8fPzY/ny5WXKjRgxAh8fH/z8/Ljnnns4e/astX7Xrl2MGzcOX19funbtypIlSwAoKipi2bJl9OnTh44dOzJp0iSOHTtWrd+dNKyQkBDc3d0BsNls2Gy2Mt/B0lQXqS5SXST1KSYmBh8fH8aOHVvpdqqLVBepLpLGQHWR6iLVRXXIyHn56aefjLu7u/n2228drl+9erXp16+f+fHHH01mZqYZNWqUAUx+fr4xxpiRI0eaF1980RhjzEsvvWRcXV3NP/7xD1NQUGAWLlxoevbsaebMmWPOnDljNm7caDw9Pc3JkyeNMcbce++95te//rXJzMw02dnZ5vrrrzcLFiwwxhizefNm4+rqav74xz+as2fPmnfeece0adPGHDt2zBhjTLdu3czHH39sjDHm2LFjZvv27Va5Hj16GGOMOXv2rOnTp4957LHHTF5enomPjzeenp7mu+++M8YYExERYTp06GC++OILk5+fb2677TYzefJk69xfeeUVc/ToUZOfn2+efPJJ07VrV5Obm2uMMebRRx81t99+u8PPrCT2efPmmTNnzpgtW7aYtm3bWsfdvHmz+eabb0xhYaH5+uuvTZcuXcxbb71ljDFm//79BjBTp041OTk55vTp08YYY6Kjo012drY5c+aMuffee81FF11kHS8iIsJ07NjRJCYmmtzcXDN69GgTGBho1qxZY/0eRo0aZYwxprCw0AwZMsQsXrzY5OXlmX379pmgoCATFxdX4XlNmDDBREZGmpycHHPo0CEzbNgw8/zzz5f5nT/zzDMmPz/fire0Sy65xKxdu9YYY8zJkyfN559/XuZcp0yZYnJycsw333xjOnXqZDZt2mSMMSYxMdF8/vnnJj8/3+zfv9/079/fPPXUU8YYY7Kzs023bt3Mk08+aXJzc012drbZtm2bMcaYp556yoSFhZnU1FRz5swZExkZaaZMmeLwdyXON3v2bNOmTRsDmIsvvtiqH86lukh1keoiqS9ZWVmmb9++5scff6z0O2WM6iLVRaqLpP6MHDnSdOrUyXTs2NFceumlZvPmzRVuq7pIdZHqorqjJNJ5OHv2rBk7dqyJjIyscJvRo0eb1atXWz9v3Lix0grKbrdb237zzTcGMD/99JO1zNfX1+zYscMUFRWZtm3bmr1791rrtm7dagIDA40xxV9iDw8P6zjGGNO5c2fr4u7Zs6d5/vnnTVZWVpl4S1dQH3/8senataspLCy01k+ZMsU8+uijxpjiL/bMmTOtde+8847p169fhZ+Fj4+PSUpKMsZUr4LKycmxlt1yyy3mT3/6k8Pt7733XnPfffcZY3750u7bt6/COI4fP24Ac+LECes8Zs2aZa1/5plnTP/+/a2fv/nmG+Pt7W2MMWbbtm2mZ8+eZfa3ZMkSM336dIfn9dNPP5nWrVuXqXhef/11q8J76aWXyu3vXJdffrl55JFHzJEjR8osLznX0gnM3//+92bGjBkO9/PUU0+ZG264wYph8ODBDrfr37+/+eCDD6yfDx48aNzc3MpcS9K4FBQUmE8++cT8+c9/NmfPnnW4jeqiX6guKqa6SOrK3LlzzbJly4wxlX+njFFdVJrqomKqi6SubNu2zUpIvPzyy8bT07NMnVCa6qJfqC4qprqo5tSdrZqKioqYOnUqrVu35rnnnqtwu4MHD9KzZ0/r54CAgEr327VrV+vfbdq0cbgsJyeHI0eOcPr0aYYOHYqPjw8+Pj5cc801HDlyxNq2Y8eOuLm5WT+3bduWnJwcAN58803effddAgICGDlyJJ9//nmFsbu4/HJZBAQEkJ6ebv3crVs3h/sHWL58OcHBwXh7e+Pj40NWVhZHjx6t9PxLdOjQgXbt2pU57sGDBwH44osvGD16NJ07d8bb25vnn3++3H5Lf+aFhYUsWLCAPn360L59ewIDAwHKlDn3M3b0mQMcOHCAgwcPWp+5j48PS5Ys4dChQw7P48CBA+Tn5+Pn52dtf9ddd3H48GGHsToSHR3N999/T//+/Rk2bBj//e9/KzzX0p/T999/z/XXX0+3bt1o3749Dz/8sHXOqamp9OnTp8KYb7zxRive4OBgXF1dKzxHcT5XV1cuu+wy0tLSWL16tcNtVBepLlJdJPUhKSmJDz74gHnz5lVre9VFqotUF0l9CQsLw8vLC3d3dyIiIvjVr37Fu+++63Bb1UWqi1QX1R0lkarBGMPMmTM5dOgQb775Jq1atapwWz8/P1JTU62ff/zxxzqJoVOnTrRp04Zdu3Zx4sQJTpw4QVZWVpkKojLDhg0jNjaWw4cPc8MNNzBp0qRy23Tv3p3U1FSKiorKxN+jR48q9//JJ5/w+OOP869//Yvjx49z4sQJvL29McZUK77jx49z6tSpMsft3r07ALfddhvjx48nNTWVrKwsfvvb35bbr81ms/79+uuvExsbywcffEBWVpY1CHp1YymtZ8+eBAUFWZ/5iRMnOHnypPUfVOnjlmzv7u7O0aNHre2zs7PL9Pc9t8y5+vbtyxtvvMHhw4eZP38+EydOLPPZnHt9lXxOs2fPpn///iQnJ5Odnc2SJUusc+7Zs2eFY+f07NmT9957r8w5njlzplq/d3GugoKCCn+vqotUF6kukvqwZcsWUlJS6NWrF926dePJJ5/kzTffZMiQIQ63V12kukh1kTQUm81W4XWtukh1keqiuqMkUjXMnj2bb7/9lrffftvKRFdk0qRJPPPMM6SlpXH8+HGWLVtWJzG4uLhw5513Mm/ePCtjmp6ezsaNG6sse/bsWV577TWysrJo1aoV7du3x9XVtdx2YWFhtGvXjieeeIL8/Hy2bNnC22+/zZQpU6o8xsmTJ3Fzc6Nz584UFBTwpz/9iezs7PM6x0cffZSzZ8/yySef8N///pdbbrnF2revry8eHh4kJCTw+uuvVxmLu7s7HTt25PTp0zz88MPnFUdpw4cPp3379jz++OPk5uZSWFjIzp07+fLLL4HibHlKSopVqfv5+XHVVVfxwAMPkJ2dTVFREfv27eOjjz6q9jFfffVVjhw5gouLCz4+PgBlfl9//vOfOX36NLt27eKll15i8uTJ1nm3b98eT09PvvvuuzItVK6//np++uknVq5cSV5eHidPnuSLL74A4Le//S0LFy7kwIEDABw5coTY2Ngaf2ZSPw4fPkxMTAw5OTkUFhayceNG3njjDWugwnOpLlJdpLpI6kNkZCT79u0jKSmJpKQkfvvb33LddddVWAeoLlJdpLpI6sOJEyfYuHEjZ86coaCggNdee42PP/6Yq6++2uH2qotUF6kuqjtKIlXhwIEDvPDCCyQlJdGtWzc8PT3x9PQsMzJ9aXfeeSdXX301F110EUOGDOGmm26qs1gef/xx7HY7l1xyCe3bt+fKK6+s9lSWr7zyCoGBgbRv357nn3+eV199tdw2rVu35j//+Q/vvfcenTp1Ys6cOaxdu5b+/ftXuf+rr76a8PBwLrjgAgICAvDw8KiySWBp3bp1o0OHDnTv3p3bb7+d559/3jru3/72Nx555BG8vLz405/+5DBDX9q0adMICAigR48eDBgwgEsuuaTacZzL1dWVt99+m6SkJIKCgujUqROzZs0iKysLwKpEO3bsaL2FXbt2LWfPnmXAgAF06NCBiRMnkpGRUe1jxsXFERISgqenJ/feey8xMTF4eHhY60eOHIndbmfs2LE8+OCDXHXVVQA8+eSTvP7663h5eXHnnXdaFReAl5cXmzZt4u2336Zbt2707duXzZs3A8UzNowfP56rrroKLy8vLrnkEqvyksbDZrOxevVq/P396dChAw8++CArV65kwoQJDrdXXaS6SHWR1Ie2bdvSrVs364+npyceHh507tzZ4faqi1QXqS6S+pCfn88f/vAHOnfu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iTfeeMMj78GXOfr7UVdXJ+68806RkJAgRo4cKXJycmQ9XmPuSCJ5Q/z0tjhj73i//fZbAUAMHz5c+nqau/Eph7EaczSJpBDCzKI5IiIiIiIiIiIiIz6xOxsREREREREREbkWk0hERERERERERNQuJpGIiIiIiIiIiKhdTCIREREREREREVG7mEQiIiIiIiIiIqJ2MYlERERERERERETtYhKJiIiIiIiIiIjaxSQSERERERERERG1i0kkIiIiIiIiIiJqF5NIRERERERERETULiaRiIiIiIiIiIioXUwiERERERERERFRu5hEIiIiIiIiIiKidjGJRERERERERERE7WISiYiIiIiIiIiI2sUkEhERERERERERtYtJJCIiIiIiIiIiaheTSERERERERERE1C4mkVxMq9VCoVCgsbERADB9+nRkZGR4eFQtvv32WwwePNjlr/Pkk0/irrvucvnrEJF5jEV6jEVEnsVYpMdYRORZjEV6jEVkDyaRbJSZmYmhQ4eia9euGDhwIL799lu7nuezzz5DcnKyk0dnv2uuuQbHjx/39DC8FgMvuVO3bt1MPpRKJR566CG7nouxyLcwFpE7abVa3HTTTejZsyf69u2LBx98ULoQ6yjGIt/CWETu9NNPP+GGG25AWFgY4uLi8O9//9vu52Is8i2MRa7FJJINvvjiCzz++ON46623cOHCBXzzzTcYMGCAp4dFZtg7ifUUbxsvedbFixelj9OnT6Nz5864/fbbPT0sMsPbfre9bbzkWcuWLUNERATKyspw6NAhfP311/j73//u6WGRGd72u+1t4yXPaWxsxKxZszBjxgycP38eaWlpuOuuu/DLL794emhkhrf9bnvbeN2NSSQbrFmzBn/9618xfvx4BAQEoF+/fujXr5/Zc3U6HR599FH06dMHAwYMwM6dO00+P3HiRLzxxhsAgLfffhtXX301Hn74YfTo0QMDBgzAnj178PbbbyMmJgYREREmZZV1dXV49NFH0b9/f0RGRuL+++/H5cuXAQC7d++GSqXCiy++iIiICERFReGtt96SHvvpp58iPj4eoaGh6NevH1544QWTxxn89NNPmDhxInr06IGEhAR8/PHH0ucWLVqEBx54ADfffDNCQ0Mxbtw4nDx5Uvr8ihUrEBMTg+7du2P06NE2V2sZxvDss8+iT58+0Gg0eO+996TP79y5EyNHjkT37t0RExODJ598UvqcoRQ1PT0d/fv3xw033AAAuP3229G3b1+EhYXh2muvxdGjR03ex7JlyzB9+nR069YNV199NX777TesXLkSPXv2xJAhQ/Djjz9K55eWluK2225DeHg4YmNjsXHjRgBAdnY2nn32WXzwwQfo1q0brrzySgBAVVUV7r33XkRFRaFfv374f//v/0Gn07X5nvfq1cvkvRjs378fSUlJ6N69OyIjI/HHP/7R5L2mpaUhOjoaUVFRePHFF00eN2HCBPTo0QNRUVF48MEHUV9fL33+6NGjmDx5Mnr16oXIyEg8++yzAICmpiakpqZi4MCB6N27N+bOnYvz58/b9L0jz9m2bRsiIiJwzTXXmP08YxFjEWMRuUpBQQHmzp2LTp06oW/fvpg2bZrJz7YxxiLGIsYicoWff/4ZpaWlePjhh6FUKnHDDTfg6quvxjvvvGP2fMYixiLGIicSZFVjY6MICgoS69atEwMHDhT9+vUTDzzwgLh06ZLZ8zdt2iQGDx4sfv31V3Hu3DkxceJEAUA0NDQIIYS47rrrxD//+U8hhBBvvfWWUCqV4s033xSNjY1i9erVIiYmRixbtkzU1taKXbt2iW7duokLFy4IIYRYsWKF+P3vfy/OnTsnqqurxYwZM8SqVauEEEJ89dVXQqlUiieeeELU19eLnTt3is6dO4vz588LIYTo27ev+Oabb4QQQpw/f14cPHhQely/fv2EEELU19eLgQMHimeeeUbU1dWJnJwc0a1bN/Hzzz8LIYRITk4WPXv2FN9//71oaGgQCxYsEHfccYf03t955x1x9uxZ0dDQIF544QURGRkpLl++LIQQYs2aNeLOO+80+zUzjP3hhx8WtbW1Yvfu3aJLly7S63711VciLy9P6HQ6cfjwYRERESH+/e9/CyGEKCgoEADE3XffLS5evCh9X9LT00V1dbWora0VK1asEFdeeaX0esnJyaJ3794iNzdXXL58WVx//fVCo9GIjIwM6fswceJEIYQQOp1OjBo1Sqxdu1bU1dWJkydPitjYWJGdnW3xfc2aNUukpKSIixcvitOnT4sxY8aI119/3eR7vnHjRtHQ0GD252j8+PFi8+bNQgghLly4IPbu3WvyXufNmycuXrwo8vLyRJ8+fcQXX3whhBAiNzdX7N27VzQ0NIiCggIxZMgQ8fLL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/OMf/zD7NerWrRsAYPfu3frnuu9xzLl2Du68804IIZCZnony0+W497Z7cf311wMAPv/8c0yYMAGjRo3C7bffjosXL0rjfeqpp/C73/0OW7duxcSJE7Fy5UpcddVVGDZsGPbv39/u94zIFzEWdTwWzZkzB0OGDJFi0caNG1FaWor7b7/fJBbdddcEzL1zCG6ccSMu1VxCva5eikVLljAWERljLHI8Fn2W+TlKy8tx/S23tJkXDR06Co8+ejsqKy8ir2g4Zs1U46nn/4klS36HnJytGH3VaNyVchcWL26JRfX1rBog/8NYZD4W1evq9TfCeiSim+oqAEax6PHHMWzObH0sChuOjZt3o/S38jbzoj/8YQIWLRqFVat4jeZPmERysvz8fDzwwAM4evQoevTogQ8//LDNOUeOHMHo0aPtev7u3btj//79ePDBB7Fy5co2n7/zzjvxwAMP4PDhw9izZw+ioqJMPj9lyhQUFRXhiiuuwLJly/D111936PkBoLGxEfv378f69euxdu1aAEB6ejrCwsJw4MABHDhwAP/85z9RUFBg9b38+OOP+OPaP+Jfu/+FU6dO4bvvvsO8e+chOjoar299HV999RXOnj2Lp59+Gl9++SV++OEHJCUl4aWXXpKeo1OnTvjvf/+LefPmAQBqamqwZ88e/P3vf8fixYvb+3IS+SzGoo7FovXr1+PYsWNSLFq+fLlJLPryyJf485o/47XXvsTP//sZk6+ZjM/f/Vx6jk6dOuGNNxiLiFpjLLI/Fh0+cBjLly1DdHg4vsrObjMveuedHzBpUhIyM18CoEBQYCM6hYTgjTf+iylT9LHoYs1FvPnmHjzyyN+xYAFjEfkvxiLTWJRX31yFZMaPP/6I9X/8I459uM10XtQ3XD8v+vcGnP3lSzz95J+la7ShQ3mN5k+YRHKy2NhYjBgxAgAwevToNj2jHDV//nzpz71795p87sKFCygpKcGtt94KQP/L27qvULdu3XDw4EGkpaUhPDwcd9xxh0kW3drzG8yePRuA6fv7/PPPsXnzZowYMQLjxo3DuXPnkJ+fb/W9jB07FpHRkQgICMCIESPMfq327duHY8eO4eqrr8aIESOQkZGBwsKWNdR33HGH2a/Ptddei+rqalRWVlodA5GvYizqWCxSqVRmY1FQQBByS3Pxv4P/w6lfTuHee01jUbAyGA26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QjabxTnnnIMdO3bgtttuQ39/f1Qh+ibra66KavMLEM7PqIx5T4V8JmOeUjX/yJpbZHytwiZDnpIlJ8mah2TIPSrlGhnyiwyvBYtIDn7/+9+X/LsLL7wQBw4cQENDAw4cOOB4LGjXrl34zW9+gx07duDUqVM4duwYfvCDH+C5556TLlYAGBkZwbJly3DnnXfi9ttvDzxGJ42NjRgcHMy9PTQ0hJkzZ3r+mLC5jeEvf/kL7rvvPvz2t7/FBRdcEGWIANzF2dfXhxUrVgAADh8+jB07diCdTuO2226LMtREKffz6UacPwNB5BYRa319Pb773e9iz549sRSRVMk3TtzEZS/8f+tb38IDDzyAw4cP48tf/nJkcfoh62uuimrzCxDOz6iMeU+FfCZjnlI1/8iaW2R8rcImQ56SJSfJmodkyD0q5RoZ8osMrwWPs3nU2dmJ7u5uAEB3d7djBXvdunUYGhqCYRjo6enB4sWLQykgVeImVtM0ce+996KlpQUPPfRQZLFdffXV6O/vx8DAAM6cOYOenh50dnYWfExnZyeeeeYZmKaJ3bt3o66uLtfqKVOcH374IW6//XY8++yzuOyyyyKNz0ucAwMDMAwDhmHge9/7Hp566ikWkCTn5usaBze55cSJE/jss89yf/7d735X8paJsKmSb5y4if2jjz7KPRnbs2cPxsfHYylmeyXra54UMv2M2kWd92TJZzLmKVXzj6y5RcbXSnYy5KkoclKceUiG3KNSrpEhv0jxWoQ/u1svhw8fNhcvXmw2NzebixcvNj/55BPTNE1zeHjY7OjomPTxcU5PdxPrH//4RxOAOX/+fPPKK680r7zySnP79u2RxLd9+3Zzzpw55uzZs82f//znpmma5ubNm83Nmzebpmma4+Pj5gMPPGDOnj3bvOKKK8re3BBnnPfee6953nnn5V6/hQsXShmn3cqVK3k7W8x+9atfmRdddJE5depUs76+3rzllltM05ycS5y+rnFzk1s++OADs62tzWxrazPnzZsXe+yq5BsnlWJ/4oknzHnz5pltbW3mtddea+7atSvOcHNWrFhhfuUrXzHT6bR50UUXmU8//bQyr7nq3OSXOH5GZcx7MuUzGfOUjPlH1txSKS5Zc3VcZMhTsuSkuPOQDLlHllwjQ35RIZekTNPhYB8REREREREREZENj7MREREREREREVFFLCIREREREREREVFFLCIREREREREREVFFLCIREREREREREVFFLCIREREREREREVFFLCIREREREREREVFFLCIREREREREREVFF/wcAeFCzdFSYjwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(nrows=2, ncols=4, figsize=(20,10), facecolor=\"w\")\n", + "ax = ax.flatten()\n", + "\n", + "i = 0\n", + "for n in range(2,10):\n", + " ydata = np.load(f'./downscale_data/{n}_ytest.npy')\n", + " \n", + " lin = np.load(f'./downscale_data/{n}_linear_out.npy')\n", + " near = np.load(f'./downscale_data/{n}_nearest_out.npy')\n", + " mcoord = np.load(f'./downscale_data/{n}_map_out.npy')\n", + " network = np.load(f'./downscale_data/{n}_network_out.npy') \n", + "\n", + "# ax[i].hist(np.log10(abs(lin-ydata)), bins='auto', label='Linear Interp.',histtype='step',density=True, color=\"blue\")\n", + "# ax[i].hist(np.log10(abs(near-ydata)), bins='auto', label='Nearest Neighbour',histtype='step',density=True, color=\"orange\")\n", + "# if n != 2:\n", + "# ax[i].hist(np.log10(abs(mcoord-ydata)), bins='auto', label='n-Cubic Spine interp.',histtype='step',density=True, color=\"green\")\n", + "# else:\n", + "# temp = abs(mcoord-ydata)\n", + "# ax[i].hist(np.log10(temp[temp != 0]), bins='auto', label='n-Cubic Spine interp.',histtype='step',density=True, color=\"green\")\n", + " \n", + "# ax[i].hist(np.log10(abs(network-ydata)), bins='auto',label='NN', histtype='step', density=True, color=\"red\")\n", + " if n > 5:\n", + " ax[i].hist(np.log10(near/ydata), bins='auto', label='Nearest Neighbour',histtype='step',density=False, color='orange')\n", + " if n > 2:\n", + " temp = mcoord/ydata\n", + " ax[i].hist(np.log10(temp[temp != 0]), bins='auto', label='n-Cubic Spine interp.',histtype='step',density=False, color='green')\n", + " ax[i].hist(np.log10(lin/ydata), bins='auto', label='Linear Interp.',histtype='step',density=False, color='blue')\n", + " \n", + " ax[i].hist(np.log10(network/ydata), bins='auto',label='NN', histtype='step', density=False, color='red')\n", + "\n", + " ax[i].legend(loc='upper left')\n", + " ax[i].set_title(f'{n} dimensional parameter space')\n", + " i += 1\n", + "\n", + "fig.suptitle('Network vs. Interpolators - log10(ratio)',fontsize=24)\n", + "#plt.xlabel('log10(|diff|) between truth and interpolated')\n", + "# plt.title('Neural Network (NN) performance vs. selected interpolation methods')\n", + "\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "8566ea0d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "sorty = np.argsort(ydata)\n", + "\n", + "plt.plot(ydata[sorty],alpha=0.5)\n", + "plt.plot(network[sorty],alpha=0.5)\n", + "plt.plot(lin[sorty],alpha=0.5)\n", + "plt.plot(mcoord[sorty],alpha=0.5)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "62eb37fb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2 1000.0\n", + "3 100.0\n", + "4 32.0\n", + "5 16.0\n", + "6 10.0\n", + "7 7.0\n", + "8 6.0\n", + "9 5.0\n" + ] + } + ], + "source": [ + "for n in range(2,10):\n", + " print(n,np.round(10**(6/n)))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0e249162", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Projects - Mock Data/SNR Mock data function/scripts/data_generation.py b/Projects - Mock Data/SNR Mock data function/scripts/data_generation.py new file mode 100644 index 0000000..895ad59 --- /dev/null +++ b/Projects - Mock Data/SNR Mock data function/scripts/data_generation.py @@ -0,0 +1,175 @@ +import numpy as np +from sys import stdout + +""" +Generating mock data to test out function approximation methods. + +Parameter space is 9-dimensional. + +M: peaks around 5e5 +q: linear then plateau +a: linear-ish increase (decrease at high M) +e: linear decrease +Y0: linear increase + +qS, qK: (sin(x)+1.25)**2 +phiS: (sin(2x)+1.25)**2 + +tpl: log increase + +We don't really care what the normalisation of this distribution is but it should be 10 +- 1 order of mag +across most of it. We can fix it such that the M peak has an SNR of ~200 and that should sort it out. + + +""" + + +def fM(lM): + return 10 * np.exp(-2 * (lM - 6) ** 2) + 0.1 + + +def fq(lq): + #lq = np.log10(q) + return 3 / (lq - 4.1) + + +def fa(a): + return 0.2*a + 0.9 + + +def fe(e): + return 1.1 - 0.2 * e + + +def fY(Y): + return Y + + +def fTh(th, phase): + return 0.4*(np.sin(2 * np.pi * th + phase)) ** 2 + 0.6 + + +def fPh(ph, phase): + return 0.4*(np.sin(2 * np.pi * 2 * ph + phase) + 1) ** 2 + 0.6 + + +def ft(t): + return t**0.5/4**0.5 + + +def func_out(M, q, a, e, Y, qS, phiS, qK, tpl): + # return fM(M) + fq(q) + fa(a) + fe(e) + fY(Y) + fTh(qS, np.pi/3) + fTh(qK, np.pi/4) + fPh(phiS, 3*np.pi/8) + ft(tpl) + return fM(M) * fq(q) * fa(a) * fe(e) * fY(Y) * fTh(qS, np.pi / 3) * fTh(qK, np.pi / 4) * fPh(phiS, + 3 * np.pi / 8) * ft( + tpl) + + +def grid_sampling(grid_dims, ranges): + + total = np.prod(grid_dims) + print(f'Total number of points: {total:.3e}') + + +def cartesian_product_recursive(arrays, out=None): + arrays = [np.asarray(x) for x in arrays] + dtype = arrays[0].dtype + + n = np.prod([x.size for x in arrays]) + if out is None: + out = np.zeros([n, len(arrays)], dtype=dtype) + + m = n // arrays[0].size + out[:, 0] = np.repeat(arrays[0], m) + if arrays[1:]: + cartesian_product_recursive(arrays[1:], out=out[0:m, 1:]) + for j in range(1, arrays[0].size): + out[j * m: (j + 1) * m, 1:] = out[0:m, 1:] + return out + + +def get_data(grid_dims, sample_ranges): + # get grid data, sampled data and some test data + + print('Generating grid data') + + iterators = [np.linspace(nums[0], nums[1], grid_dims[i]) for i,nums in enumerate(sample_ranges)] + total = np.prod(grid_dims) + + combinations = cartesian_product_recursive(iterators) + + xgrid = np.array(combinations) + ygrid = np.zeros(xgrid.shape[0]) + + for i, combo in enumerate(combinations): + ygrid[i] = func_out(*combo.tolist()) + + print('Generating sample data') + + xsamp = np.zeros((total, len(grid_dims))) + + for i in range(len(grid_dims)): + xsamp[:, i] = np.random.uniform(sample_ranges[i, 0], sample_ranges[i, 1], total) + + ysamp = np.zeros(total) + + for i, row in enumerate(xsamp): + ysamp[i] = func_out(*row.tolist()) + + print('Generating test data') + + xtest = np.zeros((total, len(grid_dims))) + + for i in range(len(grid_dims)): + xtest[:, i] = np.random.uniform(sample_ranges[i, 0], sample_ranges[i, 1], total) + + ytest = np.zeros(total) + + for i, row in enumerate(xtest): + ytest[i] = func_out(*row.tolist()) + + return xgrid, ygrid, xsamp, ysamp, xtest, ytest + + +if __name__ == '__main__': + # nM = 12 + # nq = 8 + # na = 7 + # ne = 7 + # nY = 7 + # nTh = 7 + # nPh = 8 + # nt = 8 + + nM = 8 + nq = 5 + na = 4 + ne = 4 + nY = 4 + nTh = 5 + nPh = 8 + nt = 5 + + # Our prior space (params are M,q,a,e,Y,thetaS,phiS,thetaK,t) + sample_ranges = np.array([ + [np.log10(8e4), np.log10(5e7)], + [np.log10(5e4), np.log10(5e7)], + [0.01, 0.99], + [0.01, 0.5], + [0.5, 0.99], + [0, np.pi], + [0, 2 * np.pi], + [0, np.pi], + [0.5, 4], + ]) + + xgrid, ygrid, xsamp, ysamp, xtest, ytest = get_data([nM,nq,na,ne,nY,nTh,nPh,nPh,nt],sample_ranges) + + fp = '../_data/{}' + np.save(fp.format('xgrid.npy'),xgrid) + np.save(fp.format('ygrid.npy'),ygrid) + np.save(fp.format('xsamp.npy'),xsamp) + np.save(fp.format('ysamp.npy'),ysamp) + np.save(fp.format('xtest.npy'),xtest) + np.save(fp.format('ytest.npy'),ytest) + + print('Data generation complete.') \ No newline at end of file diff --git a/Projects - Mock Data/SNR Mock data function/scripts/model_nodataloader_sepdata.py b/Projects - Mock Data/SNR Mock data function/scripts/model_nodataloader_sepdata.py new file mode 100644 index 0000000..2d4f5ab --- /dev/null +++ b/Projects - Mock Data/SNR Mock data function/scripts/model_nodataloader_sepdata.py @@ -0,0 +1,144 @@ +import torch +from torch import nn +from torch.nn.init import xavier_uniform_ +import numpy as np +import matplotlib.pyplot as plt +from MLtools.utilities import norm, norm_inputs, unnorm, unnorm_inputs +from MLtools.nn.model_creation import create_mlp + +if __name__ == '__main__': + + device = "cuda:0" + + xtrain = np.load('./xdata_pert.npy') + ytrain = np.log(np.load('./ydata_pert.npy')) + + xtest = np.load('./xtest.npy') + ytest = np.log(np.load('./ytest.npy')) + + np.save('pert_xdata_mean_std.npy',np.array([xtrain.mean(axis=0), xtrain.std(axis=0)])) + np.save('pert_ydata_mean_std.npy',np.array([ytrain.mean(), ytrain.std()])) + + xtest = torch.from_numpy(norm_inputs(xtest, xtrain)).to(device).float() + ytest = torch.from_numpy(norm(ytest, ytrain)).to(device).float() + + xtrain = torch.from_numpy(norm_inputs(xtrain, xtrain)).to(device).float() + ytrain = torch.from_numpy(norm(ytrain, ytrain)).to(device).float() + + + # xgrid = np.load('./xdata.npy') + # ygrid = np.log(np.load('./ydata.npy')) + # + # xtrain = np.load('./xtest.npy') + # ytrain = np.log(np.load('./ytest.npy')) + # + # xtest = np.load('./xtest2.npy') + # ytest = np.log(np.load('./ytest2.npy')) + # + # xtrain2 = 2*(xtrain - np.min(xgrid,axis=0))/np.max(xgrid,axis=0) - 1 + # ytrain2 = 2*(ytrain - np.min(ygrid))/np.max(ygrid) - 1 + # + # xtest2 = 2 * (xtest - np.min(xgrid, axis=0)) / np.max(xgrid, axis=0) - 1 + # ytest2 = 2 * (ytest - np.min(ygrid)) / np.max(ygrid) - 1 + # + # xtest = torch.from_numpy(xtest2).to(device).float() + # ytest = torch.from_numpy(ytest2).to(device).float() + # + # xtrain = torch.from_numpy(xtrain2).to(device).float() + # ytrain = torch.from_numpy(ytrain2).to(device).float() + + + ytrainsize = len(ytrain) + ytestsize = len(ytest) + + mlp = MLP().to(device) + loss_function = nn.MSELoss() + + LR = 1e-2 + + optimizer = torch.optim.Adam(mlp.parameters(), lr=LR) + scheduler = torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.97) + train_losses = [] + test_losses = [] + rate = [] + # Run the training loop + + datasets = {"train": [xtrain, ytrain], "test": [xtest, ytest]} + + num_epochs = 1000 + nbatch = 50 + cutoff_LR = 600 + for epoch in range(num_epochs): # 5 epochs at maximum + # Print epoch + print(f'Starting epoch {epoch + 1}') + + for phase in ['train','test']: + if phase == 'train': + mlp.train(True) + shuffled_inds = torch.randperm(ytrainsize) + + # Set current loss value + current_loss = 0.0 + + # Iterate over the DataLoader for training data + # Get and prepare inputs + inputs, targets = datasets[phase] + inputs = inputs[shuffled_inds] + targets = targets[shuffled_inds] + + targets = targets.reshape((targets.shape[0], 1)) + + for i in range(nbatch): + for param in mlp.parameters(): + param.grad = None + outputs = mlp(inputs[i * ytrainsize // nbatch : (i+1)*ytrainsize // nbatch]) + loss = torch.sqrt(loss_function(outputs, targets[i * ytrainsize // nbatch: (i+1)*ytrainsize // nbatch])) + loss.backward() + optimizer.step() + current_loss += loss.item() + + train_losses.append(current_loss / nbatch) + + else: + with torch.no_grad(): + mlp.train(False) + shuffled_inds = torch.randperm(ytestsize) + current_loss = 0.0 + inputs, targets = datasets[phase] + inputs = inputs[shuffled_inds] + targets = targets[shuffled_inds] + + targets = targets.reshape((targets.shape[0], 1)) + + for i in range(nbatch): + outputs = mlp(inputs[i * ytestsize // nbatch: (i+1)*ytestsize // nbatch]) + loss = torch.sqrt(loss_function(outputs, targets[i * ytestsize // nbatch: (i+1)*ytestsize // nbatch])) + current_loss += loss.item() + + test_losses.append(current_loss / nbatch) + + if epoch >= cutoff_LR: + scheduler.step() + rate.append(scheduler.get_last_lr()[0]) + else: + rate.append(LR) + print(f'Train loss: {train_losses[-1]}, Test loss: {test_losses[-1]}') + + torch.save(mlp.state_dict(),'pert_model.pth') + + epochs = np.arange(num_epochs) + plt.semilogy(epochs, train_losses, label='Train') + plt.semilogy(epochs, test_losses, label='Test') + plt.legend() + plt.xlabel('Epochs') + plt.ylabel('Root Mean Square Error') + plt.title('Train and Test Loss Across Train Epochs') + plt.savefig('losses.png') + plt.show() + + plt.semilogy(epochs, rate) + plt.xlabel('Epochs') + plt.ylabel('Adam learning rate') + plt.savefig('LR.png') + plt.show() + -- GitLab