From d247ad939cc0b2a8c58afef51d1e62eaeaa7a4bb Mon Sep 17 00:00:00 2001 From: manuelgloeckler <38903899+manuelgloeckler@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:54:33 +0200 Subject: [PATCH] Updated transforms base (#456) * Updated transforms base * More transforms tests and doc * refactored * add tests for plain Arrays not PyTrees (datasets) * Updating some docs * update tutorial 7 notebook with new transforms --------- Co-authored-by: Matthijs --- docs/tutorials/07_gradient_descent.ipynb | 160 +++++++------- jaxley/optimize/transforms.py | 262 +++++++++++++++-------- tests/test_transforms.py | 160 +++++++++++--- 3 files changed, 394 insertions(+), 188 deletions(-) diff --git a/docs/tutorials/07_gradient_descent.ipynb b/docs/tutorials/07_gradient_descent.ipynb index e1a71fe6..061a1d4b 100644 --- a/docs/tutorials/07_gradient_descent.ipynb +++ b/docs/tutorials/07_gradient_descent.ipynb @@ -19,7 +19,7 @@ "```python\n", "from jax import jit, vmap, value_and_grad\n", "import jaxley as jx\n", - "\n", + "import jaxley.optimize.transforms as jt\n", "\n", "net = ... # See tutorial on the basics of `Jaxley`.\n", "\n", @@ -29,10 +29,9 @@ "parameters = net.get_parameters()\n", "\n", "# Define parameter transform and apply it to the parameters.\n", - "transform = jx.ParamTransform(\n", - " lowers={\"HH_gNa\": 0.0, \"IonotropicSynapse_gS\": 0.0},\n", - " uppers={\"HH_gNa\": 1.0, \"IonotropicSynapse_gS\": 1.0},\n", - ")\n", + "transform = jx.ParamTransform([{\"IonotropicSynapse_gS\": jt.SigmoidTransform(0.0,1.0)},\n", + " {\"HH_gNa\":jt.SigmoidTransform(0.0,1,0)}])\n", + "\n", "opt_params = transform.inverse(parameters)\n", "\n", "# Define simulation and batch it across stimuli.\n", @@ -75,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 1, "id": "d09b991a", "metadata": {}, "outputs": [], @@ -106,19 +105,10 @@ }, { "cell_type": "code", - "execution_count": 264, + "execution_count": 2, "id": "9b4f07eb", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/michaeldeistler/Documents/phd/jaxley/jaxley/modules/base.py:1533: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", - " self.pointer.edges = pd.concat(\n" - ] - } - ], + "outputs": [], "source": [ "_ = np.random.seed(0) # For synaptic locations.\n", "\n", @@ -149,13 +139,13 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 3, "id": "6045dd9e-b493-4f88-8c91-96706d484a97", "metadata": {}, "outputs": [ { "data": { - "image/png": "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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAASUAAADFCAYAAAASVORBAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAjmklEQVR4nO3deVxU5f4H8M+wzAgCgyKrrC4sqRAiM9JVy6LUWy6p/bhquUTu2r3uWpl5LSnNJcm08iZZmmapt9S6KSqmgoMIKqIohkHCqGmssozM8/vjkZGRxQGZObN836/XeeU5nJn5cnI+nvOc5zyPiDHGQAghRsJK6AIIIaQuCiVCiFGhUCKEGBUKJUKIUaFQIoQYFQolQohRoVAihBgVG6ELeFRqtRoFBQVwdHSESCQSuhxCSB2MMZSWlsLLywtWVrqdA5l8KBUUFMDHx0foMgghTcjPz4e3t7dO+5p8KDk6OgLgv7STk5PA1RBC6iopKYGPj4/me6oLkw+l2ks2JycnCiVCjFRzmlaooZsQYlQolAghRoVCiRBiVEy+TUlXK1euxO7duyGTyTRL586dqRsBIUbGYkLp6NGjSE5ORnJysmZbu3bttEIqMjIS7u7uAlZJCBGZ+iBvJSUlkEqlKC4ubvLuW05ODlJSUqBQKKBQKJCRkYGqqqp6+/n6+moFVUREBBwcHPT5KxBitnT9ftZlMaH0oOrqapw7d04TUgqFAhcuXMCDh8PKygqPPfaYVlB1794dtra2rf2rEGJ2jC6U3nnnHSxdulRrW1BQEC5evAgAqKysxJw5c7B9+3ZUVVVhwIAB+OSTT5p1CdXSUGrsvdLS0qBQKJCamgqFQoH8/Px6+7Vp0wbh4eHUPkXIQxhlKH333Xc4ePCgZpuNjQ06dOgAAJg6dSr27duHhIQESKVSzJgxA1ZWVjh+/LjOn9GaodSQwsJCTUDVhlVRUVG9/eq2T0VGRkImk8HNzQ137txp9Zqaw97ensKSCMYoQ2nPnj3IyMio97Pi4mK4urpi27ZtGDlyJADg4sWLCAkJQXJyMnr37t3ge1ZVVWm1BdV2Y9dXKD1IrVYjJydHK6jS09MbbJ9ycXHBrVu39FSJF4CvAcwBkN7oXmVlZWjbtq2eaiCkaS0JJb33U7p8+TK8vLzQqVMnjBkzBnl5eQCAtLQ0qFQqREdHa/YNDg6Gr6+v1h2yB8XFxUEqlWoWQz+Ma2VlhcDAQIwZMwYfffQRkpOTkZeXh/Xr12PIkCHw8fGBjQ2/qam/QAKAOAD9ASgAfADATo+fRYjh6LVLgFwuR0JCAoKCglBYWIilS5eib9++yMzMhFKphFgshrOzs9Zr3N3doVQqG33PRYsWYfbs2Zr12jMlQ6msrMSZM2e0zpSys7Pr7WdtbQ1/f3+0a9cOHTt2xJYtW2Btbd1qdVy/Dsyffxfff28DYD4CAuZi3boq9O+v1trP3t6+1T6TEEPQaygNGjRI8+fQ0FDI5XL4+fnh22+/hZ1dy/5ll0gkkEgkrVVik9RqNbKzs7Xu0J05cwYqlarevp06ddJq+A4PD9drIHTqBHz3HfDjj8C0aUBurhUGD7bDhAnAhx8C7dvr7aMJ0SuDdp50dnZGYGAgcnJy8Oyzz6K6uhpFRUVaZ0vXr1+Hh4eHIcsCwAejunbtmtadt9TUVJSWltbb19XVVatROzIyUtN4b2iDBwNPPgm88QbwySfA5s3Avn1AfDzw0ksAtXETU2PQUCorK8OVK1fwyiuvICIiAra2tkhMTMSIESMAANnZ2cjLy0NUVJTeaykqKsKpU6e0zoIKCwvr7Wdvb4+IiAitsyA/Pz+juqPl5AR8/DEwahQwcSJw4QIQEwN8/TUPKh3H1iLEKOj17tvcuXMxePBg+Pn5oaCgAEuWLEFGRgaysrLg6uqKqVOnYv/+/UhISICTkxNmzpwJADhx4oTOn6Fr6356ejqOHTumCaBLly7V28fa2ho9evTQCqCQkBBNw7UpqKoC4uKA5csBlQpwdATefx+YMgXQcTRSQlpNi7rsMD2KiYlhnp6eTCwWs44dO7KYmBiWk5Oj+XlFRQWbNm0aa9euHbO3t2cvvvgiKywsbNZnFBcXMwCsuLi4yf2GDh3KAGgtnTt3ZqNGjWJr1qxhx48fZ+Xl5S36PY1RZiZjvXszBvDlb39jLCtL6KqIpdH1+1mXxTxmsn79evz0009abUEuLi4GrNTwamqADRuARYuAsjJALAbeegtYsID/mRB9M7rOk4ag7x7d5iAvD5g6Fdi/n6936wZs2gQ00j+VkFZjlJ0nifB8fYG9e4FvvgFcXYHz54EnngD++U+ggZuLhAiKQslCiETAP/7B78yNG8dbmtatA7p3B376SejqCLmPQsnCuLgACQnAL78A/v780u7vfwfGjAFu3hS6OkIolCzWs88CmZnA7Nm8q8C2bUBICPDVV/wsihChUChZsLZtgVWrgJQUIDQUuHULGDsWGDgQuHpV6OqIpaJQIoiMBE6d4h0uJRJ+adetG7BmDe9WQIghUSgRAICtLe/PdPYsf5buzh1+aRcVxbcRYigUSkRLYCBw6BDw2WeAVAqkpgIREbzTZWWl0NURS0ChROqxsuIP9mZlAcOHA3fvAu+9B4SFAUePCl0dMXcUSqRRXl7A99/zxdMTuHSJX9pNmQIUFwtdHTFXFErkoYYP52dNkybx9U8/5d0H9uwRtCxipiiUiE6cnXkYHTkCdO0KFBYCL74IjBzJ/0xIa6FQIs3y5JPAmTN8pEsbG35pFxLCH/ClTpekNVAokWazs+MN36dOAb168faliROBp58GLl8Wujpi6iiUSIuFhQHJybxXuL09v7QLDeUjXTYwtwIhOqFQIo/ExoZ3sszM5M/TVVbyTpgyGZCWJnR1xBRRKJFWERAA/O9/wJdf8umdMjJ4MM2bx3uHE6IrCiXSakQi/kDvhQt8ZhW1ms9B1707cPCg0NURU0GhRFqdmxsfCmXvXsDHB8jN5Zd2EybwkQgIaQqFEtGb55/nQ+/OnMnPohISgMceA3bsoO4DpHF6DaW4uDhERkbC0dERbm5uGDZsGLKzs7X2eeqppyASibSWKVOm6LMsYkCOjnzY3ePHeSDduMGH5R0yBMjPF7o6Yoz0GkpJSUmYPn06UlJScODAAahUKjz33HMoLy/X2m/ixIkoLCzULCtWrNBnWUQAUVHA6dPA0qV8mJS9e3lIrV/P254IqWXQKZZu3rwJNzc3JCUloV+/fgD4mdLjjz+OtWvX6vQeVVVVqKqq0qyXlJTAx8eHplgyIVlZvLNl7UTITzwBfP45DyliXox+iqXie4+Wt2/fXmv71q1b0aFDB3Tv3h2LFi3CnSbuIcfFxUEqlWoWHx8fvdZMWt9jjwG//srPkhwceDiFh/OzqDr/3hALZbAzJbVajSFDhqCoqAjHjh3TbP/ss8/g5+cHLy8vnD17FgsWLIBMJsOuXbsafB86UzIv+fnAtGn8cg7ggbVpE7/cI6avRZPF6mH68AZNmTKF+fn5sfz8/Cb3S0xMZABYTk6OTu/bkrnKiXFRqxnbvp0xNzfGAMZEIsZmzmSspEToysijasn30yCXbzNmzMDevXtx+PBheHt7N7mvXC4HAOTk5BiiNGIERCIgJoZ3uhw/nncXiI/nkxfs2yd0dcTQ9BpKjDHMmDEDu3fvxqFDhxAQEPDQ12RkZAAAPD099VkaMULt2wObNwMHDvDHVvLzgRdeAEaP5l0JiGXQayhNnz4dX3/9NbZt2wZHR0colUoolUpUVFQAAK5cuYJly5YhLS0NV69exQ8//ICxY8eiX79+CA0N1WdpxIhFR/MHfOfO5eOFf/MNH7NpyxbqdGkR9Hc1yRiABpfNmzczxhjLy8tj/fr1Y+3bt2cSiYR16dKFzZs3r1nXn9SmZN5OnWLs8cd5WxPA2LPPMvbbb0JXRXTVku+nQfsp6UOLWveJSVGpgNWrgXfe4UOj2NsDy5YBr7/Oh04hxsvo+ykR0hK2tsCCBXxSzKee4kOhzJnDuw2cOSN0daS1USgRk9G1K58oc9MmPlFm7XC8b7wB3GumJGaAQomYFJEIiI3l3QdGjOATZcbF8aF5k5KEro60BgolYpI8PYHvvgN27+aTZl6+zC/tJk0CioqEro48CgolYtKGDeMP+E6ezNdrH+zdvVvQssgjoFAiJk8qBTZu5JdvgYF8cszhw/nlXUGB0NWR5qJQImajXz9+N+7NN3lXgV27+FnT55/TmE2mhEKJmJU2bYB33+XTO0VG8okyJ03iE2VeuiR0dUQXFErELIWG8oky16zhnS2Tkvi2uDiaKNPYUSgRs2VtDfzrX3zyggED+AByb7zB+zalpgpdHWkMhRIxe/7+wE8/AV99Bbi48J7hvXvzXuEPDBdPjACFErEIIhHw8su80+WYMbzhe/VqPlHmL78IXR2pi0KJWBRXV+Drr4H9+wFfX+DqVX5pN24cTZRpLCiUiEUaNIi3Nf3zn/wsassWPmbTN9/QmE1Co1AiFsvBAVi7lt+l694duHmTj3I5eDCQlyd0dZaLQolYPLmc92v6978BsZiPC96tG/Dxx0BNjdDVWR4KJULAw2jxYiAjA/jb34CyMmDmTKBvX36Z9zC1cxqSR0ehREgdISHA0aPAJ58Ajo780i48nI962dhEmYwxBAYGwtfXFyNHjsSKFStw5MgRlJaWGrR2c0HD4RLSiD/+4BNl/vgjXw8J4QPMPfGE9n4FBQXw9vbGg18lkUiEkJAQyGQyzdKjRw+IxWID/QbCa8n3k0KJkCYwxsdtmjGDT/MkEvGgWr4cqPvXrbS0FKdPn4ZCodAseQ20lkskEoSHh2tCKjIyEl26dIGVlXletFAoUSgRPbl9G5g3D/jiC77u7Q1s2MDnpWuMUqlEamoqFAqF5r9//fVXvf2cnZ0RGRmpdUbl4eGhp9/EsEw2lNavX4+VK1dCqVQiLCwM8fHxkMlkOr2WQokYUmIiH3Xgt9/4ekwM8NFHgLv7w1/LGMOVK1e0zqZOnz6NqgYaq3x8fBAZKUOHDjK4ukYiKioCAwc6wdq6lX8hPTPJUNqxYwfGjh2LjRs3Qi6XY+3atdi5cyeys7Ph5ub20NdTKBFDu3MHWLoUWLWKdxlo144/sjJuHL+8aw6VSoVz585pzqQUCgXOnz9fr30KEMHGJgR9+8rw0kv8sq9z586Ct0/Z29tD1MQv3aLvZyvOO9ciMpmMTZ8+XbNeU1PDvLy8WFxcXIP7V1ZWsuLiYs2Sn59Pk1ESQaSlMRYefn+izOhoxq5cefT3/frrEgYcYcAKBoxkgG+jE7sKvZSVlTX5u7RkMkpBW9eqq6uRlpaG6OhozTYrKytER0cjOTm5wdfExcVBKpVqFh8fH0OVS4iWnj0BhQJYsYIPLnfwIO8ZvmoVn2UF4GdSR47wx1eOHHl4Z8yaGmDhQkcATwKYC2ANgO0ApgHoAcD879wJevlWUFCAjh074sSJE4iKitJsnz9/PpKSknDy5Ml6r6mqqtK6Bi8pKYGPjw9dvhFB5eTwyQsOHeLrERHAqFH8MZY//ri/n7c3b4MaPrz+e9y+fRv/+c8pzJ+vAHABQG8Ar4IHUSCAq/f2bIuwsF4IDw+AnZ0dhg4dij59+ujtd2uKPi7fTG7SY4lEAolEInQZhGjp0oWfKW3ezMdpSkvjy4OuXQNGjgS2bq2Av3+Gph0pNTUVly9fBiAFMBvABgC1X+JMALEAvADIAIRgwQJrjBplkF/N4AQNpQ4dOsDa2hrXr1/X2n79+nWzuSVKLIdIBLz6Kh8KpWvXurP2MvCznCNgTAFAgdGjzwK4W+fVDgDegEg0H4xJ720rB/+Kdr+33Ofpqb/fQ2iCtimJxWJEREQgMTFRs02tViMxMVHrco4QU8EYw7Fjeaio+A5AAoCbAEQAAgD8DmAjgNMA7qJdOzcMGjQCzz13AE5OtwC8B8aksNGcKrQFoH1VIBIBPj78mTxzJfjl2+zZszFu3Dj06tULMpkMa9euRXl5OSZMmCB0aYTopKioCB9//LHmUkz7zN8JQByAKQCKAcwDvwST4YUXfPDLLyLU7t61K3/GztaW938CtMd2qm26WbsWJtdfqVke6d5lK4mPj2e+vr5MLBYzmUzGUlJSdH5tS245EtKaysrKmLW1teY2ubW1DQN6MmAyA/7DgHMMuKvpOvDg4u/P2ObNjKlU99/z++8Z8/bW3s/Hh283JS35fgreefJRUedJYgwWLlwIT0/Pew/dPo6QEDtcu9b0KJbe3sBbbwETJvChUx5UUwP8+iuf8dfTk1+ymdoZkkn26H5UFErEGO3axe+yNfbtio3lg8i1aWPYugytJd9P83w0mRCBDRsGzJ6NOo3WnFQKbNvGh0Ax90BqKcEbugkxJ4wBP/wAvP02n18O4IPFDRrEn40bMMD0LsEMjUKJkFbAGPDzzzyMTp3i25ycgFmz+CKVNv16ch+FEiGP6NAhPr73iRN83d6eT900dy7Qvr2wtZkiCiVCWujYMR5GR47w9TZt+KiUCxYAOoy6QxpBoURIMykUPIxqp/sWi/nAb4sWAV5ewtZmDiiUCNFRejpvM9q7l6/b2PBn3d58k08BTloHhRIhD3H+PLBkCfD993zdygp45RUeUJ06CVubOaJQIqQRly7xZ9G2b+d310Qi4B//4AEVFCR0deaLQomQB/z2G5/C+6uvALWabxsxggdU9+5NvpS0AgolQu7JzwfefZdPo1Q7nO0LL/CACg8XtjZLQqFELF5hIZ9c8rPPgOpqvu2553gYyeXC1maJKJSIxbpxA/jgA+CTT4DKSr7tySf52ZJAQ14TUCgRC3T7NvDhh8C6dUB5Od8WFQUsWwY8/XTz524jrYtCiViM4mJgzRq+lJTwbb168cu0gQMpjIwFhRIxe2VlQHw8sHIl8NdffFtoKA+jIUMojIwNhRIxW3fuABs28Hajmzf5tpAQPuX2iBG8EyQxPhRKxOxUVfE7acuXA0ol39alC+/0OGoUjWdk7CiUiNlQqfhkkMuW3Z+V1s+PPw4ydmz9USCJcdLLCezVq1cRGxuLgAA+rXDnzp2xZMkSVNd2Arm3j0gkqrekpKTooyRixu7eBRIS+KMfkyfzQOrYkV+6XbrEH5qlQDIdevlfdfHiRajVanz66afo0qULMjMzMXHiRJSXl+PDDz/U2vfgwYPo1q2bZt3FxUUfJREzVFMD7NjB24guXeLb3N35ECKTJ9MY2KZKL6E0cOBADBw4ULPeqVMnZGdnY8OGDfVCycXFhaboJs2iVgO7d/PLsqwsvs3FhQ+uNn06H/mRmC6D3X8oLi5G+wbGBh0yZAjc3NzQp08f/PDDDw99n6qqKpSUlGgtxDIwBvz4IxARwacvysoCnJ15D+zcXGDePAokc2CQUMrJyUF8fDwmT56s2ebg4IBVq1Zh586d2LdvH/r06YNhw4Y9NJji4uIglUo1i4+Pj77LJwJjDPjf/4DevXm/oowMPkPI4sU8jN58k68TM9GcKXgXLFigmZq4seXChQtar/njjz9Y586dWWxs7EPf/5VXXmF9+vRpcp/KykpWXFysWfLz82nabjN2+DBjffrcn7ra3p6xBQsY+/NPoSsjumjJtN3NalOaM2cOxo8f3+Q+neoMxVdQUID+/fvjiSeewGefffbQ95fL5Thw4ECT+0gkEkgkEp3qJabrxAl+JnToEF+XSO4Pyu/uLmxtRL+aFUqurq5wdXXVad9r166hf//+iIiIwObNm2GlQ/fZjIwMeHp6NqckYmZOneJh9PPPfN3Wlg/K/8YbNCi/pdDL3bdr167hqaeegp+fHz788EPcrO3jD2jutH355ZcQi8UIvzd61q5du/DFF19g06ZN+iiJGLkzZ/jdtNomRWtrYMIE4K23eAdIYjn0EkoHDhxATk4OcnJy4O3trfUzxpjmz8uWLcPvv/8OGxsbBAcHY8eOHRg5cqQ+SiJGKiuLDzO7cydft7ICXn6ZB1TnzoKWRgQiYnVTwgSVlJRAKpWiuLgYTk5OQpdDdHT5Mu/0uG3b/UH5Y2L482nBwUJXR1pLS76f1PmeGNTVq3zIkC1beI9sAHjxRR5QPXoIWhoxEhRKxCD++AN47z1g06b7g/I//zwPqJ49ha2NGBcKJaJXSiUQFwd8+ikfUgQAnn2Wh1Hv3sLWRowThRLRi5s3gRUrgPXrgYoKvq1fPz6sSL9+wtZGjBuFEmlVf/0FrFoFfPQRH4YW4GdEy5YBzzxDQ8+Sh6NQIq2ipARYuxZYvZoP0A/wtqJly4BBgyiMiO4olMgjKS+/Pyj/7dt8W48evM1o6FAKI9J8FEqkRSoqgI0beSN2bYf94GDeEfKll2hQftJyFEqkWaqq+G395cuBggK+rXNn3ulx9GgalJ88OgolohOVio+D/e67QF4e3+bre39QfltbQcsjZoRCiTSppgbYupX3uP7tN77Ny4sPrBYby4cUIaQ1USiRBqnVwLff8jai7Gy+zc3t/qD8dnaClkfMGIUS0cIYsGcPvyzLzOTbXFyA+fP5oPxt2wpaHrEAFEoEAA+j/ft5GJ0+zbdJpcDcucDrrwM0AAMxFAolC8cYcPAgH+3x5Em+zcEB+Ne/gNmzgXbtBC2PWCAKJQt29Cgf2fHXX/m6nR0wcyafqqhDB2FrI5aLQskCpaTwM6ODB/m6RAJMnQosXEiD8hPhWUwo5ebmQqVSoUuXLjpNYmCO0tJ4m9H+/Xzd1hZ47TU+KP8DoxYTIhiLCaU1a9YgPj4eUqkUkZGRkMlkmsXcZ1A5d46H0Z49fN3aGhg/nl+6+fsLWBghDbCYUKqqqkKbNm1QXFyMgwcP4mDttQsAb29vyGQyTVj16tXLLMb7vniR9zP69tv742DXDsrfpYvQ1RHSMIuaOEClUiEzMxOpqalQKBRQKBQ4f/481Gq11n4ikQjBwcGaM6nIyEiEhoaazCSYV67wHthbt/JOkADwf//HAyokRNDSiIVp0cQe+pmslzE/P796U3rHxcVp7XPmzBnWp08fJpFImLe3N/vggw+a/TktmRa4rtLSUpaUlMRWrlzJXnrpJebv79/gdORisZjJZDI2Y8YMtmXLFnbx4kVWU1PTos/Ul6tXGYuNZcza+v4018OGMXbmjNCVEUvVku+n3s6U/P39ERsbi4kTJ2q2OTo6ou29LsElJSUIDAxEdHQ0Fi1ahHPnzuHVV1/F2rVrMWnSJJ0/Rx9TLN24cUPrbEqhUOB27WBBdUilUvTq1UurfcpLgGlcr13jT+1//jl/cBYA/v53PqZRRITByyFEw+imWHJ0dNTMiPugrVu3orq6Gl988QXEYjG6deuGjIwMrF69ulmhpA9ubm54/vnn8fzzzwPgE2jm5uZqhVRaWhqKi4uRmJiIxMREzWs7duyoCahevXohJCQEVlZWemmjun4dWL1ajE2bbFBVxUdTe+qpGixeXA25XH2vdnuIaKQ1YkL0eqZUWVkJlUoFX19fjB49GrNmzYKNDc/BsWPHoqSkBHtqbwkBOHz4MJ5++mncvn0b7RrpSlxVVYWq2mkxwJPYx8fH4JNRqlQqnD9/HgqFQnNWlZmZWa99Sn9mAVgGoPZhtKMAFt/7731lZWWas1NCDM2ozpRef/119OzZE+3bt8eJEyewaNEiFBYWYvXq1QAApVKJgIAArde43+u5p1QqGw2luLg4LF26VF9l68zW1hZBQUG4c+cO7ty5g/LycpSVleG32vE99K4YPJBSwMPoYNO7E2IimhVKCxcuxAcffNDkPhcuXEBwcDBmz56t2RYaGgqxWIzJkycjLi7uke5iLVq0SOu9a8+U9K2mpgZZWVmay7fU1FScPXsWNbXTvNYRGBiIyMhIREZGwtfXFy4uLoho5cYdlQpISqrEM8/0gEi0p9H97O3tW/VzCdG3ZoXSnDlzMH78+Cb36dSpU4Pb5XI57t69i6tXryIoKAgeHh64fv261j616421QwGARCLR+615xhjy8vLqtSGVl5fX29fd3R1yuVyrHamxs7zWNnSoQT6GEINqVii5urrC1dW1RR+UkZEBKysruLm5AQCioqLw5ptvQqVSwfbeWKoHDhxAUFCQwb7UtW7dulXvbtvN2tHw63BwcKh3t83b25sakglpRXppU0pOTsbJkyfRv39/ODo6Ijk5GbNmzcLLL7+sCZzRo0dj6dKliI2NxYIFC5CZmYmPPvoIa9as0UdJGnfu3EF6erpWCF25cqXefjY2NggLC9MKoKCgIFjTyPiE6Jc+OkylpaUxuVzOpFIpa9OmDQsJCWHLly9nlZWVWvvV7TzZsWNH9v777zf7s3TtnPXee++xxx9/nFlbWzfYOTIwMJC9/PLLbN26dSw5OZlVVFQ0uxZCiLaWdJ7Uy5lSz549kZKS8tD9QkND8WvtYD56lpubi4yMDADCtgMRQppmMQ/kvvbaaxg4cCC1AxFi5CwmlORyOeRyudBlEEIewjJHOyOEGC0KJUKIUaFQIoQYFZNvU2L3nicuKSkRuBJCyINqv5esGc/9m3wolZaWAoBBnn8jhLRMaWkppFKpTvua/HC4arUaBQUFcHR0pNv8ddQ+qJyfn28W443rGx2v5tH1eDHGUFpaCi8vL51nETL5MyUrKyt40/xAjXJycqIvWTPQ8WoeXY6XrmdItaihmxBiVCiUCCFGhULJTEkkEixZssRkpoUSGh2v5tHn8TL5hm5CiHmhMyVCiFGhUCKEGBUKJUKIUaFQIoQYFQolQohRoVAyU+vXr4e/vz/atGkDuVwOhUIhdEmCe+eddyASibSW4OBgzc8rKysxffp0uLi4wMHBASNGjKg3DZg5O3r0KAYPHgwvLy+IRCKt2asB/sjI22+/DU9PT9jZ2SE6OhqXL1/W2uf27dsYM2YMnJyc4OzsjNjYWJSVlTWrDgolM7Rjxw7Mnj0bS5YswenTpxEWFoYBAwbgxo0bQpcmuG7duqGwsFCzHDt2TPOzWbNm4ccff8TOnTuRlJSEgoICDB8+XMBqDau8vBxhYWFYv359gz9fsWIF1q1bh40bN+LkyZNo27YtBgwYgMrKSs0+Y8aMwfnz53HgwAHs3bsXR48exaRJk5pXiB4mMCACk8lkbPr06Zr1mpoa5uXlxeLi4gSsSnhLlixhYWFhDf6sqKiI2drasp07d2q2XbhwgQFgycnJBqrQeABgu3fv1qyr1Wrm4eHBVq5cqdlWVFTEJBIJ++abbxhjjGVlZTEALDU1VbPPTz/9xEQiEbt27ZrOn01nSmamuroaaWlpiI6O1myzsrJCdHQ0kpOTBazMOFy+fBleXl7o1KkTxowZg7y8PABAWloaVCqV1nELDg6Gr68vHTfw2YCUSqXW8ZFKpZDL5Zrjk5ycDGdnZ/Tq1UuzT3R0NKysrHDy5EmdP4tCycz8+eefqKmpgbu7u9Z2d3d3KJVKgaoyDnK5HAkJCfj555+xYcMG5Obmom/fvigtLYVSqYRYLIazs7PWa+i4cbXHoKm/V0qlUjMDdi0bGxu0b9++WcfQ5IcuIURXgwYN0vw5NDQUcrkcfn5++Pbbb2FnZydgZaQuOlMyMx06dIC1tXW9u0bXr1+Hh4eHQFUZJ2dnZwQGBiInJwceHh6orq5GUVGR1j503LjaY9DU3ysPD496N1Pu3r2L27dvN+sYUiiZGbFYjIiICCQmJmq2qdVqJCYmIioqSsDKjE9ZWRmuXLkCT09PREREwNbWVuu4ZWdnIy8vj44bgICAAHh4eGgdn5KSEpw8eVJzfKKiolBUVIS0tDTNPocOHYJarW7enIuP3k5PjM327duZRCJhCQkJLCsri02aNIk5OzszpVIpdGmCmjNnDjty5AjLzc1lx48fZ9HR0axDhw7sxo0bjDHGpkyZwnx9fdmhQ4fYqVOnWFRUFIuKihK4asMpLS1l6enpLD09nQFgq1evZunp6ez3339njDH2/vvvM2dnZ/bf//6XnT17lg0dOpQFBASwiooKzXsMHDiQhYeHs5MnT7Jjx46xrl27slGjRjWrDgolMxUfH898fX2ZWCxmMpmMpaSkCF2S4GJiYpinpycTi8WsY8eOLCYmhuXk5Gh+XlFRwaZNm8batWvH7O3t2YsvvsgKCwsFrNiwDh8+zADUW8aNG8cY490CFi9ezNzd3ZlEImHPPPMMy87O1nqPW7dusVGjRjEHBwfm5OTEJkyYwEpLS5tVB42nRAgxKtSmRAgxKhRKhBCjQqFECDEqFEqEEKNCoUQIMSoUSoQQo0KhRAgxKhRKhBCjQqFECDEqFEqEEKNCoUQIMSr/Dw8F+53UDlduAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -181,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 4, "id": "92cf53ea-cbab-4796-9980-6362b9adbed0", "metadata": {}, "outputs": [ @@ -220,7 +210,7 @@ }, { "cell_type": "code", - "execution_count": 196, + "execution_count": 5, "id": "0394c373-61e2-45a3-88fa-e71349419eb5", "metadata": {}, "outputs": [], @@ -231,13 +221,13 @@ }, { "cell_type": "code", - "execution_count": 197, + "execution_count": 6, "id": "3a4c1360-699d-4a2f-bc27-9820d3848198", "metadata": {}, "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -254,7 +244,7 @@ }, { "cell_type": "code", - "execution_count": 198, + "execution_count": 7, "id": "b821b875-d024-47d9-b047-a44e398186ee", "metadata": {}, "outputs": [], @@ -272,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 8, "id": "e4959638-370b-40c7-b165-cb21d54ce738", "metadata": {}, "outputs": [], @@ -290,7 +280,7 @@ }, { "cell_type": "code", - "execution_count": 201, + "execution_count": 9, "id": "10cb5b1e", "metadata": {}, "outputs": [ @@ -316,7 +306,7 @@ }, { "cell_type": "code", - "execution_count": 202, + "execution_count": 10, "id": "c90be7f3", "metadata": {}, "outputs": [ @@ -361,8 +351,8 @@ }, { "cell_type": "code", - "execution_count": 203, - "id": "12fe7828", + "execution_count": 11, + "id": "dbadd2a8", "metadata": {}, "outputs": [ { @@ -374,7 +364,7 @@ } ], "source": [ - "net.TanhRateSynapse(\"all\").make_trainable(\"TanhRateSynapse_gS\")" + "net.TanhRateSynapse.edge(\"all\").make_trainable(\"TanhRateSynapse_gS\")" ] }, { @@ -395,7 +385,7 @@ }, { "cell_type": "code", - "execution_count": 204, + "execution_count": 12, "id": "40a48eea", "metadata": {}, "outputs": [], @@ -413,7 +403,7 @@ }, { "cell_type": "code", - "execution_count": 205, + "execution_count": 13, "id": "4eb3f8f1", "metadata": {}, "outputs": [], @@ -433,7 +423,7 @@ }, { "cell_type": "code", - "execution_count": 206, + "execution_count": 14, "id": "2354c23b-12bd-4e4a-ab8b-20d062b286c7", "metadata": {}, "outputs": [], @@ -460,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 208, + "execution_count": 15, "id": "625d85e2-2af3-46c2-8739-f993584a7c0b", "metadata": {}, "outputs": [], @@ -470,13 +460,13 @@ }, { "cell_type": "code", - "execution_count": 209, + "execution_count": 16, "id": "273c6489-ee27-469a-ba51-6139edbed8f1", "metadata": {}, "outputs": [ { "data": { - "image/png": "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xetvYgohRE/VY2vgQgjh7STAhRDCS0mACyGEl5IAF0IILyUBLoQQXqrHBvibb75J37598fX1ZcKECezZs8fTRepQX331FbfccgsxMTHodDpWrFjRartSil//+tdER0fj5+fHjBkzOHHiRKt9KisruffeewkKCiIkJISHH36Yurq6TvwW7eull15i3LhxBAYGEhERwW233UZmZmarfZqamliyZAm9evUiICCAhQsXUlJS0mqf/Px85s6di8ViISIigp///Oc4HI7O/Crt7q233mL48OHupwhTU1NZu3ate3tPvS4X+sMf/oBOp+Ppp592r+vUa6N6oI8++kiZTCb1zjvvqCNHjqgf/OAHKiQkRJWUlHi6aB1mzZo16le/+pX69NNPFaA+++yzVtv/8Ic/qODgYLVixQp18OBBNX/+fJWYmKgaGxvd+8yaNUuNGDFC7dq1S23btk3169dP3XPPPZ38TdrPzTffrN599111+PBhlZ6erubMmaMSEhJUXV2de5/HHntMxcfHq02bNqlvvvlGTZw4UV133XXu7Q6HQw0dOlTNmDFDHThwQK1Zs0b17t1b/fKXv/TEV2o3q1atUl988YXKyspSmZmZ6rnnnlNGo1EdPnxYKdVzr8v59uzZo/r27auGDx+unnrqKff6zrw2PTLAx48fr5YsWeL+2el0qpiYGPXSSy95sFSd58IAd7lcKioqSv3xj390r6uqqlJms1l9+OGHSimljh49qgC1d+9e9z5r165VOp1OFRYWdlrZO1JpaakC1NatW5VS2jUwGo3q448/du9z7NgxBaidO3cqpbT/Mer1elVcXOze56233lJBQUHKarV27hfoYKGhoervf/+7XBelVG1trerfv7/auHGjmjx5sjvAO/va9LgmFJvNxr59+5gxY4Z7nV6vZ8aMGezcudODJfOcnJwciouLW12T4OBgJkyY4L4mO3fuJCQkhLFjx7r3mTFjBnq9nt27d3d6mTtCdXU1AGFhYQDs27cPu93e6rqkpKSQkJDQ6roMGzaMyMhI9z4333wzNTU1HDlypBNL33GcTicfffQR9fX1pKamynUBlixZwty5c1tdA+j83xmvH43wapWXl+N0OltdPIDIyEiOHz/uoVJ5VnFxMUCb1+TctuLiYiIiIlptNxgMhIWFuffxZi6Xi6effppJkyYxdOhQQPvOJpOJkJCQVvteeF3aum7ntnmzjIwMUlNTaWpqIiAggM8++4zBgweTnp7eo6/LRx99xP79+9m7d+9F2zr7d6bHBbgQbVmyZAmHDx9m+/btni5KlzFw4EDS09Oprq7mk08+4YEHHmDr1q2eLpZHFRQU8NRTT7Fx40Z8fX09XZye1wuld+/e+Pj4XHRXuKSkhKioKA+VyrPOfe/LXZOoqChKS0tbbXc4HFRWVnr9dXviiSdYvXo1W7ZsaTW2fFRUFDabjaqqqlb7X3hd2rpu57Z5M5PJRL9+/RgzZgwvvfQSI0aM4E9/+lOPvi779u2jtLSU0aNHYzAYMBgMbN26lT//+c8YDAYiIyM79dr0uAA3mUyMGTOGTZs2ude5XC42bdpEamqqB0vmOYmJiURFRbW6JjU1Nezevdt9TVJTU6mqqmLfvn3ufTZv3ozL5WLChAmdXub2oJTiiSee4LPPPmPz5s0kJia22j5mzBiMRmOr65KZmUl+fn6r65KRkdHqf24bN24kKCiIwYMHd84X6SQulwur1dqjr8v06dPJyMggPT3dvYwdO5Z7773X/b5Tr813vh3rhT766CNlNpvVP/7xD3X06FH16KOPqpCQkFZ3hbub2tpadeDAAXXgwAEFqFdffVUdOHBA5eXlKaW0boQhISFq5cqV6tChQ+rWW29tsxvhqFGj1O7du9X27dtV//79vbob4Y9+9CMVHBys0tLSVFFRkXtpaGhw7/PYY4+phIQEtXnzZvXNN9+o1NRUlZqa6t5+rkvYzJkzVXp6ulq3bp0KDw/3+u5yzz77rNq6davKyclRhw4dUs8++6zS6XRqw4YNSqmee13acn4vFKU699r0yABXSqk33nhDJSQkKJPJpMaPH6927drl6SJ1qC1btijgouWBBx5QSmldCZ9//nkVGRmpzGazmj59usrMzGx1joqKCnXPPfeogIAAFRQUpB566CFVW1vrgW/TPtq6HoB699133fs0Njaqxx9/XIWGhiqLxaJuv/12VVRU1Oo8ubm5avbs2crPz0/17t1b/fSnP1V2u72Tv037Wrx4serTp48ymUwqPDxcTZ8+3R3eSvXc69KWCwO8M6+NjAcuhBBeqse1gQshRHchAS6EEF5KAlwIIbyUBLgQQngpCXAhhPBSEuBCCOGlJMCFEMJLSYALIYSXkgAXQggvJQEuhBBeSgJcCCG81P8HHCEnWV91SecAAAAASUVORK5CYII=", + "image/png": "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", "text/plain": [ "
" ] @@ -508,7 +498,7 @@ }, { "cell_type": "code", - "execution_count": 210, + "execution_count": 17, "id": "a29f1ac2", "metadata": {}, "outputs": [], @@ -531,17 +521,18 @@ }, { "cell_type": "code", - "execution_count": 211, + "execution_count": 18, "id": "f38d61a9", "metadata": {}, "outputs": [], "source": [ - "jitted_grad = jit(value_and_grad(loss, argnums=0))" + "#jitted_grad = jit(value_and_grad(loss, argnums=0))\n", + "jitted_grad = (value_and_grad(loss, argnums=0))" ] }, { "cell_type": "code", - "execution_count": 212, + "execution_count": 19, "id": "9ac97e04", "metadata": {}, "outputs": [], @@ -567,23 +558,48 @@ }, { "cell_type": "code", - "execution_count": 213, - "id": "710a1545", + "execution_count": 20, + "id": "7f933f2d", + "metadata": {}, + "outputs": [], + "source": [ + "import jaxley.optimize.transforms as jt" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "b7ccdf0b", + "metadata": {}, + "outputs": [], + "source": [ + "# Define a function to create appropriate transforms for each parameter\n", + "def create_transform(name):\n", + " if name == \"axial_resistivity\":\n", + " # Must be positive; apply Softplus and scale to match initialization\n", + " return jt.ChainTransform([jt.SoftplusTransform(0), jt.AffineTransform(5000, 0)])\n", + " elif name == \"length\":\n", + " # Apply Softplus and affine transform for the 'length' parameter\n", + " return jt.ChainTransform([jt.SoftplusTransform(0), jt.AffineTransform(10, 0)])\n", + " else:\n", + " # Default to a Softplus transform for other parameters\n", + " return jt.SoftplusTransform(0)\n", + "\n", + "# Apply the transforms to the parameters\n", + "transforms = [{k: create_transform(k) for k in param} for param in params]\n", + "tf = jt.ParamTransform(transforms)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "652bee09", "metadata": {}, "outputs": [], "source": [ - "transform = jx.ParamTransform(\n", - " lowers={\n", - " \"Leak_gLeak\": 1e-5,\n", - " \"radius\": 0.1,\n", - " \"TanhRateSynapse_gS\": 1e-5,\n", - " },\n", - " uppers={\n", - " \"Leak_gLeak\": 1e-3,\n", - " \"radius\": 5.0,\n", - " \"TanhRateSynapse_gS\": 1e-2,\n", - " }, \n", - ")" + "transform = jx.ParamTransform([{\"radius\": jt.SigmoidTransform(0.1,5.0)},\n", + " {\"Leak_gLeak\":jt.SigmoidTransform(1e-5,1e-3)},\n", + " {\"TanhRateSynapse_gS\" : jt.SigmoidTransform(1e-5,1e-2)}])" ] }, { @@ -596,7 +612,7 @@ }, { "cell_type": "code", - "execution_count": 214, + "execution_count": 23, "id": "dac2b2fb-a844-4bdc-a290-939d91c2d2aa", "metadata": {}, "outputs": [], @@ -629,7 +645,7 @@ }, { "cell_type": "code", - "execution_count": 215, + "execution_count": 24, "id": "f18a5736-f282-4ebe-9140-f613bccb3f76", "metadata": {}, "outputs": [], @@ -656,7 +672,7 @@ }, { "cell_type": "code", - "execution_count": 251, + "execution_count": 25, "id": "cb3c256a-87ce-4c20-9bd3-30c34659db88", "metadata": {}, "outputs": [], @@ -688,7 +704,8 @@ " losses = jnp.abs(predictions - labels) # Mean absolute error loss.\n", " return jnp.mean(losses) # Average across the batch.\n", "\n", - "jitted_grad = jit(value_and_grad(loss, argnums=0))" + "#jitted_grad = jit(value_and_grad(loss, argnums=0))\n", + "jitted_grad = (value_and_grad(loss, argnums=0))" ] }, { @@ -703,7 +720,7 @@ }, { "cell_type": "code", - "execution_count": 252, + "execution_count": 26, "id": "6189ca28-6e22-4328-94dc-5c39ef5da0ac", "metadata": {}, "outputs": [], @@ -713,7 +730,7 @@ }, { "cell_type": "code", - "execution_count": 253, + "execution_count": 27, "id": "9d639efa", "metadata": {}, "outputs": [], @@ -733,7 +750,7 @@ }, { "cell_type": "code", - "execution_count": 254, + "execution_count": 28, "id": "dede5ef6-3afb-4b75-a23d-534dd3e2867b", "metadata": {}, "outputs": [], @@ -744,7 +761,7 @@ }, { "cell_type": "code", - "execution_count": 255, + "execution_count": 29, "id": "f7463abc-207e-413b-aa9c-260b3306cdc1", "metadata": {}, "outputs": [], @@ -766,7 +783,7 @@ }, { "cell_type": "code", - "execution_count": 256, + "execution_count": null, "id": "0e4aebd0-283e-4165-8c24-4b6fb811135e", "metadata": {}, "outputs": [ @@ -774,16 +791,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "epoch 0, loss 25.61663325387099\n", - "epoch 1, loss 21.7304402547341\n", - "epoch 2, loss 15.943236054666484\n", - "epoch 3, loss 9.191846765081072\n", - "epoch 4, loss 7.256558484588674\n", - "epoch 5, loss 6.577375342584615\n", - "epoch 6, loss 6.568056585075223\n", - "epoch 7, loss 6.510474263850299\n", - "epoch 8, loss 6.481302675498705\n", - "epoch 9, loss 6.5030439519558865\n" + "epoch 0, loss 25.09776566535514\n" ] } ], @@ -873,13 +881,13 @@ "id": "0e6045a5-76db-455e-8a4a-63e5a99ddc77", "metadata": {}, "source": [ - "This was the last tutorial of the `Jaxley` toolbox. If anything is still unclear please create a [discussion](https://github.com/jaxleyverse/jaxley/discussions). If you find any bugs, please open an [issue](https://github.com/jaxleyverse/jaxley/issues). Happy coding!" + "This was one of the last tutorials of the `Jaxley` toolbox. If anything is still unclear please create a [discussion](https://github.com/jaxleyverse/jaxley/discussions). If you find any bugs, please open an [issue](https://github.com/jaxleyverse/jaxley/issues). Happy coding!" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "jaxley12", "language": "python", "name": "python3" }, @@ -893,7 +901,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.4" + "version": "3.12.7" } }, "nbformat": 4, diff --git a/jaxley/optimize/transforms.py b/jaxley/optimize/transforms.py index bef0bc2a..d13c5e78 100644 --- a/jaxley/optimize/transforms.py +++ b/jaxley/optimize/transforms.py @@ -1,130 +1,224 @@ # This file is part of Jaxley, a differentiable neuroscience simulator. Jaxley is # licensed under the Apache License Version 2.0, see -from typing import Dict, List +from abc import ABC, abstractmethod +from typing import Any, Callable, Dict, List, Sequence +import jax import jax.numpy as jnp +from jax import Array +from jax.typing import ArrayLike from jaxley.solver_gate import save_exp -def sigmoid(x: jnp.ndarray) -> jnp.ndarray: - """Sigmoid.""" - return 1 / (1 + save_exp(-x)) +class Transform(ABC): + def __call__(self, x: ArrayLike) -> Array: + return self.forward(x) + @abstractmethod + def forward(self, x: ArrayLike) -> Array: + pass -def expit(x: jnp.ndarray) -> jnp.ndarray: - """Inverse sigmoid (expit)""" - return -jnp.log(1 / x - 1) + @abstractmethod + def inverse(self, x: ArrayLike) -> Array: + pass -def softplus(x: jnp.ndarray) -> jnp.ndarray: - """Softplus.""" - return jnp.log(1 + jnp.exp(x)) +class SigmoidTransform(Transform): + """Sigmoid transformation.""" + def __init__(self, lower: ArrayLike, upper: ArrayLike) -> None: + """This transform maps any value bijectively to the interval [lower, upper]. -def inv_softplus(x: jnp.ndarray) -> jnp.ndarray: - """Inverse softplus.""" - return jnp.log(jnp.exp(x) - 1) + Args: + lower (ArrayLike): Lower bound of the interval. + upper (ArrayLike): Upper bound of the interval. + """ + super().__init__() + self.lower = lower + self.width = upper - lower + + def forward(self, x: ArrayLike) -> Array: + y = 1.0 / (1.0 + save_exp(-x)) + return self.lower + self.width * y + + def inverse(self, y: ArrayLike) -> Array: + x = (y - self.lower) / self.width + x = -jnp.log((1.0 / x) - 1.0) + return x + + +class SoftplusTransform(Transform): + """Softplus transformation.""" + + def __init__(self, lower: ArrayLike) -> None: + """This transform maps any value bijectively to the interval [lower, inf). + + Args: + lower (ArrayLike): Lower bound of the interval. + """ + super().__init__() + self.lower = lower + + def forward(self, x: ArrayLike) -> Array: + return jnp.log1p(save_exp(x)) + self.lower + + def inverse(self, y: ArrayLike) -> Array: + return jnp.log(save_exp(y - self.lower) - 1.0) + + +class NegSoftplusTransform(SoftplusTransform): + """Negative softplus transformation.""" + + def __init__(self, upper: ArrayLike) -> None: + """This transform maps any value bijectively to the interval (-inf, upper]. + + Args: + upper (ArrayLike): Upper bound of the interval. + """ + super().__init__(upper) + + def forward(self, x: ArrayLike) -> Array: + return -super().forward(-x) + + def inverse(self, y: ArrayLike) -> Array: + return -super().inverse(-y) + + +class AffineTransform(Transform): + def __init__(self, scale: ArrayLike, shift: ArrayLike): + """This transform rescales and shifts the input. + + Args: + scale (ArrayLike): Scaling factor. + shift (ArrayLike): Additive shift. + + Raises: + ValueError: Scale needs to be larger than 0 + """ + if jnp.allclose(scale, 0): + raise ValueError("a cannot be zero, must be invertible") + self.a = scale + self.b = shift + + def forward(self, x: ArrayLike) -> Array: + return self.a * x + self.b + + def inverse(self, x: ArrayLike) -> Array: + return (x - self.b) / self.a + + +class ChainTransform(Transform): + """Chaining together multiple transformations""" + + def __init__(self, transforms: Sequence[Transform]) -> None: + """A chain of transformations + + Args: + transforms (Sequence[Transform]): Transforms to apply + """ + super().__init__() + self.transforms = transforms + + def forward(self, x: ArrayLike) -> Array: + for transform in self.transforms: + x = transform(x) + return x + + def inverse(self, y: ArrayLike) -> Array: + for transform in reversed(self.transforms): + y = transform.inverse(y) + return y + + +class MaskedTransform(Transform): + def __init__(self, mask: ArrayLike, transform: Transform) -> None: + """A masked transformation + + Args: + mask (ArrayLike): Which elements to transform + transform (Transform): Transformation to apply + """ + super().__init__() + self.mask = mask + self.transform = transform + + def forward(self, x: ArrayLike) -> Array: + return jnp.where(self.mask, self.transform.forward(x), x) + + def inverse(self, y: ArrayLike) -> Array: + return jnp.where(self.mask, self.transform.inverse(y), y) + + +class CustomTransform(Transform): + """Custom transformation""" + + def __init__(self, forward_fn: Callable, inverse_fn: Callable) -> None: + """A custom transformation using a user-defined froward and + inverse function + + Args: + forward_fn (Callable): Forward transformation + inverse_fn (Callable): Inverse transformation + """ + super().__init__() + self.forward_fn = forward_fn + self.inverse_fn = inverse_fn + + def forward(self, x: ArrayLike) -> Array: + return self.forward_fn(x) + + def inverse(self, y: ArrayLike) -> Array: + return self.inverse_fn(y) class ParamTransform: """Parameter transformation utility. - This class is used to transform parameters from an unconstrained space to a constrained space - and back. If the range is bounded both from above and below, we use the sigmoid function to - transform the parameters. If the range is only bounded from below or above, we use softplus. + This class is used to transform parameters usually from an unconstrained space to a constrained space + and back (bacause most biophysical parameter are bounded). The user can specify a PyTree of transforms + that are applied to the parameters. Attributes: - lowers: A dictionary of lower bounds for each parameter (None for no bound). - uppers: A dictionary of upper bounds for each parameter (None for no bound). + tf_dict: A PyTree of transforms for each parameter. """ - def __init__(self, lowers: Dict[str, float], uppers: Dict[str, float]): - """Initialize the bounds. + def __init__(self, tf_dict: List[Dict[str, Transform]] | Transform) -> None: + """Creates a new ParamTransform object. Args: - lowers: A dictionary of lower bounds for each parameter (None for no bound). - uppers: A dictionary of upper bounds for each parameter (None for no bound). + tf_dict: A PyTree of transforms for each parameter. """ - self.lowers = lowers - self.uppers = uppers + self.tf_dict = tf_dict - def forward(self, params: List[Dict[str, jnp.ndarray]]) -> jnp.ndarray: + def forward( + self, params: List[Dict[str, ArrayLike]] | ArrayLike + ) -> Dict[str, Array]: """Pushes unconstrained parameters through a tf such that they fit the interval. Args: - params: A list of dictionaries with unconstrained parameters. + params: A list of dictionaries (or any PyTree) with unconstrained parameters. Returns: - A list of dictionaries with transformed parameters. + A list of dictionaries (or any PyTree) with transformed parameters. """ - tf_params = [] - for param in params: - key = list(param.keys())[0] - - # If constrained from below and above, use sigmoid - if self.lowers[key] is not None and self.uppers[key] is not None: - tf = ( - sigmoid(param[key]) * (self.uppers[key] - self.lowers[key]) - + self.lowers[key] - ) - tf_params.append({key: tf}) - - # If constrained from below, use softplus - elif self.lowers[key] is not None: - tf = softplus(param[key]) + self.lowers[key] - tf_params.append({key: tf}) - - # If constrained from above, use negative softplus - elif self.uppers[key] is not None: - tf = -softplus(-param[key]) + self.uppers[key] - tf_params.append({key: tf}) - - # Else just pass through - else: - tf_params.append({key: param[key]}) - - return tf_params + return jax.tree_util.tree_map(lambda x, tf: tf.forward(x), params, self.tf_dict) - def inverse(self, params: jnp.ndarray) -> jnp.ndarray: + def inverse( + self, params: List[Dict[str, ArrayLike]] | ArrayLike + ) -> Dict[str, Array]: """Takes parameters from within the interval and makes them unconstrained. Args: - params: A list of dictionaries with transformed parameters. + params: A list of dictionaries (or any PyTree) with transformed parameters. Returns: - A list of dictionaries with unconstrained parameters. + A list of dictionaries (or any PyTree) with unconstrained parameters. """ - tf_params = [] - for param in params: - key = list(param.keys())[0] - - # If constrained from below and above, use expit - if self.lowers[key] is not None and self.uppers[key] is not None: - tf = expit( - (param[key] - self.lowers[key]) - / (self.uppers[key] - self.lowers[key]) - ) - tf_params.append({key: tf}) - - # If constrained from below, use inv_softplus - elif self.lowers[key] is not None: - tf = inv_softplus(param[key] - self.lowers[key]) - tf_params.append({key: tf}) - - # If constrained from above, use negative inv_softplus - elif self.uppers[key] is not None: - tf = -inv_softplus(-(param[key] - self.uppers[key])) - tf_params.append({key: tf}) - - # else just pass through - else: - tf_params.append({key: param[key]}) - - return tf_params + return jax.tree_util.tree_map(lambda x, tf: tf.inverse(x), params, self.tf_dict) diff --git a/tests/test_transforms.py b/tests/test_transforms.py index b74082c7..323441fc 100644 --- a/tests/test_transforms.py +++ b/tests/test_transforms.py @@ -8,15 +8,21 @@ import jax.numpy as jnp import numpy as np +import pytest from jax import jit +import jaxley as jx +import jaxley.optimize.transforms as jt from jaxley.optimize.transforms import ParamTransform -def test_inverse(): +def test_joint_inverse(): # test forward(inverse(x))=x - lowers = {"param_array_1": 2, "param_array_2": None, "param_array_3": -2} - uppers = {"param_array_1": -2, "param_array_2": 2, "param_array_3": None} + tf_dict = [ + {"param_array_1": jt.SigmoidTransform(-2, 2)}, + {"param_array_2": jt.SoftplusTransform(2)}, + {"param_array_3": jt.NegSoftplusTransform(-2)}, + ] params = [ {"param_array_1": jnp.asarray(np.linspace(-1, 1, 4))}, @@ -24,17 +30,19 @@ def test_inverse(): {"param_array_3": jnp.asarray(np.linspace(-1, 4, 4))}, ] - tf = ParamTransform(lowers, uppers) + tf = ParamTransform(tf_dict) + forward = tf.forward(params) + inverse = tf.inverse(forward) assert np.allclose( - tf.forward(tf.inverse(params))[0]["param_array_1"], params[0]["param_array_1"] - ) + inverse[0]["param_array_1"], params[0]["param_array_1"] + ), "SigmoidTransform forward, inverse failed." assert np.allclose( - tf.forward(tf.inverse(params))[1]["param_array_2"], params[1]["param_array_2"] - ) + inverse[1]["param_array_2"], params[1]["param_array_2"] + ), "SoftplusTransform forward, inverse failed." assert np.allclose( - tf.forward(tf.inverse(params))[2]["param_array_3"], params[2]["param_array_3"] - ) + inverse[2]["param_array_3"], params[2]["param_array_3"] + ), "NegSoftplusTransform forward, inverse failed." def test_bounds(): @@ -42,37 +50,133 @@ def test_bounds(): lowers = {"param_array_1": -2, "param_array_2": None, "param_array_3": -2} uppers = {"param_array_1": 2, "param_array_2": 2, "param_array_3": None} + tf_dict = [ + {"param_array_1": jt.SigmoidTransform(-2, 2)}, + {"param_array_2": jt.NegSoftplusTransform(2)}, + {"param_array_3": jt.SoftplusTransform(-2)}, + ] + params = [ {"param_array_1": jnp.asarray(np.linspace(-10, 10, 4))}, {"param_array_2": jnp.asarray(np.linspace(-10, 10, 4))}, {"param_array_3": jnp.asarray(np.linspace(-10, 10, 4))}, ] - tf = ParamTransform(lowers, uppers) - - assert all(tf.forward(params)[0]["param_array_1"] > lowers["param_array_1"]) - assert all(tf.forward(params)[0]["param_array_1"] < uppers["param_array_1"]) - assert any( - tf.forward(params)[1]["param_array_2"] < lowers["param_array_1"] - ) # lower not constrained - assert all(tf.forward(params)[1]["param_array_2"] < uppers["param_array_2"]) - assert all(tf.forward(params)[2]["param_array_3"] > lowers["param_array_3"]) - assert any( - tf.forward(params)[2]["param_array_3"] > uppers["param_array_1"] - ) # upper not constrained - - -def test_jit(): + tf = ParamTransform(tf_dict) + forward = tf.forward(params) + + assert all( + forward[0]["param_array_1"] > lowers["param_array_1"] + ), "SigmoidTransform failed to match lower bound." + assert all( + forward[0]["param_array_1"] < uppers["param_array_1"] + ), "SigmoidTransform failed to match upper bound." + assert all( + forward[1]["param_array_2"] < uppers["param_array_2"] + ), "SoftplusTransform failed to match lower bound." + assert all( + forward[2]["param_array_3"] > lowers["param_array_3"] + ), "NegSoftplusTransform failed to match lower bound." + + +@pytest.mark.parametrize( + "transform", + [ + jt.SigmoidTransform(-2, 2), + jt.SoftplusTransform(2), + jt.NegSoftplusTransform(2), + jt.AffineTransform(1.0, 1.0), + jt.CustomTransform(lambda x: x, lambda x: x), + jt.ChainTransform([jt.SigmoidTransform(-2, 2), jt.SoftplusTransform(2)]), + ], +) +def test_jit(transform): # test jit-compilation: - lowers = {"param_array_1": 2} - uppers = {"param_array_1": -2} + tf_dict = [{"param_array_1": transform}] params = [{"param_array_1": jnp.asarray(np.linspace(-1, 1, 4))}] - tf = ParamTransform(lowers, uppers) + tf = ParamTransform(tf_dict) @jit def test_jit(params): return tf.inverse(params) _ = test_jit(params) + + +@pytest.mark.parametrize( + "transform", + [ + jt.SigmoidTransform(-2, 2), + jt.SoftplusTransform(2), + jt.NegSoftplusTransform(2), + jt.AffineTransform(1.0, 1.0), + jt.CustomTransform(lambda x: x, lambda x: x), + jt.ChainTransform([jt.SigmoidTransform(-2, 2), jt.SoftplusTransform(2)]), + jt.MaskedTransform( + jnp.array([True, False, False, True]), jt.SigmoidTransform(-2, 2) + ), + ], +) +def test_correct(transform): + # Test correctness on "standard" PyTree + tf_dict = [{"param_array_1": transform}] + + params = [{"param_array_1": jnp.asarray(np.linspace(-1, 1, 4))}] + + tf = ParamTransform(tf_dict) + + forward = tf.forward(params) + inverse = tf.inverse(forward) + + assert np.allclose( + inverse[0]["param_array_1"], params[0]["param_array_1"] + ), f"{transform} forward, inverse failed." + + # Test correctness plain Array + for shape in [(4,), (4, 1), (4, 4)]: + tf_dict = transform + tf = ParamTransform(tf_dict) + x = jnp.ones(shape) + y = tf.forward(x) + x_inv = tf.inverse(y) + + assert np.allclose( + x, x_inv + ), f"{transform} forward, inverse failed on non PyTree." + + +@pytest.mark.parametrize( + "transform", + [jt.SigmoidTransform(-2, 2), jt.SoftplusTransform(2), jt.NegSoftplusTransform(2)], +) +def test_user_api(transform): + comp = jx.Compartment() + branch = jx.Branch(comp, nseg=2) + cell = jx.Cell(branch, parents=[-1, 0, 0]) + + cell.branch("all").make_trainable("radius") + cell.branch(2).make_trainable("radius") + cell.branch(1).make_trainable("length") + cell.branch(0).make_trainable("radius") + cell.branch("all").comp("all").make_trainable("axial_resistivity") + cell.make_trainable("capacitance") + + params = cell.get_parameters() + + # We scale it to something samll as axial_resistivity is large + # and then the transform becomes numerically uninvertible. + t = jt.ChainTransform([jt.AffineTransform(1e-3, 0.0), transform]) + + tf_dict = [{list(k.keys())[0]: t} for k in params] + tf = ParamTransform(tf_dict) + + forward = tf.forward(params) + reverse = tf.inverse(forward) + + flat_params, _ = jax.tree_util.tree_flatten(params) + flat_reverse, _ = jax.tree_util.tree_flatten(reverse) + assert all( + [np.allclose(a, b) for a, b in zip(flat_params, flat_reverse)] + ), f"{transform} forward, inverse failed."