diff --git a/.gitignore b/.gitignore index 20f6d1d..83668ea 100644 --- a/.gitignore +++ b/.gitignore @@ -2,9 +2,12 @@ __pycache__/ *.py[cod] *$py.class - +tony/logs/* +tony/models/* # C extensions *.so +operator/train/*.pth +operator/data/* pinn/frames/ # Distribution / packaging .Python diff --git a/operator/AdaFNN.ipynb b/operator/AdaFNN.ipynb new file mode 100644 index 0000000..07ebe71 --- /dev/null +++ b/operator/AdaFNN.ipynb @@ -0,0 +1,1234 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2440e3d5", + "metadata": {}, + "source": [ + "# Functional Neural Network with Adaptive Bases\n", + "\n", + "In this notewboook, we present a PyTorch implementation of the model proposed in \"Deep Learning for Functional Data Analysis with Adaptive Basis Layers\", ICML 2021." + ] + }, + { + "cell_type": "markdown", + "id": "2c3017f4", + "metadata": {}, + "source": [ + "Unlike many functional networks, AdaFNNs take the raw functional data as input and learn to apply parsimonious dimension reduction that focuses only on information relevant to the target rather than irrelevant variation in the input. This operation is done through a novel _Basis Layer_ that consists of _basis nodes_ implemented as micro networks. In addition, the inference and training can be done in an end-to-end manner without preprocessing the data." + ] + }, + { + "cell_type": "markdown", + "id": "6affceee", + "metadata": {}, + "source": [ + "# Implementing AdaFNNs" + ] + }, + { + "cell_type": "markdown", + "id": "2aca2c60", + "metadata": {}, + "source": [ + "First, we provide the code for two building blocks, a layer normalization module and feedforward network module (with skipping connection). We start by import the necessary packages." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "b07e35d0", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "markdown", + "id": "c730b770", + "metadata": {}, + "source": [ + "### Layer Normalization\n", + "\n", + "The layer normalization was introduced in [Layer Normalization](https://arxiv.org/abs/1607.06450). It is a transposition of Batch Normalization. " + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "8d7be4d5", + "metadata": {}, + "outputs": [], + "source": [ + "class LayerNorm(nn.Module):\n", + "\n", + " def __init__(self, d, eps=1e-6):\n", + " super().__init__()\n", + " # d is the normalization dimension\n", + " self.d = d\n", + " self.eps = eps\n", + " self.alpha = nn.Parameter(torch.randn(d))\n", + " self.beta = nn.Parameter(torch.randn(d))\n", + "\n", + " def forward(self, x):\n", + " # x is a torch.Tensor\n", + " # avg is the mean value of a layer\n", + " avg = x.mean(dim=-1, keepdim=True)\n", + " # std is the standard deviation of a layer (eps is added to prevent dividing by zero)\n", + " std = x.std(dim=-1, keepdim=True) + self.eps\n", + " return (x - avg) / std * self.alpha + self.beta" + ] + }, + { + "cell_type": "markdown", + "id": "8092aa37", + "metadata": {}, + "source": [ + "Next, we implement a feedforward network module." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4a6e44b4", + "metadata": {}, + "outputs": [], + "source": [ + "class FeedForward(nn.Module):\n", + "\n", + " def __init__(self, in_d=1, hidden=[4,4,4], dropout=0.1, activation=F.relu):\n", + " # in_d : input dimension, integer\n", + " # hidden : hidden layer dimension, array of integers\n", + " # dropout : dropout probability, a float between 0.0 and 1.0\n", + " # activation: activation function at each layer\n", + " super().__init__()\n", + " self.sigma = activation\n", + " dim = [in_d] + hidden + [1]\n", + " self.layers = nn.ModuleList([nn.Linear(dim[i-1], dim[i]) for i in range(1, len(dim))])\n", + " self.ln = nn.ModuleList([LayerNorm(k) for k in hidden])\n", + " self.dp = nn.ModuleList([nn.Dropout(dropout) for _ in range(len(hidden))])\n", + "\n", + " def forward(self, t):\n", + " for i in range(len(self.layers)-1):\n", + " t = self.layers[i](t)\n", + " # skipping connection\n", + " t = t + self.ln[i](t)\n", + " t = self.sigma(t)\n", + " # apply dropout\n", + " t = self.dp[i](t)\n", + " # linear activation at the last layer\n", + " return self.layers[-1](t)" + ] + }, + { + "cell_type": "markdown", + "id": "58931d84", + "metadata": {}, + "source": [ + "### Metric operations\n", + "\n", + "To build an AdaFNN, we need three new operations: (1) $\\langle f_1, f_2 \\rangle$ (2) $\\| f \\|_2$ and (3) $\\| f \\|_1$. The last two can be established on the first one through: \n", + "\n", + "$$ \\| f\\|_2 = \\sqrt{ \\langle f, f \\rangle} $$\n", + "and \n", + "$$ \\| f\\|_1 = \\langle 1, |f| \\rangle .$$" + ] + }, + { + "cell_type": "markdown", + "id": "02f6d199", + "metadata": {}, + "source": [ + "Since the input is densely observed (equal spacing is not required), the inner product can be approximated by any numerical integration scheme. Here, we will use the [trapezoidal rule](https://en.wikipedia.org/wiki/Trapezoidal_rule)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e2409c51", + "metadata": {}, + "outputs": [], + "source": [ + "def _inner_product(f1, f2, h):\n", + " \"\"\" \n", + " f1 - (B, J) : B functions, observed at J time points,\n", + " f2 - (B, J) : same as f1\n", + " h - (J-1,1): weights used in the trapezoidal rule\n", + " pay attention to dimension\n", + " = sum (h/2) (f1(t{j}) + f2(t{j+1}))\n", + " \"\"\"\n", + " prod = f1 * f2 # (B, J = len(h) + 1)\n", + " return torch.matmul((prod[:, :-1] + prod[:, 1:]), h.unsqueeze(dim=-1))/2" + ] + }, + { + "cell_type": "markdown", + "id": "b88e8f32", + "metadata": {}, + "source": [ + "Then $L_1$ and $L_2$ can be easily implememnted as:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "6f718d8a", + "metadata": {}, + "outputs": [], + "source": [ + "def _l1(f, h):\n", + " # f dimension : ( B bases, J )\n", + " B, J = f.size()\n", + " return _inner_product(torch.abs(f), torch.ones((B, J)), h)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "43dca4c2", + "metadata": {}, + "outputs": [], + "source": [ + "def _l2(f, h):\n", + " # f dimension : ( B bases, J )\n", + " # output dimension - ( B bases, 1 )\n", + " return torch.sqrt(_inner_product(f, f, h)) " + ] + }, + { + "cell_type": "markdown", + "id": "0dae9e31", + "metadata": {}, + "source": [ + "### AdaFNN\n", + "\n", + "To prevent the original scale of basis nodes from dominating regularizers, they are normalized.\n", + "\n", + "With these in hand, we are ready to present the AdaFNN implmentation. " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "223940df", + "metadata": {}, + "outputs": [], + "source": [ + "class AdaFNN(nn.Module):\n", + "\n", + " def __init__(self, n_base=4, base_hidden=[64, 64, 64], grid=(0, 1),\n", + " sub_hidden=[128, 128, 128], dropout=0.1, lambda1=0.0, lambda2=0.0,\n", + " device=None):\n", + " \"\"\"\n", + " n_base : number of basis nodes, integer\n", + " base_hidden : hidden layers used in each basis node, array of integers\n", + " grid : observation time grid, array of sorted floats including 0.0 and 1.0\n", + " sub_hidden : hidden layers in the subsequent network, array of integers\n", + " dropout : dropout probability\n", + " lambda1 : penalty of L1 regularization, a positive real number\n", + " lambda2 : penalty of L2 regularization, a positive real number\n", + " device : device for the training\n", + " \"\"\"\n", + " super().__init__()\n", + " self.n_base = n_base\n", + " self.lambda1 = lambda1\n", + " self.lambda2 = lambda2\n", + " self.device = device\n", + " # grid should include both end points\n", + " grid = np.array(grid)\n", + " # send the time grid tensor to device\n", + " self.t = torch.tensor(grid).to(device).float()\n", + " self.h = torch.tensor(grid[1:] - grid[:-1]).to(device).float()\n", + " # instantiate each basis node in the basis layer\n", + " self.BL = nn.ModuleList([FeedForward(1, hidden=base_hidden, dropout=dropout, activation=F.selu)\n", + " for _ in range(n_base)])\n", + " # instantiate the subsequent network\n", + " self.FF = FeedForward(n_base, sub_hidden, dropout)\n", + "\n", + " def forward(self, x):\n", + " B, J = x.size()\n", + " assert J == self.h.size()[0] + 1\n", + " T = self.t.unsqueeze(dim=-1)\n", + " # evaluate the current basis nodes at time grid\n", + " self.bases = [basis(T).transpose(-1, -2) for basis in self.BL]\n", + " \"\"\"\n", + " compute each basis node's L2 norm\n", + " normalize basis nodes\n", + " \"\"\"\n", + " l2_norm = _l2(torch.cat(self.bases, dim=0), self.h).detach()\n", + " self.normalized_bases = [self.bases[i] / (l2_norm[i, 0] + 1e-6) for i in range(self.n_base)]\n", + " # compute each score \n", + " score = torch.cat([_inner_product(b.repeat((B, 1)), x, self.h) # (B, 1)\n", + " for b in self.bases], dim=-1) # score dim = (B, n_base)\n", + " # take the tensor of scores into the subsequent network\n", + " out = self.FF(score)\n", + " return out\n", + "\n", + " def R1(self, l1_k):\n", + " \"\"\"\n", + " L1 regularization\n", + " l1_k : number of basis nodes to regularize, integer \n", + " \"\"\"\n", + " if self.lambda1 == 0: return torch.zeros(1).to(self.device)\n", + " # sample l1_k basis nodes to regularize\n", + " selected = np.random.choice(self.n_base, min(l1_k, self.n_base), replace=False)\n", + " selected_bases = torch.cat([self.normalized_bases[i] for i in selected], dim=0) # (k, J)\n", + " return self.lambda1 * torch.mean(_l1(selected_bases, self.h))\n", + "\n", + " def R2(self, l2_pairs):\n", + " \"\"\"\n", + " L2 regularization\n", + " l2_pairs : number of pairs to regularize, integer \n", + " \"\"\"\n", + " if self.lambda2 == 0 or self.n_base == 1: return torch.zeros(1).to(self.device)\n", + " k = min(l2_pairs, self.n_base * (self.n_base - 1) // 2)\n", + " f1, f2 = [None] * k, [None] * k\n", + " for i in range(k):\n", + " a, b = np.random.choice(self.n_base, 2, replace=False)\n", + " f1[i], f2[i] = self.normalized_bases[a], self.normalized_bases[b]\n", + " return self.lambda2 * torch.mean(torch.abs(_inner_product(torch.cat(f1, dim=0),\n", + " torch.cat(f2, dim=0),\n", + " self.h)))" + ] + }, + { + "cell_type": "markdown", + "id": "f0f6d739", + "metadata": {}, + "source": [ + "# Data" + ] + }, + { + "cell_type": "markdown", + "id": "2e652727", + "metadata": {}, + "source": [ + "### Data Generator\n", + "\n", + "Data is generated based on the following model:\n", + "\n", + "$$ X(t) \\ = \\ \\sum_{k=1}^{50} c_k \\phi_k (t), \\quad t \\in [0,1] ,$$ \n", + "where terms on the right hand side are defined as:\n", + "\n", + "1. $\\phi_1 (t) = 1$ and $ \\phi_k (t) = \\sqrt{2} \\cos ( (k-1) \\pi t)$ for $k = 2, \\dots, 50$.\n", + "2. $c_k = z_k r_k$, and $r_k$ are i.i.d. uniform random variables on $[-\\sqrt{3}, \\sqrt{3}]$.\n", + "\n", + "Case 1: $z_1 = 20$, $z_2 = z_3 = 5$, and $z_k = 1$ for $k \\geq 4$. $y = \\big( \\langle \\phi_3, X \\rangle \\big)^2$.\n", + "\n", + "Case 2 and 3: $z_1 = z_3 = 5$, $z_5 = z_{10} = 3$, and $z_k = 1$ for other $k$. $y = \\big( \\langle \\phi_5, X \\rangle \\big)^2$.\n", + "\n", + "Case 4: $X$ has the same configurations as Case 2. But $y=\\langle \\beta_2, X \\rangle + \\big( \\langle \\beta_1, X \\rangle \\big)^2$ with\n", + "\n", + "$$ \\beta_1 (t) = (4 - 16t) \\cdot 1 \\big\\{ 0 \\leq t \\leq 1/4 \\big\\} $$\n", + "and\n", + "$$ \\beta_2 (t) = \\big( 4 - 16|t-1/2| \\big) \\cdot 1 \\big\\{ |t-1/2| \\leq 1/4 \\big\\} .$$\n", + "\n", + "For each time point $t$, the observed $X(t)$ may be contaminated by measurement error, i.e.\n", + "\n", + "$$ \\tilde{X} (t) = X (t) + \\eta_t, \\quad \\eta_t \\stackrel{i.i.d.}{\\sim} N (0, \\sigma^2_1) .$$\n", + "\n", + "The response $y$ may also have noise, i.e. $\\tilde{y} = y + \\epsilon$ where $\\epsilon \\stackrel{i.i.d.}{\\sim} N (0, \\sigma^2_2)$.\n" + ] + }, + { + "cell_type": "markdown", + "id": "5143e254", + "metadata": {}, + "source": [ + "First, we import necessary dependencies." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "575c8aaf", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from pathlib import Path" + ] + }, + { + "cell_type": "markdown", + "id": "45be7c3b", + "metadata": {}, + "source": [ + "Next, we list configurations for each cases and implememnt functions for generating $X$ and $y$." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "5009dcc6", + "metadata": {}, + "outputs": [], + "source": [ + "z1 = [20, 5, 5] + [1] * 47\n", + "z2 = [1] * 50\n", + "z2[0] = z2[2] = 5\n", + "z2[4] = z2[9] = 3\n", + "Z = [z1, z2, z2, [1] * 50]\n", + "\n", + "\n", + "def _phi(k):\n", + " if k == 1: return lambda t: np.ones((len(t),))\n", + " return lambda t : np.sqrt(2) * np.cos((k-1) * np.pi * t)\n", + "\n", + "\n", + "def _b1(t):\n", + " return (4 - 16 * t) * (0 <= t) * (t <= 1/4)\n", + "\n", + "\n", + "def _b2(t):\n", + " return (4 - 16 * np.abs(1/2 - t)) * (1/4 <= t) * (t <= 3/4)" + ] + }, + { + "cell_type": "markdown", + "id": "491d3a4e", + "metadata": {}, + "source": [ + "The DataGenerator class generates data and save it to csv files." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "0bb165a7", + "metadata": {}, + "outputs": [], + "source": [ + "class DataGenerator:\n", + "\n", + " def __init__(self, grid, case=1, me=1, err=1):\n", + " \"\"\"\n", + " grid : array of time points, floats\n", + " case : case number, integer\n", + " me : variance of measurement error added to X, non-negative real value\n", + " err : variance of noise added to Y, non-negative real value\n", + " \"\"\"\n", + " self.t = np.array(grid)\n", + " # measurement error\n", + " self.me = me\n", + " self.err = err\n", + " # case - 1\n", + " self.case = case\n", + " self.z = np.array(Z[case-1])\n", + "\n", + " def generate(self, n=1000):\n", + " \"\"\"\n", + " n : number of subjects to generate, integer\n", + " \"\"\"\n", + " # X = sum c_k phi_k\n", + " # c_k = z_k r_k, r_k iid unif[-sqrt(3), sqrt(3)]\n", + " # generate r\n", + " r = np.random.uniform(low=-np.sqrt(3), high=np.sqrt(3), size=(n, 50))\n", + " c = r * self.z # (n, 50) elementwise multiplication\n", + " phi = np.array([_phi(k)(self.t) for k in range(1, 51)]) # (50, len(self.t))\n", + " X = np.matmul(c, phi) # (n, len(self.t))\n", + " Y = np.zeros((n, 1))\n", + " if self.case == 1:\n", + " Y = (c[:, 2]) ** 2\n", + " elif self.case == 4:\n", + " beta1 = _b1(self.t)\n", + " beta2 = _b2(self.t)\n", + " h = np.array(self.t[1:] - self.t[:-1]).T\n", + " for i in range(n):\n", + " Y[i, 0] = self._inner_product(beta2, X[i, :], h) + self._inner_product(beta1, X[i, :], h) ** 2\n", + "\n", + " else: # self.case = 2 or 3\n", + " Y = (c[:, 4]) ** 2 \n", + " self.X = X + np.random.normal(0, self.me, size=(n, len(self.t)))\n", + " self.Y = Y.reshape((n, 1)) + np.random.normal(0, self.err, size=(n, 1))\n", + " \n", + " def _inner_product(self, f1, f2, h):\n", + " prod = f1 * f2\n", + " if len(prod.shape) < 2:\n", + " prod = prod.reshape((1, -1))\n", + " res = np.matmul(prod[:, :-1] + prod[:, 1:], h) / 2\n", + " return res\n", + "\n", + " def save(self, folder):\n", + " \"\"\"\n", + " folder : folder where observations are saved\n", + " \"\"\"\n", + " Path(folder).mkdir(parents=True, exist_ok=True)\n", + " X_df = pd.DataFrame(self.X)\n", + " Y_df = pd.DataFrame(self.Y)\n", + " T_df = pd.DataFrame(self.t.reshape((1, -1)))\n", + " X_df.to_csv(folder + \"X.csv\", index=False, header=None)\n", + " Y_df.to_csv(folder + \"Y.csv\", index=False, header=None)\n", + " T_df.to_csv(folder + \"T.csv\", index=False, header=None)" + ] + }, + { + "cell_type": "markdown", + "id": "3720e239", + "metadata": {}, + "source": [ + "The time grid doesn't have to be equally spaced. The model works as long as the time gap is small enough for numerical integration to work well." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "98deebb2", + "metadata": {}, + "outputs": [], + "source": [ + "def random_grid(d=0.02):\n", + " \"\"\"\n", + " d : maximum time gap between two consecutive time points, float\n", + " \"\"\"\n", + " grid = [0.0]\n", + " while 1.0 - grid[-1] > d:\n", + " grid.append(grid[-1] + np.random.uniform(0, d, 1).item())\n", + " return grid + [1.0]" + ] + }, + { + "cell_type": "markdown", + "id": "ae58325a", + "metadata": {}, + "source": [ + "### Data Loader\n", + "\n", + "This module reads the dataset from csv files and split it according to a pre-specific train/valid/test ratio. The dataset is standardized." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "fb3d8cd5", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.preprocessing import StandardScaler\n", + "\n", + "class DataLoader:\n", + "\n", + " def __init__(self, batch_size, X, Y, T, split=(8, 1, 1), random_seed=10294): \n", + " \"\"\"\n", + " batch_size : batch size, integer\n", + " X - (n, J) : pandas.DataFrame for observed functional data, n - subject number, J - number of time points\n", + " Y - (n, 1) : pandas.DataFrame for response\n", + " split : train/valid/test split\n", + " random_seed: random seed for training data re-shuffle\n", + " \"\"\" \n", + " self.n, J = X.shape\n", + " self.t = T.iloc[0, :].to_numpy()\n", + " X, Y = X.values, Y.values\n", + "\n", + " # train/valid/test split\n", + " self.batch_size = batch_size\n", + " train_n = self.n // sum(split) * split[0]\n", + " valid_n = self.n // sum(split) * split[1]\n", + " test_n = self.n - train_n - valid_n\n", + " self.train_B = train_n // batch_size\n", + " self.valid_B = valid_n // batch_size\n", + " self.test_B = test_n // batch_size\n", + "\n", + " # random shuffle\n", + " np.random.seed(random_seed)\n", + " _order = list(range(self.n))\n", + " np.random.shuffle(_order)\n", + " X = X[_order, :]\n", + " Y = Y[_order, :]\n", + "\n", + " # standardize dataset based on the training dataset\n", + " self.X_standardizer = StandardScaler()\n", + " self.Y_standardizer = StandardScaler()\n", + "\n", + " # train/valid/test split\n", + " self.train_X = X[:(self.train_B * self.batch_size), :]\n", + " self.train_Y = Y[:(self.train_B * self.batch_size), :]\n", + " self.X_standardizer.fit(self.train_X)\n", + " self.Y_standardizer.fit(self.train_Y)\n", + " self.train_X = self.X_standardizer.transform(self.train_X)\n", + " self.train_Y = self.Y_standardizer.transform(self.train_Y)\n", + "\n", + " self.valid_X = X[(self.train_B * self.batch_size):((self.train_B + self.valid_B) * self.batch_size), :]\n", + " self.valid_Y = Y[(self.train_B * self.batch_size):((self.train_B + self.valid_B) * self.batch_size), :]\n", + " self.valid_X = self.X_standardizer.transform(self.valid_X)\n", + " self.valid_Y = self.Y_standardizer.transform(self.valid_Y)\n", + "\n", + " self.test_X = X[((self.train_B + self.valid_B) * self.batch_size):, :]\n", + " self.test_Y = Y[((self.train_B + self.valid_B) * self.batch_size):, :]\n", + " self.test_X = self.X_standardizer.transform(self.test_X)\n", + " self.test_Y = self.Y_standardizer.transform(self.test_Y)\n", + "\n", + " def shuffle(self):\n", + " # re-shuffle the training dataset\n", + " train_size = self.train_X.shape[0]\n", + " new_order = list(range(train_size))\n", + " np.random.shuffle(new_order)\n", + " self.train_X = self.train_X[new_order, :]\n", + " self.train_Y = self.train_Y[new_order, :]\n", + "\n", + " def _batch_generator(self, X, Y, N):\n", + "\n", + " def generator_func():\n", + " for i in range(1, N):\n", + " x = X[((i - 1) * self.batch_size):((i) * self.batch_size), :]\n", + " y = Y[((i - 1) * self.batch_size):((i) * self.batch_size), :]\n", + "\n", + " yield torch.Tensor(x), torch.Tensor(y)\n", + "\n", + " return generator_func()\n", + "\n", + " def get_train_batch(self):\n", + " return self._batch_generator(self.train_X, self.train_Y, self.train_B)\n", + "\n", + " def get_valid_batch(self):\n", + " return self._batch_generator(self.valid_X, self.valid_Y, self.valid_B)\n", + "\n", + " def get_test_batch(self):\n", + " return self._batch_generator(self.test_X, self.test_Y, self.test_B)" + ] + }, + { + "cell_type": "markdown", + "id": "cc49638f", + "metadata": {}, + "source": [ + "# Training the model" + ] + }, + { + "cell_type": "markdown", + "id": "068ba9f4", + "metadata": {}, + "source": [ + "First, we load necessary packages." + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "9040ebf5", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "import torch\n", + "import numpy as np\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from pathlib import Path\n", + "from torch.optim import Adam" + ] + }, + { + "cell_type": "markdown", + "id": "bfaef536", + "metadata": {}, + "source": [ + "A dataset will be generated if it is not present. \n", + "\n", + "Here, we set the measurement error variance to be 1 and noise variance to be 0.2.\n", + "\n", + "**Note**: in this example, we use a flexible time point gap (**not** equal spacing). " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "9a6f7cc7", + "metadata": {}, + "outputs": [], + "source": [ + "if not Path(\"data\").is_dir():\n", + " d = 0.02\n", + " # tp = np.arange(0, 1 + d, d)\n", + " tp = random_grid(d)\n", + " DatGen = DataGenerator(tp, case=3, me=1.0, err=0.2)\n", + " DatGen.generate(4000)\n", + " DatGen.save(\"data/\")" + ] + }, + { + "cell_type": "markdown", + "id": "ac248ade", + "metadata": {}, + "source": [ + "The dataset is loaded and split for training/validation/test." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "7d177bf7", + "metadata": {}, + "outputs": [], + "source": [ + "batch_size = 128\n", + "split = (64, 16, 20)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "ce9c71c4", + "metadata": {}, + "outputs": [], + "source": [ + "X = pd.read_csv(\"data/X.csv\", header=None)\n", + "Y = pd.read_csv(\"data/Y.csv\", header=None)\n", + "T = pd.read_csv(\"data/T.csv\", header=None)\n", + "grid = T.iloc[0, :].to_list()\n", + "dataLoader = DataLoader(batch_size, X, Y, T, split)" + ] + }, + { + "cell_type": "markdown", + "id": "41d09fa1", + "metadata": {}, + "source": [ + "Prepare the model and other training configurations:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "79a0848f", + "metadata": {}, + "outputs": [], + "source": [ + "# set up CPU/GPU\n", + "device = torch.device(\"cpu\") \n", + "# model configuration\n", + "\"\"\"\n", + "You can use a different model by modifing base_hidden, sub_hidden, n_base.\n", + "\"\"\"\n", + "base_hidden = [256, 256, 256, 256]\n", + "sub_hidden = [64, 64]\n", + "n_base = 2\n", + "lambda1, l1_k = 0.0, 2\n", + "lambda2, l2_pairs = 0.0, 3\n", + "dropout = 0.1\n", + "save_model_every = 100\n", + "model = AdaFNN(n_base=n_base,\n", + " base_hidden=base_hidden,\n", + " grid=grid,\n", + " sub_hidden=sub_hidden,\n", + " dropout=dropout,\n", + " lambda1=lambda1,\n", + " lambda2=lambda2,\n", + " device=device)\n", + "# send model to CPU/GPU\n", + "_ = model.to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "cf7301ca", + "metadata": {}, + "outputs": [], + "source": [ + "# training configuration\n", + "epoch = 500\n", + "pred_loss_train_history = []\n", + "total_loss_train_history = []\n", + "loss_valid_history = []\n", + "# instantiate an optimizer\n", + "optimizer = Adam(model.parameters(), lr=3e-4)\n", + "# use MSE loss\n", + "compute_loss = torch.nn.MSELoss()\n", + "min_valid_loss = sys.maxsize" + ] + }, + { + "cell_type": "markdown", + "id": "564cc291", + "metadata": {}, + "source": [ + "Create a folder to save checkpoints." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "593bd594", + "metadata": {}, + "outputs": [], + "source": [ + "folder = \"train/\"\n", + "Path(folder).mkdir(parents=True, exist_ok=True)" + ] + }, + { + "cell_type": "markdown", + "id": "ee4e610e", + "metadata": {}, + "source": [ + "Save and load models:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "28319be1", + "metadata": {}, + "outputs": [], + "source": [ + "def save_model(folder, k, n_base, base_hidden, grid, sub_hidden, dropout, lambda1, lambda2, model, optimizer):\n", + " checkpoint = {'n_base': n_base,\n", + " 'base_hidden': base_hidden,\n", + " 'grid': grid,\n", + " 'sub_hidden': sub_hidden,\n", + " 'dropout': dropout,\n", + " 'lambda1' : lambda1,\n", + " 'lambda2' : lambda2,\n", + " 'state_dict': model.state_dict(),\n", + " 'optimizer': optimizer.state_dict()}\n", + " torch.save(checkpoint, folder + str(k) + '_' + 'checkpoint.pth')\n", + "\n", + "\n", + "def load_model(file_path, device):\n", + " checkpoint = torch.load(file_path)\n", + " model = AdaFNN(n_base=checkpoint['n_base'],\n", + " base_hidden=checkpoint['base_hidden'],\n", + " grid=checkpoint['grid'],\n", + " sub_hidden=checkpoint['sub_hidden'],\n", + " dropout=checkpoint['dropout'],\n", + " lambda1=checkpoint['lambda1'],\n", + " lambda2=checkpoint['lambda2'],\n", + " device=device)\n", + " model.load_state_dict(checkpoint['state_dict'])\n", + " _ = model.to(device)\n", + " return model, checkpoint['grid']" + ] + }, + { + "cell_type": "markdown", + "id": "b74ef584", + "metadata": {}, + "source": [ + "Training procedure:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "235a85eb", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "epoch: 50 \n", + " prediction training loss = 1.0092152325730575 validation loss = 0.9117863327264786\n", + "epoch: 100 \n", + " prediction training loss = 1.0198108647999011 validation loss = 0.9127183258533478\n", + "epoch: 150 \n", + " prediction training loss = 0.49460057835829885 validation loss = 0.4149135798215866\n", + "epoch: 200 \n", + " prediction training loss = 0.10786365815683414 validation loss = 0.04820907302200794\n", + "epoch: 250 \n", + " prediction training loss = 0.08378865903145388 validation loss = 0.06254738755524158\n", + "epoch: 300 \n", + " prediction training loss = 0.07181917248587859 validation loss = 0.030116869136691093\n", + "epoch: 350 \n", + " prediction training loss = 0.07683030104166583 validation loss = 0.021957298275083303\n", + "epoch: 400 \n", + " prediction training loss = 0.06773263725795244 validation loss = 0.030310802161693573\n", + "epoch: 450 \n", + " prediction training loss = 0.06542162891281278 validation loss = 0.04157965909689665\n", + "epoch: 500 \n", + " prediction training loss = 0.06499655093801648 validation loss = 0.03089121775701642\n" + ] + } + ], + "source": [ + "for k in range(epoch):\n", + "\n", + " if k and k % save_model_every == 0:\n", + " save_model(folder, k, n_base, base_hidden, grid, sub_hidden, dropout, lambda1, lambda2, model, optimizer)\n", + "\n", + " pred_loss_train = []\n", + " total_loss_train = []\n", + " loss_valid = []\n", + " dataLoader.shuffle()\n", + " # set model training state\n", + " model.train()\n", + "\n", + " for i, (x, y) in enumerate(dataLoader.get_train_batch()):\n", + " x, y = x.to(device), y.to(device)\n", + " out = model.forward(x)\n", + " loss_pred = compute_loss(out, y)\n", + " loss = loss_pred + model.R1(l1_k) + model.R2(l2_pairs)\n", + " # record training loss history\n", + " total_loss_train.append(loss.item())\n", + " pred_loss_train.append(loss_pred.item())\n", + "\n", + " # update parameters using backpropagation\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " total_loss_train_history.append(np.mean(total_loss_train))\n", + " pred_loss_train_history.append(np.mean(pred_loss_train))\n", + "\n", + " # model evaluation mode\n", + "\n", + " with torch.no_grad():\n", + " model.eval()\n", + " for x, y in dataLoader.get_valid_batch():\n", + " x, y = x.to(device), y.to(device)\n", + " valid_y = model.forward(x)\n", + " valid_loss = compute_loss(valid_y, y)\n", + " # print(\"valid - check out: \", check_tensor([valid_loss]))\n", + " loss_valid.append(valid_loss.item())\n", + "\n", + " if np.mean(loss_valid) < min_valid_loss:\n", + " save_model(folder, \"best\", n_base, base_hidden, grid, sub_hidden, dropout, lambda1, lambda2, model, optimizer)\n", + " min_valid_loss = np.mean(loss_valid)\n", + "\n", + " loss_valid_history.append(np.mean(loss_valid))\n", + " \n", + " if (k+1) % 50 == 0:\n", + " print(\"epoch:\", k+1, \"\\n\",\n", + " \"prediction training loss = \", pred_loss_train_history[-1],\n", + " \"validation loss = \", loss_valid_history[-1])" + ] + }, + { + "cell_type": "markdown", + "id": "840fa063", + "metadata": {}, + "source": [ + "Please note that the validation error was computed after a training epoch was complete. So the validation error is generally smaller than the training error. " + ] + }, + { + "cell_type": "markdown", + "id": "7242dd67", + "metadata": {}, + "source": [ + "Make a loss plot after training finishes." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "d62cf2f1", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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ycmhcePG2GxnvtBdPUAVsNlsNG3atMaOHxwcrP9zeYDOs+foXHuGzrNn6Dx7Tk2c67P1/JSxfCVoEREREU9TABIREZE6RwHIg+x2O88884xuu1HDdJ49R+faM3SePUPn2XNqw7nWJGgRERGpc9QDJCIiInWOApCIiIjUOQpAIiIiUucoAImIiEidowDkIW+//TYtW7bEz8+PuLg4Fi1aZHVJ552FCxcyZMgQGjdujGEYfP31126vm6bJs88+S+PGjfH39+eyyy5j48aNbm0KCwv5xz/+QYMGDQgMDOSaa65h3759HvwWtdvYsWPp0aMH9erVIyIigqFDh7J161a3NjrP1eOdd96hS5curoXgkpKS+OGHH1yv6zzXjLFjx2IYBg888IBrn871H/fss89iGIbbIyoqyvV6rTzHptS4qVOnmj4+PuYHH3xgbtq0ybz//vvNwMBAc/fu3VaXdl6ZNWuW+eSTT5rTp083AXPGjBlur7/00ktmvXr1zOnTp5vr1683hw8fbjZq1MjMzs52tRk5cqTZpEkTc+7cuebq1avNvn37mrGxsWZJSYmHv03tNGDAAPPjjz82N2zYYCYnJ5tXX3212axZMzM3N9fVRue5esycOdP8/vvvza1bt5pbt241n3jiCdPHx8fcsGGDaZo6zzXht99+M1u0aGF26dLFvP/++137da7/uGeeecbs2LGjmZaW5npkZGS4Xq+N51gByAN69uxpjhw50m1fhw4dzMcff9yiis5/pwYgh8NhRkVFmS+99JJrX0FBgRkSEmK+++67pmma5tGjR00fHx9z6tSprjapqammzWYzf/zxR4/Vfj7JyMgwAXPBggWmaeo817SwsDDzww8/1HmuATk5OWbbtm3NuXPnmpdeeqkrAOlcV49nnnnGjI2NrfC12nqONQRWw4qKili1ahX9+/d329+/f3+WLFliUVUXnl27dpGenu52nu12O5deeqnrPK9atYri4mK3No0bN6ZTp076W5xGVlYWAOHh4YDOc00pLS1l6tSp5OXlkZSUpPNcA/7+979z9dVXc+WVV7rt17muPtu3b6dx48a0bNmSv/zlL/z+++9A7T3HuhlqDcvMzKS0tJTIyEi3/ZGRkaSnp1tU1YWn7FxWdJ53797tauPr60tYWFi5NvpblGeaJqNGjeKSSy6hU6dOgM5zdVu/fj1JSUkUFBQQFBTEjBkziImJcf0LX+e5ekydOpXVq1ezYsWKcq/pn+nqkZCQwOTJk2nXrh0HDhzghRdeoFevXmzcuLHWnmMFIA8xDMNt2zTNcvvkjzuX86y/RcXuu+8+1q1bx+LFi8u9pvNcPdq3b09ycjJHjx5l+vTp3HbbbSxYsMD1us7zH7d3717uv/9+5syZg5+f32nb6Vz/MQMHDnQ979y5M0lJSbRu3ZpPPvmExMREoPadYw2B1bAGDRrg5eVVLsFmZGSUS8Ny7squNjjTeY6KiqKoqIgjR46cto04/eMf/2DmzJn88ssvNG3a1LVf57l6+fr60qZNG+Lj4xk7diyxsbGMHz9e57karVq1ioyMDOLi4vD29sbb25sFCxYwYcIEvL29XedK57p6BQYG0rlzZ7Zv315r/3lWAKphvr6+xMXFMXfuXLf9c+fOpVevXhZVdeFp2bIlUVFRbue5qKiIBQsWuM5zXFwcPj4+bm3S0tLYsGGD/hbHmabJfffdx1dffcXPP/9My5Yt3V7Xea5ZpmlSWFio81yNrrjiCtavX09ycrLrER8fz0033URycjKtWrXSua4BhYWFbN68mUaNGtXef55rZGq1uCm7DH7ixInmpk2bzAceeMAMDAw0U1JSrC7tvJKTk2OuWbPGXLNmjQmYr732mrlmzRrXcgIvvfSSGRISYn711Vfm+vXrzRtvvLHCyyybNm1qzps3z1y9erV5+eWX61LWk/ztb38zQ0JCzPnz57tdzpqfn+9qo/NcPUaPHm0uXLjQ3LVrl7lu3TrziSeeMG02mzlnzhzTNHWea9LJV4GZps51dXjooYfM+fPnm7///ru5bNkyc/DgwWa9evVcv3O18RwrAHnIW2+9ZTZv3tz09fU1u3fv7rqsWCrvl19+MYFyj9tuu800Teells8884wZFRVl2u12s0+fPub69evdjnHs2DHzvvvuM8PDw01/f39z8ODB5p49eyz4NrVTRecXMD/++GNXG53n6nHHHXe4/p3QsGFD84orrnCFH9PUea5JpwYgnes/rmxdHx8fH7Nx48bm9ddfb27cuNH1em08x4ZpmmbN9C2JiIiI1E6aAyQiIiJ1jgKQiIiI1DkKQCIiIlLnKACJiIhInaMAJCIiInWOApCIiIjUOQpAIiIiUucoAImIVML8+fMxDIOjR49aXYqIVAMFIBEREalzFIBERESkzlEAEpHzgmma/Pvf/6ZVq1b4+/sTGxvL//73P+DE8NT3339PbGwsfn5+JCQksH79erdjTJ8+nY4dO2K322nRogWvvvqq2+uFhYU8+uijREdHY7fbadu2LRMnTnRrs2rVKuLj4wkICKBXr15s3bq1Zr+4iNQIBSAROS889dRTfPzxx7zzzjts3LiRBx98kJtvvpkFCxa42jzyyCO88sorrFixgoiICK655hqKi4sBZ3AZNmwYf/nLX1i/fj3PPvssTz/9NJMmTXK9/9Zbb2Xq1KlMmDCBzZs38+677xIUFORWx5NPPsmrr77KypUr8fb25o477vDI9xeR6qWboYpIrZeXl0eDBg34+eefSUpKcu2/6667yM/P55577qFv375MnTqV4cOHA3D48GGaNm3KpEmTGDZsGDfddBMHDx5kzpw5rvc/+uijfP/992zcuJFt27bRvn175s6dy5VXXlmuhvnz59O3b1/mzZvHFVdcAcCsWbO4+uqrOXbsGH5+fjV8FkSkOqkHSERqvU2bNlFQUEC/fv0ICgpyPSZPnszOnTtd7U4OR+Hh4bRv357NmzcDsHnzZi6++GK341588cVs376d0tJSkpOT8fLy4tJLLz1jLV26dHE9b9SoEQAZGRl/+DuKiGd5W12AiMjZOBwOAL7//nuaNGni9prdbncLQacyDANwziEqe17m5A5wf3//StXi4+NT7thl9YnI+UM9QCJS68XExGC329mzZw9t2rRxe0RHR7vaLVu2zPX8yJEjbNu2jQ4dOriOsXjxYrfjLlmyhHbt2uHl5UXnzp1xOBxuc4pE5MKlHiARqfXq1avHww8/zIMPPojD4eCSSy4hOzubJUuWEBQURPPmzQEYM2YM9evXJzIykieffJIGDRowdOhQAB566CF69OjB888/z/Dhw1m6dClvvvkmb7/9NgAtWrTgtttu44477mDChAnExsaye/duMjIyGDZsmFVfXURqiAKQiJwXnn/+eSIiIhg7diy///47oaGhdO/enSeeeMI1BPXSSy9x//33s337dmJjY5k5cya+vr4AdO/enS+++IJ//etfPP/88zRq1IgxY8YwYsQI12e88847PPHEE9x7770cOnSIZs2a8cQTT1jxdUWkhukqMBE575VdoXXkyBFCQ0OtLkdEzgOaAyQiIiJ1jgKQiIiI1DkaAhMREZE6Rz1AIiIiUucoAImIiEidowAkIiIidY4CkIiIiNQ5CkAiIiJS5ygAiYiISJ2jACQiIiJ1jgKQiIiI1DkKQCIiIlLn/H+MOk/cSuMUZAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(list(range(1, epoch+1)), total_loss_train_history, label='train_total')\n", + "plt.plot(list(range(1, epoch+1)), pred_loss_train_history, label='train_pred')\n", + "plt.xlabel('epoch')\n", + "plt.ylabel('MSE loss')\n", + "plt.legend()\n", + "# plt.savefig('loss_plot.png')\n", + "# plt.close()" + ] + }, + { + "cell_type": "markdown", + "id": "1085d369", + "metadata": {}, + "source": [ + "After training, to make predictions, we can load the best model and run it on the (test) dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "b2b0a693", + "metadata": {}, + "outputs": [], + "source": [ + "def make_prediction(dataLoader, device=torch.device(\"cpu\"), folder=\"train/\"):\n", + " ck = folder + \"best_checkpoint.pth\"\n", + " # load the best model\n", + " model, t = load_model(ck, device)\n", + " T = torch.tensor(t).to(device)\n", + " t = np.array(t)\n", + " \n", + " loss_test = []\n", + " y_pred = []\n", + " \n", + " with torch.no_grad():\n", + " model.eval()\n", + " \"\"\"\n", + " Get the performance of the best train model on test dataset\n", + " \"\"\"\n", + " for x, y in dataLoader.get_test_batch():\n", + " x, y = x.to(device), y.to(device)\n", + " test_y = model.forward(x)\n", + " y_pred.extend(test_y.detach().cpu().numpy().tolist())\n", + " test_loss = compute_loss(test_y, y)\n", + " loss_test.append(test_loss.item()) \n", + " \n", + " \"\"\"\n", + " Compute the MSE of the test dataset\n", + " \"\"\"\n", + " print(\"test accuracy MSE :\", np.mean(loss_test))\n", + " \n", + " \"\"\"\n", + " return the predicted y values by re-scaling the model output\n", + " \"\"\"\n", + " \n", + " return dataLoader.Y_standardizer.inverse_transform(y_pred)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "815c040b", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "test accuracy MSE : 0.020395083352923393\n" + ] + } + ], + "source": [ + "y_pred = make_prediction(dataLoader)" + ] + }, + { + "cell_type": "markdown", + "id": "c603e3a6", + "metadata": {}, + "source": [ + "We can plot the learned bases." + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "ee342b0b", + "metadata": {}, + "outputs": [], + "source": [ + "def plot_bases( device=torch.device(\"cpu\"), folder=\"train/\"):\n", + " ck = folder + \"best_checkpoint.pth\"\n", + " model, t = load_model(ck, device)\n", + " T = torch.tensor(t).to(device)\n", + " t = np.array(t)\n", + "\n", + " bases = []\n", + " \n", + " loss_test = []\n", + " \n", + " with torch.no_grad():\n", + " model.eval()\n", + " \n", + " for i, basis in enumerate(model.BL):\n", + " T = T.unsqueeze(dim=-1)\n", + " y = np.squeeze(basis(T).squeeze(dim=-1).detach().cpu().numpy())\n", + " y_sq = y ** 2\n", + " l2_norm = np.sqrt(np.sum((y_sq[:-1] + y_sq[1:]) * (t[1:] - t[:-1])) / 2)\n", + " bases.append(y / l2_norm)\n", + "\n", + " B = len(bases)\n", + " fig, axs = plt.subplots(1, B)\n", + " plt.xticks(fontsize=10)\n", + " plt.yticks(fontsize=10)\n", + " for i in range(B): \n", + " axs[i].plot(t, bases[i], linewidth=3.5, label=\"basis\"+str(i+1))\n", + " axs[i].legend()\n", + " \n", + " return bases\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "9537c10c", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "bases = plot_bases()" + ] + }, + { + "cell_type": "markdown", + "id": "27e98c55", + "metadata": {}, + "source": [ + "Even when both measurement error and noise were present, using roughly 60% of the dataset, the model successfully captured the important features of the true signal $\\phi_5$. " + ] + }, + { + "cell_type": "markdown", + "id": "4c0f4735", + "metadata": {}, + "source": [ + "To better understand the learned bases, we can also plot a linear combination of them and see what it looks compared to the true one." + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "78791329", + "metadata": {}, + "outputs": [], + "source": [ + "def plot(t, y, color, label):\n", + " plt.xticks(fontsize=10)\n", + " plt.yticks(fontsize=10)\n", + " plt.plot(t, y, linewidth=3.5, color=color, label=label)\n", + " plt.legend()" + ] + }, + { + "cell_type": "markdown", + "id": "037dca72", + "metadata": {}, + "source": [ + "The coefficients of learned bases can vary in different experiments (see Theorem 1 and Remark 1 in the paper)." + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "40607256", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "np_b = [np.array(b) for b in bases]\n", + "lin = np_b[1] #+ 0.4 * np_b[1] \n", + "plot(grid, lin, \"orangered\", \"learned basis1\")\n", + "phi5 = _phi(5)\n", + "plot(grid, phi5(np.array(grid)), \"green\", \"true phi5\")" + ] + }, + { + "cell_type": "markdown", + "id": "7b646673", + "metadata": {}, + "source": [ + "The true signal $\\phi_5$ in Case 3 is drawn below. We can see that two bases learned the truth successfully." + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "276a99f7", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "phi5 = _phi(5)\n", + "plot(grid, phi5(np.array(grid)), \"green\", \"true phi5\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f10ec934", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "843b446d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "torch", + "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.11.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/operator/adafnn.py b/operator/adafnn.py new file mode 100644 index 0000000..103cf80 --- /dev/null +++ b/operator/adafnn.py @@ -0,0 +1,414 @@ +""" +Deep Learning for Functional Data Analysis with Adaptive Basis Layers + +Reference: +1. https://github.com/jwyyy/AdaFNN +2. https://github.com/hanCi422/basis_operator_net/tree/main +""" +#%% +import numpy as np +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +import pandas as pd +from pathlib import Path +from sklearn.preprocessing import StandardScaler +from tqdm import trange +import matplotlib.pyplot as plt +device = "cuda" if torch.cuda.is_available() else "cpu" + +class NeuralBasis(nn.Module): + def __init__(self, dim_in=1, hidden=[4,4,4], n_base=4, activation=None, fourier_feature=None): + super().__init__() + self.sigma = activation + self.fourier_feature = fourier_feature + if fourier_feature is not None: + m=100 + dim_in = 2*m + sigma = 5 + B1 = torch.rand(m, 1) * sigma + B2 = torch.rand(m, 1) * sigma + self.B1= nn.Parameter(B1, requires_grad=True) + self.B2 = nn.Parameter(B2, requires_grad=True) + + dim = [dim_in] + hidden + [n_base] + self.layers = nn.ModuleList([nn.Linear(dim[i-1], dim[i]) for i in range(1, len(dim))]) + + def forward(self, t): + t = self.get_fourier_feature(t) # (B, J, 2M) if fourier_feature is not None else (B, J) + for i in range(len(self.layers)-1): + t = self.sigma(self.layers[i](t)) + # linear activation at the last layer + return self.layers[-1](t) + + def get_fourier_feature(self, xs): + _xs = xs # (B, 1) + if self.fourier_feature is not None: + Bxs = torch.einsum("BD, MD-> BM", _xs, self.B1) + sin_xs = torch.sin(Bxs) # (B, J, M) + cos_xs = torch.cos(Bxs) # (B, J, M) + feature = torch.cat([sin_xs, cos_xs], dim=-1) # (B, J, 2M) + return feature + else: + return xs + +def _inner_product(f1, f2, h): + """ + f1 - (J) : observed at J time points, + f2 - (J) : same as f1 + h - (J-1,1): weights used in the trapezoidal rule + pay attention to dimension + = sum (h/2) (f1(t{j}) + f2(t{j+1})) + """ + prod = f1 * f2 # (B, J = len(h) + 1) + return torch.matmul((prod[:-1] + prod[1:]), h)/2 + +def _l1(f, h): + # f dimension : ( B bases, J ) + B, J = f.size() + return _inner_product(torch.abs(f), torch.ones((B, J)), h) + + +def _l2(f, h): + # f dimension : ( B bases, J ) + # output dimension - ( B bases, 1 ) + return torch.sqrt(_inner_product(f, f, h)) + +class AdaFNN(nn.Module): + + def __init__(self, n_base=4, base_hidden=[64, 64, 64], activation=torch.nn.ReLU(), fourier_feature=None): + """ + labda1 : penalty of L1 regularization, a positive real number + lambda2 : penalty of L2 regularization, a positive real number + n_base : number of basis nodes, integer + base_hidden : hidden layers used in each basis node, array of integers + grid : observation time grid, array of sorted floats including 0.0 and 1.0 + sub_hidden : hidden layers in the subsequent network, array of integers + dropout : dropout probability + lambda1 : penalty of L1 regularization, a positive real number + lambda2 : penalty of L2 regularization, a positive real number + device : device for the training + """ + super().__init__() + self.n_base = n_base + self.device = device + self.n_base = n_base + self.dim_in = 1 + self.fourier_feature = fourier_feature + # instantiate each basis node in the basis layer + + dim_in = 1 + self.BL = NeuralBasis(dim_in=dim_in, hidden=base_hidden, n_base = n_base, activation=activation, fourier_feature=fourier_feature) + + def forward(self, xs, us): + scores, basess = self.encode(xs, us) + us_restore = self.decode(xs, scores) + return us_restore + + def encode(self, xs, us): + """ + xs: (B, J) : B functions, observed at J time points + us: (B, J) : B functions, observed at J time points + """ + B, J = xs.size() + + # send the time grid tensor to device + hs = xs[:, 1:] - xs[:, :-1]# (B, J-1): grid size + # evaluate the current basis nodes at time grid + basess = self.BL(xs.reshape(-1,1)).reshape(B,self.n_base,J) # (B, n_base, J) + scores = torch.vmap(torch.vmap(_inner_product, in_dims=(0, None, None)), in_dims=(0, 0, 0))(basess, us, hs) + # (B, n_bases, J), (B, J), (B, J-1) + + assert scores.size() == (B, self.n_base), f"Expected shape (B, n_base), got {scores.size()}" + + return scores, basess + + def decode(self, xs, scores): + """ + xs: (B, J) : B functions, observed at J time points + scores: (B, n_base) : B functions, encoded into n_base scores + """ + B, J = xs.size() + basess = self.BL(xs.reshape(-1,1)).reshape(B,J,self.n_base) # (B, J, n_base) + us_restore = torch.bmm(basess, scores.unsqueeze(-1)).squeeze(-1) # (B, J, n_base) x (B, n_base, 1) -> (B, J, 1) + return us_restore + + def get_bases_products(self, xs, basess, n_choice=None): + hs = xs[:, 1:] - xs[:, :-1]# (B, J-1): grid size + # Noramalization: compute each basis node's L2 norm normalize basis nodes + n_choice = n_choice if n_choice is not None else self.n_base + ids = np.random.choice(self.n_base, n_choice, replace=False) # Randomly select n_choice basis nodes + _basess = basess[:, ids, :] # (B, n_choice, J) + # Create scores matrix + # [, , ..., ] + # [, , ..., ] + # ... + # [, , ..., + m_scores = torch.vmap( + torch.vmap( + torch.vmap(_inner_product, # (J,), (J,), (J-1) + in_dims=(None, 0, None)), # (J,), (n_base,J), (J-1) + in_dims=(0, None, None)), # (n_base, J), (n_base, J), (J-1) + in_dims=(0, 0, 0))(_basess, _basess, hs) # (B, n_base, J), (B, n_base, J), (B, J-1) + + return m_scores + + def get_R1_R2(self, xs, bases, n_choice=None): + m_scores = self.get_bases_products(xs, bases, n_choice=n_choice) + r1 = self.R1(m_scores) + r2 = self.R2(m_scores) + return r1, r2 + + @staticmethod + def R1(m_scores): + # sample l1_k basis nodes to regularize + norm2 = torch.diagonal(m_scores) # , , ..., + ideal_norm2 = torch.ones_like(norm2) # Ideal norm is 1 for each basis node + return F.mse_loss(norm2, ideal_norm2) # Mean squared error loss between actual and ideal norms + + @staticmethod + def R2(m_scores): + cross_norm = torch.triu(m_scores, diagonal=1) + idea_cross_norm = torch.zeros_like(cross_norm) # Ideal cross norm is 0 for each pair + return F.mse_loss(cross_norm, idea_cross_norm) # Mean squared error +""" +Data Generation +""" +def _phi(k, t): + """ + basis functions + k: mode + t: sensor point + """ + return 2**0.5 * torch.cos((k-1)*torch.pi*t) + +def generate_data(zs, xs, n_batch=100): + """ + Generate data based on the given weights of basis functions and random coefficients. + + Args: + zs: weight of basis functions + xs: sensor points (batch_size, J) + n_batch (int, optional): number of batch. Defaults to 100. + Return: + us: function response at sensor points (n_batch, J) + """ + n_basis = zs.size(0) + rs = torch.Tensor.uniform_(torch.empty(n_batch, n_basis), -3**0.5, 3**0.5) + cs = zs * rs + ks = torch.arange(1, n_basis + 1) + phis = torch.vmap(torch.vmap(_phi, in_dims=(0, None)), in_dims=(None,0))(ks, xs) + + us = torch.bmm(phis.transpose(1,2), cs.unsqueeze(-1)) # (n_batch, J) + return xs, us.squeeze(dim=-1) # (n_batch, J) + + +def poly_sin_func(coeffs:torch.Tensor, x:torch.Tensor.float)->torch.Tensor.float: + """ + The function to compute the polynomial sine function based on the coefficients and sensor points. + + $$ + f(x) = \sum_{n=1}^{N} c_n \sin(n \pi x) + $$ + + coeffs: [n,]. c_1,...,c_n are the coefficients of the polynomial sine function + x: single sensor point + """ + ws = torch.arange(1, len(coeffs) + 1) # [n,] + pi_ws = 2*torch.pi * ws + + out = torch.dot(coeffs, torch.sin(pi_ws * x)) + + return out + +poly_sin_func_batched = torch.vmap(poly_sin_func, in_dims=(None, 0)) + +def generate_data_poly_sin(high_freq:int, nx:int, n_batch:int)->torch.Tensor: + """ + Generate data based on the polynomial sine function with random coefficients. + + high_freq: highest frequency used in the polynomial sine function + n_x: number of sensor points + n_batch: number of batch + """ + xs = torch.linspace(0, 1, nx).repeat(n_batch, 1)# Random sensor points (n_batch, nx) + coeffs = torch.randn(n_batch, high_freq) # Random coefficients for the polynomial sine function + us = torch.vmap(poly_sin_func_batched, in_dims=(0, 0))(coeffs, xs) # Apply the function to each batch + return xs, us + + +""" +Training +""" +def loss_fn(model, xs, us, n_choose:int=5, lambda1:float=1., lambda2:float=1.): + # ENCODE + scores, bases = model.encode(xs, us) # Encode the function into scores + # DECODE + us_restore = model.decode(xs, scores) # Decode the scores back to function + + loss_res = F.mse_loss(us_restore, us) # Mean squared error loss + + if (n_choose > 0) and (lambda1>0 or lambda2>0): + loss_r1, loss_r2 = model.get_R1_R2(xs, bases, n_choice=n_choose) # Get R1 and R2 regularization losses + else: + loss_r1, loss_r2 = torch.tensor(0.0, device=device), torch.tensor(0.0, device=device) + + return loss_res + lambda1*loss_r1 + lambda2*loss_r2, (loss_res, loss_r1, loss_r2) + + +def train(model, nstep, optimizer, data_gen, scheduler=None): + """ + Train the model for nstep steps. + """ + model.train() + xs, us = data_gen() + xs = xs.to(device) + us = us.to(device) + tstep = trange(nstep, desc="Training") + losses = [] + for step in tstep: + # Generate new data for each step + optimizer.zero_grad() + # Forward pass + us_restore = model(xs, us) + # Compute loss (mean squared error) + loss, (loss_res, loss_r1, loss_r2) = loss_fn(model, xs, us, lambda1=1.0, lambda2=1.0) + # Backward pass + loss.backward() + optimizer.step() + if scheduler is not None: + scheduler.step() + # Logging + losses.append(loss.detach().item()) + tstep.set_description(f"loss: {loss:.2e} / loss_res: {loss_res:.2e} / loss_r1: {loss_r1:.2e} / loss_r2: {loss_r2:.2e}") + return model, losses + +""" +Evaluation +""" +def error_over_freqs(model:nn.Module, n_xs:int, n_batch:int): + is_train = model.training + model.eval() + with torch.no_grad(): + error_means = [] + error_stds = [] + # Evalution on multiple frequency + freqs = np.array(list(range(1,n_xs//2 - 1,1))) ## Less than half of the sampling frequency + for freq in freqs: + data_gen_test = lambda: generate_data_poly_sin(high_freq=freq, nx=n_xs, n_batch=n_batch) + xs_test, us_test = data_gen_test() + us_pred = model(xs_test.to(device), us_test.to(device)) + + errors = torch.abs(us_pred - us_test.to(device)).cpu() + error_means.append(errors.mean().item()) + error_stds.append(errors.std().item()) + error_means = np.array(error_means) + error_stds = np.array(error_stds) + model.train() if is_train else None # Restore the mode + return freqs, error_means, error_stds + +def plot_error_over_freqs(max_freq, model:nn.Module, n_xs:int, n_batch:int): + freqs, error_means, error_stds = error_over_freqs(model, n_xs, n_batch) + fig, ax = plt.subplots() + ax.plot(freqs, error_means, marker='o', linestyle='-', color='blue') + ax.fill_between(freqs, error_means - error_stds, error_means + error_stds, color='blue', alpha=0.2) + ax.set_xlabel('Max Frequency Mode') + ax.set_ylabel('Mean Absolute Error') + ax.set_title('Error vs Max Frequency') + ax.axvline(x=max_freq, color='red', linestyle='--', label='Training Frequency') + ax.legend() + ax.set_yscale('log') + return fig, ax + + +if __name__ == "__main__": + """ + Data + """ + # Data Generation + n_batch = 64 + # Weights of basis functions + zs = torch.asarray([1, 1, 1] + [1] * 2) + # Sensor Points + n_xs = 100 + xs = torch.linspace(0, 1, n_xs).repeat(n_batch, 1) # (n_batch, J) + # Function response + xs, Us = generate_data(zs, xs, n_batch=n_batch) # (n_batch, J) + #data_gen = lambda: generate_data(zs, xs, n_batch=n_batch) + high_freq = 8 + n_xs = max(n_xs, high_freq * 2 + 1) # Ensure n_xs is at least twice the highest frequency + data_gen = lambda: generate_data_poly_sin(high_freq=high_freq, nx=n_xs, n_batch=n_batch) # Generate data for the polynomial sine function + """ + Model + """ + n_base = 45 + # Create Function Autoencoder Model + model = AdaFNN(n_base=n_base, base_hidden=[256,256,256,256], fourier_feature=True).to(device) # Change 'cpu' to 'cuda' if using GPU + # Encode function into scores + scores,_ = model.encode(xs.to(device), Us.to(device)) + # Decode scores back to function + us_restore = model.decode(xs.to(device), scores) + # Autoencoder + us_restore2 = model(xs.to(device), Us.to(device)) + + # Sanity checks + assert xs.size() == Us.size() + assert scores.size() == (n_batch, n_base) + assert us_restore.size() == (n_batch, n_xs) + assert torch.allclose(us_restore, us_restore2, atol=1e-6) + + # Train the model + nstep = 100_000 + lr=1e-3 + opt = torch.optim.Adam(model.parameters(), lr=lr) + scheduler = torch.optim.lr_scheduler.StepLR(opt, 1000, gamma=0.9, last_epoch=-1) + model_opt, losses = train(model, nstep=nstep, optimizer=opt, data_gen=data_gen, scheduler=scheduler) + + # Plotting the training loss + fig, ax = plt.subplots() + ax.plot(losses, label='Training Loss', color='blue') + ax.set_xlabel('Training Steps') + ax.set_ylabel('Loss') + ax.set_yscale('log') + # Evaluation + with torch.no_grad(): + model_opt.eval() + fig1, ax1 = plot_error_over_freqs(high_freq, model_opt, n_xs=n_xs, n_batch=n_batch) + + model_opt.eval() + for freq in [4, 16, 30]: + data_gen2 = lambda: generate_data_poly_sin(high_freq=freq, nx=n_xs, n_batch=n_batch) + xs, us = data_gen2() # Generate new data for evaluation + us_restore = model_opt(xs.to(device), us.to(device)) + scores, bases = model_opt.encode(xs.to(device), us.to(device)) + us_restore = us_restore.cpu().numpy() + # Convert to numpy + scores = scores.cpu().numpy() + bases = bases.cpu().numpy() + xs = xs.cpu().numpy() + us = us.cpu().numpy() + # Plotting + for i in [0]: + fig, ax = plt.subplots() + ax.plot(xs[i], us[i], label='Original Function', color='blue') + ax.plot(xs[i], us_restore[i], label='Restored Function', color='red') + ax.legend() + ax.set_xlabel("x") + ax.set_ylabel("u(x)") + ax.set_title(f"Max frequency Mode {freq}") + + fig1, ax1 = plt.subplots() + js = np.argsort(np.abs(scores[i])) + ax1.plot(xs[i], bases[i, js[-1]], label='Basis Functions with highest score') + ax1.plot(xs[i], bases[i, js[-2]], label='Basis Functions with 2nd score') + ax1.set_xlabel("x") + ax1.set_ylabel("Basis Function Value") + ax1.set_title(f"Max frequency Mode {freq}") + ax1.legend() + + + + + +# %% diff --git a/operator/func_autoenc.py b/operator/func_autoenc.py new file mode 100644 index 0000000..26c9ea4 --- /dev/null +++ b/operator/func_autoenc.py @@ -0,0 +1,37 @@ +""" +Function Autoencoder +Source: https://github.com/hanCi422/basis_operator_net/blob/main/src/kdv_burgers/model.py +""" +import torch +import torch.nn as nn +import torch.nn.functional as F + + +class NeuralBasis(nn.Module): + def __init__(self, dim_in=1, hidden=[4,4,4], n_base=4, activation=None): + super().__init__() + self.sigma = activation + dim = [dim_in] + hidden + [n_base] + self.layers = nn.ModuleList([nn.Linear(dim[i-1], dim[i]) for i in range(1, len(dim))]) + self.t_in = torch.tensor(grid_in).to(device) + + def forward(self, t): + for i in range(len(self.layers)-1): + t = self.sigma(self.layers[i](t)) + # linear activation at the last layer + return self.layers[-1](t) + +class FuncAutoenc(nn.Module): + def __init__(self, hidden=[4,4,4], n_base=4, activation=None, device=None): + super().__init__() + self.n_base = n_base + self.device = device + self.dim = 1 + self.BL = NeuralBasis(self.dim, hidden=hidden, n_base=n_base, activation=activation) + + def forward(self, x): + """ + x: (batch_size, dim_in) + """ + x = x.to(self.device) + B = self.BL(x)