Files
FYS-STK4155/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.ipynb
T
Morten Hjorth-Jensen 9a699212fa update on notes
2024-10-19 09:58:39 +02:00

1396 lines
200 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "b18bcd06",
"metadata": {},
"source": [
"<!-- HTML file automatically generated from DocOnce source (https://github.com/doconce/doconce/)\n",
"doconce format html exercisesweek41.do.txt -->\n",
"<!-- dom:TITLE: Exercises week 41 -->"
]
},
{
"cell_type": "markdown",
"id": "7542d6aa",
"metadata": {},
"source": [
"# Exercises week 41\n",
"**October 4-11, 2024**\n",
"\n",
"Date: **Deadline is Friday October 11 at midnight**"
]
},
{
"cell_type": "markdown",
"id": "80943a15",
"metadata": {},
"source": [
"# Overarching aims of the exercises this week\n",
"\n",
"The aim of the exercises this week is to get started with implementing\n",
"gradient methods of relevance for project 2. This exercise will also\n",
"be continued next week with the addition of automatic differentation.\n",
"Everything you develop here will be used in project 2.\n",
"\n",
"In order to get started, we will now replace in our standard ordinary\n",
"least squares (OLS) and Ridge regression codes (from project 1) the\n",
"matrix inversion algorithm with our own gradient descent (GD) and SGD\n",
"codes. You can use the Franke function or the terrain data from\n",
"project 1. **However, we recommend using a simpler function like**\n",
"$f(x)=a_0+a_1x+a_2x^2$ or higher-order one-dimensional polynomials.\n",
"You can obviously test your final codes against for example the Franke\n",
"function. Automatic differentiation will be discussed next week.\n",
"\n",
"You should include in your analysis of the GD and SGD codes the following elements\n",
"1. A plain gradient descent with a fixed learning rate (you will need to tune it) using the analytical expression of the gradients\n",
"\n",
"2. Add momentum to the plain GD code and compare convergence with a fixed learning rate (you may need to tune the learning rate), again using the analytical expression of the gradients.\n",
"\n",
"3. Repeat these steps for stochastic gradient descent with mini batches and a given number of epochs. Use a tunable learning rate as discussed in the lectures from week 39. Discuss the results as functions of the various parameters (size of batches, number of epochs etc)\n",
"\n",
"4. Implement the Adagrad method in order to tune the learning rate. Do this with and without momentum for plain gradient descent and SGD.\n",
"\n",
"5. Add RMSprop and Adam to your library of methods for tuning the learning rate.\n",
"\n",
"The lecture notes from weeks 39 and 40 contain more information and code examples. Feel free to use these examples.\n",
"\n",
"In summary, you should \n",
"perform an analysis of the results for OLS and Ridge regression as\n",
"function of the chosen learning rates, the number of mini-batches and\n",
"epochs as well as algorithm for scaling the learning rate. You can\n",
"also compare your own results with those that can be obtained using\n",
"for example **Scikit-Learn**'s various SGD options. Discuss your\n",
"results. For Ridge regression you need now to study the results as functions of the hyper-parameter $\\lambda$ and \n",
"the learning rate $\\eta$. Discuss your results.\n",
"\n",
"You will need your SGD code for the setup of the Neural Network and\n",
"Logistic Regression codes. You will find the Python [Seaborn\n",
"package](https://seaborn.pydata.org/generated/seaborn.heatmap.html)\n",
"useful when plotting the results as function of the learning rate\n",
"$\\eta$ and the hyper-parameter $\\lambda$ when you use Ridge\n",
"regression.\n",
"\n",
"We recommend reading chapter 8 on optimization from the textbook of [Goodfellow, Bengio and Courville](https://www.deeplearningbook.org/). This chapter contains many useful insights and discussions on the optimization part of machine learning."
]
},
{
"cell_type": "markdown",
"id": "2095d197",
"metadata": {},
"source": [
"# Code examples from week 39 and 40"
]
},
{
"cell_type": "markdown",
"id": "f428decb",
"metadata": {},
"source": [
"## Code with a Number of Minibatches which varies, analytical gradient\n",
"\n",
"In the code here we vary the number of mini-batches."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "ba38d454",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[4.2561719 ]\n",
" [2.65632442]]\n",
"Eigenvalues of Hessian Matrix:[0.33282365 4.37023448]\n",
"theta from own gd\n",
"[[4.2561719 ]\n",
" [2.65632442]]\n",
"theta from own sdg\n",
"[[4.25767462]\n",
" [2.65759127]]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkMAAAHHCAYAAAC88FzIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABXgElEQVR4nO3deXhTVfoH8G/a0oVCC6WUbqEtBbqw74JUWhJFRAQBUVAEFFzGDeHnOqPouBR3HMUBXEBHQQUKqKOoCS1UZBNkFKFQsEAptOzdoIUm5/dHTGho2izNcpP7/TxPntKbk3vPzU1zX855zzkKIYQAERERkUz5eboCRERERJ7EYIiIiIhkjcEQERERyRqDISIiIpI1BkNEREQkawyGiIiISNYYDBEREZGsMRgiIiIiWWMwRERERLLGYIiIbDZt2jQkJiZ6uhqSlpeXB4VCgZUrV3q6KkRkIwZDRBK0dOlSKBQK0yMgIABxcXGYNm0aSkpKPF09IiKfEuDpChBR4/75z38iKSkJNTU12LJlC5YuXYqffvoJu3fvRnBwsKerR0TkExgMEUnYyJEj0b9/fwDAjBkzEBkZiVdeeQVfffUVJk6c6OHakSdVV1cjNDTU09Ug8gnsJiPyIhkZGQCAgwcPmrZdvHgRzz77LPr164fw8HCEhoYiIyMDubm5Zq89dOgQFAoFXn/9dSxevBjJyckICgrCgAEDsH379gbHWrNmDbp3747g4GB0794dq1evtlin6upqzJkzB0qlEkFBQUhJScHrr78OIYRZOYVCgQcffBArVqxAeno6QkJCMHjwYPz+++8AgEWLFqFz584IDg5GZmYmDh06ZPX9eO6556BQKHDgwAFMmzYNbdq0QXh4OKZPn47z5883OPelS5c22IdCocBzzz3XYJ/79+/HHXfcgfDwcLRv3x7PPPMMhBAoLi7GmDFjEBYWhujoaLzxxhsW66bT6fD0008jOjoaoaGhuOmmm1BcXNyg3NatW3H99dcjPDwcLVu2xLBhw7Bp0yaL57lnzx5MnjwZbdu2xdChQwEApaWlmD59OuLj4xEUFISYmBiMGTPGpvePiAzYMkTkRYw3uLZt25q2VVRU4IMPPsCkSZMwc+ZMVFZW4sMPP8SIESOwbds29O7d22wfy5YtQ2VlJe69914oFAq8+uqrGDduHP7880+0aNECAPDDDz9g/PjxSE9PR3Z2Nk6fPm264dYnhMBNN92E3Nxc3H333ejduze+//57PPbYYygpKcFbb71lVj4/Px9fffUVHnjgAQBAdnY2brzxRjz++ON477338Le//Q1nz57Fq6++irvuugvr16+36X2ZOHEikpKSkJ2djZ07d+KDDz5AVFQUXnnlFXveXjO33nor0tLSMG/ePPz3v//Fiy++iIiICCxatAjDhw/HK6+8gs8++wz/93//hwEDBuCaa64xe/1LL70EhUKBJ554AidOnMD8+fOhVquxa9cuhISEAADWr1+PkSNHol+/fpg7dy78/PywZMkSDB8+HPn5+Rg4cKDZPm+55RZ06dIFL7/8sinYHD9+PP744w889NBDSExMxIkTJ/Djjz/iyJEjTHYnspUgIslZsmSJACA0Go04efKkKC4uFitXrhTt27cXQUFBori42FS2rq5O1NbWmr3+7NmzokOHDuKuu+4ybSsqKhIARLt27cSZM2dM29euXSsAiK+//tq0rXfv3iImJkacO3fOtO2HH34QAERCQoJp25o1awQA8eKLL5odf8KECUKhUIgDBw6YtgEQQUFBoqioyLRt0aJFAoCIjo4WFRUVpu1PPfWUAGBW1pK5c+cKAGbnKYQQN998s2jXrl2Dc1+yZEmDfQAQc+fObbDPe+65x7Strq5OxMfHC4VCIebNm2fafvbsWRESEiKmTp1q2pabmysAiLi4OLNz+vLLLwUA8fbbbwshhNDr9aJLly5ixIgRQq/Xm8qdP39eJCUliWuvvbZBnSZNmmRW97NnzwoA4rXXXmvyfSKiprGbjEjC1Go12rdvD6VSiQkTJiA0NBRfffWVWQuNv78/AgMDAQB6vR5nzpxBXV0d+vfvj507dzbY56233mrWsmTsevvzzz8BAMePH8euXbswdepUhIeHm8pde+21SE9PN9vXt99+C39/fzz88MNm2+fMmQMhBL777juz7SqVyqy1YtCgQQAMrRutW7dusN1YJ2vuu+8+s98zMjJw+vRpVFRU2PR6S2bMmGH6t7+/P/r37w8hBO6++27T9jZt2iAlJcViPe+8806zc5owYQJiYmLw7bffAgB27dqFwsJCTJ48GadPn8apU6dw6tQpVFdXQ6VSYePGjdDr9U2eZ0hICAIDA5GXl4ezZ886fK5EcsduMiIJW7BgAbp27Yry8nJ89NFH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KkHX2DV3ZYuUsWuON3lzHKVHREROJq9gqCmeSNC11jWnUBi65saM4c2+Po7SIyIiJ5JXN1lTPJGgyxXuiYiIPI7BkJEnEnQ5dw4REZHHMRiqz90Jupw7h4iIyOMUQlhKWPEtFRUVCA8PR3l5OcIaS6Cuz1kzUNtynMREQ7K0pctgnBiyqIg5Q0REJDt2378dxARqS9yVoGvsmpswwRD41A+IOHcOERGRW7CbzNM4dw4REZFHsWVICjh3DhERkccwGJIKzp1DRETkEewmIyIiIlljMERERESyxmCIiIiIZI3BEBEREckagyEiIiKSNQZDREREJGsMhoiIiEjWGAwRERGRrDEYIiIiIlmTfDCUnZ2NAQMGoHXr1oiKisLYsWOxb98+T1eLiIiIfITkg6ENGzbggQcewJYtW/Djjz/i0qVLuO6661BdXe3pqhEREZEPUAghhKcrYY+TJ08iKioKGzZswDXXXGPTayoqKhAeHo7y8nKEhYW5uIZERETkDO66f3vdQq3l5eUAgIiIiEbL1NbWora21vR7RUWFy+tFRERE3kny3WT16fV6zJo1C1dffTW6d+/eaLns7GyEh4ebHkql0o21JCIiIm/iVd1k999/P7777jv89NNPiI+Pb7ScpZYhpVLJbjIiIiIvwm6yKzz44IP45ptvsHHjxiYDIQAICgpCUFCQm2pGRERE3kzywZAQAg899BBWr16NvLw8JCUlebpKRERE5EMkHww98MADWLZsGdauXYvWrVujtLQUABAeHo6QkBAP146IiIi8neRzhhQKhcXtS5YswbRp02zaB4fWExEReR/mDP1F4rEaEREReTmvGlpPRERE5GwMhoiIiEjWGAwRERGRrDEYIiIiIlljMERERESyxmCIiIiIZI3BEBEREckagyEiIiKSNQZDREREJGsMhoiIiEjWGAwRERGRrDEYIiIiIlljMERERESyxmCIiIiIZI3BEBEREckagyEiIiKSNQZDREREJGsMhoiIiEjWGAwRERGRrDEYIiIiIlljMERERESyxmCIiIiIZI3BEBEREckagyEiIiKSNQZDREREJGsMhoiIiEjWGAwRERGRrDEYIiIiIlljMERERESyxmCIiIiIZI3BEBEREckagyEiIiKSNQZDREREJGsMhoiIiEjWGAwRERGRrDEYIiIiIlljMERERESyxmCIiIiI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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {
"filenames": {
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_5_1.png"
}
},
"output_type": "display_data"
}
],
"source": [
"%matplotlib inline\n",
"\n",
"# Importing various packages\n",
"from math import exp, sqrt\n",
"from random import random, seed\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"n = 100\n",
"x = 2*np.random.rand(n,1)\n",
"y = 4+3*x+np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.inv(X.T @ X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"# Hessian matrix\n",
"H = (2.0/n)* XT_X\n",
"EigValues, EigVectors = np.linalg.eig(H)\n",
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
"\n",
"theta = np.random.randn(2,1)\n",
"eta = 1.0/np.max(EigValues)\n",
"Niterations = 1000\n",
"\n",
"#while (iter <= Ni... or test)\n",
"for iter in range(Niterations):\n",
" gradients = 2.0/n*X.T @ ((X @ theta)-y)\n",
" theta -= eta*gradients\n",
"print(\"theta from own gd\")\n",
"print(theta)\n",
"\n",
"xnew = np.array([[0],[2]])\n",
"Xnew = np.c_[np.ones((2,1)), xnew]\n",
"ypredict = Xnew.dot(theta)\n",
"ypredict2 = Xnew.dot(theta_linreg)\n",
"\n",
"n_epochs = 50\n",
"M = 5 #size of each minibatch\n",
"m = int(n/M) #number of minibatches\n",
"t0, t1 = 5, 50\n",
"\n",
"def learning_schedule(t):\n",
" return t0/(t+t1)\n",
"\n",
"theta = np.random.randn(2,1)\n",
"\n",
"for epoch in range(n_epochs):\n",
"# Can you figure out a better way of setting up the contributions to each batch?\n",
" for i in range(m):\n",
" random_index = M*np.random.randint(m)\n",
" xi = X[random_index:random_index+M]\n",
" yi = y[random_index:random_index+M]\n",
" gradients = (2.0/M)* xi.T @ ((xi @ theta)-yi)\n",
" eta = learning_schedule(epoch*m+i)\n",
" theta = theta - eta*gradients\n",
"print(\"theta from own sdg\")\n",
"print(theta)\n",
"\n",
"plt.plot(xnew, ypredict, \"r-\")\n",
"plt.plot(xnew, ypredict2, \"b-\")\n",
"plt.plot(x, y ,'ro')\n",
"plt.axis([0,2.0,0, 15.0])\n",
"plt.xlabel(r'$x$')\n",
"plt.ylabel(r'$y$')\n",
"plt.title(r'Random numbers ')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "de04b41a",
"metadata": {},
"source": [
"In the above code, we have use replacement in setting up the\n",
"mini-batches. The discussion\n",
"[here](https://sebastianraschka.com/faq/docs/sgd-methods.html) may be\n",
"useful."
]
},
{
"cell_type": "markdown",
"id": "77fc1cca",
"metadata": {},
"source": [
"## Momentum based GD\n",
"\n",
"The stochastic gradient descent (SGD) is almost always used with a\n",
"*momentum* or inertia term that serves as a memory of the direction we\n",
"are moving in parameter space. This is typically implemented as\n",
"follows"
]
},
{
"cell_type": "markdown",
"id": "441d1f36",
"metadata": {},
"source": [
"$$\n",
"\\mathbf{v}_{t}=\\gamma \\mathbf{v}_{t-1}+\\eta_{t}\\nabla_\\theta E(\\boldsymbol{\\theta}_t) \\nonumber\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "47434945",
"metadata": {},
"source": [
"<!-- Equation labels as ordinary links -->\n",
"<div id=\"_auto1\"></div>\n",
"\n",
"$$\n",
"\\begin{equation} \n",
"\\boldsymbol{\\theta}_{t+1}= \\boldsymbol{\\theta}_t -\\mathbf{v}_{t},\n",
"\\label{_auto1} \\tag{1}\n",
"\\end{equation}\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "f3ea5060",
"metadata": {},
"source": [
"where we have introduced a momentum parameter $\\gamma$, with\n",
"$0\\le\\gamma\\le 1$, and for brevity we dropped the explicit notation to\n",
"indicate the gradient is to be taken over a different mini-batch at\n",
"each step. We call this algorithm gradient descent with momentum\n",
"(GDM). From these equations, it is clear that $\\mathbf{v}_t$ is a\n",
"running average of recently encountered gradients and\n",
"$(1-\\gamma)^{-1}$ sets the characteristic time scale for the memory\n",
"used in the averaging procedure. Consistent with this, when\n",
"$\\gamma=0$, this just reduces down to ordinary SGD as discussed\n",
"earlier. An equivalent way of writing the updates is"
]
},
{
"cell_type": "markdown",
"id": "923628c8",
"metadata": {},
"source": [
"$$\n",
"\\Delta \\boldsymbol{\\theta}_{t+1} = \\gamma \\Delta \\boldsymbol{\\theta}_t -\\ \\eta_{t}\\nabla_\\theta E(\\boldsymbol{\\theta}_t),\n",
"$$"
]
},
{
"cell_type": "markdown",
"id": "5c94031c",
"metadata": {},
"source": [
"where we have defined $\\Delta \\boldsymbol{\\theta}_{t}= \\boldsymbol{\\theta}_t-\\boldsymbol{\\theta}_{t-1}$."
]
},
{
"cell_type": "markdown",
"id": "f3f0e9c9",
"metadata": {},
"source": [
"## Algorithms and codes for Adagrad, RMSprop and Adam\n",
"\n",
"The algorithms we have implemented are well described in the text by [Goodfellow, Bengio and Courville, chapter 8](https://www.deeplearningbook.org/contents/optimization.html).\n",
"\n",
"The codes which implement these algorithms are discussed after our presentation of automatic differentiation."
]
},
{
"cell_type": "markdown",
"id": "92253eff",
"metadata": {},
"source": [
"## Practical tips\n",
"\n",
"* **Randomize the data when making mini-batches**. It is always important to randomly shuffle the data when forming mini-batches. Otherwise, the gradient descent method can fit spurious correlations resulting from the order in which data is presented.\n",
"\n",
"* **Transform your inputs**. Learning becomes difficult when our landscape has a mixture of steep and flat directions. One simple trick for minimizing these situations is to standardize the data by subtracting the mean and normalizing the variance of input variables. Whenever possible, also decorrelate the inputs. To understand why this is helpful, consider the case of linear regression. It is easy to show that for the squared error cost function, the Hessian of the cost function is just the correlation matrix between the inputs. Thus, by standardizing the inputs, we are ensuring that the landscape looks homogeneous in all directions in parameter space. Since most deep networks can be viewed as linear transformations followed by a non-linearity at each layer, we expect this intuition to hold beyond the linear case.\n",
"\n",
"* **Monitor the out-of-sample performance.** Always monitor the performance of your model on a validation set (a small portion of the training data that is held out of the training process to serve as a proxy for the test set. If the validation error starts increasing, then the model is beginning to overfit. Terminate the learning process. This *early stopping* significantly improves performance in many settings.\n",
"\n",
"* **Adaptive optimization methods don't always have good generalization.** Recent studies have shown that adaptive methods such as ADAM, RMSPorp, and AdaGrad tend to have poor generalization compared to SGD or SGD with momentum, particularly in the high-dimensional limit (i.e. the number of parameters exceeds the number of data points). Although it is not clear at this stage why these methods perform so well in training deep neural networks, simpler procedures like properly-tuned SGD may work as well or better in these applications.\n",
"\n",
"Geron's text, see chapter 11, has several interesting discussions."
]
},
{
"cell_type": "markdown",
"id": "08209015",
"metadata": {},
"source": [
"## Using Automatic differentation with OLS\n",
"\n",
"We conclude the part on optmization by showing how we can make codes\n",
"for linear regression and logistic regression using **autograd**. The\n",
"first example shows results with ordinary leats squares."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f1f7d4aa",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[3.96801916]\n",
" [2.95289375]]\n",
"Eigenvalues of Hessian Matrix:[0.27223854 4.51713064]\n",
"theta from own gd\n",
"[[3.96801916]\n",
" [2.95289375]]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkMAAAHHCAYAAAC88FzIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABYlklEQVR4nO3deVxU5f4H8M8BZHEBQ5FFUBGVBFRK0zRNvJJLo2lmmm1qZcvVkpt1u95707rVxZabmlnaJnVLrRS167imoFZuhf5yxSU0XBBXQBCUmef3xzSjAzPMwpmZM3M+79eLl3LOmXOeZ87A+fIs30cSQggQERERqZSfpwtARERE5EkMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhojIbuPGjUObNm08XQxFy83NhSRJWLJkiaeLQkR2YjBEpEBZWVmQJMn0FRAQgJYtW2LcuHE4efKkp4tHRORTAjxdACKy7l//+hfi4+NRWVmJbdu2ISsrCz/88AP27t2L4OBgTxePiMgnMBgiUrDBgwejW7duAIAnnngCzZs3x5tvvonvvvsOo0aN8nDpyJPKy8vRqFEjTxeDyCewm4zIi/Tp0wcAcPToUdO2q1evYtq0aejatSvCwsLQqFEj9OnTBzk5OWavPXbsGCRJwjvvvIOPPvoICQkJCAoKwm233YadO3fWutby5cuRkpKC4OBgpKSkYNmyZRbLVF5ejilTpiAuLg5BQUFITEzEO++8AyGE2XGSJGHSpEn49ttvkZSUhJCQEPTs2RN79uwBAMyfPx/t2rVDcHAw0tLScOzYMZvvxyuvvAJJknDkyBGMGzcOTZs2RVhYGMaPH4+Kiopadc/Kyqp1DkmS8Morr9Q656FDh/Dwww8jLCwMERERePnllyGEQGFhIYYNG4bQ0FBERUXhP//5j8Wy6XQ6/P3vf0dUVBQaNWqEe+65B4WFhbWO2759OwYNGoSwsDA0bNgQffv2xY8//mixnvv378eDDz6Im266Cb179wYAFBUVYfz48YiNjUVQUBCio6MxbNgwu94/IjJgyxCRFzE+4G666SbTttLSUnzyyScYM2YMJkyYgLKyMnz66acYOHAgduzYgdTUVLNzLFy4EGVlZXjqqacgSRLeeustjBgxAr/99hsaNGgAAFi3bh3uu+8+JCUlITMzE+fPnzc9cG8khMA999yDnJwcPP7440hNTcXatWvx4osv4uTJk5g5c6bZ8Vu2bMF3332HiRMnAgAyMzMxZMgQ/PWvf8UHH3yAP//5z7h48SLeeustPPbYY9i4caNd78uoUaMQHx+PzMxM5OXl4ZNPPkGLFi3w5ptvOvL2mhk9ejQ6duyIGTNmQKvV4vXXX0d4eDjmz5+PP/3pT3jzzTfx1Vdf4YUXXsBtt92GO++80+z1b7zxBiRJwksvvYTi4mLMmjUL6enp2L17N0JCQgAAGzduxODBg9G1a1dMnz4dfn5+WLBgAf70pz9hy5Yt6N69u9k577//frRv3x7//ve/TcHmfffdh3379uHZZ59FmzZtUFxcjPXr1+P333/nYHciewkiUpwFCxYIAOL7778XZ8+eFYWFhWLJkiUiIiJCBAUFicLCQtOx1dXVoqqqyuz1Fy9eFJGRkeKxxx4zbSsoKBAARLNmzcSFCxdM21esWCEAiP/973+mbampqSI6OlpcunTJtG3dunUCgGjdurVp2/LlywUA8frrr5tdf+TIkUKSJHHkyBHTNgAiKChIFBQUmLbNnz9fABBRUVGitLTUtH3q1KkCgNmxlkyfPl0AMKunEELce++9olmzZrXqvmDBglrnACCmT59e65xPPvmkaVt1dbWIjY0VkiSJGTNmmLZfvHhRhISEiLFjx5q25eTkCACiZcuWZnX65ptvBAAxe/ZsIYQQer1etG/fXgwcOFDo9XrTcRUVFSI+Pl7cddddtco0ZswYs7JfvHhRABBvv/12ne8TEdWN3WRECpaeno6IiAjExcVh5MiRaNSoEb777juzFhp/f38EBgYCAPR6PS5cuIDq6mp069YNeXl5tc45evRos5YlY9fbb7/9BgA4ffo0du/ejbFjxyIsLMx03F133YWkpCSzc61atQr+/v547rnnzLZPmTIFQgisXr3abHv//v3NWit69OgBwNC60aRJk1rbjWWy5emnnzb7vk+fPjh//jxKS0vter0lTzzxhOn//v7+6NatG4QQePzxx03bmzZtisTERIvlfPTRR83qNHLkSERHR2PVqlUAgN27d+Pw4cN48MEHcf78eZw7dw7nzp1DeXk5+vfvj82bN0Ov19dZz5CQEAQGBiI3NxcXL150uq5EasduMiIFmzt3Ljp06ICSkhJ89tln2Lx5M4KCgmod9/nnn+M///kPDh48iGvXrpm2x8fH1zq2VatWZt8bAyPjw/T48eMAgPbt29d6bWJiolmAdfz4ccTExJg99AGgY8eOZueydm1jsBUXF2dxu70P+LrqFBoaatc5bJ0zLCwMwcHBaN68ea3t58+fr/X6mu+fJElo166dqavz8OHDAICxY8daLUNJSYlZ4FrzfgYFBeHNN9/ElClTEBkZidtvvx1DhgzBo48+iqioKNuVJCIADIaIFK179+6m2WTDhw9H79698eCDDyI/Px+NGzcGAHz55ZcYN24chg8fjhdffBEtWrSAv78/MjMzzQZaG/n7+1u8lqgx4NkVrF27vmWy9XpJkizu1+l0Dp1TzvfO2Orz9ttv1xrXZWS8x0bGsUY3ysjIwNChQ7F8+XKsXbsWL7/8MjIzM7Fx40bccsstDpeLSI0YDBF5CWOA069fP7z//vv429/+BgBYsmQJ2rZti+zsbLOH/vTp0526TuvWrQFcb7m4UX5+fq1jv//+e5SVlZm1Dh08eNDsXJ5mbF25dOmS2faaLVdyqvn+CSFw5MgRdO7cGQCQkJAAAAgNDUV6enq9rpWQkIApU6ZgypQpOHz4MFJTU/Gf//wHX375Zb3OS6QWHDNE5EXS0tLQvXt3zJo1C5WVlQCut1bc2Dqxfft2bN261alrREdHIzU1FZ9//jlKSkpM29evX4/9+/ebHXv33XdDp9Ph/fffN9s+c+ZMSJKEwYMHO1UGuYWGhqJ58+bYvHmz2fYPPvjAZdf84osvUFZWZvp+yZIlOH36tOk96dq1KxISEvDOO+/g8uXLtV5/9uxZm9eoqKgwfQ6MEhIS0KRJE1RVVdWzBkTqwZYhIi/z4osv4v7770dWVhaefvppDBkyBNnZ2bj33nuh0WhQUFCAefPmISkpyeJD1h6ZmZnQaDTo3bs3HnvsMVy4cAFz5sxBcnKy2TmHDh2Kfv364R//+AeOHTuGLl26YN26dVixYgUyMjJMrR9K8MQTT2DGjBl44okn0K1bN2zevBmHDh1y2fXCw8PRu3dvjB8/HmfOnMGsWbPQrl07TJgwAQDg5+eHTz75BIMHD0ZycjLGjx+Pli1b4uTJk8jJyUFoaCj+97//1XmNQ4cOoX///hg1ahSSkpIQEBCAZcuW4cyZM3jggQdcVjciX8NgiMjLjBgxwtSiMGHCBIwbNw5FRUWYP38+1q5di6SkJHz55Zf49ttvkZub69Q1Bg0ahG+//Rb//Oc/MXXqVCQkJGDBggVYsWKF2Tn9/Pzw3XffYdq0afj666+xYMECtGnTBm+//TamTJkiT4VlMm3aNJw9exZLlizBN998g8GDB2P16tVo0aKFS67397//Hb/++isyMzNRVlaG/v3744MPPkDDhg1Nx6SlpWHr1q147bXX8P777+Py5cuIiopCjx498NRTT9m8RlxcHMaMGYMNGzbgv//9LwICAnDzzTfjm2++wX333eeSehH5Ikm4Y9QkERERkUJxzBARERGpGoMhIiIiUjUGQ0RERKRqDIaIiIhI1RgMERERkaoxGCIiIiJVU0WeIb1ej1OnTqFJkyZW1ygiIiIiZRFCoKysDDExMfDzc137jSqCoVOnTtVaFZuIiIi8Q2FhIWJjY112flUEQ8YFJAsLCxEaGurh0hAREZE9SktLERcXZ7YQtCuoIhgydo2FhoYyGCIiIvIyrh7iwgHUREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoeD4Y2b96MoUOHIiYmBpIkYfny5VaPffrppyFJEmbNmuW28hEREZFv83gwVF5eji5dumDu3Ll1Hrds2TJs27YNMTExbioZERERqUGApwswePBgDB48uM5jTp48iWeffRZr166FRqNxU8mIiIhIDTzeMmSLXq/HI488ghdffBHJycmeLg4RERH5GI+3DNny5ptvIiAgAM8995zdr6mqqkJVVZXp+9LSUlcUjYiIiHyAoluGfvnlF8yePRtZWVmQJMnu12VmZiIsLMz0FRcX58JSEhERkTdTdDC0ZcsWFBcXo1WrVggICEBAQACOHz+OKVOmoE2bNlZfN3XqVJSUlJi+CgsL3VdoIiIi8iqK7iZ75JFHkJ6ebrZt4MCBeOSRRzB+/HirrwsKCkJQUJCri0dEREQ+wOPB0OXLl3HkyBHT9wUFBdi9ezfCw8PRqlUrNGvWzOz4Bg0aICoqComJie4uKhEREfkgjwdDP//8M/r162f6/vnnnwcAjB07FllZWR4qFRER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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {
"filenames": {
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_16_1.png"
}
},
"output_type": "display_data"
}
],
"source": [
"# Using Autograd to calculate gradients for OLS\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"def CostOLS(beta):\n",
" return (1.0/n)*np.sum((y-X @ beta)**2)\n",
"\n",
"n = 100\n",
"x = 2*np.random.rand(n,1)\n",
"y = 4+3*x+np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"# Hessian matrix\n",
"H = (2.0/n)* XT_X\n",
"EigValues, EigVectors = np.linalg.eig(H)\n",
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
"\n",
"theta = np.random.randn(2,1)\n",
"eta = 1.0/np.max(EigValues)\n",
"Niterations = 1000\n",
"# define the gradient\n",
"training_gradient = grad(CostOLS)\n",
"\n",
"for iter in range(Niterations):\n",
" gradients = training_gradient(theta)\n",
" theta -= eta*gradients\n",
"print(\"theta from own gd\")\n",
"print(theta)\n",
"\n",
"xnew = np.array([[0],[2]])\n",
"Xnew = np.c_[np.ones((2,1)), xnew]\n",
"ypredict = Xnew.dot(theta)\n",
"ypredict2 = Xnew.dot(theta_linreg)\n",
"\n",
"plt.plot(xnew, ypredict, \"r-\")\n",
"plt.plot(xnew, ypredict2, \"b-\")\n",
"plt.plot(x, y ,'ro')\n",
"plt.axis([0,2.0,0, 15.0])\n",
"plt.xlabel(r'$x$')\n",
"plt.ylabel(r'$y$')\n",
"plt.title(r'Random numbers ')\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "1bc83f33",
"metadata": {},
"source": [
"## Same code but now with momentum gradient descent"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "dc2a3f65",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[4.]\n",
" [3.]]\n",
"Eigenvalues of Hessian Matrix:[0.29155617 4.71527295]\n",
"0 [-13.19526866] [-16.48597324]\n",
"1 [-0.06810332] [0.05402091]\n",
"2 [-0.06389233] [0.05068067]\n",
"3 [-0.05994172] [0.04754697]\n",
"4 [-0.05623539] [0.04460703]\n",
"5 [-0.05275823] [0.04184888]\n",
"6 [-0.04949606] [0.03926126]\n",
"7 [-0.04643561] [0.03683365]\n",
"8 [-0.04356439] [0.03455614]\n",
"9 [-0.0408707] [0.03241945]\n",
"10 [-0.03834357] [0.03041488]\n",
"11 [-0.0359727] [0.02853426]\n",
"12 [-0.03374843] [0.02676992]\n",
"13 [-0.03166168] [0.02511468]\n",
"14 [-0.02970397] [0.02356178]\n",
"15 [-0.0278673] [0.0221049]\n",
"16 [-0.0261442] [0.0207381]\n",
"17 [-0.02452765] [0.01945582]\n",
"18 [-0.02301105] [0.01825282]\n",
"19 [-0.02158822] [0.01712421]\n",
"20 [-0.02025337] [0.01606538]\n",
"21 [-0.01900106] [0.01507202]\n",
"22 [-0.01782618] [0.01414008]\n",
"23 [-0.01672395] [0.01326577]\n",
"24 [-0.01568987] [0.01244551]\n",
"25 [-0.01471973] [0.01167598]\n",
"26 [-0.01380957] [0.01095403]\n",
"27 [-0.01295569] [0.01027671]\n",
"28 [-0.01215461] [0.00964128]\n",
"29 [-0.01140307] [0.00904514]\n",
"theta from own gd\n",
"[[3.96330728]\n",
" [3.02910539]]\n",
"0 [-0.01069799] [0.00848586]\n",
"1 [-0.01003651] [0.00796116]\n",
"2 [-0.00921748] [0.00731149]\n",
"3 [-0.00840184] [0.0066645]\n",
"4 [-0.00763764] [0.00605833]\n",
"5 [-0.00693613] [0.00550187]\n",
"6 [-0.0062968] [0.00499474]\n",
"7 [-0.00571565] [0.00453377]\n",
"8 [-0.0051879] [0.00411514]\n",
"9 [-0.00470879] [0.00373511]\n",
"10 [-0.0042739] [0.00339014]\n",
"11 [-0.00387917] [0.00307704]\n",
"12 [-0.00352089] [0.00279284]\n",
"13 [-0.00319571] [0.0025349]\n",
"14 [-0.00290055] [0.00230078]\n",
"15 [-0.00263266] [0.00208828]\n",
"16 [-0.00238951] [0.0018954]\n",
"17 [-0.00216881] [0.00172034]\n",
"18 [-0.0019685] [0.00156145]\n",
"19 [-0.00178669] [0.00141724]\n",
"20 [-0.00162167] [0.00128634]\n",
"21 [-0.0014719] [0.00116754]\n",
"22 [-0.00133595] [0.0010597]\n",
"23 [-0.00121256] [0.00096183]\n",
"24 [-0.00110057] [0.000873]\n",
"25 [-0.00099892] [0.00079237]\n",
"26 [-0.00090666] [0.00071918]\n",
"27 [-0.00082292] [0.00065276]\n",
"28 [-0.00074692] [0.00059247]\n",
"29 [-0.00067793] [0.00053775]\n",
"theta from own gd wth momentum\n",
"[[3.99788953]\n",
" [3.00167406]]\n"
]
}
],
"source": [
"# Using Autograd to calculate gradients for OLS\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"def CostOLS(beta):\n",
" return (1.0/n)*np.sum((y-X @ beta)**2)\n",
"\n",
"n = 100\n",
"x = 2*np.random.rand(n,1)\n",
"y = 4+3*x#+np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"# Hessian matrix\n",
"H = (2.0/n)* XT_X\n",
"EigValues, EigVectors = np.linalg.eig(H)\n",
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
"\n",
"theta = np.random.randn(2,1)\n",
"eta = 1.0/np.max(EigValues)\n",
"Niterations = 30\n",
"\n",
"# define the gradient\n",
"training_gradient = grad(CostOLS)\n",
"\n",
"for iter in range(Niterations):\n",
" gradients = training_gradient(theta)\n",
" theta -= eta*gradients\n",
" print(iter,gradients[0],gradients[1])\n",
"print(\"theta from own gd\")\n",
"print(theta)\n",
"\n",
"# Now improve with momentum gradient descent\n",
"change = 0.0\n",
"delta_momentum = 0.3\n",
"for iter in range(Niterations):\n",
" # calculate gradient\n",
" gradients = training_gradient(theta)\n",
" # calculate update\n",
" new_change = eta*gradients+delta_momentum*change\n",
" # take a step\n",
" theta -= new_change\n",
" # save the change\n",
" change = new_change\n",
" print(iter,gradients[0],gradients[1])\n",
"print(\"theta from own gd wth momentum\")\n",
"print(theta)"
]
},
{
"cell_type": "markdown",
"id": "0ef007d0",
"metadata": {},
"source": [
"## But noen of these can compete with Newton's method"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "0e498aa4",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[3.86138568]\n",
" [3.1477805 ]]\n",
"Eigenvalues of Hessian Matrix:[0.36889994 4.06507762]\n",
"0 [-10.57231587] [-11.4303589]\n",
"1 [-1.09374315e-15] [-4.626889e-15]\n",
"2 [-3.72965547e-17] [-7.31971976e-17]\n",
"3 [-3.72965547e-17] [-7.31971976e-17]\n",
"4 [-3.72965547e-17] [-7.31971976e-17]\n",
"beta from own Newton code\n",
"[[3.86138568]\n",
" [3.1477805 ]]\n"
]
}
],
"source": [
"# Using Newton's method\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"def CostOLS(beta):\n",
" return (1.0/n)*np.sum((y-X @ beta)**2)\n",
"\n",
"n = 100\n",
"x = 2*np.random.rand(n,1)\n",
"y = 4+3*x+np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x]\n",
"XT_X = X.T @ X\n",
"beta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(beta_linreg)\n",
"# Hessian matrix\n",
"H = (2.0/n)* XT_X\n",
"# Note that here the Hessian does not depend on the parameters beta\n",
"invH = np.linalg.pinv(H)\n",
"EigValues, EigVectors = np.linalg.eig(H)\n",
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
"\n",
"beta = np.random.randn(2,1)\n",
"Niterations = 5\n",
"\n",
"# define the gradient\n",
"training_gradient = grad(CostOLS)\n",
"\n",
"for iter in range(Niterations):\n",
" gradients = training_gradient(beta)\n",
" beta -= invH @ gradients\n",
" print(iter,gradients[0],gradients[1])\n",
"print(\"beta from own Newton code\")\n",
"print(beta)"
]
},
{
"cell_type": "markdown",
"id": "40292cf3",
"metadata": {},
"source": [
"## Including Stochastic Gradient Descent with Autograd\n",
"In this code we include the stochastic gradient descent approach discussed above. Note here that we specify which argument we are taking the derivative with respect to when using **autograd**."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "fa819b9d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[3.94897376]\n",
" [2.96037553]]\n",
"Eigenvalues of Hessian Matrix:[0.32588151 4.12462963]\n",
"theta from own gd\n",
"[[3.94897376]\n",
" [2.96037553]]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkMAAAHHCAYAAAC88FzIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABSSElEQVR4nO3de1xUZf4H8M8AMl4SFJX7eAlvgaWpeWklccWMsDAyzcrUsu1iJavd3K2s3faHdtUtS7sodlEzRW218gpipWmim9pqamiEguYFEBNxeH5/TDMwzAxzOzPnnDmf9+tFxJkzZ54zZ/B8eZ7v8310QggBIiIiIo0KkrsBRERERHJiMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERELpswYQI6duwodzMULT8/HzqdDsuXL5e7KUTkIgZDRAqUk5MDnU5n+QoJCUFcXBwmTJiAkpISuZtHRBRQQuRuABE59o9//AOdOnXCxYsXsX37duTk5ODrr7/Gvn370LRpU7mbR0QUEBgMESlYWloa+vbtCwCYNGkS2rZti1mzZuHzzz/H6NGjZW4dyamqqgotWrSQuxlEAYHDZEQqkpycDAA4cuSIZdulS5fw/PPPo0+fPggPD0eLFi2QnJyMvLw8q+cePXoUOp0Or776Kt59910kJCRAr9fjuuuuw86dO21ea9WqVejRoweaNm2KHj16YOXKlXbbVFVVhWnTpsFgMECv16Nbt2549dVXIYSw2k+n0+HRRx/FZ599hsTERDRr1gwDBw7E3r17AQDz589H586d0bRpU6SkpODo0aNO348XXngBOp0Ohw8fxoQJE9CqVSuEh4dj4sSJuHDhgs255+Tk2BxDp9PhhRdesDnmTz/9hHvuuQfh4eFo164dnnvuOQghUFxcjIyMDISFhSE6Ohqvvfaa3bYZjUb87W9/Q3R0NFq0aIFbb70VxcXFNvt99913uOmmmxAeHo7mzZtj8ODB+Oabb+ye548//oi77roLrVu3xqBBgwAApaWlmDhxIuLj46HX6xETE4OMjAyX3j8iMmHPEJGKmG9wrVu3tmyrqKjA+++/j7Fjx+KBBx5AZWUlPvjgAwwfPhw7duxAr169rI6xePFiVFZW4sEHH4ROp8PLL7+MzMxM/Pzzz2jSpAkAYP369bj99tuRmJiI7OxsnD592nLDrU8IgVtvvRV5eXm4//770atXL6xbtw5PPvkkSkpK8MYbb1jtv3XrVnz++eeYPHkyACA7OxsjRozAU089hbfffhuPPPIIzp49i5dffhn33XcfNm/e7NL7Mnr0aHTq1AnZ2dkoLCzE+++/j8jISMyaNcudt9fKmDFjcNVVV2HmzJlYu3YtXnrpJURERGD+/Pn485//jFmzZuGTTz7BE088geuuuw433HCD1fP/9a9/QafT4emnn8bJkycxe/ZspKamYs+ePWjWrBkAYPPmzUhLS0OfPn0wY8YMBAUFYeHChfjzn/+MrVu3ol+/flbHvOOOO9ClSxf83//9nyXYvP3227F//3489thj6NixI06ePIkNGzbgl19+YbI7kasEESnOwoULBQCxceNGcerUKVFcXCyWL18u2rVrJ/R6vSguLrbse/nyZVFdXW31/LNnz4qoqChx3333WbYVFRUJAKJNmzbizJkzlu2rV68WAMR//vMfy7ZevXqJmJgYce7cOcu29evXCwCiQ4cOlm2rVq0SAMRLL71k9fqjRo0SOp1OHD582LINgNDr9aKoqMiybf78+QKAiI6OFhUVFZbt06dPFwCs9rVnxowZAoDVeQohxG233SbatGljc+4LFy60OQYAMWPGDJtj/uUvf7Fsu3z5soiPjxc6nU7MnDnTsv3s2bOiWbNmYvz48ZZteXl5AoCIi4uzOqdly5YJAGLOnDlCCCFqa2tFly5dxPDhw0Vtba1lvwsXLohOnTqJYcOG2bRp7NixVm0/e/asACBeeeWVRt8nImoch8mIFCw1NRXt2rWDwWDAqFGj0KJFC3z++edWPTTBwcEIDQ0FANTW1uLMmTO4fPky+vbti8LCQptjjhkzxqpnyTz09vPPPwMATpw4gT179mD8+PEIDw+37Dds2DAkJiZaHeuLL75AcHAwHn/8cavt06ZNgxACX375pdX2oUOHWvVW9O/fH4Cpd6Nly5Y2281tcuahhx6y+jk5ORmnT59GRUWFS8+3Z9KkSZb/Dw4ORt++fSGEwP3332/Z3qpVK3Tr1s1uO++9916rcxo1ahRiYmLwxRdfAAD27NmDQ4cO4a677sLp06fx22+/4bfffkNVVRWGDh2KgoIC1NbWNnqezZo1Q2hoKPLz83H27FmPz5VI6zhMRqRgc+fO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FRERESIlJUVs3rzZ5riBdr2FME0Xb9asmXj33XftHlMN19veOQOw+p2V6x6u+6OBRERERJqkqpwhIiIiIqkxGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNYzBERKq0ZMkSNGvWDCdOnLBsmzhxIq655hqUl5fL2DIiUhuuTUZEqiSEQK9evXDDDTfgzTffxIwZM7BgwQJs374dcXFxcjePiFQkRO4GEBF5QqfT4V//+hdGjRqF6OhovPnmm9i6dSsDISJyG3uGiEjVevfujf3792P9+vUYPHiw3M0hIhVizhARqdZXX32FAwcOwGg0IioqSu7mEJFKsWeIiFSpsLAQKSkpmD9/PnJychAWFobPPvtM7mYRkQoxZ4iIVOfo0aNIT0/H3/72N4wdOxZXXnklBg4ciMLCQvTu3Vvu5hGRyrBniIhU5cyZM7j++uuRkpKCefPmWbanp6fDaDTiq6++krF1RKRGDIaIiIhI05hATURERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItK0/weFvVxJlqLYRQAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {
"filenames": {
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_22_1.png"
}
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"theta from own sdg\n",
"[[3.95568161]\n",
" [2.9638104 ]]\n"
]
}
],
"source": [
"# Using Autograd to calculate gradients using SGD\n",
"# OLS example\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"# Note change from previous example\n",
"def CostOLS(y,X,theta):\n",
" return np.sum((y-X @ theta)**2)\n",
"\n",
"n = 100\n",
"x = 2*np.random.rand(n,1)\n",
"y = 4+3*x+np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"# Hessian matrix\n",
"H = (2.0/n)* XT_X\n",
"EigValues, EigVectors = np.linalg.eig(H)\n",
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
"\n",
"theta = np.random.randn(2,1)\n",
"eta = 1.0/np.max(EigValues)\n",
"Niterations = 1000\n",
"\n",
"# Note that we request the derivative wrt third argument (theta, 2 here)\n",
"training_gradient = grad(CostOLS,2)\n",
"\n",
"for iter in range(Niterations):\n",
" gradients = (1.0/n)*training_gradient(y, X, theta)\n",
" theta -= eta*gradients\n",
"print(\"theta from own gd\")\n",
"print(theta)\n",
"\n",
"xnew = np.array([[0],[2]])\n",
"Xnew = np.c_[np.ones((2,1)), xnew]\n",
"ypredict = Xnew.dot(theta)\n",
"ypredict2 = Xnew.dot(theta_linreg)\n",
"\n",
"plt.plot(xnew, ypredict, \"r-\")\n",
"plt.plot(xnew, ypredict2, \"b-\")\n",
"plt.plot(x, y ,'ro')\n",
"plt.axis([0,2.0,0, 15.0])\n",
"plt.xlabel(r'$x$')\n",
"plt.ylabel(r'$y$')\n",
"plt.title(r'Random numbers ')\n",
"plt.show()\n",
"\n",
"n_epochs = 50\n",
"M = 5 #size of each minibatch\n",
"m = int(n/M) #number of minibatches\n",
"t0, t1 = 5, 50\n",
"def learning_schedule(t):\n",
" return t0/(t+t1)\n",
"\n",
"theta = np.random.randn(2,1)\n",
"\n",
"for epoch in range(n_epochs):\n",
"# Can you figure out a better way of setting up the contributions to each batch?\n",
" for i in range(m):\n",
" random_index = M*np.random.randint(m)\n",
" xi = X[random_index:random_index+M]\n",
" yi = y[random_index:random_index+M]\n",
" gradients = (1.0/M)*training_gradient(yi, xi, theta)\n",
" eta = learning_schedule(epoch*m+i)\n",
" theta = theta - eta*gradients\n",
"print(\"theta from own sdg\")\n",
"print(theta)"
]
},
{
"cell_type": "markdown",
"id": "2ca466b4",
"metadata": {},
"source": [
"## Same code but now with momentum gradient descent"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "0d44a49c",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[4.1880258 ]\n",
" [2.90273253]]\n",
"Eigenvalues of Hessian Matrix:[0.32354671 4.36490166]\n",
"theta from own gd\n",
"[[4.18757012]\n",
" [2.9031162 ]]\n",
"theta from own sdg with momentum\n",
"[[4.11556912]\n",
" [2.89211256]]\n"
]
}
],
"source": [
"# Using Autograd to calculate gradients using SGD\n",
"# OLS example\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"# Note change from previous example\n",
"def CostOLS(y,X,theta):\n",
" return np.sum((y-X @ theta)**2)\n",
"\n",
"n = 100\n",
"x = 2*np.random.rand(n,1)\n",
"y = 4+3*x+np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"# Hessian matrix\n",
"H = (2.0/n)* XT_X\n",
"EigValues, EigVectors = np.linalg.eig(H)\n",
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
"\n",
"theta = np.random.randn(2,1)\n",
"eta = 1.0/np.max(EigValues)\n",
"Niterations = 100\n",
"\n",
"# Note that we request the derivative wrt third argument (theta, 2 here)\n",
"training_gradient = grad(CostOLS,2)\n",
"\n",
"for iter in range(Niterations):\n",
" gradients = (1.0/n)*training_gradient(y, X, theta)\n",
" theta -= eta*gradients\n",
"print(\"theta from own gd\")\n",
"print(theta)\n",
"\n",
"\n",
"n_epochs = 50\n",
"M = 5 #size of each minibatch\n",
"m = int(n/M) #number of minibatches\n",
"t0, t1 = 5, 50\n",
"def learning_schedule(t):\n",
" return t0/(t+t1)\n",
"\n",
"theta = np.random.randn(2,1)\n",
"\n",
"change = 0.0\n",
"delta_momentum = 0.3\n",
"\n",
"for epoch in range(n_epochs):\n",
" for i in range(m):\n",
" random_index = M*np.random.randint(m)\n",
" xi = X[random_index:random_index+M]\n",
" yi = y[random_index:random_index+M]\n",
" gradients = (1.0/M)*training_gradient(yi, xi, theta)\n",
" eta = learning_schedule(epoch*m+i)\n",
" # calculate update\n",
" new_change = eta*gradients+delta_momentum*change\n",
" # take a step\n",
" theta -= new_change\n",
" # save the change\n",
" change = new_change\n",
"print(\"theta from own sdg with momentum\")\n",
"print(theta)"
]
},
{
"cell_type": "markdown",
"id": "b82627f6",
"metadata": {},
"source": [
"## AdaGrad algorithm, taken from [Goodfellow et al](https://www.deeplearningbook.org/contents/optimization.html)\n",
"\n",
"<!-- dom:FIGURE: [figures/adagrad.png, width=600 frac=0.8] -->\n",
"<!-- begin figure -->\n",
"\n",
"<img src=\"figures/adagrad.png\" width=\"600\"><p style=\"font-size: 0.9em\"><i>Figure 1: </i></p>\n",
"<!-- end figure -->"
]
},
{
"cell_type": "markdown",
"id": "00d3aff0",
"metadata": {},
"source": [
"## Similar (second order function now) problem but now with AdaGrad"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6b85aacc",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[2.]\n",
" [3.]\n",
" [4.]]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"theta from own AdaGrad\n",
"[[2.0004377 ]\n",
" [2.99782503]\n",
" [4.0020899 ]]\n"
]
}
],
"source": [
"# Using Autograd to calculate gradients using AdaGrad and Stochastic Gradient descent\n",
"# OLS example\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"# Note change from previous example\n",
"def CostOLS(y,X,theta):\n",
" return np.sum((y-X @ theta)**2)\n",
"\n",
"n = 1000\n",
"x = np.random.rand(n,1)\n",
"y = 2.0+3*x +4*x*x\n",
"\n",
"X = np.c_[np.ones((n,1)), x, x*x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"\n",
"\n",
"# Note that we request the derivative wrt third argument (theta, 2 here)\n",
"training_gradient = grad(CostOLS,2)\n",
"# Define parameters for Stochastic Gradient Descent\n",
"n_epochs = 50\n",
"M = 5 #size of each minibatch\n",
"m = int(n/M) #number of minibatches\n",
"# Guess for unknown parameters theta\n",
"theta = np.random.randn(3,1)\n",
"\n",
"# Value for learning rate\n",
"eta = 0.01\n",
"# Including AdaGrad parameter to avoid possible division by zero\n",
"delta = 1e-8\n",
"for epoch in range(n_epochs):\n",
" Giter = 0.0\n",
" for i in range(m):\n",
" random_index = M*np.random.randint(m)\n",
" xi = X[random_index:random_index+M]\n",
" yi = y[random_index:random_index+M]\n",
" gradients = (1.0/M)*training_gradient(yi, xi, theta)\n",
" Giter += gradients*gradients\n",
" update = gradients*eta/(delta+np.sqrt(Giter))\n",
" theta -= update\n",
"print(\"theta from own AdaGrad\")\n",
"print(theta)"
]
},
{
"cell_type": "markdown",
"id": "d8ddde38",
"metadata": {},
"source": [
"Running this code we note an almost perfect agreement with the results from matrix inversion."
]
},
{
"cell_type": "markdown",
"id": "ff15b503",
"metadata": {},
"source": [
"## RMSProp algorithm, taken from [Goodfellow et al](https://www.deeplearningbook.org/contents/optimization.html)\n",
"\n",
"<!-- dom:FIGURE: [figures/rmsprop.png, width=600 frac=0.8] -->\n",
"<!-- begin figure -->\n",
"\n",
"<img src=\"figures/rmsprop.png\" width=\"600\"><p style=\"font-size: 0.9em\"><i>Figure 1: </i></p>\n",
"<!-- end figure -->"
]
},
{
"cell_type": "markdown",
"id": "66f96d12",
"metadata": {},
"source": [
"## RMSprop for adaptive learning rate with Stochastic Gradient Descent"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "888f1b4e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[2.]\n",
" [3.]\n",
" [4.]]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"theta from own RMSprop\n",
"[[1.99457257]\n",
" [2.99607686]\n",
" [3.99588057]]\n"
]
}
],
"source": [
"# Using Autograd to calculate gradients using RMSprop and Stochastic Gradient descent\n",
"# OLS example\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"# Note change from previous example\n",
"def CostOLS(y,X,theta):\n",
" return np.sum((y-X @ theta)**2)\n",
"\n",
"n = 1000\n",
"x = np.random.rand(n,1)\n",
"y = 2.0+3*x +4*x*x# +np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x, x*x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"\n",
"\n",
"# Note that we request the derivative wrt third argument (theta, 2 here)\n",
"training_gradient = grad(CostOLS,2)\n",
"# Define parameters for Stochastic Gradient Descent\n",
"n_epochs = 50\n",
"M = 5 #size of each minibatch\n",
"m = int(n/M) #number of minibatches\n",
"# Guess for unknown parameters theta\n",
"theta = np.random.randn(3,1)\n",
"\n",
"# Value for learning rate\n",
"eta = 0.01\n",
"# Value for parameter rho\n",
"rho = 0.99\n",
"# Including AdaGrad parameter to avoid possible division by zero\n",
"delta = 1e-8\n",
"for epoch in range(n_epochs):\n",
" Giter = 0.0\n",
" for i in range(m):\n",
" random_index = M*np.random.randint(m)\n",
" xi = X[random_index:random_index+M]\n",
" yi = y[random_index:random_index+M]\n",
" gradients = (1.0/M)*training_gradient(yi, xi, theta)\n",
"\t# Accumulated gradient\n",
"\t# Scaling with rho the new and the previous results\n",
" Giter = (rho*Giter+(1-rho)*gradients*gradients)\n",
"\t# Taking the diagonal only and inverting\n",
" update = gradients*eta/(delta+np.sqrt(Giter))\n",
"\t# Hadamard product\n",
" theta -= update\n",
"print(\"theta from own RMSprop\")\n",
"print(theta)"
]
},
{
"cell_type": "markdown",
"id": "2e0860f7",
"metadata": {},
"source": [
"## ADAM algorithm, taken from [Goodfellow et al](https://www.deeplearningbook.org/contents/optimization.html)\n",
"\n",
"<!-- dom:FIGURE: [figures/adam.png, width=600 frac=0.8] -->\n",
"<!-- begin figure -->\n",
"\n",
"<img src=\"figures/adam.png\" width=\"600\"><p style=\"font-size: 0.9em\"><i>Figure 1: </i></p>\n",
"<!-- end figure -->"
]
},
{
"cell_type": "markdown",
"id": "ab4a9859",
"metadata": {},
"source": [
"## And finally [ADAM](https://arxiv.org/pdf/1412.6980.pdf)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "ccdd4d77",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Own inversion\n",
"[[2.]\n",
" [3.]\n",
" [4.]]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"theta from own ADAM\n",
"[[2.00003022]\n",
" [2.99976375]\n",
" [4.00024415]]\n"
]
}
],
"source": [
"# Using Autograd to calculate gradients using RMSprop and Stochastic Gradient descent\n",
"# OLS example\n",
"from random import random, seed\n",
"import numpy as np\n",
"import autograd.numpy as np\n",
"import matplotlib.pyplot as plt\n",
"from autograd import grad\n",
"\n",
"# Note change from previous example\n",
"def CostOLS(y,X,theta):\n",
" return np.sum((y-X @ theta)**2)\n",
"\n",
"n = 1000\n",
"x = np.random.rand(n,1)\n",
"y = 2.0+3*x +4*x*x# +np.random.randn(n,1)\n",
"\n",
"X = np.c_[np.ones((n,1)), x, x*x]\n",
"XT_X = X.T @ X\n",
"theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
"print(\"Own inversion\")\n",
"print(theta_linreg)\n",
"\n",
"\n",
"# Note that we request the derivative wrt third argument (theta, 2 here)\n",
"training_gradient = grad(CostOLS,2)\n",
"# Define parameters for Stochastic Gradient Descent\n",
"n_epochs = 50\n",
"M = 5 #size of each minibatch\n",
"m = int(n/M) #number of minibatches\n",
"# Guess for unknown parameters theta\n",
"theta = np.random.randn(3,1)\n",
"\n",
"# Value for learning rate\n",
"eta = 0.01\n",
"# Value for parameters beta1 and beta2, see https://arxiv.org/abs/1412.6980\n",
"beta1 = 0.9\n",
"beta2 = 0.999\n",
"# Including AdaGrad parameter to avoid possible division by zero\n",
"delta = 1e-7\n",
"iter = 0\n",
"for epoch in range(n_epochs):\n",
" first_moment = 0.0\n",
" second_moment = 0.0\n",
" iter += 1\n",
" for i in range(m):\n",
" random_index = M*np.random.randint(m)\n",
" xi = X[random_index:random_index+M]\n",
" yi = y[random_index:random_index+M]\n",
" gradients = (1.0/M)*training_gradient(yi, xi, theta)\n",
" # Computing moments first\n",
" first_moment = beta1*first_moment + (1-beta1)*gradients\n",
" second_moment = beta2*second_moment+(1-beta2)*gradients*gradients\n",
" first_term = first_moment/(1.0-beta1**iter)\n",
" second_term = second_moment/(1.0-beta2**iter)\n",
"\t# Scaling with rho the new and the previous results\n",
" update = eta*first_term/(np.sqrt(second_term)+delta)\n",
" theta -= update\n",
"print(\"theta from own ADAM\")\n",
"print(theta)"
]
},
{
"cell_type": "markdown",
"id": "25ac988c",
"metadata": {},
"source": [
"## Introducing [JAX](https://jax.readthedocs.io/en/latest/)\n",
"\n",
"Presently, instead of using **autograd**, we recommend using [JAX](https://jax.readthedocs.io/en/latest/)\n",
"\n",
"**JAX** is Autograd and [XLA (Accelerated Linear Algebra))](https://www.tensorflow.org/xla),\n",
"brought together for high-performance numerical computing and machine learning research.\n",
"It provides composable transformations of Python+NumPy programs: differentiate, vectorize, parallelize, Just-In-Time compile to GPU/TPU, and more."
]
},
{
"cell_type": "markdown",
"id": "37d556d0",
"metadata": {},
"source": [
"### Getting started with Jax, note the way we import numpy"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "5b81d6e4",
"metadata": {},
"outputs": [],
"source": [
"import jax\n",
"import jax.numpy as jnp\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from jax import grad as jax_grad"
]
},
{
"cell_type": "markdown",
"id": "c42db672",
"metadata": {},
"source": [
"### A warm-up example"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "98eb2f26",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/jax/_src/numpy/lax_numpy.py:173: UserWarning: Explicitly requested dtype float64 requested in asarray is not available, and will be truncated to dtype float32. To enable more dtypes, set the jax_enable_x64 configuration option or the JAX_ENABLE_X64 shell environment variable. See https://github.com/google/jax#current-gotchas for more.\n",
" return asarray(x, dtype=self.dtype)\n"
]
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x11fa3db20>]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {
"filenames": {
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_39_2.png"
}
},
"output_type": "display_data"
}
],
"source": [
"def function(x):\n",
" return x**2\n",
"\n",
"def analytical_gradient(x):\n",
" return 2*x\n",
"\n",
"def gradient_descent(starting_point, learning_rate, num_iterations, solver=\"analytical\"):\n",
" x = starting_point\n",
" trajectory_x = [x]\n",
" trajectory_y = [function(x)]\n",
"\n",
" if solver == \"analytical\":\n",
" grad = analytical_gradient \n",
" elif solver == \"jax\":\n",
" grad = jax_grad(function)\n",
" x = jnp.float64(x)\n",
" learning_rate = jnp.float64(learning_rate)\n",
"\n",
" for _ in range(num_iterations):\n",
" \n",
" x = x - learning_rate * grad(x)\n",
" trajectory_x.append(x)\n",
" trajectory_y.append(function(x))\n",
"\n",
" return trajectory_x, trajectory_y\n",
"\n",
"x = np.linspace(-5, 5, 100)\n",
"plt.plot(x, function(x), label=\"f(x)\")\n",
"\n",
"descent_x, descent_y = gradient_descent(5, 0.1, 10, solver=\"analytical\")\n",
"jax_descend_x, jax_descend_y = gradient_descent(5, 0.1, 10, solver=\"jax\")\n",
"\n",
"plt.plot(descent_x, descent_y, label=\"Gradient descent\", marker=\"o\")\n",
"plt.plot(jax_descend_x, jax_descend_y, label=\"JAX\", marker=\"x\")"
]
},
{
"cell_type": "markdown",
"id": "8a5f19b5",
"metadata": {},
"source": [
"### A more advanced example"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "d8f5eb38",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x10746eeb0>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {
"filenames": {
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_41_1.png"
}
},
"output_type": "display_data"
}
],
"source": [
"backend = np\n",
"\n",
"def function(x):\n",
" return x*backend.sin(x**2 + 1)\n",
"\n",
"def analytical_gradient(x):\n",
" return backend.sin(x**2 + 1) + 2*x**2*backend.cos(x**2 + 1)\n",
"\n",
"\n",
"x = np.linspace(-5, 5, 100)\n",
"plt.plot(x, function(x), label=\"f(x)\")\n",
"\n",
"descent_x, descent_y = gradient_descent(1, 0.01, 300, solver=\"analytical\")\n",
"\n",
"# Change the backend to JAX\n",
"backend = jnp\n",
"jax_descend_x, jax_descend_y = gradient_descent(1, 0.01, 300, solver=\"jax\")\n",
"\n",
"plt.scatter(descent_x, descent_y, label=\"Gradient descent\", marker=\"v\", s=10, color=\"red\") \n",
"plt.scatter(jax_descend_x, jax_descend_y, label=\"JAX\", marker=\"x\", s=5, color=\"black\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.15"
}
},
"nbformat": 4,
"nbformat_minor": 5
}