1402 lines
201 KiB
Plaintext
1402 lines
201 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.15515965]\n",
|
|
" [2.99763835]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.3156062 4.19886862]\n",
|
|
"theta from own gd\n",
|
|
"[[4.15515965]\n",
|
|
" [2.99763835]]\n",
|
|
"theta from own sdg\n",
|
|
"[[4.18290649]\n",
|
|
" [2.96486591]]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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mSNTq4iIiEgrZA+GkpOTIYRwefsjR454rzFERESkOYpOoCYiIiLyNgZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiIiINE32YGjDhg1ITU1FXFwcdDodli5dal137do1vPzyy2jbti1q1KiBuLg4PPzwwzhx4oR8DSYiIiK/InswVFxcjPbt22P69OkV1l26dAnbt2/H66+/ju3btyMjIwP79u3DP//5TxlaSkRERP5IJ4QQcjfCQqfTYcmSJRg0aJDDbbZt24bOnTvj6NGjaNCggUv7LSwsREREBAoKChAeHi5Ra4mIiMibfHX/DvLanr2koKAAOp0OtWrVcrhNSUkJSkpKrN8XFhb6oGVERESkRrI/JnPHlStX8PLLL2PYsGGVRojp6emIiIiwfiUkJPiwlURERKQmqgmGrl27hiFDhkAIgc8++6zSbV999VUUFBRYv3JycnzUSiIiIlIbVTwmswRCR48exbp165w+NwwJCUFISIiPWkdERERqpvhgyBIIHThwAJmZmahTp47cTSIiIiI/InswVFRUhIMHD1q/z87Oxo4dOxAZGYnY2FgMHjwY27dvh8FggNFoRF5eHgAgMjISwcHBcjWbiIiI/ITsQ+uzsrLQq1evCsuHDx+OiRMnonHjxnZfl5mZieTkZJfeg0PriYiI1EczQ+uTk5NRWTymoGmQiIiIyA+pZjQZERERkTcwGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jTZh9YTERFJxmgENm4ETp4EYmOBHj2AwEC5W6UtKrwGDIaIiMg/ZGQAzz0HHD9+Y1l8PPDhh0Bamnzt0hKVXgM+JiMiIvXLyAAGD7a9CQNAbq55eUaGPO3SEhVf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QE1ERORFDIaULjAQSE6WuxVERER+i4/JiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0xQdD6enpuOWWW1CzZk3Uq1cPgwYNwr59++RuFhEREfkJxQdD69evx5gxY7BlyxasXr0a165dQ58+fVBcXCx304iIiMgP6IQQQu5GuCM/Px/16tXD+vXrcfvtt7v0msLCQkRERKCgoADh4eFebiERERFJwVf3b9WV4ygoKAAAREZGOtympKQEJSUl1u8LCwu93i4iIiJSJ8U/JivLZDJh7NixuO2225CUlORwu/T0dERERFi/EhISfNhKIiIiUhNVPSZ78skn8fPPP+OXX35BfHy8w+3s9QwlJCTwMRkREZGK8DFZOU8//TQMBgM2bNhQaSAEACEhIQgJCfFRy4iIiEjNFB8MCSHwzDPPYMmSJcjKykLjxo3lbhIRERH5EcUHQ2PGjMG8efPwww8/oGbNmsjLywMAREREICwsTObWERERkdopPmdIp9PZXT579myMGDHCpX1waD0REZH6MGfoOoXHakRERKRyqhpaT0RERCQ1BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJqmmmBo+vTpaNSoEUJDQ9GlSxf89ttvcjeJiIiI/IAqgqHvv/8e48aNw4QJE7B9+3a0b98effv2xenTp+VuGhEREamcKoKhDz74AKNHj8bIkSORmJiIGTNmoHr16pg1a5bcTSMiIiKVU3wwdPXqVfzxxx9ISUmxLgsICEBKSgo2b94sY8uIiIjIHwTJ3QBnzpw5A6PRiOjoaJvl0dHR2Lt3r93XlJSUoKSkxPp9QUEBAKCwsNB7DSUiIiJJWe7bQgivvo/i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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.98635543]\n",
|
|
" [2.9642492 ]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.31545424 4.4234122 ]\n",
|
|
"theta from own gd\n",
|
|
"[[3.98635543]\n",
|
|
" [2.9642492 ]]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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kpIghLB7+5MnT7qvMERERKQ4sm5ATURERORuDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGgMQ0RERKRoDENERESkaAxDREREpGheD0Pbtm3D0KFDERUVBZVKhdWrV5vWVVZW4oUXXkCHDh0QGhqKqKgoPP744zh79qz3CkxERES1itfDUGlpKTp16oR58+ZVW1dWVoZ9+/bh5Zdfxr59+7By5UocOXIE999/vxdKSkRERLWRSgghvF0II5VKhVWrVmH48OFWt9m7dy+6d++OU6dOoVmzZnbtt6ioCOHh4SgsLERYWJhEpSUiIiJ38tT9O8Bte3aTwsJCqFQq1K9f3+o2FRUVqKioML0uKiryQMmIiIjIF3n9MZkjysvL8cILL2DMmDE1JsTU1FSEh4ebftRqtQdLSURERL7EZ8JQZWUlRo8eDSEEPv744xq3nTlzJgoLC00/ubm5HiolERER+RqfeExmDEKnTp3Cli1bbD43DAoKQlBQkIdKR0RERL5M9mHIGISys7ORnp6Ohg0bertIREREVIt4PQyVlJTg2LFjptc5OTnYv38/GjRogMjISIwaNQr79u1DWloadDod8vPzAQANGjRAYGCgt4pNREREtYTXu9ZnZGSgX79+1ZaPGzcOr776KmJjYy2+Lz09HUlJSXYdg13riYiIfI9iutYnJSWhpjwmo2GQiIiIqBbymd5kRERERO7AMERERESKxjBEREREiub1NkNERERUC+l0wPbtwLlzQGQk0KcP4O/v7VJZxDBERERE0lq5Epg6FThz5saymBjg/feBESO8Vy4r+JiMiIiIpLNyJTBqlHkQAoC8PMPylSu9U64aMAwRERGRNHQ6Q42QpWFxjMumTTNsJyMMQ0RERCSN7dur1wjdTAggN9ewnYww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Ua9ePTRp0gTDhw/HkSNHvF0sIiIiqiVkH4a2bt2KyZMnY/fu3di0aRMqKysxYMAAlJaWertoREREVAuohBDC24VwxIULF9CkSRNs3boV99xzj13vKSoqQnh4OAoLCxEWFubmEhIREZEUPHX/DnDbnt2ksLAQANCgQQOr21RUVKCiosL0uqioyO3lIiIiIt8k+8dkN9Pr9Zg2bRruvvtuJCYmWt0uNTUV4eHhph+1Wu3BUhIREZEv8anHZE8//TTWrVuHHTt2ICYmxup2lmqG1Go1H5MRERH5ED4mu8WUKVOQlpaGbdu21RiEACAoKAhBQUEeKhkRERH5MtmHISEEnn32WaxatQoZGRmIjY31dpGIiIioFpF9GJo8eTKWLl2KNWvWoF69esjPzwcAhIeHIyQkxMulIyIiIl8n+zZDKpXK4vKFCxdi/Pjxdu2DXeuJiIh8D9sM/UnmWY2IiIh8nE91rSciIiKSGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKRrDEBERESkawxAREREpGsMQERERKZrPhKF58+ahRYsWCA4ORo8ePfDrr796u0hERERUC/hEGPruu+8wffp0zJo1C/v27UOnTp0wcOBAFBQUeLtoRERE5ON8Igy99957mDRpEiZMmID4+HgsWLAAdevWxZdffuntohEREZGPk30Yun79On777TckJyeblvn5+SE5ORm7du3yYsmIiIioNgjwdgFsuXjxInQ6HZo2bWq2vGnTpjh8+LDF91RUVKCiosL0urCwEABQVFTkvoISERGRpIz3bSGEW48j+zDkjNTUVLz22mvVlqvVai+UhoiIiFxx6dIlhIeHu23/sg9DjRo1gr+/P86fP2+2/Pz584iIiLD4npkzZ2L69Omm11evXkXz5s1x+vRpt36YclNU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hBCirKxMDBgwQDRu3FjUqVNHNG/eXEyaNElW/8MwcuS8p02bZtq2adOmYsiQIWLfvn1m+6uN11sIIQ4fPiwAiI0bN1bbl69cb2PX6Vt/jOc6btw40bdv32rv6dy5swgMDBQtW7YUCxcurLbfmj5LOXD0vPv27Vvj9kIYhhiIjIwUgYGBIjo6Wjz00EPi2LFjnj0xGxw979mzZ4u4uDgRHBwsGjRoIJKSksSWLVuq7be2XW8hDN3FQ0JCxKeffmpxn75wvS2dMwCzf7Peuoer/iwgERERkSL5VJshIiIiIqkxDBEREZGiMQwRERGRojEMERERkaIxDBEREZGiMQwRERGRojEMERERkaIxDBEREZGiMQwRERGRojEMERERkaIxDBGRT1q2bBlCQkJw7tw507IJEyagY8eOKCws9GLJiMjXcG4yIvJJQgh07twZ99xzDz788EPMmjULX375JXbv3o3o6GhvF4+IfEiAtwtAROQMlUqFN954A6NGjUJERAQ+/PBDbN++nUGIiBzGmiEi8mldunRBVlYWNm7ciL59+3q7OETkg9hmiIh81vr163H48GHodDo0bdrU28UhIh/FmiEi8kn79u1DUlISPvnkEyxatAhhYWH44YcfvF0sIvJBbDNERD7n5MmT0Gg0eOmllzBmzBi0bNkSPXv2xL59+9ClSxdvF4+IfAxrhojIp1y+fBm9evVCUlISFixYYFqu0Wig0+mwfv16L5aOiHwRwxAREREpGhtQExERkaIxDBEREZGiMQwRERGRojEMERERkaIxDBEREZGiMQwRERGRojEMERERkaIxDBEREZGiMQwRERGRojEMERERkaIxDBEREZGiMQwRERGRov0/n5oR4U7i4asAAAAASUVORK5CYII=",
|
|
"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.35350927 4.2330123 ]\n",
|
|
"0 [-10.02028415] [-11.38281882]\n",
|
|
"1 [-0.12978318] [0.11144292]\n",
|
|
"2 [-0.11894467] [0.10213605]\n",
|
|
"3 [-0.10901131] [0.09360642]\n",
|
|
"4 [-0.0999075] [0.08578912]\n",
|
|
"5 [-0.09156398] [0.07862466]\n",
|
|
"6 [-0.08391725] [0.07205852]\n",
|
|
"7 [-0.07690911] [0.06604073]\n",
|
|
"8 [-0.07048624] [0.06052551]\n",
|
|
"9 [-0.06459976] [0.05547088]\n",
|
|
"10 [-0.05920488] [0.05083837]\n",
|
|
"11 [-0.05426053] [0.04659273]\n",
|
|
"12 [-0.0497291] [0.04270166]\n",
|
|
"13 [-0.0455761] [0.03913554]\n",
|
|
"14 [-0.04176993] [0.03586723]\n",
|
|
"15 [-0.03828162] [0.03287187]\n",
|
|
"16 [-0.03508463] [0.03012666]\n",
|
|
"17 [-0.03215463] [0.02761071]\n",
|
|
"18 [-0.02946931] [0.02530487]\n",
|
|
"19 [-0.02700826] [0.0231916]\n",
|
|
"20 [-0.02475273] [0.02125481]\n",
|
|
"21 [-0.02268557] [0.01947977]\n",
|
|
"22 [-0.02079104] [0.01785297]\n",
|
|
"23 [-0.01905473] [0.01636202]\n",
|
|
"24 [-0.01746342] [0.01499559]\n",
|
|
"25 [-0.01600501] [0.01374327]\n",
|
|
"26 [-0.01466839] [0.01259554]\n",
|
|
"27 [-0.0134434] [0.01154365]\n",
|
|
"28 [-0.01232071] [0.01057961]\n",
|
|
"29 [-0.01129178] [0.00969608]\n",
|
|
"theta from own gd\n",
|
|
"[[3.9707256]\n",
|
|
" [3.0251375]]\n",
|
|
"0 [-0.01034877] [0.00888634]\n",
|
|
"1 [-0.00948452] [0.00814422]\n",
|
|
"2 [-0.00843317] [0.00724144]\n",
|
|
"3 [-0.00741349] [0.00636586]\n",
|
|
"4 [-0.00648847] [0.00557155]\n",
|
|
"5 [-0.00566909] [0.00486797]\n",
|
|
"6 [-0.00494984] [0.00425036]\n",
|
|
"7 [-0.00432069] [0.00371011]\n",
|
|
"8 [-0.00377111] [0.0032382]\n",
|
|
"9 [-0.00329131] [0.0028262]\n",
|
|
"10 [-0.0028725] [0.00246657]\n",
|
|
"11 [-0.00250697] [0.0021527]\n",
|
|
"12 [-0.00218794] [0.00187876]\n",
|
|
"13 [-0.00190952] [0.00163967]\n",
|
|
"14 [-0.00166652] [0.00143102]\n",
|
|
"15 [-0.00145445] [0.00124891]\n",
|
|
"16 [-0.00126936] [0.00108998]\n",
|
|
"17 [-0.00110783] [0.00095127]\n",
|
|
"18 [-0.00096685] [0.00083022]\n",
|
|
"19 [-0.00084381] [0.00072457]\n",
|
|
"20 [-0.00073643] [0.00063236]\n",
|
|
"21 [-0.00064272] [0.00055189]\n",
|
|
"22 [-0.00056093] [0.00048166]\n",
|
|
"23 [-0.00048955] [0.00042037]\n",
|
|
"24 [-0.00042725] [0.00036687]\n",
|
|
"25 [-0.00037288] [0.00032019]\n",
|
|
"26 [-0.00032543] [0.00027944]\n",
|
|
"27 [-0.00028402] [0.00024388]\n",
|
|
"28 [-0.00024787] [0.00021284]\n",
|
|
"29 [-0.00021633] [0.00018576]\n",
|
|
"theta from own gd wth momentum\n",
|
|
"[[3.99946593]\n",
|
|
" [3.0004586 ]]\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",
|
|
"[[4.16849001]\n",
|
|
" [3.03642937]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.3039241 4.51493779]\n",
|
|
"0 [-12.93402104] [-15.39497785]\n",
|
|
"1 [9.11944131e-15] [7.63687445e-15]\n",
|
|
"2 [2.11636264e-16] [3.19670115e-16]\n",
|
|
"3 [2.11636264e-16] [3.19670115e-16]\n",
|
|
"4 [2.11636264e-16] [3.19670115e-16]\n",
|
|
"beta from own Newton code\n",
|
|
"[[4.16849001]\n",
|
|
" [3.03642937]]\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",
|
|
"[[4.37133465]\n",
|
|
" [2.74809387]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.32760411 4.2384333 ]\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"theta from own gd\n",
|
|
"[[4.37133465]\n",
|
|
" [2.74809387]]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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UHp6OoQQkvc/ceKE9wpDREREqqPoDtRERERE3sYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqxjBEREREqsYwRERERKrGMERERESqJnsY2rZtG4YOHYqEhARoNBqsX7/e+tiNGzfw4osvolOnTmjQoAESEhLw+OOP48yZM/IVmIiIiAKK7GGovLwcXbp0wfz582s8VlFRgdzcXLzyyivIzc3F2rVrkZeXhwceeECGkhIREVEg0gghhNyFsNBoNFi3bh2GDx/ucJ/vv/8ePXv2xMmTJ9G8eXNJxy0pKUFkZCSKi4sRERHhodISERGRN/nq/h3stSN7SXFxMTQaDRo3buxwn8rKSlRWVlp/Lykp8UHJiIiIyB/J3kzmimvXruHFF1/E2LFja02ImZmZiIyMtP7odDoflpKIiIj8id+EoRs3bmDUqFEQQuD999+vdd8ZM2aguLjY+lNQUOCjUhIREZG/8YtmMksQOnnyJLZs2eK03TA0NBShoaE+Kh0RERH5M8WHIUsQOnr0KLKzs9G0aVO5i0RERER1YTQC27cDZ88C8fFA376AVitbcWQPQ2VlZTh27Jj19/z8fOzbtw9RUVGIj4/HyJEjkZubiy+//BJGoxFFRUUAgKioKISEhMhVbCIiInLH2rXAH/4AnD59a1tSEvDuu8CIEbIUSfah9Tk5Oejfv3+N7ePHj8fs2bORnJxs93nZ2dlIT0+XdA4OrSciIlKAtWuBkSOB6tFDozH/d/Vqm0Dkq/u37GHIFxiGiIiIZGY0Ai1b2tYI3U6jMdcQ5edbm8x8df/2m9FkRERE5Me2b3cchABzbVFBgXk/H2MYIiIiIu87e9az+3kQwxARERF5X3y8Z/fzIIYhIiIi8r6+fc19giydpavTaACdzryfjzEMERER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IiQkRPTs2VPs2rXL+li/fv3E+PHjbfZfuXKlaNu2rQgJCRFpaWniv//9r83jJpNJvPLKKyI2NlaEhoaKAQMGiLy8PF9ciktcue4WLVoIADV+Zs2aJYQQoqKiQuj1etGsWTNRr1490aJFCzF58mRF/cGwcOW6p06dat03NjZW/Pa3vxW5ubk2xwvE91sIIQ4fPiwACIPBUONY/vJ+W4ZOV/+xXOv48eNFv379ajyna9euIiQkRLRq1UosXry4xnFrey2VwNXr7tevX637C2GeYiA+Pl6EhISIxMREMXr0aHHs2DHfXpgTrl733LlzRUpKiggLCxNRUVEiPT1dbNmypcZxA+39FsI8XDw8PFx88MEHdo/pD++3vWsGYPNvVq57uOZmAYmIiIhUya/6DBERERF5GsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQEfml5cuXIzw8HGfPnrVumzhxIjp37ozi4mIZS0ZE/oZrkxGRXxJCoGvXrrjnnnvw3nvvYdasWfj444+xa9cuJCYmyl08IvIjwXIXgIjIHRqNBq+//jpGjhyJuLg4vPfee9i+fTuDEBG5jDVDROTXunXrhgMHDsBgMKBfv35yF4eI/BD7DBGR39q4cSMOHz4Mo9GI2NhYuYtDRH6KNUNE5Jdyc3ORnp6ORYsWYcmSJYiIiMCqVavkLhYR+SH2GSIiv3PixAkMGTIEL7/8MsaOHYtWrVqhd+/eyM3NRbdu3eQuHhH5GdYMEZFfuXz5Mvr06YP09HQsXLjQun3IkCEwGo3YuHGjjKUjIn/EMERERESqxg7UREREpGoMQ0RERKRqDENERESkagxDREREpGoMQ0RERKRqDENERESkagxDREREpGoMQ0RERKRqDENERESkagxDREREpGoMQ0RERKRqDENERESkav8f45T07LzBbNoAAAAASUVORK5CYII=",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"filenames": {
|
|
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_22_2.png"
|
|
}
|
|
},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"theta from own sdg\n",
|
|
"[[4.31985268]\n",
|
|
" [2.72067593]]\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.34039341]\n",
|
|
" [2.74045887]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.31262618 4.15129596]\n",
|
|
"theta from own gd\n",
|
|
"[[4.340226 ]\n",
|
|
" [2.74060714]]\n",
|
|
"theta from own sdg with momentum\n",
|
|
"[[4.30982672]\n",
|
|
" [2.69332574]]\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.0009282 ]\n",
|
|
" [2.99447213]\n",
|
|
" [4.00526145]]\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.99998409]\n",
|
|
" [2.99993515]\n",
|
|
" [4.00003694]]\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.00011851]\n",
|
|
" [2.99937234]\n",
|
|
" [4.00068042]]\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 0x125606520>]"
|
|
]
|
|
},
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGdCAYAAACyzRGfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABPqUlEQVR4nO3deXiU1eH28e8zk52sELIS9l1W2RQUURFFUVHcbUVr1bTRVm1rtfXVbr9SrbW0Noh1X+pSUQStoiyCKKvsyI6sCQkkZDLZl5nn/WMgggISSObMTO7Pdc0FzDxJbtKUuT3nPOdYtm3biIiIiPiJw3QAERERaVlUPkRERMSvVD5ERETEr1Q+RERExK9UPkRERMSvVD5ERETEr1Q+RERExK9UPkRERMSvwkwH+Dav10t+fj5xcXFYlmU6joiIiJwE27YpKysjIyMDh+PEYxsBVz7y8/PJysoyHUNEREROwZ49e2jXrt0Jrwm48hEXFwf4wsfHxxtOIyIiIifD7XaTlZXV8D5+IgFXPg5PtcTHx6t8iIiIBJmTWTKhBaciIiLiVyofIiIi4lcqHyIiIuJXKh8iIiLiVyofIiIi4lcqHyIiIuJXKh8iIiLiVyofIiIi4lcBt8mYiIiINBOvB3YtgvJCiE2FDsPB4fR7jEaNfEyaNIkhQ4YQFxdHSkoK48ePZ/PmzUddM2rUKCzLOuqRnZ3dpKFFRETk5E1ZPYWpc+6FyX3g5XHwzu2+Xyf3Yeqce5myeopf8zSqfCxYsICcnByWLFnC7NmzqaurY8yYMVRUVBx13R133MG+ffsaHo8//niThhYREZGT5yjaQm7eXKY6yo96fqqjgty8uTiKtvg1T6OmXWbNmnXUn1966SVSUlJYsWIFI0eObHg+JiaGtLS0pkkoIiIip87rIXvtx+AoJzcpEYBsl5upifHkJiWQU1JKdvEncIHHb1Mwp7XgtLS0FIDWrVsf9fx//vMfkpOT6dOnDw899BCVlZXH/Rw1NTW43e6jHs2hoLSaf8zZyl8+2tQsn19ERCQg7VoE7nyyXW6yS1zkJiUyoGMWuUmJ5JS4yHaVgjvPd52fnPKCU6/Xy7333suIESPo06dPw/M33XQTHTp0ICMjg7Vr1/LrX/+azZs38+677x7z80yaNInf//73pxrjpO0vq+bvc7YQHe7kZxd2JSZCa21FRKQFKC9s+G2P2joAPJZFuG2T7XIf87rmdsrvwDk5Oaxfv57PP//8qOfvvPPOht/37duX9PR0LrzwQrZv306XLl2+83keeugh7r///oY/u91usrKyTjXWcfXNTKB96xh2H6xk3qb9jOuX0eRfQ0REJODEpjb89h9JCQA4bJs6y2JqYvw3BeSI65rbKU273H333XzwwQd8+umntGvX7oTXDhs2DIBt27Yd8/XIyEji4+OPejQHy7K4rF86AB+s2dcsX0NERCTgdBgO8Rk8mZTIzogIAKbn7SPn0BTM1MQEiM/0XecnjSoftm1z9913M336dObNm0enTp2+92NWr14NQHp6+ikFbErjDpWPTzfvp7ym3nAaERERP3A4mdrvYl5M9P3Hfd/qGjrX1ZPtcpNTUkpuUgJT+43x634fjSofOTk5vPbaa7z++uvExcVRUFBAQUEBVVVVAGzfvp0//vGPrFixgp07dzJz5kxuueUWRo4cSb9+/ZrlL9AYvdPj6Zzcipp6L3M2+G9uS0RExCRvcneS6r0AXFH+zfYY2d5YcjIvxJvc3a95GrXm4+mnnwZ8G4kd6cUXX+TWW28lIiKCOXPmMHnyZCoqKsjKymLChAk8/PDDTRb4dFiWxbh+6fxz3jY+WLuP8QMzTUcSERFpdiMiMnk6zEG4bXPG4L9A6+iGHU6zDexw2qjyYdv2CV/PyspiwYIFpxWouV3WL4N/ztvGZ1sOUFpVR0J0uOlIIiIizeq/y6cCcEZVDH1G/gAsy2ieFnewXI+0OLqlxFLr8TJbUy8iIhLi6uoq+cyzG4De8RdhGS4e0ALLB9Bwm+0Ha/MNJxEREWle85b8C5fTQVK9l3Hn/tx0HKCFlo/Dt9x+vrWIkopaw2lERESaz/St0wHoUZVKn6y2htP4tMjy0TUllp5pcdR7bT7ZUGA6joiISLNwlexgqaMMgB7pNwXElAu00PIBcHn/w1Mv2nBMRERC04xFf6XesuhYA1ecc73pOA1abPk4vOHYou3FFJfXGE4jIiLS9N4v+AKAzOqedE+NM5zmGy22fHRo04q+mQl4vDYfrdfUi4iIhJZt2z9hc5iXMNumV5ds03GO0mLLB3wz+vH+Gt31IiIioeWdFVMA6FkRybihwwynOVrLLh+H1n0s23mQgtJqw2lERESaRn1dNbPKfQe6JnjPpkvbWMOJjtaiy0dmYjSDOyRh29rzQ0REQsfiVf+myGmR4PEy4Iy7TMf5jhZdPgCuGOAb/dDUi4iIhIrpm94GoLO7DZef2dVwmu9q8eVjbJ90HBas2VvKruKK7/8AERGRAOYu3cMCbwkAUWGXk5kYbTjRd7X48tE2LpIRXZMBjX6IiEjwm7X0b9RaFu1rbEYMnGA6zjG1+PIB32w49v4abTgmIiLB7b29vtPlW7s7c1n/TMNpjk3lA7j4jDQinA42F5axuaDMdBwREZFTsmPnfNY563HaNtHxPyA5NtJ0pGNS+QASosM5r4fvsB1NvYiISLB6f2UuAD0qIxh95tmG0xyfyschh6deZq7Jx7Ztw2lEREQax1Nfy0zXRgAs90AuPiPNcKLjU/k4ZHSvFKLDnew+WMmavaWm44iIiDTKsjUvUOi0iPN4SUi7hYTocNORjkvl45CYiDAu6p0KaOpFRESCz8xNbwHQpSyJcQO7GU5zYiofRzg89fLB2nw8Xk29iIhIcCgv28ec2gMAuMou4MJeKYYTnZjKxxFGdk8mPiqMQncNS3cUm44jIiJyUmYvfZJqh0VmrU3HTlcSExFmOtIJqXwcITLMyaV9fSfdzlytqRcREQkO7+2dB0Db0g6MP7Od4TTfT+XjW64c4NuQ5cN1+6ip9xhOIyIicmJ79nzBSqsWh22TX30lI7u3NR3pe6l8fMuwTq1Ji4/CXV3P/M0HTMcRERE5oZlf/guAHlXhnHXG2YQ7A/+tPfAT+pnDYTWcdDtjdZ7hNCIiIsfn9dQzs2Q9AJarH+MHBuZ26t+m8nEMVxy662XOxv2UVdcZTiMiInJsK9a9Qr4TWnm9FDKBQe2TTEc6KSofx3BGRjxd2raitt7LrPUFpuOIiIgc04wNrwPQrSyBsQO743BYhhOdHJWPY7Asi/GHFp7O1IZjIiISgCrL9/NJje8/kItd53LloSUDwUDl4zgOr/v4YlsR+8uqDacRERE52pxlk6lyWKTXevHEjaVnWrzpSCdN5eM4OrRpxcD2iXht+GDNPtNxREREjjJzz2wAUt3tuXJg4O/tcSSVjxO48tDC0xmaehERkQCSn/8lS/GNym8rGdtwo0SwUPk4gcv6ZeB0WKzZ42JHUYXpOCIiIgC8v/wfAPSodNKu3WDaJcUYTtQ4Kh8n0DYukhFdkwHt+SEiIoHB9nqZWbwagLDSMxp25g4mKh/fY/yhhafvrcrDtnXSrYiImLV6/evsdkK018tXZeMaziQLJiof3+PiM9KIDneys7iS1XtcpuOIiEgLN+OrVwDoXh7PsO7daN0qwnCixlP5+B6tIsMYc0Yq4Bv9EBERMaW6qoSPq303QZS6hnNVkGyn/m0qHyfh8P+476/dR53HaziNiIi0VPOWTabcYZFa52Vn/QVc2CvFdKRTovJxEs7pmkxybCQHK2r5bItOuhURETNm7pwFQIY7k0v7ZhEV7jSc6NSofJyEMKej4R7q6Zp6ERERAwoL17LY9m37sN11SdCcYHssKh8n6fDUy+wNhbh10q2IiPjZB8v+jtey6FblwI7uz7BOrU1HOmUqHyepT2Y8XVNiqdFJtyIi4me218uMAysAiCztxZUDM4PmBNtjUfk4SZZlNYx+TF+pqRcREfGf9RvfYYfTJtJrs650XNDe5XKYykcjHF73sWRHMfmuKsNpRESkpZix7gUAelS0okNaB7qnxhlOdHpUPhohq3UMQzu1xrZhpg6bExERP6itKeOjqj0AlLnOCvpRD1D5aLQjp1603bqIiDS3+cv+gdthkVzvZUPFBUF3gu2xqHw00qV904kIc7C5sIwN+9ym44iISIibseN/AGS50zm7axop8VGGE50+lY9GSogOZ/ShHeXe1cJTERFpRkUHNvKFtwyAna4xXH1m8E+5gMrHKZlwZjsAZqzO03brIiLSbP637Ek8lkWXaotiux8Xn5FmOlKTUPk4BSO7t6VNqwiKymtZuFXbrYuISNOzvV7e278MgJjSnoztm05MRJjhVE1D5eMUhDsdXDnAN/T1zgpNvYiISNPbuGUm2xxeIrw261zjGkbdQ4HKxyk6PO82e2MhpZXabl1ERJrWzLXPA9CjIpr4+HZBvZ36t6l8nKIzMuLpmRZHbb2X/63bZzqOiIiEkLqaCj6s2AFAVelQrj4zuLdT/zaVj1NkWVbD6Mc7K/caTiMiIqHksxX/osRh0brey9qy0SGxsdiRVD5Ow/gBmTgsWLGrhJ1FFabjiIhIiJi5fSYAHdyp9G+fQue2sYYTNS2Vj9OQEh/Fud3aAvCuRj9ERKQJHDy4jc88pQDsdo3m6hBaaHqYysdpmjDI90Px7qo8vF5tty4iIqfno6V/o96y6FQN+fUDubxf8G+n/m0qH6dpTO9U4iLD2FtSxbKdB03HERGRIDejYDEAce5ujO6dQkJMuOFETa9R5WPSpEkMGTKEuLg4UlJSGD9+PJs3bz7qmurqanJycmjTpg2xsbFMmDCBwsLCJg0dSKLCnVzWLx2Ad1Zo6kVERE7dlm0fsdHhIcy2WR9ie3scqVHlY8GCBeTk5LBkyRJmz55NXV0dY8aMoaLim8WW9913H++//z5vv/02CxYsID8/n6uvvrrJgweSw1MvH67bR2VtveE0IiISrGauegaAnhVRhEdnMbJ7W8OJmkej9mmdNWvWUX9+6aWXSElJYcWKFYwcOZLS0lKef/55Xn/9dS644AIAXnzxRXr16sWSJUs466yzmi55ABncIYmObWLYWVzJR+sKGsqIiIjIyaqvq+aDsm3gtKh1DWb8gEzCnaG5OuK0/lalpb7VuK1b+3ZdW7FiBXV1dYwePbrhmp49e9K+fXsWL158zM9RU1OD2+0+6hFsLMvimkOF4+0VewynERGRYLRo5dMUOy0SPV7WlI3hmsGh+x+yp1w+vF4v9957LyNGjKBPnz4AFBQUEBERQWJi4lHXpqamUlBQcMzPM2nSJBISEhoeWVlZpxrJqKvPbIdlwZKvD7K7uNJ0HBERCTLvbXkXgE7uZHplptAzLd5wouZzyuUjJyeH9evX8+abb55WgIceeojS0tKGx549wTlykJEYzTldkwHteCoiIo1T6trJfE8JAHmuC7k2hEc94BTLx913380HH3zAp59+Srt233yD0tLSqK2txeVyHXV9YWEhaWlpx/xckZGRxMfHH/UIVoenXqat2Ks9P0RE5KTNWvokdZZFhxrYUzeEK/qH3t4eR2pU+bBtm7vvvpvp06czb948OnXqdNTrgwYNIjw8nLlz5zY8t3nzZnbv3s3ZZ5/dNIkD2MVnpBEXGUaeq4olXxebjiMiIkFiRv5CABJLu3BR71QSYyIMJ2pejSofOTk5vPbaa7z++uvExcVRUFBAQUEBVVVVACQkJHD77bdz//338+mnn7JixQpuu+02zj777JC90+VIUeFOxh1qq9O054eIiJyEr3fMZZ2jnjDbZoPrspBeaHpYo8rH008/TWlpKaNGjSI9Pb3h8dZbbzVc8/e//51x48YxYcIERo4cSVpaGu+++26TBw9Uh+fpPly/j7LqOsNpREQk0M1YOQWAHpWRhLfqxMhuobm3x5Eatc+HbX//OoaoqChyc3PJzc095VDBbGBWIl3atmL7gQr+t3YfNwxtbzqSiIgEKE99LR+UbganRb1rIFcNbIfTYZmO1exCc/cSg3x7fvhuF9bUi4iInMiSVf9mv9Mi3uNlbdklIX+Xy2EqH83g6jMzcVjw5a4Svj5QbjqOiIgEqBmb3wagc1lr+mSl06VtrOFE/qHy0QxS46M479B+/P/9UqMfIiLyXWXuPObV+e6MLHSd3zBq3hKofDST6wb7fojeWbmXeo/XcBoREQk0Hy/9GzUOi6xamz31Z3F5/3TTkfxG5aOZXNgrlTatIjhQVsP8zQdMxxERkQAzM28BAG1KO3Jp30ziosINJ/IflY9mEhHm4KqBmQC89WVwbhkvIiLNY9euhayyanHYNhtd47h+SMuZcgGVj2Z1+Idp3qb97C+rNpxGREQCxcyV/wKgZ2U4cYk9GdIxyXAi/1L5aEbdUuMY2D4Rj9fm3ZV5puOIiEgA8Hrqeb/kKwDs0gFcO7gdlhX6e3scSeWjmV1/aOHpf5fvOalN2kREJLQtX/MC+5wWsR4v68ov5ZozW8beHkdS+Whm4/pnEBPh5OuiCr7cVWI6joiIGDZz05sAdC1PZET3jqTERxlO5H8qH80sNjKMy/r6bp/673ItPBURackqygv4pGY/AEUlIxu2ZWhpVD784LpDC0//t24f5TX1htOIiIgps5f+nWqHRUatzX7H+ZzfM8V0JCNUPvxgcIckOrdtRWWthw/W5JuOIyIihszYMxeAFHd7rhmcRbizZb4Nt8y/tZ9ZltUwtPampl5ERFqkvXuX8KVVg2XbbCm5lGtb0Hbq36by4ScTzmxHmMNi9R4XmwrcpuOIiIifvf/lUwD0qAqjfbsz6ZrSMg6ROxaVDz9pGxfJ6F6pALy5TKMfIiItie31MvPgWgAcrr7cMKS94URmqXz40Q1DfUNs767cS3Wdx3AaERHxl5XrXmWvE2K8XrbXXsmlfVvOIXLHovLhR+d2a0tmYjTu6no+Wr/PdBwREfGTGRteBaBbWQKXDehJdITTcCKzVD78yOmwGs57eUNTLyIiLUJlZRGfVBcAUOI6hxuGtuwpF1D58LtrB7fDYcGyHQfZfqDcdBwREWlmc5dOpsJhkVbnxdn6cnqlx5uOZJzKh5+lJ0Rzfg/fpjJvLtttOI2IiDS3mbs/ASC9NIubhnYwnCYwqHwYcOOhIbd3VuZRU6+FpyIioapg3yqW2pUA7Km4jMv7ZxhOFBhUPgwY1aMtqfGRHKyoZfaGQtNxRESkmby//O/YlkX3Sidn9RlFq8gw05ECgsqHAWFOxzc7nmrhqYhISLK9XmYUrQIgwt2bG4e23B1Nv03lw5DrBmdhWfD5tiJ2F1eajiMiIk1szYY32eWEKK9NdeT19M1MMB0pYKh8GJLVOoZzu7UF4I3lWngqIhJqZq5/BYAe5bFcPaw/lmUZThQ4VD4MuunQwtO3v9xDbb3XcBoREWkq1VUlfFTlm1avKh/B+IGZhhMFFpUPgy7slUJqfCRF5bV8sqHAdBwREWki85f/k3KHg5Q6L9273UxcVLjpSAFF5cOgcKeD6w8tPP3PEk29iIiEivd2fAhApjuDm87qYjhN4FH5MOz6oe1xWLD462LteCoiEgL2F65nsV3h+0P41fRtp4Wm36byYVhmYjQX9PTtePrGUo1+iIgEuw+W/R2vZdG1yuKysy4zHScgqXwEgJuG+RaeTlu5l+o67XgqIhKsbK+X9/YvByC+vLd2ND0OlY8AcF73FDITo3FV1vHR+n2m44iIyCnasHk6O8JsIr02HTvdSUyEdjQ9FpWPAOB0WA0732nhqYhI8Jq26jkAelTEcOOIwYbTBC6VjwBx3eAswhwWX+4qYXNBmek4IiLSSLU1Zcyu9v0HZCLn0zMt3nCiwKXyESBS4qO4qHcqAK8v3WU4jYiINNb85U9R6nSQXO/l/LPuMh0noKl8BJCbh3UA4N2VeVTU1BtOIyIijTFtywwAOpanMa5/B8NpApvKRwAZ3qUNnZJbUVZTz4zV+abjiIjISSoq2sQyh29vj27pPyAq3Gk4UWBT+QggDofFzYduu31l8U5s2zacSERETsY7n/8Vj2XRudripguuMx0n4Kl8BJhrB2URFe5gU0EZK3aVmI4jIiIn4aMi394enb396JjcynCawKfyEWASYsK5sr/v9MNXl2jhqYhIoFu7YQbbw23CbZvRg+81HScoqHwEoB+e7Vuo9OG6fRSV1xhOIyIix+T1wI6FTPviMQDOqIzhkkGDDIcKDiofAahPZgIDshKp89i8tXyP6TgiInKEKaunMHXOvTC5D3Uvj2OB0wXALZXFPDvvPqasnmI0XzBQ+QhQtxwa/Xh96W48Xi08FREJFI6iLeTmzWWqo5zPY6I56HTSpt7D1rA6cvPm4ijaYjpiwFP5CFCX9k0nKSacPFcV8zbtNx1HREQAvB6y135MTomL3KREJiclAJBVX8fTSQnklJSSvfYT35SMHJfKR4CKCndy3RDfeS9aeCoiEiB2LQJ3PtkuN7e7Svk6IgKA1VFR5JS4yHaVgjvPd50cl8pHAPvBsA5YFny25QA7iypMxxERkfLCht/Geb0Nvw+3bbJd7mNeJ9+l8hHAslrHcH6PFECjHyIiASHWdwZXjQX/TvBNuThtmzrLYmpi/Heuk2NT+Qhwh2+7/e+Xe3Tei4iIaR2GQ3wGv2ybTKXTQazHw/KdexrWgExNTID4TN91clwqHwHuvG5tfee9VNczfVWe6TgiIi2bw8nTfS9ifqsYAH7qchMOZLvc5JSUkpuUwNR+Y8Chs11OROUjwDkcFj88yzf6ofNeRETMW+/eB0C8x8OEsvKG57O9seRkXog3ubupaEEjzHQA+X7XDG7HE59sZkthOYu3FzO8a7LpSCIiLZLt9bKvZAuEw6CaTsTc8oxvcWlsKnQYTrZGPE6KRj6CQHxUOBPObAfAS4t2mg0jItKCffblM2wN9xLptRk37HfQ6Vzoe43vVxWPk6byESQmDvdNvczZWMjekkrDaUREWqYX1j0PwIDKZEYPGGw4TfBS+QgSXVPiOKdrMl5bt92KiJjw1abprAyrwWnbnNX1PhwOy3SkoKXyEUQmDu8IwFvL91Bdp617RUT86ZklfwOgb3krbhh1meE0wa3R5eOzzz7j8ssvJyMjA8uyeO+99456/dZbb8WyrKMel1xySVPlbdEu6JlCu6RoXJV1zFit225FRPxlz54vWIALgO6tf0RspO7XOB2NLh8VFRX079+f3Nzc415zySWXsG/fvobHG2+8cVohxcfpsBpOu31p0S7ddisi4ifPfvYHvJZF74owbr7oZtNxgl6jq9vYsWMZO3bsCa+JjIwkLS3tlEPJ8V0/uD1Pzt7Cxn1ulu44yFmd25iOJCIS0oqKNvG/ujywLNIcV9C5bazpSEGvWdZ8zJ8/n5SUFHr06MFPfvITiouLj3ttTU0Nbrf7qIccX0LMN7fdvvjFDsNpRERC36vzH6bWsuhSbTH+vJ+YjhMSmrx8XHLJJbzyyivMnTuXxx57jAULFjB27Fg8nmMvkJw0aRIJCQkNj6ysrKaOFHJuG9ERgE82FLK7WLfdiog0l/Kyffy3bCMAyZXncl4PHRjXFJq8fNxwww1cccUV9O3bl/Hjx/PBBx+wfPly5s+ff8zrH3roIUpLSxsee/bsaepIIadrShzndW+LbcPLi3eajiMiErLeXvD/KHc4yKy1OW/Y/bq9tok0+622nTt3Jjk5mW3bth3z9cjISOLj4496yPf70TmdAN9tt2XVdYbTiIiEntqaMl7dvwSA1NIBTBjcwXCi0NHs5WPv3r0UFxeTnp7e3F+qRRnZLZmuKbGU19QzbcVe03FERELOBwt/zwGnRXK9l549f0FMhG6vbSqNLh/l5eWsXr2a1atXA7Bjxw5Wr17N7t27KS8v51e/+hVLlixh586dzJ07lyuvvJKuXbty8cUXN3X2Fs2yLG49tOnYS4t24vHqtlsRkabi9dTzwu6PAWhX0oWJ5/Q0nCi0NLp8fPnllwwcOJCBAwcCcP/99zNw4EAeeeQRnE4na9eu5YorrqB79+7cfvvtDBo0iIULFxIZGdnk4Vu6q8/MJCE6nF3FlczbtN90HBGRkPHpkifY5YRYj5ek1J+RkRhtOlJIafQY0qhRo064udXHH398WoHk5MVEhHHj0PZMXbCdFz7fwUW9tQpbROR02V4vz215CxzQrTSDiVcPMh0p5OhslyB3y9kdcDosFn9dzMZ92iNFROR0fbnmRdY76on02tSF/5gz2yeajhRyVD6CXEZiNGP7+HaTff5zbTomInK6nl/7bwB6uRO54ZxzsCzdXtvUVD5CwO2HbruduTqf/WXVhtOIiASvzVs+4Asqcdg2rqobubSv7tRsDiofIWBg+yQGdUii1uPllUW7TMcREQlaLyx/AoA+5TFcdvYlhDv1Ntkc9F0NEXec6xv9eG3pLipr6w2nEREJPnv3LmFWXREALtc4bhza3nCi0KXyESIu6p1GhzYxuCrreEebjomINNrLX/wBr2XRqzKMof0nkBAdbjpSyFL5CBFOh8WPRvhGP57/fIc2HRMRaYTioi1Mr9wNQHXR+Q3/nkrzUPkIIdcObkdCdDg7iyuZs7HQdBwRkaDx+sL/R43DonM1tOt4E1mtY0xHCmkqHyEkJiKMm4f55iifW/i14TQiIsGhsnw/b7q+AiC8eBh3nNfFcKLQp/IRYiYO70i402L5zhJW73GZjiMiEvCmffYwbodFRq2NlfhDBrZPMh0p5Kl8hJjU+Ciu6J8JwLMa/RAROaG6mgpeKVgEQJuDfbh9ZA/DiVoGlY8Q9ONDt91+tG4few5WGk4jIhK4/vf5Hyh0WrSp91Jo3aIzsvxE5SME9UqP59xuyXhtbbkuInI8Xk89L+76CICskk5MPLc3Toe2UvcHlY8QlX1owdSby3dzsKLWcBoRkcCzYNlkvnbatPJ62Vn1A64dlGU6Uouh8hGihndpQ5/MeKrrvLy6WFuui4gcyfZ6eX7T6wB0d6VxzdmDiI5wGk7Vcqh8hCjLsrhrpG/04+XFO6mq9RhOJCISOFaue5U1jjoivDbbS2/klrM7mI7Uoqh8hLCxfdLIah3NwYpapq3YYzqOiEjAeGHNVAB6lyVw0Zlnk9QqwnCilkXlI4SFOR3ccW5nAJ5duIN6j9dwIhER87Zs+4jP7HIcts3u4gncfo62Uvc3lY8Qd+2gLJJiwtl9sJJZXxWYjiMiYtyLSx8H4IzyaPr3PF9bqRug8hHioiOcTBzeEYBnFnyNbevAORFpufLzv+SjugMAHCgay50jOxtO1DKpfLQAt5zdkahwB+vySlm8vdh0HBERY175/Pd4LIselU7Ssi6jT2aC6UgtkspHC9C6VQTXD/bdv/70gu2G04iImFFycDvvVPg2XqwtPq/hjkDxP5WPFuLH53bG6bBYuLWItXtdpuOIiPjdGwseptph0bEGPPFXM6JrG9ORWiyVjxYiq3UMV/bPAGDKpxr9EJGWpbKyiNdd6wCILh7C3ed3x7K0lbopKh8tSPYo3xDjxxsK2La/zHAaERH/mb7g/1HqsEivsykOv5GLz0gzHalFU/loQbqnxjGmdyq2DU/P/9p0HBERv6irq+TlfQsBSD7Ym+xRPXHoADmjVD5amJ+e3xWAGavz2FtSaTiNiEjzm/X5/7HPaZFU7yWv/gdcOSDTdKQWT+WjhRmQlcjwLm2o99o8+5lGP0QktNleLy/seB+ADiUdufW8vkSE6a3PNP0v0ALlHBr9eHP5HorKawynERFpPguX/4NtTpsYr5cdVT/ghiHtTUcSVD5apOFd2tC/XQI19V5e+HyH6TgiIs3muY2vAdDDlcoNIwYTHeE0nEhA5aNFsiyrYe3Hq4t34a6uM5xIRKTprV73H1ZZtYTbNjvLbuCHZ3c0HUkOUflooS7qlUq3lFjKaup5ZdFO03FERJrc86tyAejtjufSISNJiA43nEgOU/looRwOq2Htx/Of76Cipt5wIhGRprN9+2zm22VYtk2B6yp+fG4n05HkCCofLdi4ful0bBNDSWUdry3ZZTqOiEiTeWHpXwA4oyKKkQMvIzk20nAiOZLKRwsW5nQ0rP14duHXVNV6DCcSETl9BftW8WFtIQDug2O567zOhhPJt6l8tHBXDcykXVI0ReW1vLFst+k4IiKn7ZXPf0e9ZdG90smgfteTGh9lOpJ8i8pHCxfudPCTQ2e+PPPZdqrrNPohIsGr1LWTaeW+wzPtknPJPq+L4URyLCofwjWD2pGeEEWhu4a3V+w1HUdE5JS9seBhqhwWHWuge/fbyUiMNh1JjkHlQ4gMc3LXSN+c6NT526mt9xpOJCLSeFWVB/lP8WoAWh08k5+e391sIDkulQ8B4Iah7UmOjSTPVcX0VRr9EJHg895nj+ByWqTWecnsmEP7NjGmI8lxqHwIAFHh34x+5H66nTqPRj9EJHjU11XzUv58ANIO9iLnwt5mA8kJqXxIg5vPak9ybAS7D1YyfWWe6TgiIift4y/+TL7TItHjJSXzZ3RuG2s6kpyAyoc0iIkI466RvpXhT326VaMfIhIUbK+X57+eAUCnkvbkjDnTcCL5PiofcpQfnNWB5NhI9hys4h3d+SIiQeCLL3PZ6vQS4/WSknYvXTTqEfBUPuQo0RFOsg/tBvjUvG2680VEAt6/178EQI/Stvx0zAizYeSkqHzId9w8rEPDnS/TNPohIgFs7VdvscpZS5htk578U631CBIqH/Id0RHOhl1Pcz/V6IeIBK5nlv8DgD5lcfzkkssMp5GTpfIhx3TzsPakxPlGP95escd0HBGR7/h6xzwW4gagfeKP6JjcynAiOVkqH3JMUeFHjH7M20ZNvc58EZHAMnXhn7Atiz4VEdx56U2m40gjqHzIcd04tD2p8ZHkl1bz1nKNfohI4CgsXMts734AurS6ng5tNOoRTFQ+5Liiwp3knN8VgH/N20ZVrUY/RCQwTJ3zW+oti+5VDu4cd7fpONJIKh9yQjcMaU9mYjT7y2p4dclO03FERCh17ebD2q8B6BN9mc5wCUIqH3JCEWEOfj66GwBPz99OWXWd4UQi0mJ5PbBjIS+8exuVDgfta2yyr3jYdCo5BSof8r2uHphJ5+RWlFTW8cLnO03HEZEWZsrqKUydcy9M7kP1K5fzHvsAuL2skhkrfsOU1VPMBpRGU/mQ7xXmdHDvRd0BeG7h17gqaw0nEpGWxFG0hdy8uUx1lDMzthUHnU4y6urZ56wnN28ujqItpiNKI6l8yEkZ1zednmlxlNXU88xnX5uOIyIthddD9tqPySlxkZuUyD+SEgDoUlfL1KQEckpKyV77iW9KRoJGo8vHZ599xuWXX05GRgaWZfHee+8d9bpt2zzyyCOkp6cTHR3N6NGj2bp1a1PlFUMcDotfjOkBwEtf7GR/WbXhRCLSIuxaBO58sl1uRpdX4HY6wbZZGBNDTomLbFcpuPN810nQaHT5qKiooH///uTm5h7z9ccff5x//vOfTJ06laVLl9KqVSsuvvhiqqv1ZhXsRvdKoX9WIlV1HqZ8ut10HBFpCcoLAai0LNZGRfqesyzCbZtsl/s710lwaHT5GDt2LH/605+46qqrvvOabdtMnjyZhx9+mCuvvJJ+/frxyiuvkJ+f/50REgk+lmXxq0OjH68v3c3ekkrDiUQk5MWmAvBcYjz7w8IACLdt6iyLqYnx37lOgkOTrvnYsWMHBQUFjB49uuG5hIQEhg0bxuLFi4/5MTU1Nbjd7qMeErhGdG3D8C5tqPV4eXK2FnmJSDPrMJw9cam8EO8rGmPLK1i5c0/DGpCpiQkQnwkdhhsOKo3RpOWjoKAAgNTUoxtoampqw2vfNmnSJBISEhoeWVlZTRlJmphlWfz6kp4ATF+Vx6YClUURaUYOJ9mJ0XgcFu3q6njsQDEA2S43OSWl5CYlMLXfGHA4DQeVxjB+t8tDDz1EaWlpw2PPHp0hEuj6ZyVyad80bBv+Omuz6TgiEsLmLc5ld5gXy7b5W0kd1hGvZXtjycm8EG9yd2P55NSENeUnS0tLA6CwsJD09PSG5wsLCxkwYMAxPyYyMpLIyMimjCF+8MsxPfj4q0LmbtrP8p0HGdKxtelIIhJi6uoqefKrqRAOwyra0vO+2bBnsW9xaWwqdBhOtkY8glKTjnx06tSJtLQ05s6d2/Cc2+1m6dKlnH322U35pcSwzm1juX6Ib4rsLx9twrZtw4lEJNS8/NF97AqHBI+Xa4Y/iSMsDDqdC32v8f2q4hG0Gl0+ysvLWb16NatXrwZ8i0xXr17N7t27sSyLe++9lz/96U/MnDmTdevWccstt5CRkcH48eObOLqY9vMLuxEV7mDFrhLmbNxvOo6IhJCDB7fxQtHnAJxZNZAxxxk9l+DU6PLx5ZdfMnDgQAYOHAjA/fffz8CBA3nkkUcAeOCBB7jnnnu48847GTJkCOXl5cyaNYuoqKimTS7GpcZH8aMRnQB4fNYmPF6NfohI03jyw59S5nTQsQZuufRvWJb1/R8kQcOyA2y83O12k5CQQGlpKfHx8d//AWJUaVUdIx//lNKqOh6f0I/rhuhuJRE5PZs2z+S6xb/Btiwurr2WJ+54xHQkOQmNef82freLBLeE6HDuPr8rAH+bvZmqWp2vICKnzvZ6+dMXv8O2LPqVRZN95X2mI0kzUPmQ03bL8A60S4qm0F3Dcwt16JyInLoPF/6BNc46Ir02XZN/RdeUONORpBmofMhpiwxz8sChjceeXrBdh86JyCmprCziye3TAOjryuLuy64wnEiai8qHNInL+6XTPyuRyloPk+foFGMRabznZuWw32mRWuflzDP+RNs47QEVqlQ+pElYlsVvL+0FwJvLdrO1sMxwIhEJJnl5y3il9CsA2pWew49HDTAbSJqVyoc0maGdWjOmdype27fxmIjIyfrr3PupcVj0qHRy6bm/ITpCG4iFMpUPaVIPju1JmMNi7qb9LNpWZDqOiASBZaueY65disO2iam9hQmD25uOJM1M5UOaVOe2sdw8zPcPx/99uBGvNh4TkROor6vmz6v+CUC/0iTuvPQWnA5tKBbqVD6kyf3swm7ERYbxVb6baSv3mo4jIgHs7bm/ZLvTJt7jJSrml5zTLdl0JPEDlQ9pcm1iI7nnQt/GY3/9eDPlNfWGE4lIIHKV7OBf+z4FoFNxLx644gLDicRfVD6kWdw6vBMd28RwoKyGKZ9uMx1HRALQUx//FLfDQfsam67dfkO3VG0o1lKofEiziAhz8JtDt94+9/kO9hysNJxIRALJ5i0fMK16DwAxBy/l5xf1MZxI/EnlQ5rNRb1TGdG1DbX1XiZ9tNF0HBEJELbXy6RFj+K1LPqWRXHZuT8hqVWE6VjiRyof0mwsy+L/jeuNw4IP1xWw5Oti05FEJAB88sX/scKqJdJrU1t7Jzef1cF0JPEzlQ9pVj3T4rlxqO/W2z9+sAGPbr0VadGqKg/yxNa3AOhdksHdl11JuFNvRS2N/heXZnf/Rd2Ji/Ldevv2l3tMxxERg1765G4KnBZt671EJDzAqB4ppiOJASof0uzaxEby8wu7Ab5bb0sr6wwnEhET9uWv4IWStQCkHBjGg5efZTiRmKLyIX4xcXhHuqbEUlxRy9/nbDEdR0QMeGLevVQ7LLpXOejb5xd0TYk1HUkMUfkQvwh3Ovj9FWcA8MrinWzc5zacSET8afnqF/jE48Jh29ilN/Cz0d1NRxKDVD7Eb0Z0TebSvml4bXh0xlfYthafirQE9XXVTFr5DwD6lSbywzE/JC4q3HAqMUnlQ/zqt5f1JircwbKdB5m5Jt90HBHxg3fmPcBWp5c4jxfC72X8gEzTkcQwlQ/xq8zEaO4+33fuy//9b6POfREJcaWunTyVPxeAzsU9eHD8RViWTq1t6VQ+xO9+fG5nOrSJYX9ZDU/N22o6jog0o399nEOpw0FWjU3nrr/ljIwE05EkAKh8iN9FhTt59PLeADy/cAdbC8sMJxKR5rB12yzertoFQLzrEu6/uK/hRBIoVD7EiAt6pnJhzxTqvTYPv7dei09FQozt9TJp4cN4LIs+5ZGMH/UzEmN0fov4qHyIMb+74gyiwh0s3XGQd1fmmY4jIk1o7qLHWO6oIcJrE2lnc93gLNORJICofIgxWa1j+NmhnU///OFGXJW1hhOJSFOorirh8S3/AaCPK51fT7gOh0OLTOUbKh9i1I/P6Uy3QzufPv7xZtNxRKQJvDjrHvY5LZLrvXTv/Ht6pcebjiQBRuVDjIoIc/DH8X0AeH3pblbuLjGcSEROR8G+VbzgWg1Ax9KzuPeSoWYDSUBS+RDjzurchglntgPgt9PXU+/xGk4kIqfqsdk/o9ph0a3KwXWj/0iryDDTkSQAqXxIQPjNpT1JiA5n4z43Ly3aaTqOiJyCL1e/xBzbhWXbtHdM5JK+6aYjSYBS+ZCA0CY2kgfH9gTgydlb2HOw0nAiEWkMT30tf17xJAAD3An84pps7WQqx6XyIQHj+sFZDO3Ymspaj/b+EAkyr3/yS7aG2cR6vAzv8UeyWseYjiQBTOVDAobDYfHnq/sS4XSwYMsBHTwnEiRKS3fz7wLf+S0DK3rz49GjzAaSgKfyIQGla0os91zgO3ju9+9v4GCF9v4QCUheD+xYCOum8eQ7P8DldNCu1ubOK54izKm3Fjkx/YRIwLnrvC70SI3jYEUtf/rfBtNxROQIU1ZPYeqce2FyH3h5HNtn3sUMx0EAMp0ZLCp512xACQoqHxJwIsIc/GVCXywL3l2Zx2dbDpiOJCKHOIq2kJs3l6mOcmzgsTZJeCyLTrW1LHXuw1G0xXRECQIqHxKQBrZPYuLZHQH4zfR1VNbWmw0kIuD1kL32Y3JKXOQmJfJg2zYsjo7GYdvsiIggp6SU7LWf+KZkRE5A5UMC1i8v7kFmYjR7S6r4q7ZeFzFv1yJw55PtcpNd4uLD2FYAeC2LnBIX2a5ScOf5rhM5AZUPCVixkWH8+eq+ALy0aCfLdhw0nEikhSsvbPit2+Fs+H24bZPtch/zOpFjUfmQgHZe97ZcPzgL24YHpq2hqlbDuSLGxKYCMD86mtcT4gAIs23qLIupifHfuU7keFQ+JOD9dlwv0hOi2FlcyROfaPpFxJgOwymIT+VXKW0A6F9dzaqdexrWgExNTID4TOgw3HBQCXQqHxLw4qPCG6ZfXvhiB1/u1PSLiAker4cfJkRS7XCQXF/PC/v2A5DtcpNTUkpuUgJT+42BI6ZkRI5F5UOCwvk9Urh2UDtsG341bS3VdZp+EfG3ye9OpCAMwrxenimuI+KI17K9seRkXog3ubuxfBI8dNaxBI2Hx/Xms60H2FFUwRMfb+bhcb1NRxJpMZatfpVXK9eBZTGmfjjdfznVd1dLeaFvjUeH4WRrxENOkkY+JGgkRIcz6dD0y/Nf7GDJ18WGE4m0DO7SPfx2xWN4LIuB5a349Q1P+aZWOp0Lfa/x/ariIY2g8iFB5YKeqQ13v/ziv2soq64zHUkkpNleL7+dfgMFYRbpdTY3Dn+W1nFRpmNJkFP5kKDz/y7vTVbraPJcVfz+fZ39ItKc3vzkfuZbbsJsm7MibmfswL6mI0kIUPmQoBMbGcaT1w3AsmDair3MWl9gOpJISNq+fTZ/2zcHgMGlXXng+nsMJ5JQofIhQWlIx9bcNbIL4Dv7ZX9ZteFEIqGlprqUX8z/BTUOi16VYdxx+b+JjdQ9CtI0VD4kaN13UTd6psVxsKKWh95Zh23bpiOJhIy/TL+B7WE2SfVeBqf/H0M7p5iOJCFE5UOCVmSYk8k3DCDC6WDupv28vmy36UgiIWHeoseZVrsXgB7lY7l33CWGE0moUfmQoNYzLZ5fXdwDgD9+sIGthWWGE4kEt4KC1Tyy6WUAznQl88vrHyUiTG8V0rT0EyVB7/ZzOnFut2Sq67zc88Yq7X4qcoo89bU88NHtlDoddKqGCwbl0iMtznQsCUEqHxL0HA6Lv13XnzatIthUUMZfPtpkOpJIUHrm/dtY5aglxuulk/NebhnRy3QkCVEqHxISUuKieOLa/gC8tGgn8zYVGk4kElxWrX2NZ0rXANDr4BAevfGHWJZlOJWEqiYvH7/73e+wLOuoR8+ePZv6y4h8x/k9U7htREcAfvn2Wva7dfutyMkoLd3NA1/+Ba9l0d8dwx1XPkHrVhHf/4Eip6hZRj7OOOMM9u3b1/D4/PPPm+PLiHzHg2N70is9noMVtdz/3zV4vLr9VuREbK+XR967kQKnRXqtl74d/8aIrsmmY0mIa5byERYWRlpaWsMjOVk/yOIfkWFOnrpxANHhTj7fVkTup9tMRxIJaG99ch/z8G2f3r76h9w3drjpSNICNEv52Lp1KxkZGXTu3Jmbb76Z3buPv/9CTU0Nbrf7qIfI6eiaEscfx/cBYPKcLSzaXmQ4kUhg2rb9E57YNxeAAQe78OjNP9NtteIXTf5TNmzYMF566SVmzZrF008/zY4dOzj33HMpKzv2/guTJk0iISGh4ZGVldXUkaQFumZQO64d1A6vDT97Y7W2Xxf5luqqEn4x/5e+7dMrwrjuolyyWseYjiUthGU3857ULpeLDh068OSTT3L77bd/5/Wamhpqamoa/ux2u8nKyqK0tJT4+PjmjCYhrqrWw/jcL9hcWMbZndvw2o+H4XRo9b4IwKP/uZh36/NJqvdyceJf+e2ES01HkiDndrtJSEg4qffvZh9fS0xMpHv37mzbduy598jISOLj4496iDSF6AgnuTefSUyEk8VfF/OPOVtMRxIJCB8vnMS79fkAnFE5jl9dqe3Txb+avXyUl5ezfft20tPTm/tLiXxH15RYJl3dF4CnPt3Ggi0HDCcSMatg3yr+sPU1AAa7Unj4h7/TOg/xuyb/ifvlL3/JggUL2LlzJ4sWLeKqq67C6XRy4403NvWXEjkpVw7I5Mah7bFt+Pmbq9hzsNJ0JBEj6uuq+cWHt+N2OuhcDTee/yyZidGmY0kL1OTlY+/evdx444306NGD6667jjZt2rBkyRLatm3b1F9K5KQ9enlv+rdLwFVZx12vrqCqVue/SMvz93dvYW1YHTFeLyNTHmZMv86mI0kL1ewLThurMQtWRBoj31XF5U99TnFFLVcPzORv1/XX9tES2rwe2LUIygv5In8lP903E69lcVHVcJ64cyoOLcCWJtSY9+8wP2USMS4jMZqnbhrID59fxrur8uiflcjE4R1NxxJpclNWT8FRtIXstR+DO59Sh4NHM9PwhoXRvsZBu0F9VDzEKK0ykhZleJdkHhrrO2vojx9sYPnOg4YTiTQ9R9EWcvPmMtVRjg08mtyawrAwEuo97I70ElO63XREaeFUPqTFuf2cTlzeP4N6r81PXltJvqvKdCSRpuP1kL32Y3JKXOQmJXJPSjJzW8XgsG1Kw5zklJSSvfYT35SMiCEqH9LiWJbFYxP60jMtjqLyGu545Usqa+tNxxJpGrsWgTufbJeba91lLGjl27XUa1nklLjIdpWCO893nYghKh/SIsVEhPHcxMG0aRXBV/lufvHfNXh1Aq6EgvJCAHaHhTG31TfbpYfbNtku93euEzFB5UNarHZJMTzzw0GEOy0+Wl/AZO2AKqEgNpUDTgd3pqVw0OkEfMWjzrKYmhh/1HUipqh8SIs2uGNr/nyVbwfUf87bxvtr8g0nEjk97qT2ZKemkBfuu5nxNlcpK3fuaVgDMjUxAeIzocNww0mlJdOtttLiXTs4i637y/n3Z1/zy7fX0L51DP2zEk3HEmm0mupSsqddxZbICAB+UOrm/pJSgENTLha5SQmQeSHZDqfBpNLSaeRDBPj1JT25oGcKNfVebn95ubZgl6Djqa/l569fwrrwOsJsm/MdXfh1fcxR12R7Y8nJvBBvcndDKUV8tMOpyCHlNfVcN3UxG/a56dK2Fe/8ZDiJMRGmY4l8L9vr5cHXxvChXUi4bXN12A08/IOHj9rhlNhU31SLRjykmTTm/VsjHyKHxEaG8eJtQ8hIiGL7gQrufHUFNfXaC0EC3xNvX8eHdiGWbTO69kJ+c9NvfS84nNDpXOh7je9XFQ8JECofIkdIjY/ixduGEhcZxrIdB/nl22t1C64EtBfez+aV6s0AjKzozx9ue1Jbp0vAU/kQ+ZYeaXFM/eEgwhwW76/J57GPN5mOJHJMMz/9HZOLPwfg7NIs/nDri0SFa3RDAp/Kh8gxjOiazGMT+gHwzIKvef7zHYYTiRxt4bIpPLprGrZlMdidxEM3vEXrVlqjJMFB5UPkOCYMasevLu4B+A6he2fFXsOJRHzWbniHX3yVS71l0a88irvHvU2nlDjTsUROmsqHyAn8dFQXbj+nEwAPvLOWORu0JbWYtWPnAnKWPEKVw0HPSie3j3qLQZ20W6kEF5UPkROwLIvfXtqLq8/MxOO1yXl9JUu/LjYdS1qo/YXruXNuDi6ng441cNOgV7jgjM6mY4k0msqHyPdwOCwem9CP0b18m5D9+OUvWZ9XajqWtDDu0j3c8cFNFIRZpNd6mdD1Ka4a2s90LJFTovIhchLCnQ7+ddOZDO3YmrKaem55YRmbC8pMx5IWorqqhLumXcHXYTat671clvp7br1glOlYIqdM5UPkJEWFO3nu1sH0a5fAwYpabn5uCdv2l5uOJaHG64EdC2HdNNixkPqaCu55/RLWh9XTyuvlktif8bPLJ5hOKXJatL26SCO5Kmu56dmlbNjnJiUukrfuOptOya1Mx5IgN2X1FBxFW8he+zG4facr28AjbdvyXmw0DtvmmrCbefjmB7EsbSImgUfbq4s0o8SYCF778TB6pMaxv6yGm55dooPo5LQ5iraQmzeXqY5vRtOeSkrgvdhoAM6sb6viISFD5UPkFLRuFcF/7hhG15RY9pVWc8O/VUDkNHg9ZK/9mJwSF7lJiUxNjOc/8bE8m5gAwKiKSl5wF2LZXsNBRZqGyofIKUqOjeT1Hw+jU3Ir8lxVXPfMYr4+oDUgcgp2LQJ3Ptkud0MB+Uub1gAMq6ziqf1FWO4833UiIUDlQ+Q0pMRH8eadZzWMgFz3zBLdBSONV+7bvM4Gor02HFqK57Btni088J3rRIKdyofIaUo9VEB6pcdTVF7DDf9erH1ApHFiU/EAj7VO4ok2SWBZOGwbr2XxTGL8UdeJhAKVD5EmkBwbyRt3DKN/uwRKKuu48dklrNxdYjqWBInqlF7cn5rCfxJ857MMr6xi9c49R6wBSYD4TOgw3HBSkaah8iHSRA7fBTO4QxJl1fXc/OxS5m/ebzqWBLji4u3c8sZo5sVEATCmvIJnCg9gwaE1IKXkJiUwtd8YcDjNhhVpIiofIk0oLiqcV24fyrndkqmq8/Djl7/k3ZU6DVeO7eudn3Pze1eyMdxDuNfmHNrxt5rIo67J9saSk3kh3uTuhlKKND1tMibSDGrrvTwwbQ3vrfZtFvWbS3ty58guhlNJIPlyzRvct+JPuJwOUuq8TOzwCLdcdL1vh9Ndi3yLS2NTfVMtGvGQINCY9+8wP2USaVEiwhw8ed0A2sZF8uzCHfz5w03sd9fwm0t74XBok6iW7sPPHuOR7a9S43TQqQayB0zl0qHn+l50OKHTuWYDijQzlQ+RZuJwWPz2st6kxEXxfx9u5LnPd5DnquLJ6wYQHaH/km2pnp3xE/5VshCvw+KMynDuu/AthnXvZjqWiF+pfIg0sztGdqZtXCQPTFvLR+sLyHMt5tlbBpMaH2U6mjSXY0ydeG2bP715NW/X7wDLYnB5PL8e/x49M9uaTivid1rzIeIny3ce5K5XV3Cwopa0+CiemziYPpkJpmNJEzrW4XAAtXEZXJMYyY4wDwAjKzry+x/8l+T4aFNRRZqcDpYTCUBDOrbmvZ+OoGtKLAXuaq6duphZ6wtMx5ImdKzD4dwOiysSbHaEeXDYNuPqzubJO99T8ZAWTeVDxI/at4nh3Z8Ob7gVN/u1Ffz14014vAE1ACmn4hiHw+1zOhmXmU5eeDjhXi+Ti6r4821TiAzTmh9p2VQ+RPwsPiqcF28dwm0jOgKQ++l2bn1xGQcras0Gk9NzjMPhxmRlUBIWRiuPhzf2FXJ+eRHW7sWmk4oYp/IhYkCY08Gjl5/BP24YQHS4k4Vbi7j8qc9Zu9dlOpqcqkOHvtUDFvgOh7MssG3eyyugR23dUdeJtGQqHyIGXTkgk+k5w+nYJoY8VxXXPL2YVxbvJMDWgcvJiE1lT5iT29JT+VdSIlgW1qEC8l5cq6OuE2npVD5EDOuZFs/Me87hot6p1Hq8PDLjK+54ZYWmYYKI7fXy3NppXJOZzuoo3/boo8srWKPD4USOSeVDJADER4Xz7x8O4pFxvYlwOpizsZCx//iMRduKTEeT71Fc/DV3vTCCf7jmUenw/ZP6w1I3fz9QrMPhRI5D5UMkQFiWxY/O6cT0nOF0aduKQncNNz+/lEkfbaSm3mM6nng9sGMhrJvm+9Xr4aOF/2DCe5ezOLycMNumc31rfpwyigfqY476UB0OJ3I0bTImEoAqa+v54wcbeWPZbgC6pcTy12v7MyAr0WywFuhYG4dVWxZPtk7mjUN7dbSrtbmu3X3cesmPsCxLh8NJi6SD5USCXExEGJOu7suoHm357fT1bN1fztVTvuCOcztz30XdiQrXG5m/HN44DEc52cDmiHAebNuGbRERAHSuCeOxS2fSs13WER+kw+FETkTlQySAXXxGGkM7tuYPH2xg+qo8nvnsa2ZvLGTSVX0Z1rmN6Xih79DGYTjKyU1KZFVkJMujo6izfCcTjysr58+10VgZGYaDigQXrfkQCXBJrSL4+/UDePaWwaTERfL1gQqu//cS7ntrNfvLqk3HC22HNg7rV11L6/p6FsVENxSPH7lKmVR0EMud57tORE6ayodIkLiodyqz7zuPm4a1x7Jg+qo8LnxiAS9+sYN6j9d0vOB1jIWkh63fOpufprblrvQUDoaF+TYOA8Jtm/tKSr/5HNo4TKRRtOBUJAit2ePi/81Yz9q9vjfAnmlxPDi2J+d1b+tb8Cjf63gn0BKfwd+6D+ezA1+xyyrHY1mE2Ta9a2pYGxVFuG1TZ1nklLjIdrl9HzPxA63xkBZPp9qKhLj+WYlM/+kI/nxVXxJjwtlUUMatLy7n5ueWsm5v6fd/AjnmCbS1wF3RdbxUvIyvHRV4LIvzKqq5zl3G2qgockpcrNTGYSKnTQtORYKU02Fx07D2XNo3jdxPt/Hyol0s2l7M5f/6nMv7Z3Df6G50bhtrOmZg+Patr1nDjlpICtC5to7fJbemzOm7k6hHTS0XpdyONyOfKflzySkpbRjp8P1qkZuUAJkXkq3baEUaRdMuIiFib0klT36yhemr87BtcFhwad90cs7vSq/0lvn/peNOrcQkMzWilnosdoSH8UnsN2evxHg8PHTQxeXlFTgnfsCU0nXHmZ7JZGq/MXiTu/PTAT/1499KJDA15v1b5UMkxGzId/Pk7M3M2bi/4bnRvVLIOb8rA9snGUzmf1Pn3Etu3tyj12cA/0xM4NmkBOI8noaRDgCHbbN4115iDv+zOOF56HuN7/faOEzkhLTJmEgL1jsjnucmDmFDvpvc+dv4cN0+5mzcz5yN+xmQlcjE4R24tG86kWEh+MZ5ZEFo1ZbsNbPAWdEwtTK+rIIH2rZhVXQUAGVOJ1FeL9UOR8NC0lcS4r4pKkeeQKuNw0SajEY+RELc9gPlPD1/OzNX51N76JbcNq0iuGFoFjcMaU9W65jv+QyB77jTK8DTifHMjYlhc2SE71bZQ3cDdayto2NdHfNbxTSMjExNjCc3KdG3vsMbC/eu0+iGyEnSyIeINOjSNpYnru3Pry/pyVvLd/Pakt0UuKvJ/XQ7uZ9uZ2jH1lx1ZiaX9kknISbcdNxT8u0t0AG2hofzpzZJrDw0ygGAZWHZNk8VHmBDZARTkhKPmpLRQlIR/9DIh0gLU+/xMntDIa8t9d0dc/hfgAingwt6pjDmjFTO75FCUqsIs0FPltcDk/sw9dCdK8Mrqyh2On0jHYdEeL3UOhyE2Tb1h/bo8GLhwCa7Nhwqi7/5fFpIKnJKAmLBaW5uLn/9618pKCigf//+PPXUUwwdOvR7P07lQ8R/9pVWMWN1PtNX5rG5sKzheYcFgzokcWGvVM7r3pYeqXE4HIG3eVlVrYdtyz6i75ybAbg+PZUNUZENr3eqraVHbR2zYlsdf2rlZ6thz1ItJBU5TcbLx1tvvcUtt9zC1KlTGTZsGJMnT+btt99m8+bNpKSknPBjVT5EzNiQ7+aj9b7FqRv3uY96LT4qjCEdWzOkU2uGdGxNr/Q4YiL8P2tbVF7D2r0ulu44yPIdB1mXV8pY+wv+GfEvAL6MiuRHaSnYlkW4bXOnq/RQ0Tj6bpepiQnkJiWQk3kh2aMn+/3vIRKKjJePYcOGMWTIEP71L98/CF6vl6ysLO655x4efPDBE36syoeIeXtLKpm3aT9zN+5n+c6DVNZ6jnrdsqBjm1b0So+jZ1o8XdrGkpkUTUZiFG1jI09ri/c6j5eC0mr2llSxt6SSrfvL2bjPzcZ9ZRSV13zn+ktjtzGl/hGAhlGNw3euDKmqZmh19VHFA9DUikgzMFo+amtriYmJYdq0aYwfP77h+YkTJ+JyuZgxY8YJP17lQySw1Hu8bNjnZtmOgyzbcZCVu13HLAGHRYQ5yEiIIiEmgvioMOKjwomPDiMyzMmRncS2obymnrLqOtxV9bir6ygur6WwrJrj/atkWdCpTauGUZhhnVrTLiEC6x99meqo8I1mHG965copUFmkqRWRZmL0bpeioiI8Hg+pqalHPZ+amsqmTZu+c31NTQ01Nd/8Q+Z2u79zjYiYE+Z00K9dIv3aJfLjczsDcKCshs0FZWwqcLNhn5tdxZXklVRRWFZNbb2XncWVUFx5yl8zIsxBZmI0mYnRdE2JpWdaHD3T4+meGnvM6Z6p/S4+tJnYCbZA7zLqlPOISNMyfqvtpEmT+P3vf286hog0Qtu4SNrGRXJOt+Sjnq+t91LoribfVYW7uh53VZ1vZKO6npr6b03dYBET6SQ+Kpy4QyMkiTHhZCZFk9wqslELXL3J3ckBsos/Br45WC/bGwuZF+JN7n46f10RaWLGp12ONfKRlZWlaRcRaTxtgS5iTGOmXRxN/cUjIiIYNGgQc+fObXjO6/Uyd+5czj777O9cHxkZSXx8/FEPEZFTcngL9L7X+H5V8RAJSM0y7XL//fczceJEBg8ezNChQ5k8eTIVFRXcdtttzfHlREREJIg0S/m4/vrrOXDgAI888ggFBQUMGDCAWbNmfWcRqoiIiLQ82l5dRERETpvRNR8iIiIiJ6LyISIiIn6l8iEiIiJ+pfIhIiIifqXyISIiIn6l8iEiIiJ+pfIhIiIifqXyISIiIn6l8iEiIiJ+1Szbq5+Owxuuut1uw0lERETkZB1+3z6ZjdMDrnyUlZUBkJWVZTiJiIiINFZZWRkJCQknvCbgznbxer3k5+cTFxeHZVmm4xjndrvJyspiz549OuumGen77B/6PvuPvtf+oe/zN2zbpqysjIyMDByOE6/qCLiRD4fDQbt27UzHCDjx8fEt/gfbH/R99g99n/1H32v/0PfZ5/tGPA7TglMRERHxK5UPERER8SuVjwAXGRnJo48+SmRkpOkoIU3fZ//Q99l/9L32D32fT03ALTgVERGR0KaRDxEREfErlQ8RERHxK5UPERER8SuVDxEREfErlY8gVFNTw4ABA7Asi9WrV5uOE1J27tzJ7bffTqdOnYiOjqZLly48+uij1NbWmo4WEnJzc+nYsSNRUVEMGzaMZcuWmY4UUiZNmsSQIUOIi4sjJSWF8ePHs3nzZtOxQt5f/vIXLMvi3nvvNR0laKh8BKEHHniAjIwM0zFC0qZNm/B6vTzzzDN89dVX/P3vf2fq1Kn85je/MR0t6L311lvcf//9PProo6xcuZL+/ftz8cUXs3//ftPRQsaCBQvIyclhyZIlzJ49m7q6OsaMGUNFRYXpaCFr+fLlPPPMM/Tr1890lOBiS1D58MMP7Z49e9pfffWVDdirVq0yHSnkPf7443anTp1Mxwh6Q4cOtXNychr+7PF47IyMDHvSpEkGU4W2/fv324C9YMEC01FCUllZmd2tWzd79uzZ9nnnnWf//Oc/Nx0paGjkI4gUFhZyxx138OqrrxITE2M6TotRWlpK69atTccIarW1taxYsYLRo0c3POdwOBg9ejSLFy82mCy0lZaWAujnt5nk5ORw2WWXHfVzLScn4A6Wk2OzbZtbb72V7OxsBg8ezM6dO01HahG2bdvGU089xRNPPGE6SlArKirC4/GQmpp61POpqals2rTJUKrQ5vV6uffeexkxYgR9+vQxHSfkvPnmm6xcuZLly5ebjhKUNPJh2IMPPohlWSd8bNq0iaeeeoqysjIeeugh05GD0sl+n4+Ul5fHJZdcwrXXXssdd9xhKLnIqcnJyWH9+vW8+eabpqOEnD179vDzn/+c//znP0RFRZmOE5S0vbphBw4coLi4+ITXdO7cmeuuu473338fy7Ianvd4PDidTm6++WZefvnl5o4a1E72+xwREQFAfn4+o0aN4qyzzuKll17C4VBPPx21tbXExMQwbdo0xo8f3/D8xIkTcblczJgxw1y4EHT33XczY8YMPvvsMzp16mQ6Tsh57733uOqqq3A6nQ3PeTweLMvC4XBQU1Nz1GvyXSofQWL37t243e6GP+fn53PxxRczbdo0hg0bRrt27QymCy15eXmcf/75DBo0iNdee03/iDSRYcOGMXToUJ566inANy3Qvn177r77bh588EHD6UKDbdvcc889TJ8+nfnz59OtWzfTkUJSWVkZu3btOuq52267jZ49e/LrX/9a01wnQWs+gkT79u2P+nNsbCwAXbp0UfFoQnl5eYwaNYoOHTrwxBNPcODAgYbX0tLSDCYLfvfffz8TJ05k8ODBDB06lMmTJ1NRUcFtt91mOlrIyMnJ4fXXX2fGjBnExcVRUFAAQEJCAtHR0YbThY64uLjvFIxWrVrRpk0bFY+TpPIhcoTZs2ezbds2tm3b9p1Sp0HC03P99ddz4MABHnnkEQoKChgwYACzZs36ziJUOXVPP/00AKNGjTrq+RdffJFbb73V/4FEjkPTLiIiIuJXWkUnIiIifqXyISIiIn6l8iEiIiJ+pfIhIiIifqXyISIiIn6l8iEiIiJ+pfIhIiIifqXyISIiIn6l8iEiIiJ+pfIhIiIifqXyISIiIn6l8iEiIiJ+9f8BYGdCfJk4eWcAAAAASUVORK5CYII=",
|
|
"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 0x1253cc610>"
|
|
]
|
|
},
|
|
"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
|
|
} |