{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Introduction to NEMS\n", "\n", "Modeling with NEMS four basic steps:\n", "1. Loading properly formatted data and performing any necessary preprocessing.\n", "1. Building a model for the data.\n", "1. Fitting the model to the data.\n", "1. Assessing model performance.\n", "\n", "In this introduction, we'll cover the basic coding objects used to accomplish\n", "those steps and then walk through a simple example.\n", "\n", "## Data format\n", "All data should be formatted as `NumPy` arrays. NEMS models assume timeseries\n", "data is provided with shape (T, ..., N), where T is the number of time points\n", "and N is the number of output channels (or neurons). Data with shape\n", "(S, T, ..., N) is also supported through optional arguments, where S represents\n", "some number of trials or samples.\n", "\n", "For example, a 10-second long recording of activity from 100 neurons sampled\n", "at 100 Hz should be provided as shape (1000, 100), and a corresponding 18-channel\n", "spectrogram with the same sampling rate should have shape (1000, 18).\n", "\n", "## Important objects\n", "1. `Layer`: encapsulates a single mathematical transformation and an associated\n", " set of trainable parameters.\n", "1. `Model`: a collection of Layers that determines the transformation between input\n", " data and the predicted output.\n", "\n", "## Layer\n", "Most Layers have one or more trainable `Parameter` values tracked by a single\n", "`Phi` container. These objects determine the trainable numbers that will be\n", "substituted in the mathematical operation specified by `Layer.evaluate`.\n", "The `Parameter` and `Phi` classes can be thought of as numpy arrays and python\n", "dictionaries, respectfully, with some NEMS-specific bookkeeping tacked on.\n", "Default `Parameter` values are determined by the `Layer.initial_parameters`\n", "method.\n", "\n", "Let's design a couple new Layer subclasses to demonstrate:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from nems.layers.base import Layer, Phi, Parameter\n", "\n", "class Sum(Layer):\n", " def evaluate(self, *inputs):\n", " # All inputs are treated the same, no fittable parameters.\n", " return np.sum(inputs, axis=0)\n", "\n", "class WeightedSum(Layer):\n", "\n", " def initial_parameters(self):\n", " a = Parameter('a')\n", " b = Parameter('b')\n", " return Phi(a, b)\n", "\n", " def evaluate(self, input1, input2):\n", " # Only two inputs are supported, and they are weighted differently.\n", " a, b = self.get_parameter_values('a', 'b')\n", " return a*input1 + b*input2" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's create some instances of our new `Layers` and take a look at a summary\n", "of their properties." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sum(shape=None)\n", "================================" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sum = Sum()\n", "sum" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "WeightedSum(shape=None)\n", "================================\n", "Parameter(name=a, shape=())\n", "----------------\n", "Parameter(name=b, shape=())\n", "================================" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weighted = WeightedSum()\n", "weighted" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Notice that the two `Parameters` we created for the `WeightedSum` subclass\n", "show up here. If we want to see more detail, like their numeric values,\n", "we can `print` a full report for the `Layer` instead:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WeightedSum(shape=None)\n", "================================\n", ".parameters:\n", "\n", "Parameter(name=a, shape=())\n", "----------------\n", ".prior: Normal(μ=0.0, σ=1.0)\n", ".bounds: (-inf, inf)\n", ".is_frozen: False\n", ".values:\n", "0.0\n", "----------------\n", "Index: 0\n", "----------------\n", "\n", "Parameter(name=b, shape=())\n", "----------------\n", ".prior: Normal(μ=0.0, σ=1.0)\n", ".bounds: (-inf, inf)\n", ".is_frozen: False\n", ".values:\n", "0.0\n", "----------------\n", "Index: 0\n", "----------------\n", "\n", "================================\n" ] } ], "source": [ "print(weighted)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "We can see that both parameters currently have a value of 0. This is because\n", "the default behavior for parameter intialization is to set the values to the\n", "mean of each `Parameter`'s prior `Distribution`. Since we didn't specify the\n", "`Distribution` ourselves, it defaulted to a normal distribution with mean zero\n", "and standard deviation 1. To choose a different prior, we could have specified\n", "it in the `initial_parameters` method using the `prior` keyword argument of the\n", "`Parameter` class, or we can set it when creating a new `WeightedSum` instance:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "WeightedSum(shape=None)\n", "================================\n", ".parameters:\n", "\n", "Parameter(name=a, shape=())\n", "----------------\n", ".prior: HalfNormal(σ=1)\n", ".bounds: (-inf, inf)\n", ".is_frozen: False\n", ".values:\n", "0.7978845608028654\n", "----------------\n", "Index: 0\n", "----------------\n", "\n", "Parameter(name=b, shape=())\n", "----------------\n", ".prior: Normal(μ=0.0, σ=1.0)\n", ".bounds: (-inf, inf)\n", ".is_frozen: False\n", ".values:\n", "0.0\n", "----------------\n", "Index: 0\n", "----------------\n", "\n", "================================\n" ] } ], "source": [ "from nems.distributions import HalfNormal\n", "\n", "weighted = WeightedSum(priors={'a': HalfNormal(sd=1)})\n", "# equivalent to Parameter(..., prior=HalfNormal(sd=1))\n", "print(weighted)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Let's evaluate some toy data to see how to use the `Layers`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[3., 3., 3., 3., 3., 3., 3., 3., 3., 3.]])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = np.ones(shape=(10,1))\n", "y = np.ones(shape=(10,1))*2\n", "\n", "sum.evaluate(x,y).T" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Pretty straightforward: the two inputs are added together along the first axis.\n", "With `WeightedSum`, however, the second input should be zero'd out, so that we\n", "get `a * x` for our output:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.79788456, 0.79788456, 0.79788456, 0.79788456, 0.79788456,\n", " 0.79788456, 0.79788456, 0.79788456, 0.79788456, 0.79788456]])" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "weighted.evaluate(x,y).T" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Model\n", "\n", "A `Model` coordinates the evaluation of one or `Layer` instances to describe\n", "a composite transformation. For example, we can combine the `WeightedSum`\n", "subclass we created with a new `Layer` to get a toy `Model` that computes a\n", "weighted sum of two inputs and squares the result." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Model()\n", "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n", "WeightedSum(shape=None)\n", "================================\n", "Parameter(name=a, shape=())\n", "----------------\n", "Parameter(name=b, shape=())\n", "================================\n", "\n", "Square(shape=None)\n", "================================\n", "\n", "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nems import Model\n", "\n", "class Square(Layer):\n", " def evaluate(self, input):\n", " return input ** 2\n", "\n", "data = {'x': np.random.rand(20,1),\n", " 'y': np.random.rand(20,1)}\n", "\n", "model = Model()\n", "model.add_layers(\n", " WeightedSum(input=['x', 'y']),\n", " Square()\n", ")\n", "model" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Similar to the `Layer` class, we get a brief summary of the `Model` here. The\n", "order within the `Model` determines the flow of data: the output of each `Layer`\n", "is provided as input to the subsequent `Layer` moving from top to bottom, unless\n", "a `Layer` specifies its `input` separately.\n", "\n", "To transform the data, we use `Model.evaluate`. By default, this produces a\n", "dictionary containing all of the input data, any named intermediate outputs,\n", "and the final model output (with a default name of 'output'). If we only want\n", "the output, we can use the `return_full_data=False` keyword argument, or\n", "we can use `Model.predict`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "dict_keys(['x', 'y', 'output'])\n" ] } ], "source": [ "dict_out = model.evaluate(data)\n", "print(dict_out.keys())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", " 0., 0., 0., 0.]])" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "out = model.predict(data)\n", "out.T" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Currently our output is all zeroes because the default `Parameter` values are\n", "all zeroes. Let's try it with randomly sampled values instead. First, we create\n", "a new randomized model and print its `Parameter` values, then generate a new\n", "output." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'WeightedSum': {'a': array(0.14423579), 'b': array(1.59272023)}, 'Square': {}}\n" ] }, { "data": { "text/plain": [ "array([[1.14480989e+00, 2.08852269e+00, 1.08547141e-03, 2.12767500e-02,\n", " 5.44160615e-01, 2.35349162e+00, 1.75074923e-01, 7.36308937e-02,\n", " 2.72810510e+00, 1.26032176e+00, 3.73930608e-03, 9.13512452e-01,\n", " 1.40198324e+00, 2.96283257e-01, 4.13780794e-02, 5.55361038e-01,\n", " 8.04765963e-01, 3.33742762e-01, 2.79700128e-02, 4.45304643e-01]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model = model.sample_from_priors()\n", "print(model.get_parameter_values())\n", "out = model.predict(data)\n", "out.T" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Modeling a Simple Simulated Neuron\n", "\n", "Let's take a look at how we can use NEMS to actually model neural data.\n", "To demonstrate, we'll synthesize data for a simple linear auditory neuron with\n", "a firing rate proportional to the intensity of a single tone. We can simulate\n", "the sound input with the `scipy.signal` package for convenience." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAEGCAYAAABLgMOSAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAABVzklEQVR4nO2dd3hVVdb/PyuFFAJJIARCkSIBEQgtoIgIKhZGEcWGFV5Fx7Hrb3T0dUYdHV51HGcUx8bYHRXbjIINEQsgtiChiFKlQwJpBEjP+v1x7ok3ye01hP15nvPk3H3aysnN+Z611t5ri6piMBgMBoO/xETbAIPBYDAcmhgBMRgMBkNAGAExGAwGQ0AYATEYDAZDQBgBMRgMBkNAxEXbgEiSkZGhvXr1irYZBoPBcEixbNmyvaraqWn7YSUgvXr1Ii8vL9pmGAwGwyGFiGxx1W5CWAaDwWAICCMgBoPBYAgIIyAGg8FgCAgjIAaDwWAICCMgBoPBYAiIqAqIiDwvIoUistrNdhGRWSKyQURWishwp23TRGS9Y5kWOasNBoPBANH3QF4ETvewfSKQ7ViuBp4CEJEOwD3AMcAo4B4RSQ+rpQaDwWBoRFQFRFUXAcUedpkMvKwW3wBpIpIFnAYsUNViVS0BFuBZiAwRpK6ujueee46amppom2JopRw8eJBnnnmG6urqaJtyWBNtD8Qb3YBtTp+3O9rctTdDRK4WkTwRyduzZ0/YDDX8ypIlS5gxYwafffZZtE0JipkzZzJw4EBycnIYOnQo3377bVivd++99/K3v/2tUVtpaSkdO3bEnrfn66+/RkTYvn07AGVlZXTo0IH6+vqQ2XHbbbcxcOBAbrvttpCdM9Q8/vjjXHPNNbzyyivRNuWwpqULSNCo6mxVzVXV3E6dmo3EN4SBvXv3Nvp5KPL111/z/vvv88MPP7By5Uo+/fRTevToEXE70tLSyMrK4qeffgJg6dKlDBs2jKVLlwLwzTffMGrUKGJiQvevPHv2bFauXMnDDz/s0/61tbUhu7av13vyyScBS0jMpHjRo6ULyA7A+b+2u6PNXbuhBVBcXNzo56HIrl27yMjIICEhAYCMjAy6du0KwMKFCxk2bBiDBw/miiuuoKqqCrBK5diimZeXx/jx4wHLs7jiiisYP348ffr0YdasWQ3XmTlzJv369eP4449n7dq1Lm057rjjGgRj6dKl3HLLLY0+jxkzhs2bNzN27FiGDx/O8OHDG7ZPnTqVDz74oOFc06dP5+2336auro7bbruNkSNHkpOTwzPPPAPAWWedxf79+xkxYgRvvPEGmzdv5qSTTiInJ4eTTz6ZrVu3Npznmmuu4ZhjjuH2229n+vTp/O53v+PYY4+lT58+fPHFF1xxxRUMGDCA6dOnB/33cGbu3Lls3bqVSZMmsWLFChYvXhzS8xt8p6XXwpoLXC8ic7AS5mWquktE5gP/55Q4PxW4M1pGGhoTagG5+eabyc/PD8m5bIYOHcqjjz7qdvupp57KfffdR79+/ZgwYQIXXngh48aNo7KykunTp7Nw4UL69evH5ZdfzlNPPcXNN9/s8Xo///wzn3/+OeXl5fTv35/f/e53rFy5kjlz5pCfn09tbS3Dhw9nxIgRzY4dM2YMX375JTNmzGDTpk2cf/75DQ/8pUuXcscdd5CZmcmCBQtITExk/fr1XHTRReTl5XHhhRfy5ptvcsYZZ1BdXc3ChQt56qmneO6550hNTeX777+nqqqKMWPGcOqppzJ37lxSUlIa7vekSZOYNm0a06ZN4/nnn+fGG2/k3XffBWD79u0sXbqU2NhYpk+fTklJCV9//TVz587lrLPO4quvvuLZZ59l5MiR5OfnM3To0AD+Us155pln6NmzJ6+++io9e/bk6aef5oQTTgjJuQ3+Ee1uvK8DXwP9RWS7iFwpIteIyDWOXT4ENgEbgH8B1wKoajFwP/C9Y7nP0WZoAbQGDyQlJYVly5Yxe/ZsOnXqxIUXXsiLL77I2rVr6d27N/369QNg2rRpLFq0yOv5zjjjDBISEsjIyCAzM5OCggIWL17MOeecQ3JyMu3bt+ess85yeaztgfzyyy/06tWLxMREVJX9+/ezbNkyjjnmGGpqarjqqqsYPHgw559/PmvWrAFg4sSJfP7551RVVfHRRx9xwgknkJSUxCeffMLLL7/M0KFDOeaYYygqKmL9+vXNrv31119z8cUXA3DZZZexZMmShm3nn38+sbGxDZ8nTZqEiDB48GA6d+7M4MGDiYmJYeDAgWzevNnne++NvLw8Tj/9dNq1a8fJJ5/MsmXLQnZug39E1QNR1Yu8bFfgOjfbngeeD4ddhuAItYB48hTCSWxsLOPHj2f8+PEMHjyYl156iWHDhrndPy4uriGZXVlZ2WibHQqzz+tP3iA7O5vS0lLmzZvH6NGjARgxYgQvvPACvXr1IiUlhXvvvZfOnTuzYsUK6uvrSUxMBCAxMZHx48czf/583njjDaZOnQqAqvL4449z2mmn+WxHU9q2bevyd4yJiWn0+8bExIQsT1JcXExxcXGDgGdnZ/Puu+9SW1tLXFxLD6i0Plp6DsRwCFJUVNTo56HI2rVrG72R5+fn07NnT/r378/mzZvZsGEDAK+88grjxo0DrByI/Tb8zjvveL3GCSecwLvvvktFRQXl5eXMmzfP7b7HHnssjz32WIOAjB49mkcffZQxY8YAVm+srKwsYmJieOWVV6irq2s49sILL+SFF15g8eLFnH661dv9tNNO46mnnmroar1u3ToOHDjQ7LrHHXccc+bMAeDVV19l7NixXn+vcGL/TbKzsxt+1tbWsmWLy2rjhjBjBMQQclpDCGv//v1MmzaNo48+mpycHNasWcO9995LYmIiL7zwAueff35DiOaaa6yI6z333MNNN91Ebm5uo9COO4YPH86FF17IkCFDmDhxIiNHjnS775gxY9i2bRu5ubmAJSCbNm3iuOOOA+Daa6/lpZdeYsiQIfz888+NvINTTz2VL7/8kgkTJtCmTRsAZsyYwdFHH83w4cMZNGgQv/3tb116CY8//jgvvPACOTk5vPLKKzz22GO+38QwsG7dOqCxgDi3GyKLHE5d4HJzc9VMKBV+cnJyWLVqFdnZ2eYf2xBS7r77bmbOnElFRQVt2rShsLCQzp0789hjj3HjjTdG27xWi4gsU9Xcpu3GAzGEnNbggRhaJuvXr6dXr14NnlSnTp1o3769yw4AhvBjBMQQcmzhKCkpCekIaYNh3bp1DWErABExnm4UMQJiCCkVFRVUVFSQkZFBfX09+/bti7ZJhlaCqrJ+/fqGHlg2/fr1Mx5IlDACYggpJSUlwK/JTRPGMoSKwsJCysvLG3kgYH3XtmzZ0lARwBA5jIAYQootGEZADKGmaQ8sm+zsbOrr69m0aVM0zDqsMQJiCCm2YPTt27fRZ4MhWH755RcAjjzyyEbt9md7uyFyGAExhJTWJCCxsbEMHTqUQYMGMWnSJEpLS6Nt0mHN7t27AcjKymrUbn+2txsihxEQQ0hpTQKSlJREfn4+q1evpkOHDjzxxBPRNumwpqCggLZt25KSktKovXPnzg3bDZHFCIghpNiCYYcVDmUBcWb06NHs2GHNGLBx40ZOP/10RowYwdixY/n5558BeOuttxg0aBBDhgxpqA774osvMnnyZMaPH092djZ//vOfG87597//nUGDBjFo0KCGel+bN29mwIABXHXVVQwcOJBTTz2ViooKAGbNmtUwMt6uaXXgwAGuuOIKRo0axbBhw3jvvfcidUsizu7duxvEwpmkpCTat29vPJAoYKqPGUJKcXEx8fHxpKenk5KSEhoBuflmCHE5d4YOBR+LNNbV1bFw4UKuvPJKAK6++mqefvppsrOz+fbbb7n22mv57LPPuO+++5g/fz7dunVrFO767rvvWL16NcnJyYwcOZIzzjgDEeGFF17g22+/RVU55phjGDduHOnp6axfv57XX3+df/3rX1xwwQW88847XHrppTz44IP88ssvJCQkNJx/5syZnHTSSTz//POUlpYyatQoJkyY0KzQYWtg9+7ddOnSxeW2Ll26GAGJAkZADCGlqKiIDh06ICJ06NDhkC6oWFFRwdChQ9mxYwcDBgzglFNOYf/+/SxdupTzzz+/YT+7++iYMWOYPn06F1xwAVOmTGnYfsopp9CxY0cApkyZwpIlSxARzjnnnIYH/ZQpU1i8eDFnnXUWvXv3bpg7Y8SIEQ2l0HNycrjkkks4++yzOfvsswH45JNPmDt3bsNUuJWVlWzdupUBAwaE89ZEhYKCAvr37+9yW5cuXUwIKwoYATGElOLiYjp06ABAhw4dQuOBRKmcu50DOXjwIKeddhpPPPEE06dPJy0tzeUEV08//TTffvstH3zwASNGjGiozCsijfZr+rkpTUu/2yGsDz74gEWLFjFv3jxmzpzJqlWrUFXeeecdtw/W1sTu3bvdThzVuXNnVq5cGWGLDCYHYggpxcXFpKdbE0WGTECiTHJyMrNmzeKRRx4hOTmZ3r1789ZbbwHW6OgVK1YAVm7kmGOO4b777qNTp05s27YNgAULFlBcXExFRQXvvvsuY8aMYezYsbz77rscPHiQAwcO8N///tdjqfT6+nq2bdvGiSeeyEMPPURZWRn79+/ntNNOazQv+PLly8N8N6JDTU0NRUVFJoTVwjACYggpBw4coF27doA1q5+rOSYORYYNG0ZOTg6vv/46r776Ks899xxDhgxh4MCBDYnr2267jcGDBzNo0CCOO+44hgwZAsCoUaM4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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import scipy.signal as ss\n", "import matplotlib.pyplot as plt\n", "\n", "t = np.linspace(-0.001, 0.001, 100, endpoint=False)\n", "# gausspulse returns a vector representing a gaussian-modulated sinusoid\n", "# with center frequency `fc` in Hz. See `scipy` documentation for other details.\n", "high_freq, high_envelope = ss.gausspulse(t, fc=5000, retenv=True)\n", "low_freq, low_envelope = ss.gausspulse(t, fc=2000, retenv=True)\n", "waveform = np.concatenate([high_freq, low_freq])\n", "response = 0.3*np.concatenate([np.zeros_like(t), low_envelope])\n", "\n", "fig, ax = plt.subplots(1,1)\n", "plt.plot(waveform, 'k-', label='Sound Waveform')\n", "plt.plot(response, 'r-', label='Response')\n", "plt.xlabel('Time (ms)')\n", "plt.ylabel('Amplitude // Firing Rate')\n", "plt.legend(frameon=False)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Note that our imaginary neuron doesn't fire at all in response to the 5 KHz\n", "tone, but responds in direct proportion to the amplitude of the 2 KHz tone.\n", "We can model this simple linear behavior with a new `WeightChannels` Layer.\n", "In particuar, if we represent the sound waveform as a 2-channel\n", "pseudo-spectrogram, we should fit weights of 0 and 0.3 for the high- and\n", "low-frequency channels, respectively. Note that in the spectrogram generated\n", "below, frequency is represented discretely on the vertical axis and amplitude\n", "is represented by saturation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "high_channel = np.concatenate([high_envelope, np.zeros_like(t)])\n", "low_channel = np.concatenate([np.zeros_like(t), low_envelope])\n", "spectrogram = np.vstack([high_channel, low_channel]).T\n", "\n", "def plot_data(prediction=None):\n", " fig, ax = plt.subplots(1,1)\n", " ax2 = ax.twinx()\n", " ax.imshow(spectrogram.T, aspect='auto', interpolation='none', cmap='binary')\n", " ax2.plot(response, 'r-')\n", " if prediction is not None:\n", " ax2.plot(prediction, 'b--')\n", "\n", " ax.yaxis.set_visible(False)\n", " ax.set_xlabel(\"Time (ms)\")\n", " ax2.set_ylabel(\"Firing Rate (Hz)\")\n", "\n", "plot_data()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now, let's use `Model.fit` to try to match the response data. We'll create a\n", "new Layer that computes a weighted sum of the spectrogram input to predict\n", "the response. A successful fit should be able to find the correct parameter\n", "values, `[0.0, 0.3]`. Note that `WeightChannels` already exists in the\n", "`nems.layers` library, but we'll re-create a simple version here to demonstrate." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 0\n", "==============================\n", " Iteration 0, error is: 0.00758946...\n", "Fit successful: False\n", "Status: 2\n", "Message: ABNORMAL_TERMINATION_IN_LNSRCH\n", "\n", "Fitted parameter values:\n", "{'WeightChannels': {'coefficients': array([[-3.70172149e-09],\n", " [ 2.99999997e-01]])}}\n" ] } ], "source": [ "class WeightChannels(Layer):\n", " def initial_parameters(self):\n", " coefficients = Parameter('coefficients', shape=self.shape)\n", " return Phi(coefficients)\n", "\n", " def evaluate(self, spectrogram):\n", " # Only two inputs are supported, and they are weighted differently.\n", " coefficients = self.get_parameter_values()\n", " # @ represents matrix multiplication, and the squeeze prevents an\n", " # extra dimension from being prepended to the output.\n", " return np.squeeze(spectrogram @ coefficients, axis=0)\n", "\n", "linear_model = Model(layers=WeightChannels(shape=(2,1)))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "First, we'll check that the model behaves as expected with some random\n", "initial parameters." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[0.14423579]\n", " [1.59272023]]\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "random_model = linear_model.sample_from_priors()\n", "print(random_model.get_parameter_values()['WeightChannels']['coefficients'])\n", "plot_data(random_model.predict(spectrogram))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Depending on the parameters you generated, you should see that the blue curve\n", "responds strongly to the first sound if the first coefficient is large, and\n", "responds strongly to the second sound if the second coefficient is large.\n", "\n", "Now, let's fit to the simulated data." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch 0\n", "==============================\n", " Iteration 0, error is: 0.22535711...\n", " Iteration 5, error is: 0.00800495...\n", " Iteration 10, error is: 0.00023635...\n", " Iteration 15, error is: 0.00000697...\n", " Iteration 20, error is: 0.00000023...\n", "Fit successful: False\n", "Status: 2\n", "Message: ABNORMAL_TERMINATION_IN_LNSRCH\n", "\n", "Fitted parameter values:\n", "{'WeightChannels': {'coefficients': array([[-3.12388031e-09],\n", " [ 3.00000000e-01]])}}\n" ] } ], "source": [ "fitted_model = random_model.fit(spectrogram, response)\n", "print(f\"\\nFitted parameter values:\\n{fitted_model.get_parameter_values()}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "In this case we can clearly see that the fit was successful since there are\n", "only two parameter values to check. However, we can also use `Model.score` to\n", "get a more succinct assessment for larger models. By default, this computes the\n", "pearson correlation between the `Model` prediction and the target data." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fitted_model.score(spectrogram, response)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plot_data(fitted_model.predict(spectrogram))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "A perfect match!" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "nems-env", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.12" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "db2be69b1998ea19ccbeea4ffe5a2fe921bd3007ff03eaeffbb421f0a1755fa8" } } }, "nbformat": 4, "nbformat_minor": 2 }