diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b8c232b4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +*.hdf5 +notebooks/dev/ diff --git a/README.md b/README.md index 8fee5465..574272ef 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,13 @@ You will get two datasets, based on two different simulations, which will allow The first dataset, which can be found under `data` after download is based on the CosmoDC2 simulation. The second dataset, found under `data_buzzard` is based on the Buzzard simulations. +## Installing dependencies + +From the root folder: +``` +$ pip install -r requirements.txt +``` + ## Metric diff --git a/bin/challenge.py b/bin/challenge.py index 0dd301e6..6cdf28b0 100755 --- a/bin/challenge.py +++ b/bin/challenge.py @@ -107,9 +107,7 @@ def run_one(classifier_name, bands, settings, train_data, train_z, valid_data, name = str(classifier.__name__) code = abs(hash(str(settings))) tc.metrics.plot_distributions(valid_z, results, f"plots/{name}_{code}_{bands}.png", metadata=settings) - return scores - if __name__=="__main__": main() diff --git a/example/example_output.txt b/example/example_output.txt new file mode 100644 index 00000000..c918a23c --- /dev/null +++ b/example/example_output.txt @@ -0,0 +1,5 @@ +RandomForest run_1 {'bins': 1} {'SNR_ww': 134.80948870306673, 'SNR_gg': 555.4535070472674, 'SNR_3x2': 562.3045275125236, 'FOM_3x2': 11406.381379130828} +RandomForest run_2 {'bins': 2} {'SNR_ww': 153.37996427859213, 'SNR_gg': 749.4259413373646, 'SNR_3x2': 752.8800006487635, 'FOM_3x2': 11420.79691061082} +RandomForest run_3 {'bins': 3} {'SNR_ww': 159.18538698343457, 'SNR_gg': 922.7346985760454, 'SNR_3x2': 925.4853956272517, 'FOM_3x2': 43768.68018337518} +RandomForest run_4 {'bins': 4} {'SNR_ww': 160.84108815042694, 'SNR_gg': 1037.3860103346599, 'SNR_3x2': 1039.8374894959643, 'FOM_3x2': 13800.43390167526} +IBandOnly run_3 {'bins': 3} {'SNR_ww': 135.13888426367922, 'SNR_gg': 565.866023397332, 'SNR_3x2': 572.2806557629426, 'FOM_3x2': 25548.34390335924} diff --git a/example/neural_network_buzzard_griz.yaml b/example/neural_network_buzzard_griz.yaml new file mode 100644 index 00000000..80b09e42 --- /dev/null +++ b/example/neural_network_buzzard_griz.yaml @@ -0,0 +1,34 @@ +metrics: [SNR_ww, SNR_gg, SNR_3x2, FOM_3x2, FOM_DETF_3x2] +bands: griz +training_file: data_buzzard/training.hdf5 +validation_file: data_buzzard/validation.hdf5 +output_file: example/neural_output_buzzard_griz.txt +# Backend implementing the metrics, either: "firecrown" (default), "jax-cosmo" +metrics_impl: jax-cosmo + +run: + # hello + NeuralNetwork: + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: FOM_DETF + output_dir: models_buzzard + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} + + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: SNR + output_dir: models_buzzard + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} diff --git a/example/neural_network_buzzard_riz.yaml b/example/neural_network_buzzard_riz.yaml new file mode 100644 index 00000000..824258d6 --- /dev/null +++ b/example/neural_network_buzzard_riz.yaml @@ -0,0 +1,34 @@ +metrics: [SNR_ww, SNR_gg, SNR_3x2, FOM_3x2, FOM_DETF_3x2] +bands: riz +training_file: data_buzzard/training.hdf5 +validation_file: data_buzzard/validation.hdf5 +output_file: example/neural_output_buzzard_riz.txt +# Backend implementing the metrics, either: "firecrown" (default), "jax-cosmo" +metrics_impl: jax-cosmo + +run: + # hello + NeuralNetwork: + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: FOM_DETF + output_dir: models_buzzard + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} + + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: SNR + output_dir: models_buzzard + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} diff --git a/example/neural_network_dc2_griz.yaml b/example/neural_network_dc2_griz.yaml new file mode 100644 index 00000000..06a5ef7d --- /dev/null +++ b/example/neural_network_dc2_griz.yaml @@ -0,0 +1,34 @@ +metrics: [SNR_ww, SNR_gg, SNR_3x2, FOM_3x2, FOM_DETF_3x2] +bands: griz +training_file: data/training.hdf5 +validation_file: data/validation.hdf5 +output_file: example/neural_output_griz.txt +# Backend implementing the metrics, either: "firecrown" (default), "jax-cosmo" +metrics_impl: jax-cosmo + +run: + # hello + NeuralNetwork: + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: FOM_DETF + output_dir: models + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} + + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: SNR + output_dir: models + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} diff --git a/example/neural_network_dc2_riz.yaml b/example/neural_network_dc2_riz.yaml new file mode 100644 index 00000000..25cee4f0 --- /dev/null +++ b/example/neural_network_dc2_riz.yaml @@ -0,0 +1,34 @@ +metrics: [SNR_ww, SNR_gg, SNR_3x2, FOM_3x2, FOM_DETF_3x2] +bands: riz +training_file: data/training.hdf5 +validation_file: data/validation.hdf5 +output_file: example/neural_output_riz.txt +# Backend implementing the metrics, either: "firecrown" (default), "jax-cosmo" +metrics_impl: jax-cosmo + +run: + # hello + NeuralNetwork: + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: FOM_DETF + output_dir: models + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} + + {% for nbins in [5, 10] %} + run_{{ nbins}}: + bins: {{ nbins }} + metric: SNR + output_dir: models + # These special settings decide whether the + # color and error colums are passed to the classifier + # as well as the magnitudes + colors: True + errors: True + {% endfor %} diff --git a/example/neural_output_fom.txt b/example/neural_output_fom.txt new file mode 100644 index 00000000..85df85e9 --- /dev/null +++ b/example/neural_output_fom.txt @@ -0,0 +1,3 @@ +NeuralNetwork run_2 {'bins': 2, 'metric': 'FOM'} {'SNR_ww': 135.7762701025696, 'SNR_gg': 747.3564650562411, 'SNR_3x2': 752.2536087103781, 'FOM_3x2': 9051.18761144165} +NeuralNetwork run_3 {'bins': 3, 'metric': 'FOM'} {'SNR_ww': 138.1739975730084, 'SNR_gg': 843.9211384344102, 'SNR_3x2': 847.0072653794633, 'FOM_3x2': 84547.97008004926} +NeuralNetwork run_4 {'bins': 4, 'metric': 'FOM'} {'SNR_ww': 143.93512392186238, 'SNR_gg': 937.789093247378, 'SNR_3x2': 940.4664612599967, 'FOM_3x2': 14978.628112642044} diff --git a/example/neural_output_snr.txt b/example/neural_output_snr.txt new file mode 100644 index 00000000..4e397208 --- /dev/null +++ b/example/neural_output_snr.txt @@ -0,0 +1,3 @@ +NeuralNetwork run_2 {'bins': 2, 'metric': 'SNR'} {'SNR_ww': 135.8368248575087, 'SNR_gg': 770.3102116003334, 'SNR_3x2': 775.1787513453132, 'FOM_3x2': 19945.877149713706} +NeuralNetwork run_3 {'bins': 3, 'metric': 'SNR'} {'SNR_ww': 145.57034579817267, 'SNR_gg': 919.1359275700552, 'SNR_3x2': 921.8455311553354, 'FOM_3x2': 19930.736921522202} +NeuralNetwork run_4 {'bins': 4, 'metric': 'SNR'} {'SNR_ww': 159.623483697185, 'SNR_gg': 987.2312600491794, 'SNR_3x2': 989.8354725475687, 'FOM_3x2': 45587.37245610679} diff --git a/models/README.md b/models/README.md new file mode 100644 index 00000000..dac6d3e8 --- /dev/null +++ b/models/README.md @@ -0,0 +1 @@ +# Folder for storing trained models diff --git a/notebooks/LearningToBin-2bins-FoM-DETF.ipynb b/notebooks/LearningToBin-2bins-FoM-DETF.ipynb new file mode 100644 index 00000000..087536a2 --- /dev/null +++ b/notebooks/LearningToBin-2bins-FoM-DETF.ipynb @@ -0,0 +1,615 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Populating the interactive namespace from numpy and matplotlib\n" + ] + } + ], + "source": [ + "import sys\n", + "sys.path.insert(0, '..')\n", + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "%pylab inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found classifier IBandOnly\n", + "Found classifier NeuralNetwork\n", + "Found classifier Random\n", + "Found classifier RandomForest\n" + ] + } + ], + "source": [ + "# Import JAX instead of numpy\n", + "import jax.numpy as np\n", + "import jax.random as rand\n", + "from jax import jit, vmap, grad, value_and_grad\n", + "\n", + "# Import modified version of challenge metrics\n", + "from tomo_challenge import jax_metrics as metrics\n", + "\n", + "# Import tools from jax-cosmo\n", + "from jax_cosmo.redshift import kde_nz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "../tomo_challenge/data.py:76: UserWarning: Setting inf (undetected) bands to mag=30\n", + " warnings.warn(\"Setting inf (undetected) bands to mag=30\")\n" + ] + } + ], + "source": [ + "from tomo_challenge.data import load_data, load_redshift\n", + "from sklearn.preprocessing import StandardScaler, RobustScaler\n", + "features_scaler = RobustScaler()\n", + "\n", + "data = load_data('../data/training.hdf5','riz',colors=True, errors=True, array=True)\n", + "m = (data[:,0] <29) & (data[:,1] <29) & (data[:,2] <29)\n", + "data = data[m]\n", + "\n", + "features = np.clip(np.array(features_scaler.fit_transform(data)),-4,4)\n", + "labels = np.array(load_redshift('../data/training.hdf5'))[m]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(8552577, 12)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's grab some data\n", + "batch_size = 2000\n", + "\n", + "batch_labels = labels[:batch_size]\n", + "batch_features = features[:batch_size]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's build an n(z) using a KDE\n", + "nz = kde_nz(batch_labels, np.ones_like(batch_labels), bw=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 0, 'redshift z')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "z = np.linspace(0,4)\n", + "hist(batch_labels, 64, density=True)\n", + "plot(z, nz(z), label='KDE nz')\n", + "xlim(0,4)\n", + "legend()\n", + "xlabel('redshift z')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Checking normalization of features\n", + "for i in range(12):\n", + " hist(batch_features[:,i],100, alpha=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "import jax_cosmo" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "ell, delta_ell = metrics.ell_binning()\n", + "\n", + "@jax.jit\n", + "def FoM_DETF(weights, labels=batch_labels, inds=[5,6]):\n", + " \n", + " # Retrieve the probes\n", + " probes = metrics.get_probes(weights, labels)\n", + " \n", + " # Compute the derivatives of the data vector\n", + " @jax.jit\n", + " def mean(params):\n", + " cosmo = jax_cosmo.Cosmology(\n", + " Omega_c = params[0],\n", + " Omega_b = params[1],\n", + " h = params[2],\n", + " n_s = params[3],\n", + " sigma8 = params[4],\n", + " Omega_k=0.,\n", + " w0=params[5], wa=params[6]\n", + " )\n", + " return jax_cosmo.angular_cl.angular_cl(cosmo, ell, probes, nonlinear_fn=jax_cosmo.power.halofit)\n", + "\n", + " # Compute the jacobian of the data vector at fiducial cosmology\n", + " fid_params = np.array([0.27, 0.045, 0.67, 0.96, 0.840484495, -1., 0.])\n", + " jac_mean = jax.jacfwd(lambda x: mean(x).flatten())\n", + " \n", + " mu = mean(fid_params)\n", + " dmu = jac_mean(fid_params)\n", + " \n", + " # Compute the covariance matrix\n", + " cl_noise = jax_cosmo.angular_cl.noise_cl(ell, probes)\n", + " C = jax_cosmo.angular_cl.gaussian_cl_covariance(ell, probes, mu, cl_noise)\n", + " \n", + " invCov = np.linalg.inv(C)\n", + " \n", + " # Compute constant covariance FoM\n", + " t2 = np.einsum('pa,pq,qb->ab', dmu, invCov, dmu)\n", + " F = t2\n", + "\n", + " # Compute covariance\n", + " i,j = inds\n", + " covmat_chunk = np.linalg.inv(F)[:, [i, j]][[i, j], :]\n", + " \n", + " # And get the FoM, the inverse area of the 2 sigma contour\n", + " # area.\n", + " area = 6.17 * np.pi * np.sqrt(np.linalg.det(covmat_chunk))\n", + " return 1/area" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a neural network classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "from flax import nn\n", + "from flax import optim" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "nbins=2\n", + "# Here is a trivial classifier for 2 bins\n", + "class BinningNN(nn.Module):\n", + " def apply(self, x):\n", + " \"\"\"\n", + " Takes as an input the features to use for binning\n", + " \"\"\"\n", + " net = nn.Dense(x, 500, name='fc1')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc2')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc3')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " # The output of the model should be a gumbell softmax layer\n", + " return nn.softmax(nn.Dense(net, nbins))" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "@jit\n", + "def train_step(optimizer, batch):\n", + " def loss_fn(model):\n", + " w = model(batch['features'])\n", + " \n", + " return 1./FoM_DETF(w, batch['labels'])\n", + " loss, g = value_and_grad(loss_fn)(optimizer.target)\n", + " optimizer = optimizer.apply_gradient(g)\n", + " return optimizer, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's get some initial weights\n", + "_, initial_params = BinningNN.init_by_shape( rand.PRNGKey(0), [((1, 12), np.float32)])\n", + "model = nn.Model(BinningNN, initial_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "optimizer = optim.Adam(learning_rate=0.001).create(model)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as onp\n", + "batch_size = 5000\n", + "def get_batch():\n", + " inds = onp.random.choice(len(labels), batch_size)\n", + " return {'labels': labels[inds], 'features': features[inds]}" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [], + "source": [ + "losses = []" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype requested in astype is not available, and will be truncated to dtype int32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loss : 0.082741\n", + "Loss : 0.034619\n", + "Loss : 0.032469\n", + "Loss : 0.030701\n", + "Loss : 0.029780\n", + "Loss : 0.029895\n", + "Loss : 0.028904\n", + "Loss : 0.028402\n", + "Loss : 0.029422\n", + "Loss : 0.028546\n", + "Loss : 0.028567\n", + "Loss : 0.028745\n", + "Loss : 0.029307\n", + "Loss : 0.029505\n", + "Loss : 0.028731\n", + "Loss : 0.029062\n", + "Loss : 0.029456\n", + "Loss : 0.028111\n", + "Loss : 0.029254\n", + "Loss : 0.029030\n", + "Loss : 0.028546\n", + "Loss : 0.028672\n", + "Loss : 0.028209\n", + "Loss : 0.028525\n", + "Loss : 0.028569\n", + "Loss : 0.028465\n", + "Loss : 0.028751\n", + "Loss : 0.028193\n", + "Loss : 0.027388\n", + "Loss : 0.028440\n", + "Loss : 0.028882\n", + "Loss : 0.028365\n", + "Loss : 0.027255\n", + "Loss : 0.029375\n", + "Loss : 0.027457\n", + "Loss : 0.027656\n", + "Loss : 0.027917\n", + "Loss : 0.028244\n", + "Loss : 0.027760\n", + "Loss : 0.027672\n", + "Loss : 0.028509\n", + "Loss : 0.028216\n", + "Loss : 0.026999\n", + "Loss : 0.027938\n", + "Loss : 0.027820\n", + "Loss : 0.027959\n", + "Loss : 0.028084\n", + "Loss : 0.027936\n", + "Loss : 0.028269\n", + "Loss : 0.027375\n", + "Loss : 0.027988\n", + "Loss : 0.028952\n", + "Loss : 0.027801\n", + "Loss : 0.027517\n", + "Loss : 0.028212\n", + "Loss : 0.028704\n", + "Loss : 0.027859\n", + "Loss : 0.028038\n", + "Loss : 0.027359\n", + "Loss : 0.027605\n", + "Loss : 0.027820\n", + "Loss : 0.028344\n", + "Loss : 0.028213\n", + "Loss : 0.029190\n", + "Loss : 0.027842\n", + "Loss : 0.028516\n", + "Loss : 0.028345\n", + "Loss : 0.028616\n", + "Loss : 0.028527\n", + "Loss : 0.028457\n", + "Loss : 0.028649\n", + "Loss : 0.028257\n", + "Loss : 0.027986\n", + "Loss : 0.028186\n", + "Loss : 0.028515\n", + "Loss : 0.027159\n", + "Loss : 0.027894\n", + "Loss : 0.028938\n", + "Loss : 0.028104\n", + "Loss : 0.028077\n", + "Loss : 0.028151\n", + "Loss : 0.028668\n", + "Loss : 0.027535\n", + "Loss : 0.026811\n", + "Loss : 0.028016\n", + "Loss : 0.027758\n", + "Loss : 0.028673\n", + "Loss : 0.028277\n", + "Loss : 0.027811\n", + "Loss : 0.028761\n", + "Loss : 0.027651\n", + "Loss : 0.027972\n", + "Loss : 0.028059\n", + "Loss : 0.028788\n", + "Loss : 0.029010\n", + "Loss : 0.028531\n", + "Loss : 0.027501\n", + "Loss : 0.027884\n", + "Loss : 0.027875\n", + "Loss : 0.028836\n" + ] + } + ], + "source": [ + "for i in range(1000):\n", + " batch = get_batch()\n", + " optimizer, loss = train_step(optimizer, batch)\n", + " losses.append(loss)\n", + " if i%10 == 0:\n", + " print('Loss : %f'%loss)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot(losses[10:])" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "# Sweet :-D let's see if it did anything\n", + "w = optimizer.target(batch['features'])\n", + "nzs = [kde_nz(batch['labels'], w[:,i], bw=0.05, zmax=4.) for i in range(nbins)]" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "#figure(figsize=(13,7))\n", + "z = np.linspace(0,4)\n", + "nz_total = kde_nz(batch['labels'], np.ones_like(batch['labels']), bw=0.05)\n", + "plot(z, nz_total(z)*len(nz_total.params[0]))\n", + "for i, nz in enumerate(nzs):\n", + " plot(z, nz(z)*nz.params[1].sum(), '--', label='nz_%d'%i)\n", + "xlim(0,4)\n", + "legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "# Exporting the trained model\n", + "from flax import serialization\n", + "import pickle\n", + "\n", + "with open('BinningNN_3x2_2b_FoM_DETF.pckl', 'wb') as file:\n", + " pickle.dump(serialization.to_bytes(optimizer.target), file)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/LearningToBin-2bins-FoM.ipynb b/notebooks/LearningToBin-2bins-FoM.ipynb new file mode 100644 index 00000000..5b4c5325 --- /dev/null +++ b/notebooks/LearningToBin-2bins-FoM.ipynb @@ -0,0 +1,522 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Populating the interactive namespace from numpy and matplotlib\n" + ] + } + ], + "source": [ + "import sys\n", + "sys.path.insert(0, '..')\n", + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "%pylab inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found classifier IBandOnly\n", + "Found classifier NeuralNetwork\n", + "Found classifier Random\n", + "Found classifier RandomForest\n" + ] + } + ], + "source": [ + "# Import JAX instead of numpy\n", + "import jax.numpy as np\n", + "import jax.random as rand\n", + "from jax import jit, vmap, grad, value_and_grad\n", + "\n", + "# Import modified version of challenge metrics\n", + "from tomo_challenge import jax_metrics as metrics\n", + "\n", + "# Import tools from jax-cosmo\n", + "from jax_cosmo.redshift import kde_nz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "../tomo_challenge/data.py:76: UserWarning: Setting inf (undetected) bands to mag=30\n", + " warnings.warn(\"Setting inf (undetected) bands to mag=30\")\n" + ] + } + ], + "source": [ + "from tomo_challenge.data import load_data, load_redshift\n", + "from sklearn.preprocessing import StandardScaler, RobustScaler\n", + "features_scaler = RobustScaler()\n", + "\n", + "data = load_data('../data/training.hdf5','riz',colors=True, errors=True, array=True)\n", + "m = (data[:,0] <29) & (data[:,1] <29) & (data[:,2] <29)\n", + "data = data[m]\n", + "\n", + "features = np.clip(np.array(features_scaler.fit_transform(data)),-4,4)\n", + "labels = np.array(load_redshift('../data/training.hdf5'))[m]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(8552577, 12)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's grab some data\n", + "batch_size = 2000\n", + "# Let's grab some data\n", + "batch_labels = labels[:batch_size]\n", + "batch_features = features[:batch_size]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "nz = kde_nz(batch_labels, np.ones_like(batch_labels), bw=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 0, 'redshift z')" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "z = np.linspace(0,4)\n", + "hist(batch_labels, 64, density=True)\n", + "plot(z, nz(z), label='KDE nz')\n", + "xlim(0,4)\n", + "legend()\n", + "xlabel('redshift z')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD4CAYAAAAXUaZHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAmUUlEQVR4nO3de3Bc53nf8e+DXVyWuBAkAVKkSImUKMmmZVmSace52CNfEstuGrkzacaatFESz2jSOrc2rWMnM9H04pmkySRx0jZTNVItdTyyXdux1cRKZFFiZNcSZZICRRIUSBC8ACAILC6L69737R/nLLAAFrfdBRc4/H1mONjznvecfUgCz754z3sx5xwiIhIsNdUOQEREKk/JXUQkgJTcRUQCSMldRCSAlNxFRAIoXO0AANra2tz+/furHYaIyKZy4sSJYedce7FzGyK579+/n+PHj1c7DBGRTcXMrix1Tt0yIiIBpOQuIhJASu4iIgGk5C4iEkArJncze9rMhszszILy3zCzt83srJn9l4LyL5hZt5l1mdnH1yNoERFZ3mpGy3wZ+K/As/kCM/sw8AjwHudc0sx2+uWHgE8D7wL2AC+Z2d3OuWylAxcRkaWt2HJ3zr0KjC4o/lfAHzrnkn6dIb/8EeCrzrmkc+4S0A28v4LxiojIKpTa53438EEzO2Zm/2hm7/PLbwV6C+r1+WWLmNnjZnbczI5Ho9ESwxARkWJKTe5hYDvwAeDfA183M1vLDZxzTzrnDjvnDre3F51gJSIiJSo1ufcB33KeN4Ac0Ab0A/sK6u31y0Q2rOjwkWqHIFJxpSb3bwMfBjCzu4E6YBh4Hvi0mdWb2QHgLuCNCsQpIiJrsOJoGTN7DngIaDOzPuAJ4GngaX94ZAp4zHn79Z01s68DnUAG+KxGyoiI3HgrJnfn3KNLnPoXS9T/IvDFcoISEZHyaIaqiEgAKbmLiASQkruISAApuYuIBJCSu4hIACm5i4gEkJK7iEgAKbmLiASQkruISAApuYuIBJCSu4hIACm5i4gEkJK7iEgAKbmLiASQkruISAApuYuIBJCSu4hIAK2Y3M3saTMb8rfUW3jud8zMmVmbf2xm9hdm1m1mb5nZg+sRtIiILG81LfcvAw8vLDSzfcDPAFcLij+Btyn2XcDjwF+VH6LI+urv66erq6vaYYhU1IrJ3Tn3KjBa5NSfAZ8DXEHZI8CzzvM60GpmuysSqYiIrFpJfe5m9gjQ75w7teDUrUBvwXGfX1bsHo+b2XEzOx6NRksJQ6QiMsNxUr2T1Q5DpKLWnNzNbAvwe8AflPPGzrknnXOHnXOH29vby7mViIgsEC7hmjuBA8ApMwPYC5w0s/cD/cC+grp7/TIREbmB1txyd86dds7tdM7td87tx+t6edA5dx14Hvglf9TMB4Bx59xAZUMWqaytI53VDkGk4lYzFPI54DXgHjPrM7PPLFP9u0AP0A38T+BfVyRKERFZkxW7ZZxzj65wfn/Bawd8tvywRESkHJqhKiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkBK7iIiAaTkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkBK7iIiAaTkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkCr2WbvaTMbMrMzBWV/bGZvm9lbZvY3ZtZacO4LZtZtZl1m9vF1iltERJaxmpb7l4GHF5R9D7jXOXcfcB74AoCZHQI+DbzLv+a/m1moYtGKiMiqrJjcnXOvAqMLyl50zmX8w9eBvf7rR4CvOueSzrlLeBtlv7+C8YqIyCpUos/9V4EX/Ne3Ar0F5/r8MhERuYHKSu5m9vtABvhKCdc+bmbHzex4NBotJwwREVmg5ORuZr8M/Czwi8455xf3A/sKqu31yxZxzj3pnDvsnDvc3t5eahgiIlJEScndzB4GPgf8nHNupuDU88CnzazezA4AdwFvlB+miIisRXilCmb2HPAQ0GZmfcATeKNj6oHvmRnA6865X3POnTWzrwOdeN01n3XOZdcreBERKW7F5O6ce7RI8VPL1P8i8MVyghIRkfJohqrc9LonagGId45UORKRylFyFxEJICV3uen101DtEEQqTsldRCSAlNxFRAJIyV0EeDaarHYIIhWl5C4iEkBK7iIiAaTkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkBK7iJAhgFGE9+vdhgiFaPkLiISQEruIiIBpOQuIhJAKyZ3M3vazIbM7ExB2XYz+56ZXfC/bvPLzcz+wsy6zewtM3twPYMXKUd0+AjR4SMAvGuqg4brb1Y5IpHKWU3L/cvAwwvKPg8ccc7dBRzxjwE+gbcp9l3A48BfVSZMkfU3OhmrdggiFbNicnfOvQqMLih+BHjGf/0M8KmC8med53Wg1cx2VyhWkYpKXZ3kSkd3tcMQWRel9rnvcs4N+K+vA7v817cCvQX1+vwyERG5gcp+oOqcc4Bb63Vm9riZHTez49FotNwwRESkQKnJfTDf3eJ/HfLL+4F9BfX2+mWLOOeedM4dds4dbm9vLzEMEREpptTk/jzwmP/6MeA7BeW/5I+a+QAwXtB9I7LhFY6gEdnMwitVMLPngIeANjPrA54A/hD4upl9BrgC/IJf/bvAJ4FuYAb4lXWIWUREVrBicnfOPbrEqY8WqeuAz5YblIiIlGfF5C4SVA3X32TrZAxornYoIhWn5QdECtRd+lG1QxCpCLXc5aZ1JlPHFI3VDkNkXajlLiISQGq5ixTIROOkQpPQVu1IRMqjlruISAApuYuIBJCSu4hIACm5i/jO08iZTF21wxCpCCV3Ed/ARA19Y2te4FRkQ1JyF1lCvHOEeOdItcMQKYmSu4hIACm5i4gEkCYxyU2rb8wRT6l9I8Gk72wRkQBSchcp4ulTnbyUjFc7DJGSKbmLiARQWcndzP6NmZ01szNm9pyZNZjZATM7ZmbdZvY1M9OsEBGRG6zk5G5mtwK/CRx2zt0LhIBPA38E/Jlz7iAwBnymEoGKiMjqldstEwYiZhYGtgADwEeAb/jnnwE+VeZ7iIjIGpWc3J1z/cCfAFfxkvo4cAKIOecyfrU+4NZygxQRkbUpp1tmG/AIcADYAzQCD6/h+sfN7LiZHY9Go6WGIVJR8VSCgdHBaochUrZyumU+BlxyzkWdc2ngW8BPAq1+Nw3AXqC/2MXOuSedc4edc4fb29vLCEOkMjKpVLVDEKmYcpL7VeADZrbFzAz4KNAJvAL8vF/nMeA75YUoIiJrVU6f+zG8B6cngdP+vZ4Efhf4t2bWDewAnqpAnCIisgZlrS3jnHsCeGJBcQ/w/nLuK1JtmWgcdrRUOwyRkmmGqohIACm5i4gEkJK7iEgAKbmLiASQkruISAApuYsUcSGaqHYIImVRchdZRve1S3R1dVU7DJE1U3IXEQkgJXeRTeJo71GO9h6tchSyWSi5iyxhKnWWJCdI9U4S7xypdjgia1LW8gMiQbR1pJN3Tk0D76p2KCIlU8tdRCSAlNxFlrBn8Hi1Q5inozdGR2+s2mHIJqFuGbnp3YhNOl7q9HZ3+tihXev+XiKg5C5SVI5RIHLD3zf/IQD6IJDyqFtGZAWvYbOvo8NHiA4fqWI0Iquj5C4iEkBlJXczazWzb5jZ22Z2zsx+3My2m9n3zOyC/3VbpYIVuRG6J2qrHYJI2cptuX8J+Hvn3DuA9wDngM8DR5xzdwFH/GORDSeZiK/qYWqabkYT398w3TELZ6q+1Dk4r69eBMpI7ma2FfgQ/gbYzrmUcy4GPAI841d7BvhUeSGKVMdUfJqtI53sHzm1bu9RiSUFzsRe40zstUqEIwFSTsv9ABAF/peZvWlmf21mjcAu59yAX+c6oEf+IiI3WDnJPQw8CPyVc+4BYJoFXTDOOQe4Yheb2eNmdtzMjkej0TLCEBGRhcpJ7n1An3PumH/8DbxkP2hmuwH8r0PFLnbOPemcO+ycO9ze3l5GGCKrN/nyKyvW6adhUdkPrlmRmpWzbv3mXS94f+SmU3Jyd85dB3rN7B6/6KNAJ/A88Jhf9hjwnbIiFKmi8zQC0NDzIv19/fT39d+4N1diljKUO0P1N4CvmFkd0AP8Ct4HxtfN7DPAFeAXynwPERFZo7KSu3OuAzhc5NRHy7mvSLVlUil6hyFcV8fulpxXNhxne7qbuvQ1aFv/b/H8ImH337N8PZFitLaMyCoMhBrpo5VPFJTlN/CIHNpR0fdqu/Zy0fKWkbe8F/s+VNH3k2BSchdZRiaVIpVMA7UkpieZmh5hR1tlkzn9J2ibGli5nsgaKLmLrGBw0luO4I7xs2v7iel6gY7eGMN7PrI+gS2gZYWlkBYOExEJILXcRQJitq8+1Ar3fGLZuhJ8Su5y03KJJITn//K6ll2ZBi9PALC/yAPViyeOQd8laNwgi6Lmx8sr6d80lNxFSvTDkUkA9i+TOKNX+piY7GDrPfcDXtK/s2l0yfpFLTWRSROcZBnqcxcRCSC13EXWaGygn+ETx5gaHZ9XfvHEMe58748BMHhpAkZquDA6SbL+bd7N/QCcjp6hNx2jdWoPw9lBws3etSfjF2bv82DkrnllsbHGonHkJzm15K/1rxMBtdxF1sQSYJNFFzrdMDp6Y9q8Q9RyF1mNdC5FMpOcPT4dPUMs2UJr/dai9a9MXIHE3FLW+c003PAUW9PTwAW4eIE72huJXRwmNZGgbu/qHr72dLwKzLXwRYpRy11EJIDUchcBXDqF1dat6RqL9JGpHaWjtwWA5m3by94yr5ie6HTF7ynBp+QuUqbolT4AmrfdUZH7FT5cLcfR3qMw1slD2w5V5H6yuSi5S+Att/uSSy8/aSmdW3x+IjkDQCKdxWUzUAtTo2Fef2OA6Hu81Rsjk3M7N0UmL1M3Ms7EjvtK/BsUt/BDIH+svngB9bnLTeqlzkGSqRzpDGSykM2kIesl8lQ2RyqbW/b6kM1PrAOZMYaSfbieK6T6xpa8rqWnb95xT3Sa6xOJEv8WpZl8+ZVVbTcom5uSu4hIACm5i5Roq13jzvQ5RuMZklmojw8Rmby8qN7OmVtoH51bfyY7uB2AVN/YbCu/6epIxePr6I3RE52enewkN5eyk7uZhczsTTP7W//4gJkdM7NuM/uav7+qyLq69NbwqutOvvwKDT/6YUXfv3lbH42tfXQ17aWraW9J9yhM9uVqu/by3M5NclOqRMv9t4BzBcd/BPyZc+4gMAZ8pgLvIbKiS28NL5nkr1y+uOL1Lp1Z9gFrdLqenqnI7LHlMmQy08QnQ7NlW8d3sXW8tM0ycrFmcrHmkq4tZltnP9s6+yt2P9lcykruZrYX+CfAX/vHBnwE+IZf5RngU+W8h4iIrF25QyH/HPgckG9u7ABizrmMf9wH3FrsQjN7HHgc4LbbbiszDJHyZXIGuSxWmyPrsqRzBqHlf0SG6lpoTsH5+G5sVwORceiN17Izk75BUYsUV3LL3cx+Fhhyzp0o5Xrn3JPOucPOucPt7e2lhiGyyLzuma4XoL+kb9ElvZ1t4rVYO1nmLyBWOHqyq/UWItFJLtds5a2tc9/fke1Lb4QdiU4SiU5WNFaAmtNdFb+nbHzltNx/Evg5M/sk0AC0AF8CWs0s7Lfe9wLq9JMNo/eal5CvTL9NlizmchjLjGnPZuYfr9AcyjRdIzmzlyb/uIVtFN7h1uR1Eu4c/ayuXz7/gHW1i4oVczE1wNTLL/Duptto1k5MN42SW+7OuS845/Y65/YDnwZeds79IvAK8PN+tceA75QdpYiIrMl6LD/wu8BXzew/A28CT63De4isaPLlV6D/7Jqvs0wW/AEwLuctI2AuSy7nuFLfCFOOxJbsbP2D6SvUZSbITtcDcJniQyF3X69dcyylGr1WR2JmDw1brt2w95SNpSLJ3Tl3FDjqv+4B3l+J+4oUym9A8bFDc10aaxnfvpysy+EchKymoMyB85N7zvlfU5AztizzvPSBzFtkJuYq1IRHycV2zg07WG1Mg9vJxTLUtK6tH/5k/ALZ1PbZriG5OWmGqgTSqasxTi0xM3Pw+kUSw6NFz2Vdjqxbfl2ZhcKN1wEYiUcYic+Ng6/ZHSW5bW5HJBsOkcvcuNa73NyU3EVEAkjJXW4qg5fOEBu8Mq/MuRqcm/+jYJkclsnNjm9ceP6emfOrfs+7Z86zK3V6Xln76A52ztyyltDnyQ5un12jRqQYJXeRNci6LNnlhk4CofppQuH4DYqoMrQEcPBosw4JlFNXY4vKeke3QrobamPA6taxW9hSny3LzS/PkiNFZlHdYurjQ4QKNtkGCtaSWd2qkMu11vPryIwdKjopHFASv5mo5S6BcSZ6mivTby95/h8vn+Py2CVi2bk9SUt5gDp38dLXhQlxR2YcgDQ5cjPTZMZja7p9U+/I7IzVc6FdnAstnvhULNlHjjuaeot/WLx6amrJB80SLEruIiIBpG4Z2XCO9h4F4KF9D62q/pnoaRjt9o92A1B74RzdyetMkuL2yNLXrlk2B6Eaf8jj8i3+3kwrvdPN3F0P4ekUddk4bIdQ73XCNdtItzfPrSVTP//aVN8Y5p/aE04yPOV13+yczjDUOFH0/RIze5aN5/TUVaLJRrYy9yBX3TTBpZa7bDz9J7w/XS9UO5KK22JNtLD8OjGJMxnaowdos7kknJuKkJsq/1OqPj5Ey+ipsu8jG59a7rI5zSb+9wFwfdx/UFmBvS6KPUxdTm+ydf7iY37rfqFTO9uJN7SzP+Ydh1uuEEmPER+aS+KRnddhCGhtKyHypQ1OJFeuJIGilruISAApuUugxeJpBifiXBgMEx1rmS3PxhtvWAwj8QjdzUlqWodmy8ZqjNSkNxa+zW6hrS3ktdp9ZzNbZl/PJGqom4hzaOQYAOenI6Sjc/daq4upAU4Pz02qyi+DLMGibhmpuqUeoHb0xhjODs5bKGy2/lgnAJPTDeseX0myueKvizi1s50HM1eABC22jZZdSa7VXIfpxevQjKemoW599pzPP1xt/siH1+X+cmMpuUvV5JP6WnX0xmgZmeaO9tJb37XJcdIuS3blqostSNzRcJP3k7RCEs+raR0iXBsml60HEiS3DdI80suENTFV490jlMgAxRcZ225j9NVlOeAfJ854k6gihIrWX4pGygSbumVERAJILXfZsE7GLzARi/AxPgXAVI838Numw7Cl+DVbJi8TnbxMbXJtrdj1cn/6XNHyVH2KuuTK3Sv7wlcZ9sfuF9PUO8Jo3F/HJjK3gvv27A4AZlh6s458v3sr964Yh2w+arlL1fV0vEpPx6vVDmNpq+xuWWiovmXe64OJCwDEzXuAuTvTz56st977lcb5m8Qnarw6C8fEW3QMG58iPLP00MY9XJx9Hd4anfenVBdPHOPiiWMlXy83XsktdzPbBzwL7AIc8KRz7ktmth34GrAfuAz8gnNurPxQJejyOy0t/Kac65uf274uO7idyUQ90M1m05tpLVqeDIWI4CX9Tn8D7UutLfw9BzmYTJDNpubVr8n1McXyD5S3ZHYwE56/zkxiZg/jw81sbVvbDk+yuZTTcs8Av+OcOwR8APismR0CPg8ccc7dBRzxj0W8iUdrnHXaMvKWN1t1jerjQ9THveGC1zNj8xYLq5ZoMkI0ufQs067UHjpTXlK/O9dDPNzHkL9z05WU14XTuXPnbP3szDRnmlsX3ae2eRjbcZFTuQgnp/aTSs0tLla3o5e6Hb2M15zl0vD8f5Mrly9y5fLFhbeTTark5O6cG3DOnfRfTwLngFuBR4Bn/GrPgN9hKiIiN0xFHqia2X7gAeAYsMs5N+Cfug4sXqfUu+Zx4HGA2267rRJhSED0RIu0svtP0DLqdS9sSXnfXrNLDmwSabx+9KH6FkhATaYV8BYXuycE78hdJkw91Hh1ckQAB5n5ff6XmtpJumb2chmA8zu99ds/MDm+6lhqUzHq45PQ9i7Am8gUHXW0b7fZOhdPHOPi7e/gZ9q2lvx3Xkm+H//O9/7Yur3Hzars5G5mTcA3gd92zk2YzX1zOOecmRWd/uacexJ4EuDw4cOaIie0XXsZgKsLyvPJfv8K1xeuYZ6YjAHQUKTbYqO5P30OQhCt30aIMPuysaL1hjK1tGfPs7d+hrdq30lT1hsytIX8KJlxzuzYhQvt5J3TVznYGOMiByEXoT5+O5OhSdIzcx+c8aFbaGhupnNnLT+RSBd9z4Hu81y8Mv/D5aXOQe7MeKORDty3ujVwlMRvvLKSu5nV4iX2rzjnvuUXD5rZbufcgJntxlsGSW5iR3uP0tEb46GZOPfva53rd9+ytlUOL6YGVq60QD7JbyZXGtshUfxcTf00xdLwOzJn2Z69k5bG6aLXnkq2cceWuQeoZ1rvJBONMJ6KYTNnGByaSwWTL78yb5bqD9Je7+1P1Za4qYlURcl97uY10Z8Czjnn/rTg1PPAY/7rx4DvlB6eiIiUopzRMj8J/EvgI2bW4f/5JPCHwE+b2QXgY/6xyGL5ddsFgJD/i/RwYvFvNOmmGNmGqXllw6kQY0lvstJI2htVE7fs7I6uuezc3q5xsiQo3vt5cXLu/aKjruhCYqnYhbnXvfOHUL44PM6Lw6vv75cbo+RuGefcDwBb4vRHS72v3LxOxi+sXClACic5FVNTv/zwzVBogvszp9mRSTNCLaO2+AHzndlubkmPcZZ2ziVu4Z2p8+wLjZBO1HCWQ2SSCaiFE1u9h6bvHfeTdNcLwHaS2W6mYynCCaB90e1XbSZ9gi21711U3nvdm9twZ5Fr1E9fHi0/IDfcUX9Fx6KjYpawrbOfxIxjat+O9Qprw1pqCQPwPgBCDXFqEhFub/g+bqaNzFJNLiBrS59sSEdoTK5uKbWB82/6rx7geirOtpDBGkbVdLz0nPf8RdaNlh8QEQkgtdzlhurojdETr9xs0fzwx3yLfjOOjoHi/ezLSeJmx83nXY7MDUu8lG4BMiynZvs4qexW0pks1EHMeQuQRSa/zgvndzLU/k+xSed1yQBHfjDOsc63iIcnScVHAW878rH+HqanjVeHBvjQx99HvNP7P4kcWvq3rLGBfgaSg8Ada/p7y+opuUvl5Yc63vOJecXr1aeemIwR7owtNXow8Ip9MPTVN7FnJjZ7nMtmCWfDhKnnZPggeyzLvbkBwhalKR3lyswD3J96m9YcJBLTxKcmGa6NQXKGOn9d+Uz9JWLTl5icaGOH/zkSe+MUdVu88+Ojf8fp139EU/QBAA4c+nH+75t9AAxkt/HR4svTA9DV1cU999xT/j+GzFJyl/XT9QIdvTE61jieHbw+9rFD3szL7OB2EjOLR3AUTlqSuSTf1hCfLRuobWSm3qBwzTGr5VqyFuobqMUwV9KWJUXFBuM01cCliWMc4Mdny2+LvsXVyX4uRfbP21mrZnTx/+vFE8d46mqae3bXa2x9GdTnLrIJLfeQdWimnlwuR8rmljy4O9fD3bmeFe97vqmB7mQjTCRovPg9GvvOA3AxNrf2/MHQS+zJ/i1npkK8OBqje8Lr/jlVfwvbx7uIxF4H4Iff+B5954q854LF496ctHnlM+mlh8d2dXWt+HcQj5K7iEgAqVtGNpTsoLc8bWLGETnutTqn9lUzos1vOBGB+gg7kxOLzqVxhDDeE/o+xQayZzM5ptJx4hnHVDpOY87rQ7883chdmQ5e3nqQSDgF3MpdE51Mp+O47Dh9NPG+5HFuz9SS5Q6ujdWw1wY4e+L/YFtzi1qV8fgxTp/tYcuU9/8/MT0N1M+r88r//hNydQ3qm18lJXdZF7Nj2ePTtMRXqLxG6msvLpcrvX96OBGhHZh2KYZrG2jPJskWrEZ5X+IMt2SmuR6e25R8qCHBfYkzXGjyJicNj9cxzC521taQTmW5sCVM2B+wk5pJEw8luINzpJtbqMmmSGZTbJ+OAQ+SGY4X3d77B+maohOcFnpxeHxdV6/cjJTcZbGuF7zkfOt7eWjfQ0Wr/PkPvw3Ab//Ep4C53ZKWql9MdnA7oV2jK9YrTOZK7Ku30gzYQmFCjKRqCIVqqFlmVEteKGvUFMyHytRfmm2ND8WhIQTRUe/DoXagf9618YkEg9O13O3vIXIgeZLopSlSmSaOXU3zaMGWsclsN0f/boAdsZNMTEHTdm/nqfzs1UxTK69fnWb3A/5HQNcLi0ZpAasanhk06nMXEQkgtdxlSR29MTKTg/OGri00u+9p89xx27W1T1TK97XLjZd1Xgu7pn56Xms87+BkJ0PMjZYp7JpZjZbrR5gBrpl3nfnrjk0OT2N4LelUPA7ESU9f442BCM6GiI73ArAj5o2QuVYzw4FMPx0vPceu5CDDsRh1hx8FINk7SXwoQ6RY3w7Qfe0SAO/2W+7R4SMAtLcFdxksJfdNJp9Ml0u4pdzzTOy1ubU+/P7yWf4QtY7e2OxEpPwv/G0zcYb3fMQ76D9B29Ta11zPWzjbdCmbdRZqta2lmyYar5/NDkMzdctXLiKRnVvErH8MQg1gCybM9kxFgChFO9sLXKgZZ3CiFstAcmSCq0NdhCPeqoXx+DH2jk7QnNlKd+07aR65wP57PkFHx7PcuvdWmobuX3PsQaFuGaHt2sveRtRFnIm9NvtwtJiT8Qucib225Pns4PbZVnn+dWGZbH7xTJKpdHlPzQdCjQyEGomnk5yc8T5V7hg9yx2jZxmcWPwQ4GIqiqub27NranSE/9f5D5yfmP8JUnPtCDXXvFZ688gPufy1v5h/oyU2bO/q6tr0Y+qV3EVEAkjdMtW2xDosS8nvM8qhR9f8Ph29MYb3fGTFLp38UrwteK35HqB1Kraqtxm95v0Kn03Nb5kv1VJP9Y0BEKqdO7/UiBh1x9xgmfmtYJdKL5kxLo83cF/+IDwBmZa510B+35BQuMY/ztFHhFC4ht3Zuecz986cxvlLJVgEnN9oz3fpDIQaITQDNJIL1zGYaqYhE6NmMgOhcXpS4zz17BN8uH2GuvQ14A6+0X+eybo4Dxc0Zesu/QiAkWicxHSSH7ZuZ2vLe/jgUGbRiJrC/vn8a4DU1Um2N3xww47AUXKvovzDx1jTNeiNrGkYIcwNPwRo7fL6uvP95kf99Vwyk+8EoO1azP/6MoRaOTrWuWg99Z6OV9f8dwBoGXmLHj8fZ9ewz2k6OgR4T2JDZWwEITdQJgPh+WnjvsSZVV9eOHY+f5zJ5Mi63GzizyfywUkvsy+1Av3gZC2nL0xx71Qf9TbXdZOKxzl9ZYbWdCuR2iTJRJzd42/ALm/yU3T4CF0zYfbMDLKVLbPXjU+cYubyEU5Em9kzM8jE7nfz4vAtjPvdQg/hJfbU1fk7UZVqvYdnrltyN7OHgS/hPS75a+fcumy3l3/ACAUPGVcxTrscpYzpLlQY83L3LXbcE7/Ag5G7/IegMe6vuQjASX90SmzMH8mwxZtYku8PbylYkfHk+dXHmm9xn9xVuRUdw51ezOn2ZiJR7welIeE9VVPrfOMarGvyXhS26MNLpJDw4tmwS1k4+salU1jt/Ie4+Q+F/AdAnqW8D4NU0W3DIZ72+uUHQo0MDHuza29/bRiALiJscXUcBHae+T4AZ6hjZmKCLiL0DNezPfk64fYIQz0DXCHG7fcfBKDh+pskbnmA7muXSF77Brfff3B25E0+aedFDu2oyjj7dUnuZhYC/hvw00Af8CMze945t/STuQ2g6AcFzHZp5HVsiXgtZL9L5eiWCB29MR6aiXP/vtbZVvNqk39PdBqic63mfCu8J36BiR330dH77dkkDv7SuRcveCNW2hsX3wtm77f68RHLW9itEto1OluWn4i03EPSpt6RRYk7n9hlE8sn+oVJvkgLf179vII6s636LGC5+Yncvy5LeF75vTOn510fCtd4Lf8snOstvq/rlasJdjV7HwY1tSky515iKtzCwIR3390tfhwR2DN4HAZhaMtBto500t8XIXx9kt3AwOgg4OWM1NVJ+q9+m+0NH5x9n9GE94FRN9xMKuF/r5/0vhTWWy/r9UD1/UC3c67HOZcCvgo8sk7vJSIiC6xXt8ytQG/BcR8wb5dbM3sceNw/nDKzzTLuqA0YrnYQJdisccPmjV1x33ibNfZS4759qRNVe6DqnHsSeLJa718qMzvunDtc7TjWarPGDZs3dsV9423W2Ncj7vXqlukHChdq3euXiYjIDbBeyf1HwF1mdsDM6oBPA8+v03uJiMgC69It45zLmNmvA/+ANxTyaefc2fV4ryrYdF1Jvs0aN2ze2BX3jbdZY6943Obc4g1qRURkc9PaMiIiAaTkLiISQEruJTCz/2Rmb5lZh5m9aGZ7qh3TapjZH5vZ237sf2NmrdWOaTXM7J+b2Vkzy5nZhh/mZmYPm1mXmXWb2eerHc9qmdnTZjZkZqtfLGYDMLN9ZvaKmXX63ye/Ve2YVsvMGszsDTM75cf+Hyp2b/W5r52ZtTjnJvzXvwkccs79WpXDWpGZ/Qzwsv/A+48AnHO/W+WwVmRm7wRywP8A/p1z7niVQ1qSv/TGeQqW3gAe3ehLbwCY2YeAKeBZ59y91Y5ntcxsN7DbOXfSzJqBE8CnNsm/uQGNzrkpM6sFfgD8lnPu9XLvrZZ7CfKJ3dcIbIpPSOfci865/OIer+PNP9jwnHPnnHObZQbzpl16wzn3KrDyjuUbjHNuwDl30n89CZzDmyW/4TnPlH9Y6/+pSD5Rci+RmX3RzHqBXwT+oNrxlOBXgeLb0Eg5ii29sSkSTRCY2X7gAeBYlUNZNTMLmVkHMAR8zzlXkdiV3JdgZi+Z2Zkifx4BcM79vnNuH/AV4NerG+2cleL26/w+kMGLfUNYTdwiyzGzJuCbwG8v+O16Q3POZZ1z9+P9Jv1+M6tIl5g261iCc+5jq6z6FeC7wBPrGM6qrRS3mf0y8LPAR90GeuCyhn/vjU5Lb1SB31/9TeArzrlvVTueUjjnYmb2CvAwUPZDbbXcS2BmdxUcPgK8Xa1Y1sLfQOVzwM8552aqHU9AaemNG8x/KPkUcM4596fVjmctzKw9P2rNzCJ4D+Irkk80WqYEZvZN4B68ERxXgF9zzm341pmZdQP1QH6rmNc3ySiffwb8JdAOxIAO59zHqxrUMszsk8CfM7f0xherG9HqmNlzwEN4y88OAk84556qalCrYGY/BXwfOI33Mwnwe86571YvqtUxs/uAZ/C+V2qArzvn/mNF7q3kLiISPOqWEREJICV3EZEAUnIXEQkgJXcRkQBSchcRCSAldxGRAFJyFxEJoP8PrUU6Yrk54hsAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for i in range(12):\n", + " hist(batch_features[:,i],100, alpha=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "import jax_cosmo" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in asarray is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n", + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in array is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + } + ], + "source": [ + "ell, delta_ell = metrics.ell_binning()\n", + "\n", + "@jax.jit\n", + "def FoM(weights, labels=batch_labels, inds=[0,4]):\n", + " \n", + " # Retrieve the probes\n", + " probes = metrics.get_probes(weights, labels)\n", + " \n", + " # Compute the derivatives of the data vector\n", + " @jax.jit\n", + " def mean(params):\n", + " cosmo = jax_cosmo.Cosmology(\n", + " Omega_c = params[0],\n", + " Omega_b = params[1],\n", + " h = params[2],\n", + " n_s = params[3],\n", + " sigma8 = params[4],\n", + " Omega_k=0.,\n", + " w0=-1., wa=0.\n", + " )\n", + " return jax_cosmo.angular_cl.angular_cl(cosmo, ell, probes)\n", + "\n", + " # Compute the jacobian of the data vector at fiducial cosmology\n", + " fid_params = np.array([0.27, 0.045, 0.67, 0.96, 0.840484495])\n", + " jac_mean = jax.jacfwd(lambda x: mean(x).flatten())\n", + " \n", + " mu = mean(fid_params)\n", + " dmu = jac_mean(fid_params)\n", + " \n", + " # Compute the covariance matrix\n", + " cl_noise = jax_cosmo.angular_cl.noise_cl(ell, probes)\n", + " C = jax_cosmo.angular_cl.gaussian_cl_covariance(ell, probes, mu, cl_noise)\n", + " \n", + " invCov = np.linalg.inv(C)\n", + " print(invCov)\n", + " \n", + " # Compute both terms of the Fisher matrix and combine them\n", + " #t1 = 0.5*np.einsum('nqa,ql,lmb,mn', dc, invCov, dc, invCov)\n", + " t2 = np.einsum('pa,pq,qb->ab', dmu, invCov, dmu)\n", + " F = t2 #t1+t2\n", + " \n", + " # Compute covariance\n", + " i,j = inds\n", + " covmat_chunk = np.linalg.inv(F)[:, [i, j]][[i, j], :]\n", + " \n", + " # And get the FoM, the inverse area of the 2 sigma contour\n", + " # area.\n", + " area = 6.17 * np.pi * np.sqrt(np.linalg.det(covmat_chunk))\n", + " print(\"allgood\")\n", + " # Actually, maybe we should just return the AREA, which a quantity we want to optimize\n", + " return area*10000. #np.linalg.det(covmat_chunk)/9.277426e-09" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a neural network classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from flax import nn\n", + "from flax import optim" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "nbins=2\n", + "# Here is a trivial classifier for 2 bins\n", + "class BinningNN(nn.Module):\n", + " def apply(self, x):\n", + " \"\"\"\n", + " Takes as an input the features to use for binning\n", + " \"\"\"\n", + " net = nn.Dense(x, 500, name='fc1')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc2')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc3')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " # The output of the model should be a gumbell softmax layer\n", + " return nn.softmax(nn.Dense(net, nbins))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "@jit\n", + "def train_step(optimizer, batch):\n", + " def loss_fn(model):\n", + " w = model(batch['features'])\n", + " \n", + " return FoM(w, batch['labels'])\n", + " loss, g = value_and_grad(loss_fn)(optimizer.target)\n", + " optimizer = optimizer.apply_gradient(g)\n", + " return optimizer, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's get some initial weights\n", + "_, initial_params = BinningNN.init_by_shape( rand.PRNGKey(0), [((1, 12), np.float32)])\n", + "model = nn.Model(BinningNN, initial_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "optimizer = optim.Momentum(learning_rate=0.001, beta=0.9).create(model)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as onp\n", + "batch_size = 5000\n", + "def get_batch():\n", + " inds = onp.random.choice(len(labels), batch_size)\n", + " return {'labels': labels[inds], 'features': features[inds]}" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "losses = []" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype requested in astype is not available, and will be truncated to dtype int32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + } + ], + "source": [ + "for i in range(1000):\n", + " batch = get_batch()\n", + " optimizer, loss = train_step(optimizer, batch)\n", + " losses.append(loss)\n", + " if i%10 == 0:\n", + " print('Loss : %f'%loss)" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot(losses[10:])" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": {}, + "outputs": [], + "source": [ + "# Sweet :-D let's see if it did anything\n", + "w = optimizer.target(batch['features'])\n", + "nzs = [kde_nz(batch['labels'], w[:,i], bw=0.05, zmax=4.) for i in range(nbins)]" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 70, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "#figure(figsize=(13,7))\n", + "z = np.linspace(0,4)\n", + "nz_total = kde_nz(batch['labels'], np.ones_like(batch['labels']), bw=0.05)\n", + "plot(z, nz_total(z)*len(nz_total.params[0]))\n", + "for i, nz in enumerate(nzs):\n", + " plot(z, nz(z)*nz.params[1].sum(), '--', label='nz_%d'%i)\n", + "xlim(0,4)\n", + "legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "# Exporting the trained model\n", + "from flax import serialization\n", + "import pickle\n", + "\n", + "with open('BinningNN_3x2_2b_FoM.pckl', 'wb') as file:\n", + " pickle.dump(serialization.to_bytes(optimizer.target), file)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/LearningToBin-3bins-FoM-DETF.ipynb b/notebooks/LearningToBin-3bins-FoM-DETF.ipynb new file mode 100644 index 00000000..698bc791 --- /dev/null +++ b/notebooks/LearningToBin-3bins-FoM-DETF.ipynb @@ -0,0 +1,646 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Populating the interactive namespace from numpy and matplotlib\n" + ] + } + ], + "source": [ + "import sys\n", + "sys.path.insert(0, '..')\n", + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "%pylab inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found classifier IBandOnly\n", + "Found classifier NeuralNetwork\n", + "Found classifier Random\n", + "Found classifier RandomForest\n" + ] + } + ], + "source": [ + "# Import JAX instead of numpy\n", + "import jax.numpy as np\n", + "import jax.random as rand\n", + "from jax import jit, vmap, grad, value_and_grad\n", + "\n", + "# Import modified version of challenge metrics\n", + "from tomo_challenge import jax_metrics as metrics\n", + "\n", + "# Import tools from jax-cosmo\n", + "from jax_cosmo.redshift import kde_nz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "../tomo_challenge/data.py:76: UserWarning: Setting inf (undetected) bands to mag=30\n", + " warnings.warn(\"Setting inf (undetected) bands to mag=30\")\n" + ] + } + ], + "source": [ + "from tomo_challenge.data import load_data, load_redshift\n", + "from sklearn.preprocessing import StandardScaler, RobustScaler\n", + "features_scaler = RobustScaler()\n", + "\n", + "data = load_data('../data/training.hdf5','riz',colors=True, errors=True, array=True)\n", + "m = (data[:,0] <29) & (data[:,1] <29) & (data[:,2] <29)\n", + "data = data[m]\n", + "\n", + "features = np.clip(np.array(features_scaler.fit_transform(data)),-4,4)\n", + "labels = np.array(load_redshift('../data/training.hdf5'))[m]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(8552577, 12)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's grab some data\n", + "batch_size = 2000\n", + "\n", + "batch_labels = labels[:batch_size]\n", + "batch_features = features[:batch_size]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's build an n(z) using a KDE\n", + "nz = kde_nz(batch_labels, np.ones_like(batch_labels), bw=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 0, 'redshift z')" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "z = np.linspace(0,4)\n", + "hist(batch_labels, 64, density=True)\n", + "plot(z, nz(z), label='KDE nz')\n", + "xlim(0,4)\n", + "legend()\n", + "xlabel('redshift z')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Checking normalization of features\n", + "for i in range(12):\n", + " hist(batch_features[:,i],100, alpha=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "import jax_cosmo" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in asarray is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n", + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in array is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + } + ], + "source": [ + "ell, delta_ell = metrics.ell_binning()\n", + "\n", + "@jax.jit\n", + "def FoM_DETF(weights, labels=batch_labels, inds=[5,6]):\n", + " \n", + " # Retrieve the probes\n", + " probes = metrics.get_probes(weights, labels)\n", + " \n", + " # Compute the derivatives of the data vector\n", + " @jax.jit\n", + " def mean(params):\n", + " cosmo = jax_cosmo.Cosmology(\n", + " Omega_c = params[0],\n", + " Omega_b = params[1],\n", + " h = params[2],\n", + " n_s = params[3],\n", + " sigma8 = params[4],\n", + " Omega_k=0.,\n", + " w0=params[5], wa=params[6]\n", + " )\n", + " return jax_cosmo.angular_cl.angular_cl(cosmo, ell, probes, nonlinear_fn=jax_cosmo.power.halofit)\n", + "\n", + " # Compute the jacobian of the data vector at fiducial cosmology\n", + " fid_params = np.array([0.27, 0.045, 0.67, 0.96, 0.840484495, -1., 0.])\n", + " jac_mean = jax.jacfwd(lambda x: mean(x).flatten())\n", + " \n", + " mu = mean(fid_params)\n", + " dmu = jac_mean(fid_params)\n", + " \n", + " # Compute the covariance matrix\n", + " cl_noise = jax_cosmo.angular_cl.noise_cl(ell, probes)\n", + " C = jax_cosmo.angular_cl.gaussian_cl_covariance(ell, probes, mu, cl_noise)\n", + " \n", + " invCov = np.linalg.inv(C)\n", + " \n", + " # Compute constant covariance FoM\n", + " t2 = np.einsum('pa,pq,qb->ab', dmu, invCov, dmu)\n", + " F = t2\n", + "\n", + " # Compute covariance\n", + " i,j = inds\n", + " covmat_chunk = np.linalg.inv(F)[:, [i, j]][[i, j], :]\n", + " \n", + " # And get the FoM, the inverse area of the 2 sigma contour\n", + " # area.\n", + " area = 6.17 * np.pi * np.sqrt(np.linalg.det(covmat_chunk))\n", + " return 1/area" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a neural network classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from flax import nn\n", + "from flax import optim" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "nbins=3\n", + "# Here is a trivial classifier for 3 bins\n", + "class BinningNN(nn.Module):\n", + " def apply(self, x):\n", + " \"\"\"\n", + " Takes as an input the features to use for binning\n", + " \"\"\"\n", + " net = nn.Dense(x, 500, name='fc1')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc2')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc3')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " # The output of the model should be a gumbell softmax layer\n", + " return nn.softmax(nn.Dense(net, nbins))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "@jit\n", + "def train_step(optimizer, batch):\n", + " def loss_fn(model):\n", + " w = model(batch['features'])\n", + " \n", + " return 1./FoM_DETF(w, batch['labels'])\n", + " loss, g = value_and_grad(loss_fn)(optimizer.target)\n", + " optimizer = optimizer.apply_gradient(g)\n", + " return optimizer, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's get some initial weights\n", + "_, initial_params = BinningNN.init_by_shape( rand.PRNGKey(0), [((1, 12), np.float32)])\n", + "model = nn.Model(BinningNN, initial_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "optimizer = optim.Adam(learning_rate=0.001).create(model)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as onp\n", + "batch_size = 5000\n", + "def get_batch():\n", + " inds = onp.random.choice(len(labels), batch_size)\n", + " return {'labels': labels[inds], 'features': features[inds]}" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "losses = []" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype requested in astype is not available, and will be truncated to dtype int32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loss : 0.060084\n", + "Loss : 0.018406\n", + "Loss : 0.016993\n", + "Loss : 0.016767\n", + "Loss : 0.017496\n", + "Loss : 0.016901\n", + "Loss : 0.015647\n", + "Loss : 0.015569\n", + "Loss : 0.015788\n", + "Loss : 0.015055\n", + "Loss : 0.016284\n", + "Loss : 0.014903\n", + "Loss : 0.014478\n", + "Loss : 0.014679\n", + "Loss : 0.013919\n", + "Loss : 0.013948\n", + "Loss : 0.013831\n", + "Loss : 0.013720\n", + "Loss : 0.013641\n", + "Loss : 0.014490\n", + "Loss : 0.014215\n", + "Loss : 0.013409\n", + "Loss : 0.013412\n", + "Loss : 0.013810\n", + "Loss : 0.013854\n", + "Loss : 0.013982\n", + "Loss : 0.013744\n", + "Loss : 0.013479\n", + "Loss : 0.013459\n", + "Loss : 0.013864\n", + "Loss : 0.013955\n", + "Loss : 0.013941\n", + "Loss : 0.013346\n", + "Loss : 0.014114\n", + "Loss : 0.014597\n", + "Loss : 0.013867\n", + "Loss : 0.013475\n", + "Loss : 0.013776\n", + "Loss : 0.013404\n", + "Loss : 0.013482\n", + "Loss : 0.013345\n", + "Loss : 0.013325\n", + "Loss : 0.013364\n", + "Loss : 0.013693\n", + "Loss : 0.013431\n", + "Loss : 0.013460\n", + "Loss : 0.013241\n", + "Loss : 0.013021\n", + "Loss : 0.013623\n", + "Loss : 0.013338\n", + "Loss : 0.013764\n", + "Loss : 0.013228\n", + "Loss : 0.013783\n", + "Loss : 0.013509\n", + "Loss : 0.013506\n", + "Loss : 0.013747\n", + "Loss : 0.013137\n", + "Loss : 0.014308\n", + "Loss : 0.013285\n", + "Loss : 0.013308\n", + "Loss : 0.013232\n", + "Loss : 0.013559\n", + "Loss : 0.013478\n", + "Loss : 0.012901\n", + "Loss : 0.013253\n", + "Loss : 0.013590\n", + "Loss : 0.013385\n", + "Loss : 0.013531\n", + "Loss : 0.013267\n", + "Loss : 0.013815\n", + "Loss : 0.013428\n", + "Loss : 0.013334\n", + "Loss : 0.013975\n", + "Loss : 0.013919\n", + "Loss : 0.013623\n", + "Loss : 0.014203\n", + "Loss : 0.014085\n", + "Loss : 0.013265\n", + "Loss : 0.013506\n", + "Loss : 0.013367\n", + "Loss : 0.014097\n", + "Loss : 0.013645\n", + "Loss : 0.013190\n", + "Loss : 0.013499\n", + "Loss : 0.013555\n", + "Loss : 0.013627\n", + "Loss : 0.014037\n", + "Loss : 0.014181\n", + "Loss : 0.013527\n", + "Loss : 0.013784\n", + "Loss : 0.013359\n", + "Loss : 0.013072\n", + "Loss : 0.013352\n", + "Loss : 0.013335\n", + "Loss : 0.014063\n", + "Loss : 0.014213\n", + "Loss : 0.013667\n", + "Loss : 0.013324\n", + "Loss : 0.013596\n", + "Loss : 0.013308\n" + ] + } + ], + "source": [ + "for i in range(1000):\n", + " batch = get_batch()\n", + " optimizer, loss = train_step(optimizer, batch)\n", + " losses.append(loss)\n", + " if i%10 == 0:\n", + " print('Loss : %f'%loss)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot(losses[10:])" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# Sweet :-D let's see if it did anything\n", + "w = optimizer.target(batch['features'])\n", + "nzs = [kde_nz(batch['labels'], w[:,i], bw=0.05, zmax=4.) for i in range(nbins)]" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "#figure(figsize=(13,7))\n", + "z = np.linspace(0,4)\n", + "nz_total = kde_nz(batch['labels'], np.ones_like(batch['labels']), bw=0.05)\n", + "plot(z, nz_total(z)*len(nz_total.params[0]))\n", + "for i, nz in enumerate(nzs):\n", + " plot(z, nz(z)*nz.params[1].sum(), '--', label='nz_%d'%i)\n", + "xlim(0,4)\n", + "legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "75.14277126540426" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1./0.013308" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "# Exporting the trained model\n", + "from flax import serialization\n", + "import pickle\n", + "\n", + "with open('BinningNN_3x2_2b_FoM_DETF.pckl', 'wb') as file:\n", + " pickle.dump(serialization.to_bytes(optimizer.target), file)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/LearningToBin-6bins-FoM-DETF.ipynb b/notebooks/LearningToBin-6bins-FoM-DETF.ipynb new file mode 100644 index 00000000..37378dee --- /dev/null +++ b/notebooks/LearningToBin-6bins-FoM-DETF.ipynb @@ -0,0 +1,610 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Populating the interactive namespace from numpy and matplotlib\n" + ] + } + ], + "source": [ + "import sys\n", + "sys.path.insert(0, '..')\n", + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "%pylab inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found classifier IBandOnly\n", + "Found classifier NeuralNetwork\n", + "Found classifier Random\n", + "Found classifier RandomForest\n" + ] + } + ], + "source": [ + "# Import JAX instead of numpy\n", + "import jax.numpy as np\n", + "import jax.random as rand\n", + "from jax import jit, vmap, grad, value_and_grad\n", + "\n", + "# Import modified version of challenge metrics\n", + "from tomo_challenge import jax_metrics as metrics\n", + "\n", + "# Import tools from jax-cosmo\n", + "from jax_cosmo.redshift import kde_nz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "../tomo_challenge/data.py:76: UserWarning: Setting inf (undetected) bands to mag=30\n", + " warnings.warn(\"Setting inf (undetected) bands to mag=30\")\n" + ] + } + ], + "source": [ + "from tomo_challenge.data import load_data, load_redshift\n", + "from sklearn.preprocessing import StandardScaler, RobustScaler\n", + "features_scaler = RobustScaler()\n", + "\n", + "data = load_data('../data/training.hdf5','riz',colors=True, errors=True, array=True)\n", + "m = (data[:,0] <29) & (data[:,1] <29) & (data[:,2] <29)\n", + "data = data[m]\n", + "\n", + "features = np.clip(np.array(features_scaler.fit_transform(data)),-4,4)\n", + "labels = np.array(load_redshift('../data/training.hdf5'))[m]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(8552577, 12)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's grab some data\n", + "batch_size = 2000\n", + "\n", + "batch_labels = labels[:batch_size]\n", + "batch_features = features[:batch_size]" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's build an n(z) using a KDE\n", + "nz = kde_nz(batch_labels, np.ones_like(batch_labels), bw=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 0, 'redshift z')" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "z = np.linspace(0,4)\n", + "hist(batch_labels, 64, density=True)\n", + "plot(z, nz(z), label='KDE nz')\n", + "xlim(0,4)\n", + "legend()\n", + "xlabel('redshift z')" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD4CAYAAAAXUaZHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy86wFpkAAAACXBIWXMAAAsTAAALEwEAmpwYAAAmUUlEQVR4nO3de3Bc53nf8e+DXVyWuBAkAVKkSImUKMmmZVmSace52CNfEstuGrkzacaatFESz2jSOrc2rWMnM9H04pmkySRx0jZTNVItdTyyXdux1cRKZFFiZNcSZZICRRIUSBC8ACAILC6L69737R/nLLAAFrfdBRc4/H1mONjznvecfUgCz754z3sx5xwiIhIsNdUOQEREKk/JXUQkgJTcRUQCSMldRCSAlNxFRAIoXO0AANra2tz+/furHYaIyKZy4sSJYedce7FzGyK579+/n+PHj1c7DBGRTcXMrix1Tt0yIiIBpOQuIhJASu4iIgGk5C4iEkArJncze9rMhszszILy3zCzt83srJn9l4LyL5hZt5l1mdnH1yNoERFZ3mpGy3wZ+K/As/kCM/sw8AjwHudc0sx2+uWHgE8D7wL2AC+Z2d3OuWylAxcRkaWt2HJ3zr0KjC4o/lfAHzrnkn6dIb/8EeCrzrmkc+4S0A28v4LxiojIKpTa53438EEzO2Zm/2hm7/PLbwV6C+r1+WWLmNnjZnbczI5Ho9ESwxARkWJKTe5hYDvwAeDfA183M1vLDZxzTzrnDjvnDre3F51gJSIiJSo1ufcB33KeN4Ac0Ab0A/sK6u31y0Q2rOjwkWqHIFJxpSb3bwMfBjCzu4E6YBh4Hvi0mdWb2QHgLuCNCsQpIiJrsOJoGTN7DngIaDOzPuAJ4GngaX94ZAp4zHn79Z01s68DnUAG+KxGyoiI3HgrJnfn3KNLnPoXS9T/IvDFcoISEZHyaIaqiEgAKbmLiASQkruISAApuYuIBJCSu4hIACm5i4gEkJK7iEgAKbmLiASQkruISAApuYuIBJCSu4hIACm5i4gEkJK7iEgAKbmLiASQkruISAApuYuIBJCSu4hIAK2Y3M3saTMb8rfUW3jud8zMmVmbf2xm9hdm1m1mb5nZg+sRtIiILG81LfcvAw8vLDSzfcDPAFcLij+Btyn2XcDjwF+VH6LI+urv66erq6vaYYhU1IrJ3Tn3KjBa5NSfAZ8DXEHZI8CzzvM60GpmuysSqYiIrFpJfe5m9gjQ75w7teDUrUBvwXGfX1bsHo+b2XEzOx6NRksJQ6QiMsNxUr2T1Q5DpKLWnNzNbAvwe8AflPPGzrknnXOHnXOH29vby7mViIgsEC7hmjuBA8ApMwPYC5w0s/cD/cC+grp7/TIREbmB1txyd86dds7tdM7td87tx+t6edA5dx14Hvglf9TMB4Bx59xAZUMWqaytI53VDkGk4lYzFPI54DXgHjPrM7PPLFP9u0AP0A38T+BfVyRKERFZkxW7ZZxzj65wfn/Bawd8tvywRESkHJqhKiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkBK7iIiAaTkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkBK7iIiAaTkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkCr2WbvaTMbMrMzBWV/bGZvm9lbZvY3ZtZacO4LZtZtZl1m9vF1iltERJaxmpb7l4GHF5R9D7jXOXcfcB74AoCZHQI+DbzLv+a/m1moYtGKiMiqrJjcnXOvAqMLyl50zmX8w9eBvf7rR4CvOueSzrlLeBtlv7+C8YqIyCpUos/9V4EX/Ne3Ar0F5/r8MhERuYHKSu5m9vtABvhKCdc+bmbHzex4NBotJwwREVmg5ORuZr8M/Czwi8455xf3A/sKqu31yxZxzj3pnDvsnDvc3t5eahgiIlJEScndzB4GPgf8nHNupuDU88CnzazezA4AdwFvlB+miIisRXilCmb2HPAQ0GZmfcATeKNj6oHvmRnA6865X3POnTWzrwOdeN01n3XOZdcreBERKW7F5O6ce7RI8VPL1P8i8MVyghIRkfJohqrc9LonagGId45UORKRylFyFxEJICV3uen101DtEEQqTsldRCSAlNxFRAJIyV0EeDaarHYIIhWl5C4iEkBK7iIiAaTkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkBK7iJAhgFGE9+vdhgiFaPkLiISQEruIiIBpOQuIhJAKyZ3M3vazIbM7ExB2XYz+56ZXfC/bvPLzcz+wsy6zewtM3twPYMXKUd0+AjR4SMAvGuqg4brb1Y5IpHKWU3L/cvAwwvKPg8ccc7dBRzxjwE+gbcp9l3A48BfVSZMkfU3OhmrdggiFbNicnfOvQqMLih+BHjGf/0M8KmC8med53Wg1cx2VyhWkYpKXZ3kSkd3tcMQWRel9rnvcs4N+K+vA7v817cCvQX1+vwyERG5gcp+oOqcc4Bb63Vm9riZHTez49FotNwwRESkQKnJfTDf3eJ/HfLL+4F9BfX2+mWLOOeedM4dds4dbm9vLzEMEREpptTk/jzwmP/6MeA7BeW/5I+a+QAwXtB9I7LhFY6gEdnMwitVMLPngIeANjPrA54A/hD4upl9BrgC/IJf/bvAJ4FuYAb4lXWIWUREVrBicnfOPbrEqY8WqeuAz5YblIiIlGfF5C4SVA3X32TrZAxornYoIhWn5QdECtRd+lG1QxCpCLXc5aZ1JlPHFI3VDkNkXajlLiISQGq5ixTIROOkQpPQVu1IRMqjlruISAApuYuIBJCSu4hIACm5i/jO08iZTF21wxCpCCV3Ed/ARA19Y2te4FRkQ1JyF1lCvHOEeOdItcMQKYmSu4hIACm5i4gEkCYxyU2rb8wRT6l9I8Gk72wRkQBSchcp4ulTnbyUjFc7DJGSKbmLiARQWcndzP6NmZ01szNm9pyZNZjZATM7ZmbdZvY1M9OsEBGRG6zk5G5mtwK/CRx2zt0LhIBPA38E/Jlz7iAwBnymEoGKiMjqldstEwYiZhYGtgADwEeAb/jnnwE+VeZ7iIjIGpWc3J1z/cCfAFfxkvo4cAKIOecyfrU+4NZygxQRkbUpp1tmG/AIcADYAzQCD6/h+sfN7LiZHY9Go6WGIVJR8VSCgdHBaochUrZyumU+BlxyzkWdc2ngW8BPAq1+Nw3AXqC/2MXOuSedc4edc4fb29vLCEOkMjKpVLVDEKmYcpL7VeADZrbFzAz4KNAJvAL8vF/nMeA75YUoIiJrVU6f+zG8B6cngdP+vZ4Efhf4t2bWDewAnqpAnCIisgZlrS3jnHsCeGJBcQ/w/nLuK1JtmWgcdrRUOwyRkmmGqohIACm5i4gEkJK7iEgAKbmLiASQkruISAApuYsUcSGaqHYIImVRchdZRve1S3R1dVU7DJE1U3IXEQkgJXeRTeJo71GO9h6tchSyWSi5iyxhKnWWJCdI9U4S7xypdjgia1LW8gMiQbR1pJN3Tk0D76p2KCIlU8tdRCSAlNxFlrBn8Hi1Q5inozdGR2+s2mHIJqFuGbnp3YhNOl7q9HZ3+tihXev+XiKg5C5SVI5RIHLD3zf/IQD6IJDyqFtGZAWvYbOvo8NHiA4fqWI0Iquj5C4iEkBlJXczazWzb5jZ22Z2zsx+3My2m9n3zOyC/3VbpYIVuRG6J2qrHYJI2cptuX8J+Hvn3DuA9wDngM8DR5xzdwFH/GORDSeZiK/qYWqabkYT398w3TELZ6q+1Dk4r69eBMpI7ma2FfgQ/gbYzrmUcy4GPAI841d7BvhUeSGKVMdUfJqtI53sHzm1bu9RiSUFzsRe40zstUqEIwFSTsv9ABAF/peZvWlmf21mjcAu59yAX+c6oEf+IiI3WDnJPQw8CPyVc+4BYJoFXTDOOQe4Yheb2eNmdtzMjkej0TLCEBGRhcpJ7n1An3PumH/8DbxkP2hmuwH8r0PFLnbOPemcO+ycO9ze3l5GGCKrN/nyKyvW6adhUdkPrlmRmpWzbv3mXS94f+SmU3Jyd85dB3rN7B6/6KNAJ/A88Jhf9hjwnbIiFKmi8zQC0NDzIv19/fT39d+4N1diljKUO0P1N4CvmFkd0AP8Ct4HxtfN7DPAFeAXynwPERFZo7KSu3OuAzhc5NRHy7mvSLVlUil6hyFcV8fulpxXNhxne7qbuvQ1aFv/b/H8ImH337N8PZFitLaMyCoMhBrpo5VPFJTlN/CIHNpR0fdqu/Zy0fKWkbe8F/s+VNH3k2BSchdZRiaVIpVMA7UkpieZmh5hR1tlkzn9J2ibGli5nsgaKLmLrGBw0luO4I7xs2v7iel6gY7eGMN7PrI+gS2gZYWlkBYOExEJILXcRQJitq8+1Ar3fGLZuhJ8Su5y03KJJITn//K6ll2ZBi9PALC/yAPViyeOQd8laNwgi6Lmx8sr6d80lNxFSvTDkUkA9i+TOKNX+piY7GDrPfcDXtK/s2l0yfpFLTWRSROcZBnqcxcRCSC13EXWaGygn+ETx5gaHZ9XfvHEMe58748BMHhpAkZquDA6SbL+bd7N/QCcjp6hNx2jdWoPw9lBws3etSfjF2bv82DkrnllsbHGonHkJzm15K/1rxMBtdxF1sQSYJNFFzrdMDp6Y9q8Q9RyF1mNdC5FMpOcPT4dPUMs2UJr/dai9a9MXIHE3FLW+c003PAUW9PTwAW4eIE72huJXRwmNZGgbu/qHr72dLwKzLXwRYpRy11EJIDUchcBXDqF1dat6RqL9JGpHaWjtwWA5m3by94yr5ie6HTF7ynBp+QuUqbolT4AmrfdUZH7FT5cLcfR3qMw1slD2w5V5H6yuSi5S+Att/uSSy8/aSmdW3x+IjkDQCKdxWUzUAtTo2Fef2OA6Hu81Rsjk3M7N0UmL1M3Ms7EjvtK/BsUt/BDIH+svngB9bnLTeqlzkGSqRzpDGSykM2kIesl8lQ2RyqbW/b6kM1PrAOZMYaSfbieK6T6xpa8rqWnb95xT3Sa6xOJEv8WpZl8+ZVVbTcom5uSu4hIACm5i5Roq13jzvQ5RuMZklmojw8Rmby8qN7OmVtoH51bfyY7uB2AVN/YbCu/6epIxePr6I3RE52enewkN5eyk7uZhczsTTP7W//4gJkdM7NuM/uav7+qyLq69NbwqutOvvwKDT/6YUXfv3lbH42tfXQ17aWraW9J9yhM9uVqu/by3M5NclOqRMv9t4BzBcd/BPyZc+4gMAZ8pgLvIbKiS28NL5nkr1y+uOL1Lp1Z9gFrdLqenqnI7LHlMmQy08QnQ7NlW8d3sXW8tM0ycrFmcrHmkq4tZltnP9s6+yt2P9lcykruZrYX+CfAX/vHBnwE+IZf5RngU+W8h4iIrF25QyH/HPgckG9u7ABizrmMf9wH3FrsQjN7HHgc4LbbbiszDJHyZXIGuSxWmyPrsqRzBqHlf0SG6lpoTsH5+G5sVwORceiN17Izk75BUYsUV3LL3cx+Fhhyzp0o5Xrn3JPOucPOucPt7e2lhiGyyLzuma4XoL+kb9ElvZ1t4rVYO1nmLyBWOHqyq/UWItFJLtds5a2tc9/fke1Lb4QdiU4SiU5WNFaAmtNdFb+nbHzltNx/Evg5M/sk0AC0AF8CWs0s7Lfe9wLq9JMNo/eal5CvTL9NlizmchjLjGnPZuYfr9AcyjRdIzmzlyb/uIVtFN7h1uR1Eu4c/ayuXz7/gHW1i4oVczE1wNTLL/Duptto1k5MN42SW+7OuS845/Y65/YDnwZeds79IvAK8PN+tceA75QdpYiIrMl6LD/wu8BXzew/A28CT63De4isaPLlV6D/7Jqvs0wW/AEwLuctI2AuSy7nuFLfCFOOxJbsbP2D6SvUZSbITtcDcJniQyF3X69dcyylGr1WR2JmDw1brt2w95SNpSLJ3Tl3FDjqv+4B3l+J+4oUym9A8bFDc10aaxnfvpysy+EchKymoMyB85N7zvlfU5AztizzvPSBzFtkJuYq1IRHycV2zg07WG1Mg9vJxTLUtK6tH/5k/ALZ1PbZriG5OWmGqgTSqasxTi0xM3Pw+kUSw6NFz2Vdjqxbfl2ZhcKN1wEYiUcYic+Ng6/ZHSW5bW5HJBsOkcvcuNa73NyU3EVEAkjJXW4qg5fOEBu8Mq/MuRqcm/+jYJkclsnNjm9ceP6emfOrfs+7Z86zK3V6Xln76A52ztyyltDnyQ5un12jRqQYJXeRNci6LNnlhk4CofppQuH4DYqoMrQEcPBosw4JlFNXY4vKeke3QrobamPA6taxW9hSny3LzS/PkiNFZlHdYurjQ4QKNtkGCtaSWd2qkMu11vPryIwdKjopHFASv5mo5S6BcSZ6mivTby95/h8vn+Py2CVi2bk9SUt5gDp38dLXhQlxR2YcgDQ5cjPTZMZja7p9U+/I7IzVc6FdnAstnvhULNlHjjuaeot/WLx6amrJB80SLEruIiIBpG4Z2XCO9h4F4KF9D62q/pnoaRjt9o92A1B74RzdyetMkuL2yNLXrlk2B6Eaf8jj8i3+3kwrvdPN3F0P4ekUddk4bIdQ73XCNdtItzfPrSVTP//aVN8Y5p/aE04yPOV13+yczjDUOFH0/RIze5aN5/TUVaLJRrYy9yBX3TTBpZa7bDz9J7w/XS9UO5KK22JNtLD8OjGJMxnaowdos7kknJuKkJsq/1OqPj5Ey+ipsu8jG59a7rI5zSb+9wFwfdx/UFmBvS6KPUxdTm+ydf7iY37rfqFTO9uJN7SzP+Ydh1uuEEmPER+aS+KRnddhCGhtKyHypQ1OJFeuJIGilruISAApuUugxeJpBifiXBgMEx1rmS3PxhtvWAwj8QjdzUlqWodmy8ZqjNSkNxa+zW6hrS3ktdp9ZzNbZl/PJGqom4hzaOQYAOenI6Sjc/daq4upAU4Pz02qyi+DLMGibhmpuqUeoHb0xhjODs5bKGy2/lgnAJPTDeseX0myueKvizi1s50HM1eABC22jZZdSa7VXIfpxevQjKemoW599pzPP1xt/siH1+X+cmMpuUvV5JP6WnX0xmgZmeaO9tJb37XJcdIuS3blqostSNzRcJP3k7RCEs+raR0iXBsml60HEiS3DdI80suENTFV490jlMgAxRcZ225j9NVlOeAfJ854k6gihIrWX4pGygSbumVERAJILXfZsE7GLzARi/AxPgXAVI838Numw7Cl+DVbJi8TnbxMbXJtrdj1cn/6XNHyVH2KuuTK3Sv7wlcZ9sfuF9PUO8Jo3F/HJjK3gvv27A4AZlh6s458v3sr964Yh2w+arlL1fV0vEpPx6vVDmNpq+xuWWiovmXe64OJCwDEzXuAuTvTz56st977lcb5m8Qnarw6C8fEW3QMG58iPLP00MY9XJx9Hd4anfenVBdPHOPiiWMlXy83XsktdzPbBzwL7AIc8KRz7ktmth34GrAfuAz8gnNurPxQJejyOy0t/Kac65uf274uO7idyUQ90M1m05tpLVqeDIWI4CX9Tn8D7UutLfw9BzmYTJDNpubVr8n1McXyD5S3ZHYwE56/zkxiZg/jw81sbVvbDk+yuZTTcs8Av+OcOwR8APismR0CPg8ccc7dBRzxj0W8iUdrnHXaMvKWN1t1jerjQ9THveGC1zNj8xYLq5ZoMkI0ufQs067UHjpTXlK/O9dDPNzHkL9z05WU14XTuXPnbP3szDRnmlsX3ae2eRjbcZFTuQgnp/aTSs0tLla3o5e6Hb2M15zl0vD8f5Mrly9y5fLFhbeTTark5O6cG3DOnfRfTwLngFuBR4Bn/GrPgN9hKiIiN0xFHqia2X7gAeAYsMs5N+Cfug4sXqfUu+Zx4HGA2267rRJhSED0RIu0svtP0DLqdS9sSXnfXrNLDmwSabx+9KH6FkhATaYV8BYXuycE78hdJkw91Hh1ckQAB5n5ff6XmtpJumb2chmA8zu99ds/MDm+6lhqUzHq45PQ9i7Am8gUHXW0b7fZOhdPHOPi7e/gZ9q2lvx3Xkm+H//O9/7Yur3Hzars5G5mTcA3gd92zk2YzX1zOOecmRWd/uacexJ4EuDw4cOaIie0XXsZgKsLyvPJfv8K1xeuYZ6YjAHQUKTbYqO5P30OQhCt30aIMPuysaL1hjK1tGfPs7d+hrdq30lT1hsytIX8KJlxzuzYhQvt5J3TVznYGOMiByEXoT5+O5OhSdIzcx+c8aFbaGhupnNnLT+RSBd9z4Hu81y8Mv/D5aXOQe7MeKORDty3ujVwlMRvvLKSu5nV4iX2rzjnvuUXD5rZbufcgJntxlsGSW5iR3uP0tEb46GZOPfva53rd9+ytlUOL6YGVq60QD7JbyZXGtshUfxcTf00xdLwOzJn2Z69k5bG6aLXnkq2cceWuQeoZ1rvJBONMJ6KYTNnGByaSwWTL78yb5bqD9Je7+1P1Za4qYlURcl97uY10Z8Czjnn/rTg1PPAY/7rx4DvlB6eiIiUopzRMj8J/EvgI2bW4f/5JPCHwE+b2QXgY/6xyGL5ddsFgJD/i/RwYvFvNOmmGNmGqXllw6kQY0lvstJI2htVE7fs7I6uuezc3q5xsiQo3vt5cXLu/aKjruhCYqnYhbnXvfOHUL44PM6Lw6vv75cbo+RuGefcDwBb4vRHS72v3LxOxi+sXClACic5FVNTv/zwzVBogvszp9mRSTNCLaO2+AHzndlubkmPcZZ2ziVu4Z2p8+wLjZBO1HCWQ2SSCaiFE1u9h6bvHfeTdNcLwHaS2W6mYynCCaB90e1XbSZ9gi21711U3nvdm9twZ5Fr1E9fHi0/IDfcUX9Fx6KjYpawrbOfxIxjat+O9Qprw1pqCQPwPgBCDXFqEhFub/g+bqaNzFJNLiBrS59sSEdoTK5uKbWB82/6rx7geirOtpDBGkbVdLz0nPf8RdaNlh8QEQkgtdzlhurojdETr9xs0fzwx3yLfjOOjoHi/ezLSeJmx83nXY7MDUu8lG4BMiynZvs4qexW0pks1EHMeQuQRSa/zgvndzLU/k+xSed1yQBHfjDOsc63iIcnScVHAW878rH+HqanjVeHBvjQx99HvNP7P4kcWvq3rLGBfgaSg8Ada/p7y+opuUvl5Yc63vOJecXr1aeemIwR7owtNXow8Ip9MPTVN7FnJjZ7nMtmCWfDhKnnZPggeyzLvbkBwhalKR3lyswD3J96m9YcJBLTxKcmGa6NQXKGOn9d+Uz9JWLTl5icaGOH/zkSe+MUdVu88+Ojf8fp139EU/QBAA4c+nH+75t9AAxkt/HR4svTA9DV1cU999xT/j+GzFJyl/XT9QIdvTE61jieHbw+9rFD3szL7OB2EjOLR3AUTlqSuSTf1hCfLRuobWSm3qBwzTGr5VqyFuobqMUwV9KWJUXFBuM01cCliWMc4Mdny2+LvsXVyX4uRfbP21mrZnTx/+vFE8d46mqae3bXa2x9GdTnLrIJLfeQdWimnlwuR8rmljy4O9fD3bmeFe97vqmB7mQjTCRovPg9GvvOA3AxNrf2/MHQS+zJ/i1npkK8OBqje8Lr/jlVfwvbx7uIxF4H4Iff+B5954q854LF496ctHnlM+mlh8d2dXWt+HcQj5K7iEgAqVtGNpTsoLc8bWLGETnutTqn9lUzos1vOBGB+gg7kxOLzqVxhDDeE/o+xQayZzM5ptJx4hnHVDpOY87rQ7883chdmQ5e3nqQSDgF3MpdE51Mp+O47Dh9NPG+5HFuz9SS5Q6ujdWw1wY4e+L/YFtzi1qV8fgxTp/tYcuU9/8/MT0N1M+r88r//hNydQ3qm18lJXdZF7Nj2ePTtMRXqLxG6msvLpcrvX96OBGhHZh2KYZrG2jPJskWrEZ5X+IMt2SmuR6e25R8qCHBfYkzXGjyJicNj9cxzC521taQTmW5sCVM2B+wk5pJEw8luINzpJtbqMmmSGZTbJ+OAQ+SGY4X3d77B+maohOcFnpxeHxdV6/cjJTcZbGuF7zkfOt7eWjfQ0Wr/PkPvw3Ab//Ep4C53ZKWql9MdnA7oV2jK9YrTOZK7Ku30gzYQmFCjKRqCIVqqFlmVEteKGvUFMyHytRfmm2ND8WhIQTRUe/DoXagf9618YkEg9O13O3vIXIgeZLopSlSmSaOXU3zaMGWsclsN0f/boAdsZNMTEHTdm/nqfzs1UxTK69fnWb3A/5HQNcLi0ZpAasanhk06nMXEQkgtdxlSR29MTKTg/OGri00u+9p89xx27W1T1TK97XLjZd1Xgu7pn56Xms87+BkJ0PMjZYp7JpZjZbrR5gBrpl3nfnrjk0OT2N4LelUPA7ESU9f442BCM6GiI73ArAj5o2QuVYzw4FMPx0vPceu5CDDsRh1hx8FINk7SXwoQ6RY3w7Qfe0SAO/2W+7R4SMAtLcFdxksJfdNJp9Ml0u4pdzzTOy1ubU+/P7yWf4QtY7e2OxEpPwv/G0zcYb3fMQ76D9B29Ta11zPWzjbdCmbdRZqta2lmyYar5/NDkMzdctXLiKRnVvErH8MQg1gCybM9kxFgChFO9sLXKgZZ3CiFstAcmSCq0NdhCPeqoXx+DH2jk7QnNlKd+07aR65wP57PkFHx7PcuvdWmobuX3PsQaFuGaHt2sveRtRFnIm9NvtwtJiT8Qucib225Pns4PbZVnn+dWGZbH7xTJKpdHlPzQdCjQyEGomnk5yc8T5V7hg9yx2jZxmcWPwQ4GIqiqub27NranSE/9f5D5yfmP8JUnPtCDXXvFZ688gPufy1v5h/oyU2bO/q6tr0Y+qV3EVEAkjdMtW2xDosS8nvM8qhR9f8Ph29MYb3fGTFLp38UrwteK35HqB1Kraqtxm95v0Kn03Nb5kv1VJP9Y0BEKqdO7/UiBh1x9xgmfmtYJdKL5kxLo83cF/+IDwBmZa510B+35BQuMY/ztFHhFC4ht3Zuecz986cxvlLJVgEnN9oz3fpDIQaITQDNJIL1zGYaqYhE6NmMgOhcXpS4zz17BN8uH2GuvQ14A6+0X+eybo4Dxc0Zesu/QiAkWicxHSSH7ZuZ2vLe/jgUGbRiJrC/vn8a4DU1Um2N3xww47AUXKvovzDx1jTNeiNrGkYIcwNPwRo7fL6uvP95kf99Vwyk+8EoO1azP/6MoRaOTrWuWg99Z6OV9f8dwBoGXmLHj8fZ9ewz2k6OgR4T2JDZWwEITdQJgPh+WnjvsSZVV9eOHY+f5zJ5Mi63GzizyfywUkvsy+1Av3gZC2nL0xx71Qf9TbXdZOKxzl9ZYbWdCuR2iTJRJzd42/ALm/yU3T4CF0zYfbMDLKVLbPXjU+cYubyEU5Em9kzM8jE7nfz4vAtjPvdQg/hJfbU1fk7UZVqvYdnrltyN7OHgS/hPS75a+fcumy3l3/ACAUPGVcxTrscpYzpLlQY83L3LXbcE7/Ag5G7/IegMe6vuQjASX90SmzMH8mwxZtYku8PbylYkfHk+dXHmm9xn9xVuRUdw51ezOn2ZiJR7welIeE9VVPrfOMarGvyXhS26MNLpJDw4tmwS1k4+salU1jt/Ie4+Q+F/AdAnqW8D4NU0W3DIZ72+uUHQo0MDHuza29/bRiALiJscXUcBHae+T4AZ6hjZmKCLiL0DNezPfk64fYIQz0DXCHG7fcfBKDh+pskbnmA7muXSF77Brfff3B25E0+aedFDu2oyjj7dUnuZhYC/hvw00Af8CMze945t/STuQ2g6AcFzHZp5HVsiXgtZL9L5eiWCB29MR6aiXP/vtbZVvNqk39PdBqic63mfCu8J36BiR330dH77dkkDv7SuRcveCNW2hsX3wtm77f68RHLW9itEto1OluWn4i03EPSpt6RRYk7n9hlE8sn+oVJvkgLf179vII6s636LGC5+Yncvy5LeF75vTOn510fCtd4Lf8snOstvq/rlasJdjV7HwY1tSky515iKtzCwIR3390tfhwR2DN4HAZhaMtBto500t8XIXx9kt3AwOgg4OWM1NVJ+q9+m+0NH5x9n9GE94FRN9xMKuF/r5/0vhTWWy/r9UD1/UC3c67HOZcCvgo8sk7vJSIiC6xXt8ytQG/BcR8wb5dbM3sceNw/nDKzzTLuqA0YrnYQJdisccPmjV1x33ibNfZS4759qRNVe6DqnHsSeLJa718qMzvunDtc7TjWarPGDZs3dsV9423W2Ncj7vXqlukHChdq3euXiYjIDbBeyf1HwF1mdsDM6oBPA8+v03uJiMgC69It45zLmNmvA/+ANxTyaefc2fV4ryrYdF1Jvs0aN2ze2BX3jbdZY6943Obc4g1qRURkc9PaMiIiAaTkLiISQEruJTCz/2Rmb5lZh5m9aGZ7qh3TapjZH5vZ237sf2NmrdWOaTXM7J+b2Vkzy5nZhh/mZmYPm1mXmXWb2eerHc9qmdnTZjZkZqtfLGYDMLN9ZvaKmXX63ye/Ve2YVsvMGszsDTM75cf+Hyp2b/W5r52ZtTjnJvzXvwkccs79WpXDWpGZ/Qzwsv/A+48AnHO/W+WwVmRm7wRywP8A/p1z7niVQ1qSv/TGeQqW3gAe3ehLbwCY2YeAKeBZ59y91Y5ntcxsN7DbOXfSzJqBE8CnNsm/uQGNzrkpM6sFfgD8lnPu9XLvrZZ7CfKJ3dcIbIpPSOfci865/OIer+PNP9jwnHPnnHObZQbzpl16wzn3KrDyjuUbjHNuwDl30n89CZzDmyW/4TnPlH9Y6/+pSD5Rci+RmX3RzHqBXwT+oNrxlOBXgeLb0Eg5ii29sSkSTRCY2X7gAeBYlUNZNTMLmVkHMAR8zzlXkdiV3JdgZi+Z2Zkifx4BcM79vnNuH/AV4NerG+2cleL26/w+kMGLfUNYTdwiyzGzJuCbwG8v+O16Q3POZZ1z9+P9Jv1+M6tIl5g261iCc+5jq6z6FeC7wBPrGM6qrRS3mf0y8LPAR90GeuCyhn/vjU5Lb1SB31/9TeArzrlvVTueUjjnYmb2CvAwUPZDbbXcS2BmdxUcPgK8Xa1Y1sLfQOVzwM8552aqHU9AaemNG8x/KPkUcM4596fVjmctzKw9P2rNzCJ4D+Irkk80WqYEZvZN4B68ERxXgF9zzm341pmZdQP1QH6rmNc3ySiffwb8JdAOxIAO59zHqxrUMszsk8CfM7f0xherG9HqmNlzwEN4y88OAk84556qalCrYGY/BXwfOI33Mwnwe86571YvqtUxs/uAZ/C+V2qArzvn/mNF7q3kLiISPOqWEREJICV3EZEAUnIXEQkgJXcRkQBSchcRCSAldxGRAFJyFxEJoP8PrUU6Yrk54hsAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Checking normalization of features\n", + "for i in range(12):\n", + " hist(batch_features[:,i],100, alpha=0.3)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "import jax\n", + "import jax_cosmo" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in asarray is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n", + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in array is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + } + ], + "source": [ + "ell, delta_ell = metrics.ell_binning()\n", + "\n", + "@jax.jit\n", + "def FoM_DETF(weights, labels=batch_labels, inds=[5,6]):\n", + " \n", + " # Retrieve the probes\n", + " probes = metrics.get_probes(weights, labels)\n", + " \n", + " # Compute the derivatives of the data vector\n", + " @jax.jit\n", + " def mean(params):\n", + " cosmo = jax_cosmo.Cosmology(\n", + " Omega_c = params[0],\n", + " Omega_b = params[1],\n", + " h = params[2],\n", + " n_s = params[3],\n", + " sigma8 = params[4],\n", + " Omega_k=0.,\n", + " w0=params[5], wa=params[6]\n", + " )\n", + " return jax_cosmo.angular_cl.angular_cl(cosmo, ell, probes, nonlinear_fn=jax_cosmo.power.halofit)\n", + "\n", + " # Compute the jacobian of the data vector at fiducial cosmology\n", + " fid_params = np.array([0.27, 0.045, 0.67, 0.96, 0.840484495, -1., 0.])\n", + " jac_mean = jax.jacfwd(lambda x: mean(x).flatten())\n", + " \n", + " mu = mean(fid_params)\n", + " dmu = jac_mean(fid_params)\n", + " \n", + " # Compute the covariance matrix\n", + " cl_noise = jax_cosmo.angular_cl.noise_cl(ell, probes)\n", + " C = jax_cosmo.angular_cl.gaussian_cl_covariance(ell, probes, mu, cl_noise)\n", + " \n", + " invCov = np.linalg.inv(C)\n", + " \n", + " # Compute constant covariance FoM\n", + " t2 = np.einsum('pa,pq,qb->ab', dmu, invCov, dmu)\n", + " F = t2\n", + "\n", + " # Compute covariance\n", + " i,j = inds\n", + " covmat_chunk = np.linalg.inv(F)[:, [i, j]][[i, j], :]\n", + " \n", + " # And get the FoM, the inverse area of the 2 sigma contour\n", + " # area.\n", + " area = 6.17 * np.pi * np.sqrt(np.linalg.det(covmat_chunk))\n", + " return 1/area" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a neural network classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "from flax import nn\n", + "from flax import optim" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "nbins=6\n", + "# Here is a trivial classifier for 3 bins\n", + "class BinningNN(nn.Module):\n", + " def apply(self, x):\n", + " \"\"\"\n", + " Takes as an input the features to use for binning\n", + " \"\"\"\n", + " net = nn.Dense(x, 500, name='fc1')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc2')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc3')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " # The output of the model should be a gumbell softmax layer\n", + " return nn.softmax(nn.Dense(net, nbins))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "@jit\n", + "def train_step(optimizer, batch):\n", + " def loss_fn(model):\n", + " w = model(batch['features'])\n", + " \n", + " return 1./FoM_DETF(w, batch['labels'])\n", + " loss, g = value_and_grad(loss_fn)(optimizer.target)\n", + " optimizer = optimizer.apply_gradient(g)\n", + " return optimizer, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's get some initial weights\n", + "_, initial_params = BinningNN.init_by_shape( rand.PRNGKey(0), [((1, 12), np.float32)])\n", + "model = nn.Model(BinningNN, initial_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "optimizer = optim.Adam(learning_rate=0.001).create(model)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as onp\n", + "batch_size = 5000\n", + "def get_batch():\n", + " inds = onp.random.choice(len(labels), batch_size)\n", + " return {'labels': labels[inds], 'features': features[inds]}" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "losses = []" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype requested in astype is not available, and will be truncated to dtype int32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loss : 0.054322\n", + "Loss : 0.011856\n", + "Loss : 0.010839\n", + "Loss : 0.009803\n", + "Loss : 0.008954\n", + "Loss : 0.009057\n", + "Loss : 0.008771\n", + "Loss : 0.008708\n", + "Loss : 0.008740\n", + "Loss : 0.008621\n", + "Loss : 0.008631\n", + "Loss : 0.008483\n", + "Loss : 0.008230\n", + "Loss : 0.008611\n", + "Loss : 0.008609\n", + "Loss : 0.008789\n", + "Loss : 0.008152\n", + "Loss : 0.008959\n", + "Loss : 0.008292\n", + "Loss : 0.008429\n", + "Loss : 0.008198\n", + "Loss : 0.008407\n", + "Loss : 0.008273\n", + "Loss : 0.008162\n", + "Loss : 0.008307\n", + "Loss : 0.008299\n", + "Loss : 0.008356\n", + "Loss : 0.008102\n", + "Loss : 0.008222\n", + "Loss : 0.008180\n", + "Loss : 0.008604\n", + "Loss : 0.008261\n", + "Loss : 0.008292\n", + "Loss : 0.008106\n", + "Loss : 0.008415\n", + "Loss : 0.008104\n", + "Loss : 0.008033\n", + "Loss : 0.008248\n", + "Loss : 0.008105\n", + "Loss : 0.008495\n", + "Loss : 0.008555\n", + "Loss : 0.008377\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1000\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mbatch\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_batch\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0moptimizer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrain_step\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbatch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mlosses\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mloss\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mi\u001b[0m\u001b[0;34m%\u001b[0m\u001b[0;36m10\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.local/lib/python3.8/site-packages/jax/api.py\u001b[0m in \u001b[0;36mf_jitted\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 167\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0marg\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs_flat\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0m_check_arg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 168\u001b[0m \u001b[0mflat_fun\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_tree\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mflatten_fun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0min_tree\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 169\u001b[0;31m out = xla.xla_call(flat_fun, *args_flat, device=device, backend=backend,\n\u001b[0m\u001b[1;32m 170\u001b[0m name=flat_fun.__name__, donated_invars=donated_invars)\n\u001b[1;32m 171\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mtree_unflatten\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout_tree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.local/lib/python3.8/site-packages/jax/core.py\u001b[0m in \u001b[0;36mcall_bind\u001b[0;34m(primitive, fun, *args, **params)\u001b[0m\n\u001b[1;32m 1098\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mtop_trace\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1099\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mnew_sublevel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1100\u001b[0;31m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mprimitive\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimpl\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfun\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1101\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1102\u001b[0m \u001b[0mtracers\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtop_trace\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfull_raise\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.local/lib/python3.8/site-packages/jax/interpreters/xla.py\u001b[0m in \u001b[0;36m_xla_call_impl\u001b[0;34m(fun, device, backend, name, donated_invars, *args)\u001b[0m\n\u001b[1;32m 542\u001b[0m *unsafe_map(arg_spec, args))\n\u001b[1;32m 543\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 544\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mcompiled_fun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 545\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mFloatingPointError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 546\u001b[0m print(\"Invalid value encountered in the output of a jit function. \"\n", + "\u001b[0;32m~/.local/lib/python3.8/site-packages/jax/interpreters/xla.py\u001b[0m in \u001b[0;36m_execute_compiled\u001b[0;34m(compiled, uses_outfeed, handlers, *args)\u001b[0m\n\u001b[1;32m 773\u001b[0m \u001b[0mdevice\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompiled\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlocal_devices\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 774\u001b[0m \u001b[0minput_bufs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mdevice_put\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdevice\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0margs\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mtoken\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 775\u001b[0;31m \u001b[0mout_bufs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompiled\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexecute\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput_bufs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 776\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mFLAGS\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjax_debug_nans\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mcheck_nans\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxla_call_p\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_bufs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 777\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mhandler\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout_buf\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mhandler\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_buf\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandlers\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_bufs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "for i in range(1000):\n", + " batch = get_batch()\n", + " optimizer, loss = train_step(optimizer, batch)\n", + " losses.append(loss)\n", + " if i%10 == 0:\n", + " print('Loss : %f'%loss)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found classifier NeuralNetwork\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot(losses[10:])" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "# Sweet :-D let's see if it did anything\n", + "w = optimizer.target(batch['features'])\n", + "nzs = [kde_nz(batch['labels'], w[:,i], bw=0.05, zmax=4.) for i in range(nbins)]" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "#figure(figsize=(13,7))\n", + "z = np.linspace(0,4)\n", + "nz_total = kde_nz(batch['labels'], np.ones_like(batch['labels']), bw=0.05)\n", + "plot(z, nz_total(z)*len(nz_total.params[0]))\n", + "for i, nz in enumerate(nzs):\n", + " plot(z, nz(z)*nz.params[1].sum(), '--', label='nz_%d'%i)\n", + "xlim(0,4)\n", + "legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "117.6470588235294" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "1./0.0085" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "# Exporting the trained model\n", + "from flax import serialization\n", + "import pickle\n", + "\n", + "with open('BinningNN_3x2_6b_FoM_DETF.pckl', 'wb') as file:\n", + " pickle.dump(serialization.to_bytes(optimizer.target), file)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/LearningToBin-Signal2Noise.ipynb b/notebooks/LearningToBin-Signal2Noise.ipynb new file mode 100644 index 00000000..32699a0d --- /dev/null +++ b/notebooks/LearningToBin-Signal2Noise.ipynb @@ -0,0 +1,491 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Populating the interactive namespace from numpy and matplotlib\n" + ] + } + ], + "source": [ + "import sys\n", + "sys.path.insert(0, '..')\n", + "%pylab inline" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Found classifier IBandOnly\n", + "Found classifier NeuralNetwork\n", + "Found classifier Random\n", + "Found classifier RandomForest\n" + ] + } + ], + "source": [ + "# Import JAX instead of numpy\n", + "import jax\n", + "import jax.numpy as np\n", + "import jax.random as rand\n", + "\n", + "# Import modified version of challenge metrics\n", + "from tomo_challenge import jax_metrics as metrics\n", + "\n", + "# Import tools from jax-cosmo\n", + "from jax_cosmo.redshift import kde_nz" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Loading the data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "../tomo_challenge/data.py:76: UserWarning: Setting inf (undetected) bands to mag=30\n", + " warnings.warn(\"Setting inf (undetected) bands to mag=30\")\n" + ] + } + ], + "source": [ + "from tomo_challenge.data import load_data, load_redshift\n", + "from sklearn.preprocessing import StandardScaler, RobustScaler\n", + "features_scaler = RobustScaler()\n", + "\n", + "data = load_data('../data/training.hdf5','riz',colors=True, errors=True, array=True)\n", + "m = (data[:,0] <32) & (data[:,1] <32) & (data[:,2] <32)\n", + "data = data[m]\n", + "\n", + "features = np.clip(np.array(features_scaler.fit_transform(data)),-4,4)\n", + "labels = np.array(load_redshift('../data/training.hdf5'))[m]" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's grab some data\n", + "batch_size = 10000\n", + "# Let's grab some data\n", + "batch_labels = labels[:batch_size]\n", + "batch_features = features[:batch_size]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "nz = kde_nz(batch_labels, np.ones_like(batch_labels), bw=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 0, 'redshift z')" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "z = np.linspace(0,4)\n", + "hist(batch_labels, 64, density=True)\n", + "plot(z, nz(z), label='jax-cosmo KDE')\n", + "xlim(0,4)\n", + "legend()\n", + "xlabel('redshift z')" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "for i in range(12):\n", + " hist(batch_features[:,i],100, alpha=0.3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Create a neural network classifier" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from flax import nn\n", + "from flax import optim" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "nbins=3\n", + "# Here is a trivial classifier for 2 bins\n", + "class BinningNN(nn.Module):\n", + " def apply(self, x):\n", + " \"\"\"\n", + " Takes as an input the features to use for binning\n", + " \"\"\"\n", + " net = nn.Dense(x, 500, name='fc1')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc2')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " net = nn.Dense(net, 500, name='fc3')\n", + " net = nn.leaky_relu(net)\n", + " net = nn.BatchNorm(net)\n", + " # The output of the model should be a gumbell softmax layer\n", + " return nn.softmax(nn.Dense(net, nbins))" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "@jax.jit\n", + "def train_step(optimizer, batch):\n", + " def loss_fn(model):\n", + " w = model(batch['features'])\n", + " return -metrics.compute_snr_score(w, batch['labels'])\n", + " loss, g = jax.value_and_grad(loss_fn)(optimizer.target)\n", + " optimizer = optimizer.apply_gradient(g)\n", + " return optimizer, loss" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# Let's get some initial weights\n", + "_, initial_params = BinningNN.init_by_shape( rand.PRNGKey(0), [((1, 12), np.float32)])\n", + "model = nn.Model(BinningNN, initial_params)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "optimizer = optim.Momentum(learning_rate=0.001, beta=0.9).create(model)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as onp\n", + "batch_size = 10000\n", + "def get_batch():\n", + " inds = onp.random.choice(len(labels), batch_size)\n", + " return {'labels': labels[inds], 'features': features[inds]}" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Before optimization, this is what the neural network gets us\n", + "batch = get_batch()\n", + "w = optimizer.target(batch['features'])\n", + "nzs = [kde_nz(batch['labels'], w[:,i], bw=0.01, zmax=4.) for i in range(nbins)]" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "z = np.linspace(0,4)\n", + "nz_total = kde_nz(batch['labels'], np.ones_like(batch['labels']), bw=0.01)\n", + "plot(z, nz_total(z)*len(nz_total.params[0]))\n", + "for i, nz in enumerate(nzs):\n", + " plot(z, nz(z)*nz.params[1].sum(), '--', label='nz_%d'%i)\n", + "xlim(0,4)\n", + "legend()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All the bins are overlapping and pretty much the same because the NN\n", + "is randomly assigning galaxies to bin, without strong hints from the\n", + "photometry" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "losses = []" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in asarray is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n", + "/home/francois/.local/lib/python3.8/site-packages/jax/lax/lax.py:5591: UserWarning: Explicitly requested dtype float64 requested in array is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n", + " warnings.warn(msg.format(dtype, fun_name , truncated_dtype))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loss : -590.973816\n", + "Loss : -893.604553\n", + "Loss : -892.638184\n", + "Loss : -891.500549\n", + "Loss : -889.718262\n", + "Loss : -893.868958\n", + "Loss : -891.760742\n", + "Loss : -891.517090\n", + "Loss : -893.302673\n", + "Loss : -898.416748\n", + "Loss : -894.637329\n", + "Loss : -895.955505\n", + "Loss : -892.862488\n", + "Loss : -893.471008\n", + "Loss : -897.341125\n" + ] + } + ], + "source": [ + "# Now let's train the model for a little while\n", + "for i in range(1500):\n", + " optimizer, loss = train_step(optimizer, get_batch())\n", + " losses.append(loss)\n", + " if i%100 == 0:\n", + " print('Loss : %f'%loss)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plot(losses[10:])" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "# Sweet :-D let's see if it did anything\n", + "batch = get_batch()\n", + "w = optimizer.target(batch['features'])\n", + "nzs = [kde_nz(batch['labels'], w[:,i], bw=0.01, zmax=4.) for i in range(nbins)]" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "z = np.linspace(0,4)\n", + "nz_total = kde_nz(batch['labels'], np.ones_like(batch['labels']), bw=0.01)\n", + "plot(z, nz_total(z)*len(nz_total.params[0]))\n", + "for i, nz in enumerate(nzs):\n", + " plot(z, nz(z)*nz.params[1].sum(), '--', label='nz_%d'%i)\n", + "xlim(0,4)\n", + "legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# Exporting the trained model\n", + "from flax import serialization\n", + "import pickle\n", + "\n", + "with open('BinningNN5b.pckl', 'wb') as file:\n", + " pickle.dump(serialization.to_bytes(optimizer.target), file)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.8.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/plots/NeuralNetwork_{'bins': 2, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png b/plots/NeuralNetwork_{'bins': 2, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png new file mode 100644 index 00000000..02579435 Binary files /dev/null and b/plots/NeuralNetwork_{'bins': 2, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png differ diff --git a/plots/NeuralNetwork_{'bins': 3, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png b/plots/NeuralNetwork_{'bins': 3, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png new file mode 100644 index 00000000..e169a363 Binary files /dev/null and b/plots/NeuralNetwork_{'bins': 3, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png differ diff --git a/plots/NeuralNetwork_{'bins': 4, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png b/plots/NeuralNetwork_{'bins': 4, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png new file mode 100644 index 00000000..e987382d Binary files /dev/null and b/plots/NeuralNetwork_{'bins': 4, 'metric': 'FOM_DETF', 'colors': True, 'errors': True}_riz.png differ diff --git a/plots/RandomForest_bins_1_riz.png b/plots/RandomForest_bins_1_riz.png new file mode 100644 index 00000000..cd53d1ae Binary files /dev/null and b/plots/RandomForest_bins_1_riz.png differ diff --git a/plots/RandomForest_bins_2_riz.png b/plots/RandomForest_bins_2_riz.png new file mode 100644 index 00000000..1025318f Binary files /dev/null and b/plots/RandomForest_bins_2_riz.png differ diff --git a/plots/RandomForest_bins_3_riz.png b/plots/RandomForest_bins_3_riz.png new file mode 100644 index 00000000..bfe84703 Binary files /dev/null and b/plots/RandomForest_bins_3_riz.png differ diff --git a/plots/RandomForest_bins_4_riz.png b/plots/RandomForest_bins_4_riz.png new file mode 100644 index 00000000..41a6d5b0 Binary files /dev/null and b/plots/RandomForest_bins_4_riz.png differ diff --git a/requirements.txt b/requirements.txt index 5dc13c50..e1988b10 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ camb click progressbar jax-cosmo==0.1rc6 +flax diff --git a/tomo_challenge/classifiers/iband_only.py b/tomo_challenge/classifiers/iband_only.py index 83a91a23..e6b0cc20 100644 --- a/tomo_challenge/classifiers/iband_only.py +++ b/tomo_challenge/classifiers/iband_only.py @@ -2,7 +2,7 @@ from .base import Tomographer class IBandOnly(Tomographer): - """Classifier for people who love nothing more than the i-band. + """Classifier for people who love nothing more than the i-band. Classifies in uniform bins in the i-band mag. """ valid_options = ['bins'] @@ -11,7 +11,7 @@ def __init__ (self, bands, options): self.opt = options if 'bins' not in options: self.opt['bins'] = 3 - + def train (self,training_data, training_z): pass diff --git a/tomo_challenge/classifiers/neural_network.py b/tomo_challenge/classifiers/neural_network.py new file mode 100644 index 00000000..e5262358 --- /dev/null +++ b/tomo_challenge/classifiers/neural_network.py @@ -0,0 +1,185 @@ +import numpy as onp + +import os.path +import pickle + + +# Some JAX imports +import jax +import jax.numpy as np +import jax.random as rand + +# Import JAX-based Neural Network library +from flax import nn, optim, serialization + +# And some good old sklearn +from sklearn.preprocessing import RobustScaler + +import tomo_challenge.jax_metrics as metrics + +from .base import Tomographer + +# Conviniently stores the number of features +n_features = {'riz':12, 'griz':20} + +# Function creating the neural network for a specific number of bins +def get_classifier(n_bin, n_features): + # Let's create a cute little neural network for classification + class BinningNN(nn.Module): + def apply(self, x): + net = nn.Dense(x, 500, name='fc1') + net = nn.leaky_relu(net) + net = nn.BatchNorm(net) + net = nn.Dense(net, 500, name='fc2') + net = nn.leaky_relu(net) + net = nn.BatchNorm(net) + net = nn.Dense(net, 500, name='fc3') + net = nn.leaky_relu(net) + net = nn.BatchNorm(net) + return nn.softmax(nn.Dense(net, n_bin)) + # Initializing neural network weights for this configuration + _, initial_params = BinningNN.init_by_shape( rand.PRNGKey(0), + [((1, n_features), np.float32)]) + # This instantiates the model, now ready to use + return nn.Model(BinningNN, initial_params) + +class NeuralNetwork(Tomographer): + """ Neural Network Classifier """ + + # valid parameter -- see below + valid_options = ['bins', 'metric', 'output_dir'] + # this settings means arrays will be sent to train and apply instead + # of dictionaries + wants_arrays = True + + def __init__ (self, bands, options): + """Constructor + + Parameters: + ----------- + bands: str + string containg valid bands, like 'riz' or 'griz' + options: dict + options come through here. Valid keys are listed as valid_options + class variable. + + Note: + ----- + Valiad options are: + 'bins' - number of tomographic bins + + """ + self.bands = bands + self.opt = options + + self.n_features = n_features[bands] + self.n_bin = options['bins'] + self.metric = options['metric'] + self.output_dir = options['output_dir'] + # Build a name for the model based on bands and options + self.export_name = f'{self.output_dir}/{self.metric}_{bands}_{self.n_bin}.flax' + + # Create classifier + self.model = get_classifier(self.n_bin, self.n_features) + # Create scaler + self.features_scaler = RobustScaler() + + def train (self, training_data, training_z, + batch_size=5000, niter=2000): + """Trains the classifier + + Parameters: + ----------- + training_data: numpy array, size Ngalaxes x Nbands + training data, each row is a galaxy, each column is a band as per + band defined above + training_z: numpy array, size Ngalaxies + true redshift for the training sample + + """ + # create scaler + + features = self.features_scaler.fit_transform(training_data) + features = np.clip(features,-4,4) + labels = training_z + + # If model is already trained, we just load the weights + if os.path.exists(self.export_name): + with open(self.export_name, 'rb') as file: + self.model = serialization.from_bytes(self.model, pickle.load(file)) + return + + lr = 0.001 + optimizer = optim.Adam(learning_rate=lr).create(self.model) + + @jax.jit + def train_step(optimizer, batch): + # This is the loss function + def loss_fn(model): + # Apply classifier to features + w = model(batch['features']) + # returns - score, because we want to maximize score + if self.metric == 'SNR': + return - metrics.compute_snr_score(w, batch['labels']) + elif self.metric == 'FOM': + # Minimizing the Area + return 1. / metrics.compute_fom(w, batch['labels']) + elif self.metric == 'FOM_DETF': + # Minimizing the Area + return 1. / metrics.compute_fom(w, batch['labels'], inds=[5,6]) + else: + raise NotImplementedError + # Compute gradients + loss, g = jax.value_and_grad(loss_fn)(optimizer.target) + # Perform gradient descent + optimizer = optimizer.apply_gradient(g) + return optimizer, loss + + # This function provides random batches of data, TODO: convert to JAX + print("Size of dataset", len(labels)) + def get_batch(): + inds = onp.random.choice(len(labels), batch_size) + return {'labels': labels[inds], 'features': features[inds]} + + losses = [] + for i in range(niter): + optimizer, loss = train_step(optimizer, get_batch()) + losses.append(loss) + if i%100 == 0: + print('iter: %d; Loss : %f'%(i,loss)) + + # Export model to disk + with open(self.export_name, 'wb') as file: + pickle.dump(serialization.to_bytes(optimizer.target), file) + + self.model = optimizer.target + + def apply (self, data): + """Applies training to the data. + + Parameters: + ----------- + Data: numpy array, size Ngalaxes x Nbands + testing data, each row is a galaxy, each column is a band as per + band defined above + + Returns: + tomographic_selections: numpy array, int, size Ngalaxies + tomographic selection for galaxies return as bin number for + each galaxy. + """ + features = np.array(self.features_scaler.transform(data)) + features = np.clip(features,-4,4) + + # Retrieves the classification data as bin probabilities, by batch + bs = 10000 + s = len(features) + weights = np.concatenate([self.model(features[bs*i:min((bs*(i+1)), s)]) for i + in range(s//bs + 1)]) + + # let's just check we didn't forget anyone + assert len(weights) == s + + # Retrieve most likely bin for each galaxy + tomo_bin = weights.argmax(axis=-1) + return tomo_bin diff --git a/tomo_challenge/config.yml b/tomo_challenge/config.yml index f56af53d..579dee30 100644 --- a/tomo_challenge/config.yml +++ b/tomo_challenge/config.yml @@ -9,7 +9,6 @@ parameters: w0: -1.0 wa: 0.0 - # Defines options when running one of the samplers # through cosmosis cosmosis: @@ -25,6 +24,7 @@ cosmosis: h: [0.5, 0.67, 0.9] sigma8: [0.74, 0.8404844953840714, 0.94] n_s: [0.9, 0.96, 1.02] + # I'd like to do the proper DETF FoM, # but right now our camb config rejects this # since it crosses w=-1. So for now use an diff --git a/tomo_challenge/data.py b/tomo_challenge/data.py index 03eadc5c..3c955ed7 100644 --- a/tomo_challenge/data.py +++ b/tomo_challenge/data.py @@ -75,7 +75,7 @@ def download_data(): filename = f'{f}.hdf5' progress = MyProgressBar() urlretrieve(f'{url_root_buzzard}/{filename}', f'data_buzzard/{filename}', reporthook=progress) - + def load_mags(filename, bands, errors=False): diff --git a/tomo_challenge/jax_metrics.py b/tomo_challenge/jax_metrics.py index e9e1ca50..40eeaf1d 100644 --- a/tomo_challenge/jax_metrics.py +++ b/tomo_challenge/jax_metrics.py @@ -21,7 +21,7 @@ def ell_binning(): delta_ell =(ell_edges[1:]-ell_edges[:-1]) return ell, delta_ell -def get_probes(weights, labels, kernel_bandwidth=0.05, what='3x2', binned_nz=False): +def get_probes(weights, labels, kernel_bandwidth=0.02, what='3x2', binned_nz=False): """ JAX function that builds the 3x2pt probes, which can then be used within any metric