Files
FYS-STK4155/doc/LectureNotes/_build/jupyter_execute/exercisesweek41.ipynb
T
Morten Hjorth-Jensen 620d191340 update jupyter-book
2024-11-03 14:50:52 +01:00

1414 lines
202 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",
"[[3.7056279 ]\n",
" [3.11632514]]\n",
"Eigenvalues of Hessian Matrix:[0.27378241 4.9133261 ]\n",
"theta from own gd\n",
"[[3.7056279 ]\n",
" [3.11632514]]\n",
"theta from own sdg\n",
"[[3.62227539]\n",
" [3.09214577]]\n"
]
},
{
"data": {
"image/png": "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zHmFISIiIsWRdQdqIiIiImdjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjR3B4Mbdy4EYMGDUJMTAwkSUJWVpZx3c2bN/Hqq6+ibdu2CA4ORkxMDJ544gmcOnXKfQUmIiIir+L2YKikpATt27fH3LlzK627du0adu7ciTfffBM7d+5EZmYmDh06hMGDB7uhpEREROSNJCGEcHchDCRJwrJly5Cammpxmx07dqBLly44fvw4GjVqZNNxi4uLERoaiqKiIoSEhDiotERERORMrnp++zntyE5SVFQESZJQr149i9uUlpaitLTU+Lq4uNgFJSMiIiJP5PZmMntcv34dr776KoYPH15lhJieno7Q0FDjj0qlcmEpiYiIyJN4TDB08+ZNDBs2DEIIfPbZZ1VuO3nyZBQVFRl/8vPzXVRKIiIi8jQe0UxmCISOHz+O9evXW203DAgIQEBAgItKR0RERJ5M9sGQIRDKzc1FdnY2wsPD3V0kIiIi8iJuD4auXr2KI0eOGF/n5eVh9+7dCAsLQ3R0NIYOHYqdO3dixYoV0Gq1OHPmDAAgLCwM/v7+7io2EREReQm3p9bn5OSgd+/elZaPGjUKb7/9Npo2bWp2v+zsbCQnJ9t0DqbWExEReR7FpNYnJyejqnhMRsMgERERkRfymGwyIiIiImdgMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkVz+wjUREREpHBaLbBpE3D6NBAdDfTsCfj6uuz0DIaIiIjIfTIzgRdfBE6evL0sLg6YMwdISXFJERgMERERkXtkZgJDhwIV5yEtKNAv//prlxSDfYaIiIjI9bRafY2Q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9lx348aNBYBKP1OmTBFCCHHt2jVx3333iYYNG4patWqJxo0bi3HjxsnqC8PAnutOS0szbhsZGSnuv/9+sXPnTpPjeeP9FkKIgwcPCgBizZo1lY7lKffbkDpd8cdwraNGjRK9evWqtE+HDh2Ev7+/aNasmViwYEGl41b1XsqBvdfdq1evKrcXQj/EQHR0tPD39xexsbHikUceEUeOHHHthVlh73V/8MEHIj4+XgQGBoqwsDCRnJws1q9fX+m43na/hdCniwcFBYnPP//c7DE94X6bu2YAJr+z7nqGS7cKSERERKRIHtVniIiIiMjRGAwRERGRojEYIiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiKPtHjxYgQFBeH06dPGZWPGjEG7du1QVFTkxpIRkafh3GRE5JGEEOjQoQPuuecefPzxx5gyZQq+/PJLbN26FbGxse4uHhF5ED93F4CIqDokScJ7772HoUOHIioqCh9//DE2bdrEQIiI7MaaISLyaB07dsT+/fuxZs0a9OrVy93FISIPxD5DROSxVq1ahYMHD0Kr1SIyMtLdxSEiD8WaISLySDt37kRycjLmz5+PjIwMhISE4LvvvnN3sYjIA7HPEBF5nGPHjmHgwIH4xz/+geHDh6NZs2bo1q0bdu7ciY4dO7q7eETkYVgzREQe5eLFi+jevTuSk5Mxb9484/KBAwdCq9Vi1apVbiwdEXkiBkNERESkaOxATURERIrGYIiIiIgUjcEQERERKRqDISIiIlI0BkNERESkaAyGiIiISNEYDBEREZGiMRgiIiIiRWMwRERERIrGYIiIiIgUjcEQERERKRqDISIiIlK0/wcaREHz3DxqYQAAAABJRU5ErkJggg==",
"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",
"[[4.39586211]\n",
" [2.54142449]]\n",
"Eigenvalues of Hessian Matrix:[0.29253829 4.61759155]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"theta from own gd\n",
"[[4.39586211]\n",
" [2.54142449]]\n"
]
},
{
"data": {
"image/png": "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69aulYuP9209LmMYIiIiIv8aMsQ8akyS7D8uSYBGAwwa5JfqMAwRERGRf4WGmofPA7UDkeX7RYv8Nt8QwxARERH537hxwOrVQGKi7fakJPN2P84zxEkXiYiIKDDGjQPGjOEM1ERERKRioaGAVhvQKvA2GREREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakal+MgIiKqL6Mx4OtrkecYhoiIiOojKwt48EHg2LE/tyUlAa+95tnK6wxWfsfbZERERJ7KygLGj7cNQgBQWGjenpXl/v5SUgCdDpg0yfxvSor7+yG3MAwRERF5wmg0twgJUfsxy7ZZs8zlXOHtYEUu420yIiIiT2Rn1w4uNQkBFBQABoP5Nlddt72cBStJMgerMWN4y8wHGIaIiIg8ceKEa+UmTADOnv3ze3v9iVwNVtnZgFbrUXXJMd4mIyIi8kTr1q6VqxmEAPu3vVwNVq6WI7cwDBEREXliyBBzK48kufc8e/2JXA1WrpYjtzAMEREReSI01Hy7C/AsEFluewHOg5UkARqNuRx5HcMQERGRp8aNA1avBhITbbfHxLj2fMttr7qCleX7RYvYedpHGIaIiIjqY9w44MgRQK8Hli83/7typWvPrXnby1GwSkoyb/dkAkdyiSSEvXF8waW0tBTR0dEoKSlBVFRUoKtDRETBzmg0T5ZYWGh/uLwkmUNOfr79YfacgRqA/67fHFpPRETkbZbbXuPHm4NPzUDk7LZXaCiHz/sZb5MRERH5Am972Wc0mieiXLHC/K+rM3T7EFuGiIiIfGXcOPOs0bztZebtRW29JOAtQ5s2bcLo0aORkJAASZKwdu1am8eFEJg7dy5at26Nhg0bYvjw4cjLywtMZYmIiNxlue01caL5XzUHIZmuvRbwMFRRUYEePXpg8eLFdh9/8cUX8e9//xtvvfUWtm/fjsaNG2PEiBG4ePGin2tKREREHvH2orZeFvDbZCNHjsTIkSPtPiaEwKJFi/Dkk09izJgxAIAPPvgArVq1wtq1a3HHHXf4s6pERETkCZmvvRbwlqG65Ofno6ioCMOHD7dui46ORv/+/bF161aHz6usrERpaanNFxEREQWIzNdek3UYKioqAgC0atXKZnurVq2sj9mTkZGB6Oho65dG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Vqww/6vWDsIMmERE5AecZ8gX6jNBIOfUqY3ruRERqRLXJvMi2a1N5ggnbXSMM1ATEakOw5AXKSIMGY1ASorjoeSSZG4hys9nCCAiIlXgDNRqwzl1iIiIAoILtcqFGubU4a0uIiKSIYYhuQj2OXXYMZyIiGSKt8kAeQxlD+Y5dbjYKhERyRjDUFaWueOyTgdMmmT+NyXF/xfoYJ1Th4utEhGRzKk7DMmtxcJbkzbKCTuGExGRzKm3z5CzFgtJMrdYjBnj39aYcePMrxksHY3V0DGciIgUTb1hyJ0WC63Wb9UCYA4+/n5NXwn2juFERKR46r1NxhYL/wjmjuFERBQU1BuG2GLhH8HaMZyIiIKGesMQWyz8Jxg7hhMRUdBQb58hS4vF+PHm4FOzIzVbLLwv2DqGExFR0FBvGAL+bLGwNzPyokVssfC2YOoYTkREQUPdYQhgiwUREZHKMQwBbLEgIiJSMfV2oCYiIiICwxARERGpHMMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREama7MNQRkYG+vbti6ZNmyIuLg5jx45Fbm5uoKtFREREQUL2YWjjxo247777sG3bNnz//feoqqrC9ddfj4qKikBXjYiIiIKAJIQQga6EO06dOoW4uDhs3LgR11xzjUvPKS0tRXR0NEpKShAVFeXjGhIREZE3+Ov6HeazPftISUkJACAmJsZhmcrKSlRWVlq/Ly0t9Xm9iIiISJlkf5usJpPJhFmzZuHqq69G165dHZbLyMhAdHS09Uuj0fixlkRERKQkirpNdu+99+Lrr7/G5s2bkZSU5LCcvZYhjUbD22REREQKwttkV7j//vvx5ZdfYtOmTXUGIQCIiIhARESEn2pGRERESib7MCSEwAMPPIA1a9bAYDAgNTU10FUiIiKiICL7MHTfffdh+fLlWLduHZo2bYqioiIAQHR0NBo2bBjg2hEREZHSyb7PkCRJdrcvW7YM06ZNc2kfHFpPRESkPOwzdJnMsxoREREpnKKG1hMRERF5G8MQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqRrDEBEREakawxARERGpGsMQERERqZpiwtDixYuRkpKCyMhI9O/fHzt27Ah0lYiIiCgIKCIMffrpp3jooYcwb9487Nq1Cz169MCIESNw8uTJQFeNiIiIFE4RYeiVV17BzJkzMX36dHTu3BlvvfUWGjVqhKVLlwa6akRERKRwsg9Dly5dws8//4zhw4dbt4WEhGD48OHYunVrAGtGREREwSAs0BVw5vTp0zAajWjVqpXN9latWiEnJ8fucyorK1FZWWn9vqSkBABQWlrqu4oSERGRV1mu20IIn76O7MOQJzIyMjB//vxa2zUaTQBqQ0RERPVx5swZREdH+2z/sg9DsbGxCA0NRXFxsc324uJixMfH233OnDlz8NBDD1m/P3/+PJKTk/H777/79GTKTWlpKTQaDQoKChAVFRXo6vgNj5vHrQY8bh63GpSUlKBNmzaIiYnx6evIPgyFh4ejd+/eWL9+PcaOHQsAMJlMWL9+Pe6//367z4mIiEBERESt7dHR0ar6IbKIioricasIj1tdeNzqotbjDgnxbRdn2YchAHjooYcwdepU9OnTB/369cOiRYtQUVGB6dOnB7pqREREpHCKCEO33347Tp06hblz56KoqAg9e/bEN998U6tTNREREZG7FBGGAOD+++93eFvMmYiICMybN8/urbNgxuPmcasBj5vHrQY8bt8etyR8PV6NiIiISMZkP+kiERERkS8xDBEREZGqMQwRERGRqjEMERERkaopMgwtXrwYKSkpiIyMRP/+/bFjx446y69atQrp6emIjIxEt27d8NVXX9k8LoTA3Llz0bp1azRs2BDDhw9HXl6eLw/BI+4c9zvvvIMhQ4agefPmaN68OYYPH16r/LRp0yBJks3XDTfc4OvDcJs7x52ZmVnrmCIjI23KBOP7rdVqax23JEkYNWqUtYwS3u9NmzZh9OjRSEhIgCRJWLt2rdPnGAwG9OrVCxEREWjfvj0yMzNrlXH3b4a/uXvcWVlZuO6669CyZUtERUVh4MCB+Pbbb23KPP3007Xe7/T0dB8ehfvcPW6DwWD357yoqMimXLC93/Z+dyVJQpcuXaxllPB+Z2RkoG/fvmjatCni4uIwduxY5ObmOn2eP67higtDn376KR566CHMmzcPu3btQo8ePTBixAicPHnSbvkff/wREydOxD333IPdu3dj7NixGDt2LPbu3Wst8+KLL+Lf//433nrrLWzfvh2NGzfGiBEjcPHiRX8dllPuHrfBYMDEiROh1+uxdetWaDQaXH/99SgsLLQpd8MNN+DEiRPWrxUrVvjjcFzm7nED5hlaax7T0aNHbR4Pxvc7KyvL5pj37t2L0NBQ3HbbbTbl5P5+V1RUoEePHli8eLFL5fPz8zFq1CjodDrs2bMHs2bNwowZM2yCgSc/Q/7m7nFv2rQJ1113Hb766iv8/PPP0Ol0GD16NHbv3m1TrkuXLjbv9+bNm31RfY+5e9wWubm5NscVFxdnfSwY3+/XXnvN5ngLCgoQExNT6/db7u/3xo0bcd9992Hbtm34/vvvUVVVheuvvx4VFRUOn+O3a7hQmH79+on77rvP+r3RaBQJCQkiIyPDbvkJEyaIUaNG2Wzr37+/+Mtf/iKEEMJkMon4+Hjx0ksvWR8/f/68iIiIECtWrPDBEXjG3eO+UnV1tWjatKl4//33rdumTp0qxowZ4+2qepW7x71s2TIRHR3tcH9qeb9fffVV0bRpU1FeXm7dpoT3uyYAYs2aNXWWefTRR0WXLl1stt1+++1ixIgR1u/rey79zZXjtqdz585i/vz51u/nzZsnevTo4b2K+Zgrx63X6wUAce7cOYdl1PB+r1mzRkiSJI4cOWLdprT3WwghTp48KQCIjRs3Oizjr2u4olqGLl26hJ9//hnDhw+3bgsJCcHw4cOxdetWu8/ZunWrTXkAGDFihLV8fn4+ioqKbMpER0ejf//+Dvfpb54c95UuXLiAqqqqWovdGQwGxMXFIS0tDffeey/OnDnj1brXh6fHXV5ejuTkZGg0GowZMwa//fab9TG1vN/vvfce7rjjDjRu3Nhmu5zfb084+/32xrlUApPJhLKyslq/33l5eUhISEDbtm0xefJk/P777wGqoXf17NkTrVu3xnXXXYctW7ZYt6vl/X7vvfcwfPhwJCcn22xX2vtdUlICAHUuwuqva7iiwtDp06dhNBprLcPRqlWrWveMLYqKiuosb/nXnX36myfHfaXHHnsMCQkJNj8wN9xwAz744AOsX78eCxYswMaNGzFy5EgYjUav1t9Tnhx3Wloali5dinXr1uGjjz6CyWTCoEGDcOzYMQDqeL937NiBvXv3YsaMGTbb5f5+e8LR73dpaSn++OMPr/zuKMHChQtRXl6OCRMmWLf1798fmZmZ+Oabb/Cf//wH+fn5GDJkCMrKygJY0/pp3bo13nrrLXz22Wf47LPPoNFooNVqsWvXLgDe+Vspd8ePH8fXX39d6/dbae+3yWTCrFmzcPXVV6Nr164Oy/nrGq6Y5TjIcy+88AI++eQTGAwGm87Ed9xxh/X/3bp1Q/fu3dGuXTsYDAYMGzYsEFWtt4EDB2LgwIHW7wcNGoROnTphyZIlePbZZwNYM/9577330K1bN/Tr189mezC+3wQsX74c8+fPx7p162z6zowcOdL6/+7du6N///5ITk7GypUrcc899wSiqvWWlpaGtLQ06/eDBg3CoUOH8Oqrr+LDDz8MYM385/3330ezZs0wduxYm+1Ke7/vu+8+7N27Vzb9mhTVMhQbG4vQ0FAUFxfbbC8uLkZ8fLzd58THx9dZ3vKvO/v0N0+O22LhwoV44YUX8N1336F79+51lm3bti1iY2Nx8ODBetfZG+pz3BYNGjTAVVddZT2mYH+/Kyoq8Mknn7j0x09u77cnHP1+R0VFoWHDhl75GZKzTz75BDNmzMDKlStr3Uq4UrNmzdCxY0dFv9/29OvXz3pMwf5+CyGwdOlSTJkyBeHh4XWWlfP7ff/99+PLL7+EXq9HUlJSnWX9dQ1XVBgKDw9H7969sX79eus2k8mE9evX27QG1DRw4ECb8gDw/fffW8unpqYiPj7epkxpaSm2b9/ucJ/+5slxA+Ye9s8++yy++eYb9OnTx+nrHDt2DGfOnEHr1q29Uu/68vS4azIajfj111+txxTM7zdgHoJaWVmJO++80+nryO399oSz329v/AzJ1YoVKzB9+nSsWLHCZgoFR8rLy3Ho0CFFv9/27Nmzx3pMwfx+A+bRWAcPHnTpw44c328hBO6//36sWbMGGzZsQGpqqtPn+O0a7lbXbxn45JNPREREhMjMzBT79u0T//d//yeaNWsmioqKhBBCTJkyRTz++OPW8lu2bBFhYWFi4cKFYv/+/WLevHmiQYMG4tdff7WWeeGFF0SzZs3EunXrxC+//CLGjBkjUlNTxR9//OH343PE3eN+4YUXRHh4uFi9erU4ceKE9ausrEwIIURZWZl4+OGHxdatW0V+fr744YcfRK9evUSHDh3ExYsXA3KM9rh73PPnzxfffvutOHTokPj555/FHXfcISIjI8Vvv/1mLROM77fF4MGDxe23315ru1Le77KyMrF7926xe/duAUC88sorYvfu3eLo0aNCCCEef/xxMWXKFGv5w4cPi0aNGolHHnlE7N+/XyxevFiEhoaKb775xlrG2bmUA3eP++OPPxZhYWFi8eLFNr/f58+ft5aZPXu2MBgMIj8/X2zZskUMHz5cxMbGipMnT/r9+Bxx97hfffVVsXbtWpGXlyd+/fVX8eCDD4qQkBDxww8/WMsE4/ttceedd4r+/fvb3acS3u97771XREdHC4PBYPNze+HCBWuZQF3DFReGhBDi9ddfF23atBHh4eGiX79+Ytu2bdbHhg4dKqZOnWpTfuXKlaJjx44iPDxcdOnSRfz3v/+1edxkMomnnnpKtGrVSkRERIhhw4aJ3NxcfxyKW9w57uTkZAGg1te8efOEEEJcuHBBXH/99aJly5aiQYMGIjk5WcycOVNWfzAs3DnuWbNmWcu2atVK3HjjjWLXrl02+wvG91sIIXJycgQA8d1339Xal1Leb8vQ6Su/LMc6depUMXTo0FrP6dmzpwgPDxdt27YVy5Ytq7Xfus6lHLh73EOHDq2zvBDmKQZat24twsPDRWJiorj99tvFwYMH/XtgTrh73AsWLBDt2rUTkZGRIiYmRmi1WrFhw4Za+w2291sI83Dxhg0birffftvuPpXwfts7ZgA2v7OBuoZLlytIREREpEqK6jNERERE5G0MQ0RERKRqDENERESkagxDREREpGoMQ0RERKRqDENERESkagxDREREpGoMQ0RERKRqDENERESkagxDREREpGoMQ0SkSCtWrEDDhg1x4sQJ67bp06eje/fuKCkpCWDNiEhpuDYZESmSEAI9e/bENddcg9dffx3z5s3D0qVLsW3bNiQmJga6ekSkIGGBrgARkSckScLzzz+P8ePHIz4+Hq+//jqys7MZhIjIbWwZIiJF69WrF3777Td89913GDp0aKCrQ0QKxD5DRKRY33zzDXJycmA0GtGqVatAV4eIFIotQ0SkSLt27YJWq8WSJUuQmZmJqKgorFq1KtDVIiIFYp8hIlKcI0eOYNSoUfjnP/+JiRMnom3bthg4cCB27dqFXr16Bbp6RKQwbBkiIkU5e/YsBg0aBK1Wi7feesu6fdSoUTAajfjmm28CWDsiUiKGISIiIlI1dqAmIiIiVWMYIiIiIlVjGCIiIiJVYxgiIiIiVWMYIiIiIlVjGCIiIiJVYxgiIiIiVWMYIiIiIlVjGCIiIiJVYxgiIiIiVWMYIiIiIlVjGCIiIiJV+38pDYjbv7sIxAAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {
"filenames": {
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_16_2.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.28360073 4.6466172 ]\n",
"0 [-12.76941488] [-15.71728253]\n",
"1 [-0.06385864] [0.05142606]\n",
"2 [-0.0599611] [0.04828733]\n",
"3 [-0.05630145] [0.04534017]\n",
"4 [-0.05286516] [0.04257289]\n",
"5 [-0.0496386] [0.0399745]\n",
"6 [-0.04660896] [0.03753471]\n",
"7 [-0.04376424] [0.03524382]\n",
"8 [-0.04109314] [0.03309276]\n",
"9 [-0.03858507] [0.03107298]\n",
"10 [-0.03623008] [0.02917648]\n",
"11 [-0.03401882] [0.02739573]\n",
"12 [-0.03194252] [0.02572366]\n",
"13 [-0.02999295] [0.02415365]\n",
"14 [-0.02816236] [0.02267946]\n",
"15 [-0.02644351] [0.02129525]\n",
"16 [-0.02482956] [0.01999552]\n",
"17 [-0.02331412] [0.01877511]\n",
"18 [-0.02189117] [0.0176292]\n",
"19 [-0.02055507] [0.01655322]\n",
"20 [-0.01930051] [0.01554291]\n",
"21 [-0.01812253] [0.01459427]\n",
"22 [-0.01701644] [0.01370353]\n",
"23 [-0.01597786] [0.01286715]\n",
"24 [-0.01500267] [0.01208182]\n",
"25 [-0.014087] [0.01134442]\n",
"26 [-0.01322722] [0.01065202]\n",
"27 [-0.01241991] [0.01000189]\n",
"28 [-0.01166188] [0.00939144]\n",
"29 [-0.01095011] [0.00881824]\n",
"theta from own gd\n",
"[[3.96374557]\n",
" [3.02919609]]\n",
"0 [-0.01028178] [0.00828003]\n",
"1 [-0.00965425] [0.00777467]\n",
"2 [-0.00887675] [0.00714854]\n",
"3 [-0.00810172] [0.0065244]\n",
"4 [-0.00737473] [0.00593895]\n",
"5 [-0.00670653] [0.00540084]\n",
"6 [-0.00609674] [0.00490977]\n",
"7 [-0.0055417] [0.00446279]\n",
"8 [-0.00503695] [0.00405631]\n",
"9 [-0.00457811] [0.0036868]\n",
"10 [-0.00416103] [0.00335092]\n",
"11 [-0.00378195] [0.00304564]\n",
"12 [-0.00343739] [0.00276817]\n",
"13 [-0.00312423] [0.00251598]\n",
"14 [-0.0028396] [0.00228676]\n",
"15 [-0.0025809] [0.00207843]\n",
"16 [-0.00234577] [0.00188907]\n",
"17 [-0.00213205] [0.00171697]\n",
"18 [-0.00193781] [0.00156054]\n",
"19 [-0.00176127] [0.00141837]\n",
"20 [-0.00160081] [0.00128915]\n",
"21 [-0.00145497] [0.0011717]\n",
"22 [-0.00132241] [0.00106495]\n",
"23 [-0.00120193] [0.00096793]\n",
"24 [-0.00109243] [0.00087975]\n",
"25 [-0.00099291] [0.0007996]\n",
"26 [-0.00090245] [0.00072675]\n",
"27 [-0.00082023] [0.00066054]\n",
"28 [-0.0007455] [0.00060036]\n",
"29 [-0.00067758] [0.00054567]\n",
"theta from own gd wth momentum\n",
"[[3.99782845]\n",
" [3.00174877]]\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.60911869]\n",
" [3.33987045]]\n",
"Eigenvalues of Hessian Matrix:[0.31385073 4.08833652]\n",
"0 [-17.89749468] [-19.42504764]\n",
"1 [-6.56419363e-15] [-6.5758826e-15]\n",
"2 [-4.99600361e-16] [-5.64393388e-16]\n",
"3 [-4.99600361e-16] [-5.64393388e-16]\n",
"4 [-4.99600361e-16] [-5.64393388e-16]\n",
"beta from own Newton code\n",
"[[3.60911869]\n",
" [3.33987045]]\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.41451936]\n",
" [2.55289042]]\n",
"Eigenvalues of Hessian Matrix:[0.33812981 4.19713213]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"theta from own gd\n",
"[[4.41451936]\n",
" [2.55289042]]\n"
]
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkMAAAHHCAYAAAC88FzIAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABW3UlEQVR4nO3deXwTdf4/8Ffa0hQKLRR60gClQMshIKcgSLNUEZEFEVFQBAS8D1bWA3cR/O36LV4rruKKF3gBIhRQ1xumtAgocqwXLVeBUig36QEtNPn8/ogJTZs0dzKTeT0fjzzaTj4z8/lkks47n1MjhBAgIiIiUqmwYGeAiIiIKJgYDBEREZGqMRgiIiIiVWMwRERERKrGYIiIiIhUjcEQERERqRqDISIiIlI1BkNERESkagyGiIiISNUYDBGRy6ZOnYoOHToEOxuylpeXB41Gg1WrVgU7K0TkIgZDRDK0dOlSaDQa6yMiIgJt27bF1KlTUVpaGuzsERGFlIhgZ4CIHPt//+//IS0tDdXV1di6dSuWLl2KTZs24ddff0VUVFSws0dEFBIYDBHJ2MiRI9GvXz8AwIwZM9CmTRs899xz+PTTTzFhwoQg546CqaqqCtHR0cHOBlFIYDMZkYIMHToUALB//37rtosXL+Lpp59G3759ERsbi+joaAwdOhSSJNnse/DgQWg0Grz44ot48803kZ6eDq1Wi/79+2Pbtm0NzrV27Vr06NEDUVFR6NGjB9asWWM3T1VVVZg9ezZ0Oh20Wi0yMjLw4osvQghhk06j0eDBBx/EJ598gm7duqFp06YYNGgQfvnlFwDA4sWL0alTJ0RFRSErKwsHDx50+nrMnz8fGo0G+/btw9SpU9GyZUvExsZi2rRpOH/+fIOyL126tMExNBoN5s+f3+CYe/bswR133IHY2FjEx8dj7ty5EEKgpKQEY8aMQUxMDJKSkvDSSy/ZzZvRaMRTTz2FpKQkREdH489//jNKSkoapPvhhx9w/fXXIzY2Fs2aNcOwYcPw/fff2y3n77//jkmTJqFVq1YYMmQIAKCsrAzTpk1DamoqtFotkpOTMWbMGJdePyIyY80QkYJYbnCtWrWybisvL8fbb7+NiRMnYubMmaioqMA777yDESNG4Mcff0Tv3r1tjrFs2TJUVFTgnnvugUajwfPPP49x48bhwIEDaNKkCQDgm2++wc0334xu3bohJycHp0+ftt5w6xJC4M9//jMkScL06dPRu3dvfP3113jsscdQWlqKl19+2SZ9QUEBPv30UzzwwAMAgJycHNx44414/PHH8frrr+P+++/H2bNn8fzzz+Ouu+7Chg0bXHpdJkyYgLS0NOTk5GDHjh14++23kZCQgOeee86dl9fGrbfeiq5du2LBggX473//i3/+85+Ii4vD4sWL8ac//QnPPfccPvroI/z1r39F//79cc0119js/+yzz0Kj0eCJJ57AiRMnsHDhQmRnZ2PXrl1o2rQpAGDDhg0YOXIk+vbti3nz5iEsLAxLlizBn/70JxQUFGDAgAE2x7zlllvQuXNn/N///Z812Lz55pvx22+/4aGHHkKHDh1w4sQJfPvttzh8+DA7uxO5ShCR7CxZskQAEN999504efKkKCkpEatWrRLx8fFCq9WKkpISa9ra2lpRU1Njs//Zs2dFYmKiuOuuu6zbiouLBQDRunVrcebMGev2devWCQDis88+s27r3bu3SE5OFufOnbNu++abbwQA0b59e+u2tWvXCgDin//8p835x48fLzQajdi3b591GwCh1WpFcXGxddvixYsFAJGUlCTKy8ut2+fMmSMA2KS1Z968eQKATTmFEOKmm24SrVu3blD2JUuWNDgGADFv3rwGx7z77rut22pra0VqaqrQaDRiwYIF1u1nz54VTZs2FVOmTLFukyRJABBt27a1KdPKlSsFAPHKK68IIYQwmUyic+fOYsSIEcJkMlnTnT9/XqSlpYlrr722QZ4mTpxok/ezZ88KAOKFF15o9HUiosaxmYxIxrKzsxEfHw+dTofx48cjOjoan376qU0NTXh4OCIjIwEAJpMJZ86cQW1tLfr164cdO3Y0OOatt95qU7NkaXo7cOAAAODYsWPYtWsXpkyZgtjYWGu6a6+9Ft26dbM51hdffIHw8HA8/PDDNttnz54NIQS+/PJLm+3Dhw+3qa0YOHAgAHPtRosWLRpst+TJmXvvvdfm76FDh+L06dMoLy93aX97ZsyYYf09PDwc/fr1gxAC06dPt25v2bIlMjIy7ObzzjvvtCnT+PHjkZycjC+++AIAsGvXLuzduxeTJk3C6dOncerUKZw6dQpVVVUYPnw48vPzYTKZGi1n06ZNERkZiby8PJw9e9bjshKpHZvJiGRs0aJF6NKlCwwG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LFu2DM888wzWrVtn03dm5MiR1t979uyJgQMHon379li5ciWmT58ejKx6LSMjAxkZGda/Bw8ejP379+Pll1/GBx98EMScBc57772Hli1bYuzYsTbblXa9H3jgAfz666+y6dekqJqhNm3aIDw8HMePH7fZfvz4cSQlJdndJykpqdH0lp/uHDPQPCm3xYsvvogFCxbgm2++Qc+ePRtN27FjR7Rp0wb79u3zOs++4E25LZo0aYIrr7zSWqZQv95VVVVYsWKFS//85Ha9PeHo8x0TE4OmTZv65D0kZytWrMCMGTOwcuXKBk0J9bVs2RJdunRR9PW2Z8CAAdYyhfr1FkLg3XffxeTJkxEZGdloWjlf7wcffBCff/45JElCampqo2kDdQ9XVDAUGRmJvn37Yv369dZtJpMJ69evt6kNqGvQoEE26QHg22+/taZPS0tDUlKSTZry8nL88MMPDo8ZaJ6UGzD3sP/HP/6Br776Cv369XN6niNHjuD06dNITk72Sb695Wm56zIajfjll1+sZQrl6w2Yh6DW1NTgjjvucHoeuV1vTzj7fPviPSRXy5cvx7Rp07B8+XKbKRQcqaysxP79+xV9ve3ZtWuXtUyhfL0B82isffv2ufRlR47XWwiBBx98EGvWrMGGDRuQlpbmdJ+A3cPd6votAytWrBBarVYsXbpU/P777+Luu+8WLVu2FGVlZUIIISZPniyefPJJa/rvv/9eREREiBdffFHs3r1bzJs3TzRp0kT88ssv1jQLFiwQLVu2FOvWrRM///yzGDNmjEhLSxMXLlwIePkccbfcCxYsEJGRkWLVqlXi2LFj1kdFRYUQQoiKigrx17/+VWzZskUUFxeL7777TvTp00d07txZVFdXB6WM9rhb7meeeUZ8/fXXYv/+/WL79u3itttuE1FRUeK3336zpgnF620xZMgQceuttzbYrpTrXVFRIXbu3Cl27twpAIh//etfYufOneLQoUNCCCGefPJJMXnyZGv6AwcOiGbNmonHHntM7N69WyxatEiEh4eLr776yprG2WspB+6W+6OPPhIRERFi0aJFNp/vc+fOWdPMnj1b5OXlieLiYvH999+L7Oxs0aZNG3HixImAl88Rd8v98ssvi7Vr14q9e/eKX375RTzyyCMiLCxMfPfdd9Y0oXi9Le644w4xcOBAu8dUwvW+7777RGxsrMjLy7N5354/f96aJlj3cMUFQ0II8eqrr4p27dqJyMhIMWDAALF161brc8OGDRNTpkyxSb9y5UrRpUsXERkZKbp37y7++9//2jxvMpnE3LlzRWJiotBqtWL48OGiqKgoEEVxizvlbt++vQDQ4DFv3jwhhBDnz58X1113nYiPjxdNmjQR7du3FzNnzpTVPwwLd8o9a9Ysa9rExERxww03iB07dtgcLxSvtxBCFBYWCgDim2++aXAspVxvy9Dp+g9LWadMmSKGDRvWYJ/evXuLyMhI0bFjR7FkyZIGx23stZQDd8s9bNiwRtMLYZ5iIDk5WURGRoq2bduKW2+9Vezbty+wBXPC3XI/99xzIj09XURFRYm4uDiRlZUlNmzY0OC4oXa9hTAPF2/atKl488037R5TCdfbXpkB2Hxmg3UP1/yRQSIiIiJVUlSfISIiIiJfYzBEREREqsZgiIiIiFSNwRARERGpGoMhIiIiUjUGQ0RERKRqDIaIiIhI1RgMERERkaoxGCIiIiJVYzBEREREqsZgiIgUafny5WjatCmOHTtm3TZt2jT07NkTBoMhiDkjIqXh2mREpEhCCPTu3RvXXHMNXn31VcybNw/vvvsutm7dirZt2wY7e0SkIBHBzgARkSc0Gg2effZZjB8/HklJSXj11VdRUFDAQIiI3MaaISJStD59+uC3337DN998g2HDhgU7O0SkQOwzRESK9dVXX6GwsBBGoxGJiYnBzg4RKRRrhohIkXbs2IGsrCwsXrwYS5cuRUxMDD755JNgZ4uIFIh9hohIcQ4ePIhRo0bhqaeewsSJE9GxY0cMGjQIO3bsQJ8+fYKdPSJSGNYMEZGinDlzBoMHD0ZWVhbeeOMN6/ZRo0bBaDTiq6++CmLuiEiJGAwRERGRqrEDNREREakagyEiIiJSNQZDREREpGoMhoiIiEjVGAwRERGRqjEYIiIiIlVjMERERESqxmCIiIiIVI3BEBEREakagyEiIiJSNQZDREREpGoMhoiIiEjV/j95gYzLb9JJoQAAAABJRU5ErkJggg==",
"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.38642255]\n",
" [2.56985133]]\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",
"[[3.89425071]\n",
" [3.03737777]]\n",
"Eigenvalues of Hessian Matrix:[0.32691458 3.94394646]\n",
"theta from own gd\n",
"[[3.89408559]\n",
" [3.03753095]]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"theta from own sdg with momentum\n",
"[[3.92801972]\n",
" [3.02259232]]\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",
"[[1.99987339]\n",
" [3.00070766]\n",
" [3.99931264]]\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.99430797]\n",
" [3.0204309 ]\n",
" [3.97790579]]\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",
"[[1.99988575]\n",
" [3.00066222]\n",
" [3.99946201]]\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 0x12288f460>]"
]
},
"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 0x110657310>"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAiIAAAGdCAYAAAAvwBgXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB8EklEQVR4nO29eXgk5XXv/63e1WrtGmk2zQ4MGAbMMsNmG2w2G1/HdoIhxgtcmyfJBS4EJ8CYxNwktoc4xBu2MfHvF5sEMCQkQLzAhRiDbdZh2DEzwwyj2bSv3Wqp16r7R/dbVdK0WrW8b9Xb6vN5Hj3PjEZSvyO1qk99z/d8j6JpmgaCIAiCIAgfCPh9AIIgCIIg6hcqRAiCIAiC8A0qRAiCIAiC8A0qRAiCIAiC8A0qRAiCIAiC8A0qRAiCIAiC8A0qRAiCIAiC8A0qRAiCIAiC8I2Q3weohqqq6OvrQ1NTExRF8fs4BEEQBEFYQNM0pFIpLF++HIFAdc1D6kKkr68PPT09fh+DIAiCIAgHHDx4ECtXrqz6MVIXIk1NTQBK/5Hm5mafT0MQBEEQhBWSySR6enr01/FqSF2IsHZMc3MzFSIEQRAEUWNYsVWQWZUgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgCN+gQoQgCIIgJOG1gxP459/tg6pqfh/FM6TevksQBEEQ9cRXHnkTrx2axHHLm3H6ug6/j+MJpIhUIZMvQtPqpyolCIIg/GU4lQUAHByb9vkk3kGFyDwcGp/Ge//2CVxz3ytUjBAEQRCekMoUAABD5YKkHqBCZB7e6ktiJl/EL97ox4M7Dvl9HIIgCGKRo6oapnLlQiSZ8fk03kGFyDxkC6r+57/7+e/r6klBEARBeM9UrgAmwJMiQiCbL+p/TmYK+KuH36QWDUEQBCEM1pYBgME6uvmlQmQeMmVF5KiuBEIBBY//fhC/eKPf51MRBEEQi5VUJq//eTBJikjdwxSR45Y343+duwEAcOsjb2EsnfPzWARBEMQiJTljKCLDqWzdqPBUiMwD84hEQwFcc+4GHN2dwGg6h7/52Vs+n4wgCIJYjJgVkVxRxcR0vspHLx6oEJkHoxAJIhIK4Bt/dCICCvDIq314+cC4z6cjCIIgFhtmjwhQP4ZVzwqR2267DYqi4Prrr/fqIV3BWjOxcOlbdFJPK85YX0q52zec9u1cBEEQxOLErIgA9WNY9aQQ2b59O+666y5s2rTJi4fjglkRYcQjpUT8TKFY8XMIgiAIwinJOYoIFSKcmJqawuWXX44f/ehHaGtrE/1w3MiWi41oyPgWxcKloiSTVyt+DkEQBEE4hVozgrj66qtx8cUX47zzzhP9UFxhxUY0bCpEykVJlhQRgiAIgjOsNaMopb/XS5Cm0O27999/P15++WVs377d0sdns1lks0YFmEwmRR1t4bMUmEfEaM2wooQUEYIgCII3TBHpaYvjwNg0KSJuOXjwIK677jrce++9iMVilj5n27ZtaGlp0d96enpEHW9BsnljfJcRK/tFSBEhCIIgeMMUkfVLGgGQR8Q1O3bswNDQEE4++WSEQiGEQiE8/fTT+O53v4tQKIRi8cgX861bt2JyclJ/O3jwoKjjLUhG94gcqYhkSREhCIIgOMMUkQ1dCQD1k64qrDXzoQ99CG+88cas91155ZXYuHEjbrrpJgSDwSM+JxqNIhqNijqSLVixEQsfqYhk8qSIEARBEHxhhcj6JaVChKWrKsw0skgRVog0NTXh+OOPn/W+xsZGdHR0HPF+Gak0vsv8IubNvARBEATBA701U1ZEWLpqW2PEz2MJh5JV56HS+K5hViVFhCAIguALU0Q6GiNojYcB1McIr9Cpmbk89dRTXj6cK4zxXZMiEiJFhCAIguCPqmqYypUKkaZYGN1NMUxM5zGYzOCYpU1CHvPd4Sn0jqaxsi2Oo7vFPIYVSBGZB1JECIIgCK+YyhXAlu02xULoai75JUVOzvzi9X78z5+8hB8/s0/YY1iBCpF5YKqH2awaJbMqQRAEIQDWlokEA4iFg+hqKsVeiGzN5Iqq/ph+QoXIPLBiY7ZZlSWr+tOaGZnK4p3BlC+PTRAEQYiDGVWbYiXHRHdZERGZrporv5ZFQv6WAp56RGoFTdOMqRkJFJHJ6TzufHovfvzMPmQLKp76i3OwprPR0zMQBEEQ4mCKCCtEuprKhYhARSRLhYi85Iua3qurpIh4FfGeyRfxk2d7cedTezE5Y6yHPjA2TYUIQRDEIsJQRErTMt3NpdaMSI8Ia82EfW7NUCFSAXOEe6Xtu160ZnpH0vjjHz2P/snSk/Do7gTS2SIOT8xgKltY4LMJgiCIWuIIRUQvRMQpInlJFBHyiFTArHjMmpph23c9aM08vXsY/ZMZdCaiuP2SE/Hode/H0d2lkJupDBUiBEEQi4nkPK0Zlq4qAjKrSox5dNccreulIsJUjw9uXII/OmUlggEFibJklyJFhCAIYlExtzXDxndZuqoIcoUjl7v6ARUiFcjO88Nhf88VVRRVMRUqY7ocbBOPGN2zRLT0Z1JECIIgFhdzWzPRUFB4uqosUzNUiFRAH90Nz17MFzP93ewjEUE6W/r6jVHjMdkTdCorpjomCIIg/GGuIgIA3U1iDauymFWpEKlApTAzYLZCkhU8OVNVEaHWDEEQxKKCKSLNMeOaLzpdlRQRiWFFhnl0FwBCwQBCgZJnJCNaEcmVFZGIcQZWiKSoNUMQBLGoSM7MDjQDIDxdlcyqElNpzwxDN6yKVkTKqkc8alJEYqSIEARBLEYMRcTUmhGcrkqKiMSw8d3YHI8IYBQn3ikiRiHSRGZVgiAIrgxMZoR7/qxgmFWNQkR0uioVIhJjRRERna6qe0RMZlVSRAiCIPhxYHQaZ972K3zsjmdmpVf7wdxdM4D4dFVqzUjMfOO7gLF7RnSo2XT2SEWEPCIEQRD8eHsgCVUDdg2m8Gf37NAVAj+YO74LiE9XpWRViWFFRuXWTFkREfyETetTM5XGd6kQIQiCcMvEdE7/87N7R/Hlh94QlmJaDVXVMJWbvzUjKl1VV0SoEJGPaoqIsfjOI0XEbFaNlp6gU9mCL78sBEEQi4mxdKkdsn5JIwIK8OCOQ/jek3s8P8dUrqAvWm2qML4rKl1V375LrRn5MAqRIxWRWEh8zLumaboiMmt8t/wELaqaZxuACYIgFivjZUXkgxu78Ld/cDwA4B+f2I1HXj3s6TlYWyYSDMxS4qOhINoEpquSWVVijGTV+T0iIhWRbEEFS5A3j+/Gw0Gw1TcpSlclCIJwxXi6VIi0NUbwmdNX40/evw4A8Jf//jr2DKU8O0cloyqjS2C6ap7MqvJiJKv6o4ikTR6QBtMZAgEFiQiN8BIEQfCAKSJt8QgA4KaLNuKU1W3IFVU89+6YZ+eoZFRliEpXLRSNG15SRCSEmVX9mpqZLmeINISDCAaUWf9GI7wEQRB8GEvPLkQCAQXrOhsBGCqFF1TaM8MQla7KjKoAFSJSUtWsyqZmBBYiuj8keqQiQxt4CYIg+MAMoO2NEf19rBhIznh3ja2miIhKVzWPKlNrRkIyVcZ32dSM2NZM6fHNC+8YTBFJkSJCEAThijG9NWMoEawY8FIRSVYtRAQpIuXXMEXBEcq711AhUoHqgWbiFZHpChkiDFJECIIg3FNUNT1Ntc2kiDQ3lIoSL4Mjq7dmSorIAG9FxGRUVRQqRKSj+viud4qIOUOEIVOo2e7BFM7c9iv820sH/T4KQRCELSZn8np2R2vDkYpI0lOPyPyKSGvZv8K7MJJldBegQqQi1cd3JVFEJChEfvlGP/omM/jn3+3z+ygEQRC2YEbV5lgIIZNHojnm/SqNaoqIPiDBeTEfU0QqKf9e4/8JJKSaIqJv3xUYKFZp8y6DpavKsG+mdyQNANg5kMLolJhdCARBECJg8e5moyoANMfYNdZ7RaS5giLCXnOynF9zcpKkqgJUiFRE375bQRFhBlaRa6Ons0du3mUY47v+B5rtG53W//y8hzP3BEEQbmGKCGt9MGSbmokKyq5ihUiYFBE5YZVnRbOqz4pIk0Rm1f2jaf3Pz+4d8fEkBEEQ9hifRxHxY2qmamsmJLY1Q4qIpGQK1cZ3PfCIWFJE/C1EJqZzs5YwPbt31MfTEARB2GO8fP1qjc9+8WeFSDpXRKHozU6vqoqIKTKC57JTMqtKTjVFxGjN+OUR8d5IVYl9ZX9IS0MYAaX0976JGV/PRBAEYRW2Z6Z9ntYM4N0Nn1GIVFJESq85mgbki1SI1A3WzKo+Tc1IoojsL/tDNi5twgkrWwEAz5EqQhBEjTBmWnhnJhIK6MGVXt3wJassvTPfEPNsz1BrRnKMZNX5FZGcXzkikozvMkVkbWcjzlzfAYDaMwRB1A6sNdM2RxEBTIZVD3wiqqrp1/OFCxF+rzukiEiMpmm1oYj43JrpLRtVV3c04qz1nQCA5/aOcO1hEgRBiMIwqx7ZDmFjtF5MzqRzBT1YrblCa0ZRFL1Y4FmI5EkRkRfzRsJq47sZvz0iPisiveXWzNrOOE5Z3YZIMIC+yYzesiEIgpCZ8enZm3fNNHmYJcL2zISDyrzhYkaWCMfWDCki8mKuOCubVfk/IeZSbWqmqRxoliuoQrNMFoKFma3pbERDJIj3rmoFQO0ZgiBqg/F5PCKAeYRX/A2feXR3vp0vIrJEslSIyAtruShKZcmKPSFEKiLTVRSRRlNxwrwkXjOezunLola3NwIAziy3ZyhPhCAI2SmqGiZm5veIsMV3XnhEqo3uMqICWjNkVpUY8+hupeqUKSJFVRM2Y54ue0QaKygioWAADeX2kF8+kX1lf8jS5hgayj6WMzeUDKvP7R2FqpJPhCAIeUmaF97F5/eIeKuIVClEBCjxlKwqMdWMqsDskDNRqsh0WemIV1BEAMOwmvIp5p0lqq7pjOvvO3FlKxrCQYymc9g9lPLlXARBEFYYK/tDmmIhhCsoAl56RHRFJHpkQcQQ0Zohs6rEVBvdBWb/0ERMzuQKqi6ZVWrNAP7HvO8bYUbVRv19kVAAp61tBwA8u4d8IgRByIseZlbBHwJ4OzWT9Ks1U5g/uNNr/D+BZCykiAQCYkapGDM5o7hpqDC+C/gfasaMqqs7Gme9n/JECIKoBYx498qFiK6IeKA6V9szwxCxb4amZiRG37xb5YcjMkuE+UMiwcC8T5CEz6FmemtmnkLkhXdHPdvRQBAEYRcj3r3yi7+3UzOlx2huqOYRKbdmOC5bJbOqxOhm1XlaM4DYxXd6mFkFoyrDz30zmqbNSlU1857lLWiKhZDKFrBzgHwiBEHIyViVDBHACBZLzsimiPAf3yWzqoQwRSQ2T2sGMGWJCGjN6PHu8/hDAH9bM+PTeb2nuao9PuvfggFFV0kGkxnPz0YQBGEFPcxsHo+IL4qIJY8Iv5tftkCPFBEJ0T0iVRQRPUtEYGumUrw7w0+zKlNDlrXEKnpYmPlrtCx9EgRByMZCZlVj14x3hUh1syr/qZlcuaghj4iEGDki/igi+uhuhYV3DD8Vkfn8IYyORLkQmaJChCAIOTHMqpXbIcyv4U2gmYXWjJ4jQkvv6oJMofr4LmCqTgUqIo1VFJFElM24e1+ImKPdK9GZiAIARqeynp2JIAjCDoZZtboi4sUqDXvJqhynZoryjO/O/z+vU+woIhmO1SmDxbvPF2YGmBUR7wPN9pWX2q3piFf89w5qzRBE3TOdK+C5vaN4sXcM5x7ThdPXdfh9pFkws+p847sJkyKdyhQQTcz/euAWoxDxONCsUPKIVAp08xoqROZgZXw3pj8pBCgi2fnj3RnMI+LHrhkjVXW+1kxJERkhRYQg6orxdA4Pv3oYv941jOffHdWl/yfeGsSTf3GOv4ebw0S5NTOfRyQYUNAULU0AJmfyutIrgqSViHcBikhWovFdKkTmwFQOc5T7XKJ+KyJsfNdjj0i10V0GU0TGSBEhiLri2p++gt/tMZZeLm+JoW8yg32jaWTyxarXVC8pqhom9KmZ+VUIFkUgsgWuqpru9bO2a4Y8InWB74qIFY8Ia814YKQyM5bO6b+Uc0d3GWRWJYj6Q1U1vHxgHABw3YeOwn/f8H48c/MH0dIQhqYB7w6nfT6hQXImD7aXs7WhsiICmPfNiCtE0rmCvnyv2ePWDE3NSEzWQv5+VA8082lqxqdk1d5yW2Z5S2zeuxvWmhlNZ6FptIWXIOqBQ+MzmM4VEQkFcO0HN2BDVxMURcGGrgQAYM/wlM8nNGAZIk3RUNUXYS8mZ1iREw4qltK8RZhVZfCI+H8CyTCSVau0ZjyIeK+miDTF/MkR6S0vu5vPHwIYrZl8UfNkBp8gCP/ZOZAEAGxYkkDI9MK2YUm5EBmSrxBprdKWAbzZwGs2qiqKMu/HiUhWZWZVGaZm/D+BZGSstGbC/GUyhh1FJJ0roqh6pzr0LmBUBUrfG3Y+GuEliPqArXTYuLRp1vuZIrJXokJkLF02qs4zMcPwIl01ZcGoCgjeNUOFiHzUgiKSMD1p2cd7ATOqzje6y2A+ETKsEkR9sIsVIssqFyIyKiLzxbszvNg3YyVDBBC8fZdaM/JhyawqUhGxMDUTDQX1J4+X7Zn9eobI/IoIYIzEjZBhlSDqAtaaOWZp86z3s0Jk30hamo3cLMxsvoV3DFYciGwx66O70eptIhGtGZqakRgr47tGoJk/OSKAPzHvVlozANDRaBhWCYJY3GTyRV0tnduaWdHagFg4gFxRxaHxGT+OdwQs3n3hQkT81Ay78Vzoes97akbTNDKryowVRcRYeuePIgKYskQ8UkTyRVV/rK6m6uE+nTTCSxB1w56hKahaaW/L3GtDIKBgXadc7Rlj4V11FcKLqRm2JqSaFaD073xbM2zzLkCKiJRYGd+NcX5SmJnOWVREPB7hNRc8iSpGWsCcJUKKCEEsdsxG1UqTH7KN8C4U787wYmomU369iVVZKQKYWjOcbn5zpjYZTc1IiFGIVGvN8HcwM1hse+NCiojHI7zMsNUYCc4az6uE0ZohRYQgFju7yv6QjXP8IYz1ko3wslTV+eLdGV5MzWR0RaT6NZV3ayZn+jpkVpUQ9sSovn237BHhrIgUVQ0zedaaqV4hN+mKiDfpquyXsbmhupwJULoqQdQTTBE5Zo4/hCHb5Ayb5muNL9CaYVMzIlszdhURTq85rBAJBRQEAvPnl3gFFSJz8FMRmTGZXxsXaH8kPKjWzVhZzMQgsypB1A9WC5G9Q1NSpC2PL7DwjtEskyISNqZmeHwPWSEig1EVoELkCLIWnhiiFJHpst8joCzct/PaI8JaM9X2ITBIESGI+mAsncNwqnTDcUx35UJkTWccAaW0pHMo5e/NiWpaeLdwoJkxNSOqgNKnNBdUREr/rmmzjaZOkSnMDKBC5Ah081DV8V0xikg6Z/hDqsX9At57RJy0Zsamc54mvxIE4S0sP2RVe3xeFTcaCmJ1OXvI7/ZMMmNaeLdAIcKmZoqqpk8z8oa1WqpZAYDZN6Y82jMyZYgAVIjMQtM0/QdkZWqGtyLCMkTiC0zMAGaPiHytGXanoWmGMYwgiMXHrgXaMgxZDKvMH5JYYOEdADSEgwiW/ROi2jN6kvcCZ5ldiLi/AdYVkXpozWzbtg2nnXYampqa0NXVhY9//OPYtWuXyId0hfkHbC1HhHNrJmdtYgYw5Yh4VoiUFRELrZlQMKAbwWhyhiAWLzv7K++YmYsshlXmD1nIqAoAiqKYJmfEGFaN4YjqN5+KouiFE5dCxMINt5cIPcXTTz+Nq6++Gs8//zyeeOIJ5PN5XHDBBUin0yIf1jHmH3C1JwZv4xCD7Y2xoogkygWB1+O7VhQRwNjCO0JZIgSxaNk5yAqRyqO7DGkKkbS10V2G6MmZrAUrAMPIEuHXmpHFrGrtVcUhjz322Ky//+QnP0FXVxd27NiB97///SIf2hHsBxxQSmNN82E2DuWKatUJGzvom3dtKCJet2aseEQAoCMRxd7hNBlWCWKRoqoa3hm01prRJ2d8DjXTF94t4A9hiN43o0/NWFAmoqEgUihwUUTy9WxWnZycBAC0t7d7+bCWMY/uVjOLmo1FPJcQWdm8y2jyy6xqoTUDmGPeSREhiMXIwfFpTOeKiIQCC27kXr+kZFYdSmWF5nIshFGIWLuOiQ41yxSstWYAvovvsvVqVlVVFddffz3OOussHH/88RU/JpvNIplMznrzEn3PzAIO5kgwAFan8PSJTOtmVQkVEdutmVKWyBh5RAhiUfJ22R9yVFdiwbTlplgYS5tjAPxtz4ylywvvLLZm2Agvu/7xRjerLvCaY/4YLq2ZejKrmrn66qvx5ptv4v7775/3Y7Zt24aWlhb9raenx6vjAbA+060oCvfsf8A8vmvFIyLWRDWXpI3xXcDowY7UaCGSyRexezAlRQATQcjIrgFr/hCGDD6RCZutmWbBG3gz+pJVK4oIv5j3uhzfveaaa/Dzn/8cv/71r7Fy5cp5P27r1q2YnJzU3w4ePOjF8XSsKiKAKUuE4wgvW3hnxSNiHt/14sUyZWN8F6jt1oyqavjs//8CLvjWb3D747uoGCGICuwaZDtmqvtDGOaEVb9gCq11RUT01Awzq1rxiPBrzTCPSF2YVTVNw7XXXouHHnoITz31FNauXVv146PRKKLR6ivmRWJ1phtgqklefyLxQF94Z2lqpvSjU7VSNLyV4sUNdpJVgZJZFajNdNWHXjmM7b3jAIDv/3ovFCj40gVHLxgyRxD1BBvdXcioylgvgSIybjFVldGsm1VFtWaceET4Tc3Uxfju1VdfjXvuuQf33XcfmpqaMDAwgIGBAczMzIh8WMfYMg6xUDOeHhEbikhDOAg22CPasKqqmp5XwtIGF4KN79Zajkg6W8DfP7YTALBlbclU/b1f78E3n9hNyghBlMnki+gdLcUwWFZEWKiZj5Mzk+UbqhaLLWbWihbXmrFeEEQ5JnrXVWvmzjvvxOTkJM455xwsW7ZMf3vggQdEPqxj7CsivKdmrHtEFEXxLNQsnSuAvQbbV0RqqzXzg6f2YCiVxeqOOP7lC5vx1x89DgBwx5N78C0qRggCAPDO4BRUreQFW9JkTcVmrZmDY9PcwyCtwm7aEhZbzCKnZlTVSPL2empGNrOq8NZMLWFl8y5DiCJiY2oGKDm6k5mCcEWEGVUjwYBlKY8pIslMAbmCKk3lXY0Do9P40W/3AQBu+cixiIaC+MLZa6FpGr76i7fx3Sf3IBoO4upzN/h8UoLwl3eGSm2Zo7sTlluWnYkIWhrCmJzJY99IGscus2Zy5QmbMkxYaH8DYqdmWDEAeN+aYa914ZAc7Wb5Xx08RDer+q6IWCtEvBrhTelhZgsv42O0NIT1PQ21MsL79V++jVxBxVkbOnD+cd36+7/4vnW45SPHAgDuePIdvYVGEPVK30Spvd7TVj0/xIyiKHqeiB8+EU3TjGusxZs9kVMz5ptYq4FmAF+zaiTIJ4zTLVSImDAczD57RCxW6wnBYTuM5Ezp6zdZbMsAQCCgGCO8NdCeeXbvCB57awABBfjKR99zRMH1xfetxar2ODJ5FU/uHPLplAQhB4cnMgCAZa0Ntj5vZblwGUxmuJ9pIbIFVd8GnrCsOoubmmGvN8GAYml6xcgRIY/IosaOImIsvuOniLCId9kUEWNixl4nr1YMq4Wiir/92e8BAJ85fXXFKQBFUXDxpmUAgF+83u/p+QhCNvonS4rIitaYrc/rSPh3TTBfJ61eY0VGvLPXm5jFYkDE1AwVIhJiJ+UuFub3pGDoS+8smFUBQxGZEhxqlsqyDBHriggAdCZYuqrcisjTu4excyCFloYw/vy8o+f9uItPKBUiT+4cQtqjRFuCkBHWmlnWYk8RYTcnYz6M9TMvXTwSRKDKLjEzbGpmKlvQ1RReZPTXG2vXexGBZnUxvltrOEm5E6KIWJUNPVNE7I3uMvS7H8mzRHbsL2WGXPSepVWDjt6zvBlrOuLIFlT8itozRB3TX27NLLfZmtGn6Xy4OWHXSavXV2B2gCPv66yviogeaEZmVenwUxEpGamsL70D4Nn4rt0wM4bhEZG7EHn9UGkZ46aelqofN7s90yf8XAQhI8lMXr/mLLfZmmn3sV2b1idmrBci0VBQb1/wnpyx40kEOHtEJBvfleMUkmBnfJc9eXgpItmCCqb8WR3fTXi0gZdddKzGuzM6ayBLRNM0vH5oAgBw4srWBT/+4hOWAwB+vWvYs4WDBCETTA1pjYdtJzqz1Q9+TNKxGz07hQggbnKGDTpY9WmI2TVDUzPSoUtlNnL/eU3NmD0HDRYrZO/NqvYUkVowq/aOTiOZKSASCliKqj52WRPWdTYiV1Dxq7cHPTghQchF36QzfwgAtDf6t/physYKDTPNgiZnsjbCzAAyq9YNunnIhiLCK0dkujzf3hAO6vkbC9HklSJic/Muw+gHy1uIMDXkuGXNlkboaHqGqHeYUdXuxAxgtGamsgXP01X1VFWbioioyZlM3vqNL8A5WZUKEXmxFWim9+s4KSLMH2KjWk9Ey5KhaEXE5uZdRkcNbOB97WDJH3Liyur+EDOsEHlq97CwrZwEISusNeNEEWmOhXSDpNftmbQDsypg3jfD2yNifTgC4LxrRveIkFlVOrJ2FhCxqRlOZlW2eddOz5UFn4keJXXdmpHYrMoUkU0W/CGMY7qbsH4Ja8/Q9AxRXzBFxO7EDFBSFJkq4nUh4mRqBhC3b8ZozXg/NaMnq5IiIh8ZGyuZYxwdzIB58651RSRePueMYImT/QLaV0RKrZmZfFHKWPRCUcWbfWVFZIGJGTOl9kzJtPpzas8QdQbziNidmGF0lH0iXicusxu2JruFSFTMvhk7rzeAoNYMRbzLhwyKiJ1qvaFctMzkxBYiSX3XjD1FpDES1L+XMqoi7wxNIZNXkYiGsK4zYetzP1puz/xm97D+/SGIeqDPYYYIo8OnyRmj/W23NSMmJsHO603p40RMzchRAshxCknI2ki6k0IRiXijiBiBZvYKEUVR9BFeGffNsLbM8SuaLSctMo7ubsJRXQnkijQ9Q9QPqqphYJJ5RJwqIv4UIkzZtd+aEeMRydpVRDhmV2WpEJEXO0l3rFjhpojY3LwLGE9gkYpIJl/UjU12WzOAf3c/VnjtEDOqtjr6/PPKG3qf3TPK60gEITUj6SxyRRWKAnQ3OytE2vXWjD9m1YTN8V19amaG89SM0/FdjmZVSlaVEDvZ/0aOCCdFJGtv8y5g5I2Yt0ryhrUdFAVI2AwvAkxJihK2ZpwYVc1sWdsOAHhh3xinExGE3LCJme6mmKVx90oYNydee0Tst78Bw6TPuwVrTM1435phZlXaNSMhdnp2Ro6If4qIecJG1Ey+blSNhmy3LwCTMU2yxXeZfBE7+1MA7BlVzZy6ph3BgIIDY9P6JAFBLGb0ZXcOjaqAf9N0Uw4i3gGBUzN2I95FBJqRWVU+bOWIcF5650QRMZ9zWlB7hjnF7W7eZXRKuvju7f4kCqqGjsYIVjg03SWiIRy/vBkA8MI+as8Qi5++SXdGVcC/fTNOI96bRCkiNl5vALNHRIWmuVPAyawqMXYq1Cj3QDP7ikggoOjtGVGKSNJhqipD1lAzfdHdyhYoivM+6ZZ1HQCAF96l9gyx+NEzRBwaVQH/NvBOOTSr6lMzgpJVrVgBAKM1o2lAvui8EFFVDYVyK58KEclQVU038NhpzWS4Rbzbn5oBjBFeUYpIymGqKoO1ZmSLeX/NpT+EQT4Rop7on3QeZsbQp2ZqpDWj7/QSFWhm2SNifJyb9gx7nQPIrCod5h+OHbNqrqBC5WAUdWqkahAcaqaP7jpszfiVorgQTBFx6g9hnLqmHYoC7BtJYyiZ4XE0gpCWwy7i3RlMJU3nip7tmykUVf2F3/Y1NmJMSLptiZhxGmgGuDOsml/rSBGRDPMvhJUK1fzkMf9gneJeERGTXGqEmTlTRFripQJmknMqoRtSmTz2Dk8BcK+ItDSEcdyykk/keVJFiEVOv77wznkhkoiGEClP3HillLIbPcD+9l12s6dp/JacAuYlq9ZehhVF0QsHV4WI6XMjDiefeCPHKSSA/WCDAQUhCz8cc7HCo6p34hEBINwjwlozThWR1rK3ZHJankLkjcOT0LTSxZQFrrlhy1rmEyHDKrF4yRVUDJe9Xm6mZmbtm/GoPTNVvlGLBAOWl8wxGkw3nTwzm7I2c0QAc5aIi9aMPjETcOWP4wkVImWyNqvTUDCAYHmclUeV7GRqBjDHvPOr1M0YrRlnikhrvHTBSWUL+uy635iNqjzYso58IsTiZzCZgaaV5Hzm83AKa894NdZvGFXtj6uGggFdOZjmeMNnN1kV4JMlwgoRWfwhABUiOnqqqo0nRUwPNXP/5Jx2qYiIb804U0TMBQzvpVFOcRtkNpfNa0qFyJ6hKSmj7AmCB4dNEzNu76Q9V0Qcbt5liNjrZTfQzPyxbgoR2TbvAlSI6Njt1wGmmHcOWSLGQiZ7FTvzlAgPNHOoiISCAX3bpSw+kbf6kgD4KSJtjRFsXNoEAHiRVBFikcJjYobR6fEIb9rhxAyjQcA6DUetGQ6xEbLtmQGoENGxE2bGiHFMupsum6kaHCsiYgPNnHpEAMOwOiFBIVIoqjg0Xrqgbuiyt3G3GvoYL/lEiEVKH4eJGYbXoWZuCxERC0aNqRk7igiH1gwpIvJixLvbaM1wUkSKpgwTqzPljAbBG3gNRcR5IdIal8ew2j+ZQVHVEAkFsISDUZWhB5uRIkIsUvr0iRnnRlWGvm+mRlozMQEt8IyD1xwerRmzWVUW5DmJzzipTiOcPCLmcSo7Mh0gRjI043Z8FwBaG0oXnYkZ/7NEDoxNAwB62hoc7c6Zj81lRWTnQArjkmWmEAQPjD0z7hWRDo8VEadhZowGzi3wQtFYVGpPEXGvwhtmVXle/uU5ic+4UUTcTs2Yn9x2tyGKVkS4tmYkUERYIbKqPc7163Ymonqr58VeUkWIxUc/hz0zjHaPE5fTWedTMwD/1ow5kduWIsJec1yo8LJt3gWoENHRPSI2qlNWybqtktnyo5DFDBMzItzcjEJR1fNNnJpVgVLoFyCHWVVUIQKYfSJUiBCLj8Mc9swwvN5BNeUwuZoR4+zFc3rzybU1Q4WIfBg5It7OdJsf225bBjCZVQUoIkzOBFx6RBrkUUQOstaMiEJE94mQYZVYXKQyed0vxrM149XqB6aINLk1q3IqRMyTK3ZaxFxaM2RWlRdjE6J/iogTqUwf3xWgiLAws4Zw0NWTtlWimHeRhcjpZUXk9/1J7ivDCZ/Zvh1YtgxYssR4W7as9P46gLVlmmMhxz4LM2wD73SuKMzfZibtNkeEsxfPSYZI6ePd3/xmyawqL4ZHxP4oletCxIUiwlsyNJN0uXmXoZtVp/03cYpszXQ1x9DT3gBNA145MMH96xMes3070NEBKAqweTOmBwYQHRnBBSMjiI6MYHpgALjkEr9P6QnMqMrDHwIAjRHj5saLLJEUr0AzXh4RB6mqgDlHhEeyqjwv//KcxGecmVXd9+sAI5zGjhrDiJdzR0SYVd2mqjJkyRFJZfIYL7eHRCgiAHDq6pIqsoMMq7XLvn3A5s3Ali2YHhtDFEAgFEX7yvcgsPpE/Hb1iQisOQkda96LoRlvtsf6DcsQ4VWIKIqCTjY548EIL69AM143fEaYmV1FxH1rRsZkVfca2yLByfiuPjXjujVjvwhiiBzfdZuqypDFrHpwrHRX194Y4SIvV+KU1W146JXDeGn/uJCvTwhkaAi47jrg4YeRy2SwHkBfQzOaTv4ouk6+GMH4kUm87w8quP7pvfjC2WulusPkjZGq6t6oymhPRNA3mfHEJ8KrEOE1vmu0ZmwqIhx3zVAhIiFOFBEeDmbAvPzI/hND5Pguj9FdQJ5AswMC/SGM08p7Z149OIFCUbU9BUX4xL59wLnnorB/P84B8EJLN5pO+zhWbDofgXDpxbeQGoWaSZX2wQNQwlGgbTlue3QnHnm1D7d98gSc2NPq239BJGxihkeqKsPLEV5uu2Y4XWeNAQXvFZGcAxuCaKgQKeMo4p1TlcwUkZgbRURIa6a8eddla8YINMtD0zTfVk8fNIWZieKorgSaYyEkMwW83Z/CCZz22RCCSKeBH/8Y+OpXkRscRBOA6MkfxfIPfgFKsPS8z/a/g+QLD2J693OANvum48GXDuKrv/g93u5P4uM/eAafP2MNbv7wRkd+L5npL7dmVnBqzQAwtWbEe0TS5fFdt4Fm/Foz5ZtPu4oID49IUT6zKhUiZZyM0Eb1ZFU+gWZOPCIic0RSvMyqZUWkqGqYyhZcjQK74eC4OKMqIxBQcPLqNjy1axgv7R+jQkRm0mngllugfuc7+AqAb0TiaPnIdWg85iwAwEzva0g+9wAyB16v+Omjo6Nob2/HOccswdd+8Tb+85XD+MmzvZiYzuHbl73Xw/+IePommSLCsTXj4QjvFKdAM36tmbIqYVsR4deakamVKM9JfCbjQK4yklXdPTmzLhQRc+KfVpaMecHGd922ZmLhoP599TNLROTEjJlTV7cBAPlEZCadBm68Eep3voMPAPiH7vVYcsV30HjMWdCKeYz9910YeuAWvQhpBDCzdCm0aBRaQwO0chEClEZRv3npSfj/PncqAgrw8Kt9+Pnrff793zijaZo+vsuzNcNGeEcEm1U1TdO3m8tiVtU9ibY9IpQjsqhxMrkS5bT0zo1HhBVD5sV5vOCxZ4Yhg2HVq0LkFH1yZpx7cUhwgCkhP/gBPgDg1U3nY+lnbke4bRkKk4MYuPcmpHb8DADQBCD7sY9hamYGsf5+IJMBpqeBchFi5rzjunHNuRsAALc89CYGyi/etc74dF6/i+5u4bco0gg1E9uamc4Vma0HCYfqLtuKzjvQzPb4LiWrLm6cqBJ6a8alIuLUQQ0YiggAZHJ8CxGjNeO+leJ3qJmqajhUnpoRaVYFgJN6WhEKKBhIZnSTHyEJpnbM+wG8ceZl6PjwdVBCYUzvfg79P/7fyPXvRhjAl1etwsTMDCKPPALErLUkrv3QUThhRQsmZ/L4ywdfg6rWfiHKJmY6ExFH16j50GPeBbdm2MRMQDGUDbvw9uI5DjTjsGuGChGJcZas6v5JATifKQdKfb5QOSJ4Os9vRTVgbs24V0SMUDN/CpGhVBa5oopgQOHa565EQySI9yxvBgDsoPaMPAwNAZ/8ZKkIUQJ4+/w/Rev7PgMAmHj2fgw/9DWo2TR6gkFMP/YYvrZvHwIWCxBGOBjAty49CdFQAL99ZwT/8lyvgP+ItzBlZynn35t2j3JEdH9IJOTYKM874t3wiPjYmiGPiHw4CjTjrIg4ddqLMqzqrRkOiogRauZPuipry6xobfBkpJa1Z17qpUJECoaGgI9+FIXHH8eaYAi7PnYjmk7+KDRNxdgTP8Tkb+8BAPQ0NKB3ehqhCy8EAs6eJxu6EvjyR44FAGx7dCfeGUxx+2/4AfOHLG3mO23WUR7fFW1WdTu6CxjXZm7juwVn7XhqzSxyHEW8c1JE9OrY4RND1AhvSh/f5aGI+Lv4zsgQETe6a+bUNWRYlQZWhGzfjo5IA3KX/A0aN54NrZDHyH99A6mXfw4A6IlG8e7EBAKRiOuH/NwZq/H+o5cgW1Dx5//2ak23aAZ0oypfRYS1ZmbyRUzn+Kq5ZtxOzAD8b/YyDpasmj/eTSGSJ0VEXhzliHBSRPTHXsyKSLkQSfrkETnokVGVwSZndg0kda8N4QOmIqQzlkD80q8itvpEqNlpDP37rZje+TsAwNmdnehNJhHiUIQApQjzf/ijTWiKhvDm4SSe2j3E5ev6Qb+g1kw8YkzTiWzP6BkiLq5j8fK1OVdUUeAwFOBYEQm7b81kSRGRF6Zq2Pnh8FZEHLdmBCgimqaZIt75mVX9UkREbt2tBFuAp9ICPP8wFyENzYhf9nVElx+D4kwSgz/dqo/mnr1iBZ7u7+eihJjpbo7hss09AIAfP9PL9Wt7yUCSf4YIUN43kxCfrmrEu7tXRAA+11mn13y9NUNm1cWJk0VArJp1v33XmYOawTv1j32tYllO5jK+G2fpqv56RHravClEAGMBHrVnfMBchCTaEf/0bYh0r0NxahyD921FbnAvGgHccvrpeLq3F4GQmGzHz56+BooC/PadEewdnhLyGKIRZVYFzKFm4kZ4zWZVp0RDATCfK5dCxIECX/p4DoFmRQo0kxb2w7HlESk/KXJud804nCln8E79A4y2TCigOB55MyOLR8Sr1gxQWoAHADv20yZeTzEVIUual6Dx07ch0rkKheQwBu67CfmR/WgOBDDx+OP46jPPCCtCAGBVRxwf2tgFAPiXZ3uFPY4oRIWZMZhPRGSo2ZTLhXdASb3huWDUSZI3sHi378pzEp/R5aqg90vvnGz+NcM79Q+YvXmXx24YP3NEMvkihlKlOy4vCxFmWH3lwASXvjJhAXMR0rYcjZf/PcJty5GfGMDgfTejMN6H5kAAo+k0Quef73gyxg6fP3MNAODBHYdqzi+Uyhb068rSZpGKiPjWjJupGWB2irVb3HtEVMdhifrSO1JE5MNJ34wVIrmi6soVn3EwOmyGd+ofYNq863LhHcPPZNVD5R0zTdGQXhB5wdFdTWiKhTCdK2LnQG2PcNYEpiKka8kaJD799wg1dyE/ehCD992EwuSgUYTYzAdxw9kbOrF+SSPSuSL+Y8chzx6XB6wt0xoPz/JJ8KLDg0JEV0Rc5iHFON7wOQ2xZB+vaUC+6K4QIUVEMlRVQ6FcSISD1u/+zVMubuLV3US8A0BD+fN4mlWTnBbeMfwMNGNtmZXtcU83/wYCCk5eVR7j7aX2jFDMRciyo9H4x9sQTLQhN7gXA/fdjGJq1JciBCjJ+leUVZF/eW5/TY3yGhkiYr5nxr4ZcR6RNIfWDGAozxkerRmHIZZm64DT9gwVIpJiLiKcKCKAOxezW48Iz94lQ88Q4bQplwWazeSLXL0sVjhYjnZf5VGGiJnNa0uG1RepEBFDOg1873vAli0obN+O7p4TkLj0qwg2NCFz+G0M/PTLUKcnfStCGJ88eSWaoiG8O5LGb94Z9uUMThgQsHXXjDetmdL1ptGlosOzNeN26R3g3BJAZlVJcVqIhAIKyunqrsxD7qdmyq0ZnorIDL8MEaDUFmHfK6+zRPwwqjJOX1cqRJ5/d4wW4PGG7Y259lr8VW8vlmzYjMZL/g8C0Thmel/F0AN/DS2b9r0IAUr+hD86dSUA4O4aMq0aGSJiivjOhPiY9xQnjwjf1gyLeLd3zVcURX+NclyIkCIiJ+apFztpc4qicBmn4qWI8DSrJk1mVR4EAoruE5nwqRDxKkPEzAkrWtEQDmIsncM7Q7U5viklpuV1HwDwnRMvRPMnbkEgHMX0O89j6MG/gZbPSFGEMD53xhoAwFO7h9E7kvb3MBYRlarKaPcg5p1Xa0aEWdWJL9DIEnHYmqFkVTkxJmYCtj0EPJLunMp0DJHjuzzCzBh+GVa9DjMzEwkF9OmZ5/aOev74ixLz8joAb5z9aXRcdC2UQBCp1/4vhh/6OlDMS1WEAMDazkacc8wSaBpw7wv7/T6OJUSlqjKYWXVUYI5ImpNZlWeCtZsQS7c3vzkH60xEI89JfIT9YOwYVRnsh5lx6BHRNM3R5l8zMT3QjN++Bl6/vGb0UDMPDauapnke7z6X09d1AACef5cKEdfs2wecfnppeZ0SwNsXXYvWsz4NAJh45j6MPXYHoKnSFSGMy05bBQB49M2BmmjViVZEmHcsk1eFecd4LL0DgIYwvxa4m3a8m9iIQlEF80pTa0Yy3AS8uK1OC6qmPzEcKyJ6xDu/rAp9P4OLWOS5GKFm3qWrjqVzSJfvYFa0em9WBQyfyAv7xmpqYkI6hoaAiy5Cbt8+JCINyHzyr9B04oXQ1CJGH/seJn93HwCgJxyWsggBgPcf3YloKIBD4zPYVQNbefsFm1WboiEEy+YxUd4xblMzkdLrg9sWuKZprtrxugrvoCAy+yHJrCoZbpYAuU26M98FOFVEDMmQnyLCpmbc3kWY8SPUjPlDljbHHHtw3LJpJflEXGGejNm9G60t3Wj/zD8gvmEz1HwWww99HVOvPQagvLxuakrKIgQA4pEQzt7QCQB44q1Bn09TnXS2oHvFugWN7yqKeO8YP0WETwvcfNPqJLLBzc1vvmDcCJEiIhk5N4pI2J2D2dzScbtrhufUDK+7CDN+xLz7OTHDCAfNPpER385Rk6TTwI036pMxnSvfg47PfRORJWtQSI1i8KdbMbPnBQDiltfx5vzjugEAT7wtdyEykCy1ZRLREFev2FxEXheyhaIe/JVwsWsG4BccmZ11zXdhVnXwmpMtls6uKKWpT1mgQgRmj4iL6tRhWyRrWn7kNGxLRI5IOse/EPHDrHp4oiQtr2zzpy3DMHwilCdiGWZK/cEPSpMxmy5Ay2VfQzDegmz/Oxj4lxuQ69+NMMQvr+PJB4/tgqIArx+a1D0YMiJy2Z2ZZoHXBdZiBoBGl21mXtOJ7JofUNz5Ep2o8G4GM0Qi/2+tB+RdjDO5b824G90FxBQivORMM8YGXu8KEd1s1+qvVM8KkRf2jUJVNQQkuhuRkn37gA99CIV9+7AuGMLUuV9ExykfBQCk3/4NRn/5HWiFLCIAUo89hohHe2N40NUUw0k9rXjlwAT+++1BfOb01X4fqSL9go2qDNayFeEdY8puLBxAyKUngtd0ovma76QYYIneTm5+ZcwQAUgRAeBunMnt4ju3YWYA3/l2htjWjHdmVdER1VbZtLIF8UgQ49N57B6S36ToG0NDwGc/C5x4InL79qGpqRP5T9+G5nIRMvHbezDyX9+AVsiiWVGQTqcRufDCmilCGHp75vfytmdYqqro351WgYoIj827DEMRcefFyxTcXfPdvObImCECUCECwF2V6HZqxm2YmflzeQaaTS0Ss+pgUmwypFVKPpFyyirliVRmaAj48IdRuOcevC+VQtuak9B5xXcQXb4RxZkUhv79/2Dy2fsBoDSeOz2NUNw/748bLigXIs/tHdVfLGXDO0VE3Fg/T2WXlxcv61IFd6PCM7MqKSISwsWs6vDJmeWoiGQL7rYAM1RV00de3fZVzRgSrHeFiFcXUyuwMd7nKE9kNuk08I//CLznPSi8/DI6lADeOPMydH7qb0t+kIE9GLj7esy8+xIAucdzrbJ+SQJrOuLIFVX8Zrecu2e8KuKNqRn+SqleiLg0qgL8WuBMEXFeiDi/+c2VzapUiEhI1pVZ1WVrxuWTEsCs9dw82jPTpq/RFK3dZNVcQdW3eoo23FnB8IlQnogOm4r5i7/ALSMjaEy0I/apv0Pr+z4DRQkg9eqjGLjnL1GYHCyZUo87TurxXKsoiiJ9e8arIt64LvBXhngGM/Jqgbttxxs3vw6mZgp12pr5/ve/jzVr1iAWi2HLli148cUXRT+kbdyZVV22ZnSZzvmPwhyExqMQYb+8AcXduebS0lCSYJOZPIoevBAPpTLQtNLPtT3u/0jnCStKPpGJ6XxNhFkJp5ySyqZivrnuFHRdeQca1pwINZfByC++ibH/+32gmEcEwNRjj+Grb7wh/XiuVc4/bikA4MmdQ/o1SCa8mprxwqzKwyMS49yaifrQmqlLs+oDDzyAG264AbfeeitefvllnHjiibjwwgsxNDQk8mFt484j4nJqxsXyI0YgoOgFA4/JGXNfleeIF7vz0TQglRGvirALaXdLVIoplVk+kXpuz5gNqW++ibZACG+e+z/RfcnfIBhvQW7wXfTffR3Sbz4JAFgZDNasKbUap6xuQ1s8jMmZPF7qHff7OLPI5IsYLS+i82pqRoxZlbWYJWzNODarumjNuFD/RSL0NN/85jdx1VVX4corr8Rxxx2HH/7wh4jH4/jnf/5nkQ9rG1eFiAuZDDCPcrn7Uei/JBwUEWZU5TkxA5S+v43luwovfCK6tNzsr1HVzBnl9kzdLsCbY0htbluO+Gf+AS2bPwkASL70X+j/1y+hMHa41Io59ljsr2FTajWCAQUf3Chne2YoWWppxsIB/QZCFEwpFWJW1a9l7r1ucU5L7zI+KiIs3K1uFJFcLocdO3bgvPPOMx4sEMB5552H5557ruLnZLNZJJPJWW9e4G58121rhi28c/eLEueU+geIGd1ltHqYJeKVtGyHut07w2LaTzutZEgF8MoJ56Hriu8guuyo0lTMf/wdxn/1T7NbMW++uWhaMZUwUlblWoJn7JhpEB58JbQ1k+NvVp3OF139rLJuFREXN7/MrCrT5l1AYCEyMjKCYrGI7u7uWe/v7u7GwMBAxc/Ztm0bWlpa9Leenh5Rx5sFm5pxZ1Z12prhs5KZKSo8RnhFhJkxRKYozkWmiRnG8StakIiGMDmTx2uHJvw+jjeYY9oPHEBrtBGRj92Izo9cj0CkAZn9r6P/x9foUe09i7QVUwm2BO/g2Az2SLSHiMW7e5G/wxSXVLbA3Ts2xdGsyoYCNM35jSfgPsSSR2um7syqdti6dSsmJyf1t4MHD3ryuG5CXngFmrldyMYUER6rtEXEuzO8DDUbSJYDmSQqRMLBAD5wzBIAwH9LvmuEC0NDwMc+phtSb19xLFqvvAONx74fWrGA8ad+gsEH/grF1CjCAL587LHoXaStmErEIyGctka+sW4vi3iR3jGe6m6D6RrtRnl2PTXDwaxaNx6Rzs5OBINBDA7OvtgODg5i6dKlFT8nGo2iubl51psXuPOIuN01U66OXZhVAX57EACzwYv/tlovQ81kVEQA4Pxj5fQFcKc8FVN48kmsUQJ4/fRL0P3p2xBq6UJ+vA8D996I5AsPApqKlcEgph97DF9b5K2YSrB2nUwGZi/bmuFgQC8UePtE0hzV3VAwoN+suvHiuQ2xdJesWmcekUgkglNOOQW/+tWv9Pepqopf/epXOOOMM0Q9rCN8nZrRPSIuzaocY95FpKoyvAw1My6m8phVAeDcY7oQDCjYPTiF/aNpv4/Dn7kx7Yl2ZD/1d2j7wOehBIKYeuvX6P/Jdcj17wYAnN3RUTKk1kErphLmhYiy+EQMj4g3RbwRasb3upDifC3TpxPdFCKuc0Ro14wtbrjhBvzoRz/C3Xffjbfffht/9md/hnQ6jSuvvFLkw9rGz4h3vV/ISRGZcbkHATDuIpoEFCIiHfJmCkUVQ6mS8182RaQlHsaWtaW74EWnisyNaV97Mjqv+O6sbJDRn/8jtNwM4ihvzR0YqDsVxMymla1oCAcxls5h96AcPhGvi3hRhlWjzcxH3W3gMDnjth2/GHNEhG7fvfTSSzE8PIyvfOUrGBgYwEknnYTHHnvsCAOr3/jpEdEd1DIpIgLNql6lq45M5VBUNQQDCjoTUaGP5YTzju3Gs3tH8cTvB/HF963z+zh8MG3M7VACUM66DJ1nXgZFCSA3+C6G/+vvURg7DKC8K+axxxD60IfqUgUxEwkFcOqaNvz2nRE8/+4ojlna5PeRPG9riroupMtt5gSnhOiSFy/LqTXjx9K7csR7vXhEGNdccw3279+PbDaLF154AVu2bBH9kLbJ+7prhs/UjFGpu09o5NlXnYvhERFrVmXScndTFEEJwszmwsY2t/eOYTzt3TZiIbDR3DPOQG7fPiQamhG75P+g9axPl2LaX/mlng0SBHBWY2NpV8z559d9EcIw2jP++0TyRRXDHq9GEOUdM26q+CgiPBaMGmZVH6dmJFNE5DqNT7gZaWJPipxrRYSTWTXPoTXjydSMWEVExgwRMz3tcWxc2gRVK0V81yxDQ8AnP1kazR0cROuyo9F5xbfRsPZkqPkMRn7+jxh7/Ad6Nsj03/89fjcxUfO7YngjU77MUCrr+WoEUS1b3plIPELN3IZYss9zFWgmmSIitDVTK2S5mFXdJqu6Hd8tfX6Gw9QMb4OXmZa4GFPaXFgOwjLJjKpmLjiuGzsHUnji94P4w1NW+n0c+zA/yMsvYx2AsRPOw5ILr4YSDCM/dhjDD30d+ZH9AEox7fuSyboZy7XLCSsMn8g7Q1O+tmcGmJro4WoEESb2oqrpygWva5mRYO38ho8VEM6TVZ2bVd281olErtP4BJeId7dTM64DzfiN7wpNVvXIrCq7IgIA55XbM795Z5hL/ounDA0BH/1oKSVVCWDq3C+g8yPXQwmGMb3rWfTf/efIj+xf9DHtvGA+EQB4bu+Ir2fxYzWCrpRybNmmTcZ9XtcyHi3wjMt2vPGaQ62ZRYW7ZFVOOSKcFBE+23eZwUucIpKcyQsdVZQ1Q8TMCStasLQ5hulcsXZ2zzA/yJYtKGzfjo5IHLE//AqaN38CADDxu/sw/PA2aLnpuolp54V5jNdPjGWR3v3uMLNqkqNSym6oQgGFW6S5kdfkXBHJuGzHu5qacTGYIRK5TuMTrsyqnJJVXeeIcNoMCfA3eJlhdz65osqlaJoP/WLqQUS1UxRFwXnHdQEAHq+FMd50GrjllpIfpLcXba1L0fjZ29Gw/lSo+QyGH7kNk8/cB0Crq5h2XrBC5IV9o776RA6OTQMAVrZ5qIgIaM2kBWwRZ9dZNwpmlmPEu92buVy5eAmTIiIf+tI7F+O7uaLq6OLBqmOnDmoGz/FdkWbVeCSIcLB0URDZnulPehvI5JTzjyulDP/324O+mxSrwvbFfOc7+ACAf1h2NFo/+4+IdK5CITWKwXtvwvTO3wEAzu7srKuYdl5sWtmChnAQ49N57B5K+XaOg+Ol351V7d79/HSzKkdFZEqAssvjOmtc8921ZjTNMJ9ahX28k9c6kch1Gp/gEfEOGLKXHbIuHdQMw0TlrhDRNM1Ync1hUdRcFEURHmqmqhoGJ70dP3TK6evakYiGMJzK4vXDk34fpzJMCSnvi9mx7lR0X/Z1BOMtyPa/g4F/+XPkBveiEeWAsv5+asU4IBw0fCLP+9iqO1BWRHravCtERCgiRkI0P2WXFSJuvHjuFRHjtcJue4Y8IhLjZhHQrCeFA58Ir6V3PBL/gJLcVyjfmYuYmgFMFx1BWSJj0znkiioUBehqkrsQiYaC+MDRpSV4j79VeSu1r7AipKyEvLrpfCz5w79GIBLDzLs7MPjTrShOjaE5EMDE44/jq888g0CIhvGcwtozfi3A0zRNb814qYiY84V4ecdEBDPGebRmXIZYmv0ddi0BVIhIjJtFQKGAAjbh5sQ8lCm4c1AzeJlVWV8VABojYl5Q9BRFQYoI84d0JqLS/cJV4sMnlNozD+445DiPRgimIuT9AN448zJ0fPi60r6YN/4bQ//xt9DyGfSEwxRQxokz1jOfiD95IsOpLLIFFcGAgmWt3ptV80WNm3dMxPQfD0XEmJpxdvOpKIpjb2KWzKrywgw8Tl60Sk8KZ0l3mqbpLzxuFRFe47tsYqYhHBSWSNreWJLtRwUlitbCxIyZC45biiVNUQylsnj0zX6/j1NiVhGi4Pfn/Qla3/cZAMDksw9g9JffBtQiehoa0Ds1RQFlnDhhRQvikSAmpvPYNei9T4S1ZZa1xDxdFd8QDuovjrzaM6lM6es0x/jEuwN8lGceaz30QsRm0aar/5LdoMl1Gp9wO9LkNEvEXLi4H98tVf1uA81E7plhdJQLkTFBhQgLZFoq8cSMmUgogMu3rAIA3P1sr7+HAWYXIUoAOz9yHZpP+R/QNBWjj9+Jid/+KwCgJxrFuxMT5AfhSMknUkpZ9SPu/YAPbRmg7B3j7BNJlj0izQ0cFRGXXryiqumGUTeLTvUNvDZvfvOkiMhLzmV7hH1exqZHxNxndL1rRo94L7rqsbJCpEmAUZXRkSgrIuV9FrypNUUEAD69ZRXCQQUvH5jAG4d8NK2ai5BgCLv+4CYkTjgPmlrE6M+/ialXfgGgPBmTTCJERQh3WNx7PRUiAP9QM5ZJ0sRREXEb8T7rms9DESGPyOKgUFTBWrFOpUinrRn28cGA4loGZZKhueJ2QlpghgijvbG0DVdUa8brFeY86GqK4SMnLAMA/MQvVYTtjfnOd/C+UBTvfPKv0XjMWdAKeQw/vA3p3z8FADh7xQqajBHIlrWlQuSl3nGhoX+VODhWUhN7/ChE4ny9Y2xVRTPHm6qYS0VklgruRhFx2ZrhFfDGC7lO4wPmF22nVaLTpDt9YobDk6LB1NpxY/bSWzOCjKoA0KkrIuQRMXPFmWsAAD97rQ8jgtSieWGR7Y8/jjWRBuz91N+gYd0pUHMZDP3H32DmnecBlIuQ3l6ajBHI8StaEAkFMJrOoXd02tPHZhMzfhQiuomdU5ZIknlEGjh6RFwGR7JrfiQYcLXHx+nNb85FeKdI5DqND5inFBwXIg6z/3X3tEt/CACEg4puLnVjpBK5Z4bRLtojkpR/z0wl3ruqDSeubEGuqOL+Fw9498CsCNm+HZ2xBPKXfhWxnuOhZtMY+re/Rqb3VQBUhHhFNBTEphUtAICXer2Ne/ezNcM71IwVIjzbzMyL5/Rmj9duMaevOW6iKkQi12l8IFssPTEUpTSK6wSn+2Z09zSH6lRRFH3GnYsi4kEhIqI1o2ka+idrI1W1Ep8vqyL3PH9AN5YJxVyENDQjftnXEV1+DIozSQz+9MvIHn4bABUhXnNKOdhsx/5xzx4zky9iMFUq4ns8jHdn8A41M1ozPKdmStdqp9OJrHBwe/PpVIUnRURSdPNOMOB4H4Hz1gyf0V1GTJ9xd76QiRUiIlJVGZ2JkkdkfDrHPSshOVPQv68y75mZj4s3LUNnIoKBZAaPvyV4/4y5CEm0I/7p2xDpXofi1DgG79uK3OBeAFSE+MGpq8s+EQ8LkcMTM9A0oDES1G8WvKS1wQg14wEzq3JtzXBSRNwmabObXzsDEua4CJqakQwePxinDma9X8ipOmWObjepf160ZtripYtcUdW49YMZbMdMe2OEW4HnJdFQEH+82YNRXlMRsqR5CRo/fVtpb0xyGAP33YT8yH4jsp2KEM85ZXVJEdkzNIVxQS3MuRww+UN4LYmzgyhFhGdrhnlEcgUVRSe7xfJ8zKJObn55+CFFIddpfCDvIlWV4XZqhtcLZgOHUDO2KEqkWTUSCuhO9tE0X1MmM6rWSoZIJS7fshqhgIIXe8fwzJ4R/g9gLkI6V6PxM7cj3LYc+YkBDNx7EwrjfRTZ7jPtjRGsW9IIwLv2zCEf/SGAoVzwuDnRNM0wqwoY3wWcqSJGmJnL1kzYviJi3oVGiohk8Jir1o1DNp+YvGQ6Bo/UPy/GdwGgo9ye4T05M1CjEzNmlrbEcNnmHgDAX/z7a/xUo3Qa+N73gC1bUNi+HV0rjkPi8r9HqKkDueH9GLz3JhSTQ2gOBCiyXQJOLasiXrVnDvg4MQMArXF+yzAzeVW/yeTZmjErGU6us7za8TEHikiWY24Vb+Q6jQ/kiu7bI25bM053DsyFxwbetAeBZoCRrsrbsKorIjVciADA1g8fizUdcfRPZnDrI2+6/4IsqOzaa/FXvb1YsmEzEpf+HYKxBDKH3sLgvTeiODVqFCEU2e47zCeyY783kzN+TswAZo+I+0KExbsHlJLnhReKorga4WWFg9tCIOZAEcmabAhuRodFUPeFSJaLR8Rta4aTIuJyxh0AUh5MzQDiJmcGanhixkxjNIRvXnoSAgrw8Kt9+Nlrfc6/2L59wOmn6xt0v7PpfDR/4hYEwlFMv/MChh74CtRsmooQyWCTM68dmnS0UNMuB8phZr4VIrpHxP01wRjdDXP3u7hZMJrlpIg48YjoN76cXm94It+JPIbHXLXrQDNeHhEOG3jTHhUiLOZ9jHNrpr8GU1Xn4+RVbbjm3A0AgFseekNvO1mGtWLOOAO5N99EWzCM319wtbFB9/XHMfzQ16AVslSESMi6zka0N0aQK6h483BS6GNpmqZ7RHra/fndaS3niKRzRdej65Mz4pRdY8Go/enEDIeFd+Yz2ImM0EeHOSnwPKn7QoSLWVX3iDhTRHj163iYVb2YmgGADj3mna9ZdWARmFXNXPuho7BpZQuSmQL+8sHXrI8779sHnHZaqRUzOIjmtuVo/Ow/oum9H4amqZj43X0YffS7gKZSESIpiqLg5FUsT0Rse2ZiOq+roSvb/FFEmmIhMPHCbXtGxOZdhhtFhFc73thvZsMjImm8O0CFCB+zqtPWDGdFhMf4rhdTM4DI1szi8IgwwsEAvnXpSYiFA/jtOyP45hO7q48N7tsHbN4MHHUUcm+/jTYA39p4Nro+/+1SRsj0JIb+7VZMPnMfAKAnHKYiRGJOLbdnXuoVa1hl/pDu5qhvY++BgKIXDm4NqyI27zLcDAUYrRlOioiN15ws5+EInsh3Io9hZlU3VaLj1gzn8V0j0KwGzKoCNvAmM8ZdXa17RMysX5LALR85FgDwvV/vwSd+8Aze6itv6O3uLsUCs7d165Dbvh09xSKalh+D6CduwZI/uBmBaByZg2+i/8f/G5neVwCUN+hOTVERIjGnmRJWRS7AOzhebsv4pIYw9MV3LkPNUhn+m3cZboYCMgU+iggrJuzcdGYkbs3UfUCADIFmvKSyeNhd6l+hqOqfK9wjUm7N8Nw30z9RUkNaGsLCz+81nzl9NULBAL7+y7fx+qFJfOx7z+CL71uL68cm8e8APq9/pIKG9aeiecsfYlnP8QAATVORfP5BTPz2HkBTEQbwl1u24O9+9zvKCJGcuQvw1nY2CnkcvydmGK0NYewHB0Vkhn+8O6PBxQ2fsV+MT7KqE0VERrNq3V+FuJhVHRiHzB/Pz6xa+j84nZpJmz5PfI4I/w28feWJmeWttW9UnYuiKPjjzavwoY1d+Juf/R6/eKMfdz39Lh644acYnhjFckWBoihQQhEEG0t30Voxj/RbTyH54n8iP3oQANCsKBh99FHKCKkR2AK8l/aP46XeMWGFiJ9bd820cMoSMTbvCmjNhJ23wI39Ym4DzRaXR4QKES7Jqk5bM3wVEbfju6wtEw4qwuU7liPC9s3wmGvvmygXIouoLTOXruYYvn/5yfjE7wfxlUfeRN8kEG5bNutj1Ow0Uq8+itRL/4Xi1Kj+/jPjcTw9OkqtmBrjlDVteGn/OHbsH8clp/YIeYyD5dFd3wsRTlkiQlszLjwi3ALNHBRDvKc0eUKFiI9mVWOum5ci4q4149XoLgC0lQsRVSut/eaxZIu1ZhajIjKX847rxtlHdeLt/iROP+NMABqgld7yY4eg5Wb0jw0DSH7ta4jdeCNArZia49TV7bgL7wpNWJWpNQOUrgluMFoz4hQRZ60ZPjefTuwAMisi8p3IY/gUIs48InqgmSSKSMqj0V2g1Apjdz+8DKtMEVnWWh93/LFwEO9d1YYfbduKXN8u5Pp3Izfwzqwi5OaODmTSacS+/GUqQmoU8wI8HmFfcykUVRye8DfMjKGbVV3+P0XsmWG4mU7ktV/MiSJCOSISo0e8u/KIuNs1w0sRcTPfDniXIcLgHfPOPCIr6kARMfO5z30O2t13QwNKb+vXQzvjDGiPPYZtQ0MIxP19cSHcYV6AJ2KMt38yg6KqIRIKoKspyv3r26GFkyKSEjm+y0ERcTtCa+SI2FFEaHxXWnhu383Zbs3wVUTcJP4B3rZmAP6G1b4JtvCuvgoRAMDnPqe3ZrBnD/Dss8CFF5IhdZGwZW1p78wL+0YX+Ej7MKPqyrYG33eQ8Fp8l5wRp4i4aYGzAQX347v27QAZTo8tgrq/Svk5vstLpmMYkqGzeGQ9zMyjQoT5QsY4pKuqqqaHmS2vk9YMUT9sWdsBAHhhH/+EVVn8IQBPsyrLQxKRI+J8OpGXKmFEvNtpzfAdjuCJfCfymCwPj0jY2dRMlnOOiDHf7k4RSQge3WV0JEoy8AgHRWQknUWuqEJRgO5FEu9OEIwt60qKyJuHJ/WJEF7IVIgYgWbyju/GXSgivKZmHJlVOcdF8KTuCxGuUzM2lQjuS+9cJP4BwJRPHhEeoWZsYqa7KeYqE4YgZGRZSwNWtcehauA+PXNwvDy663OqKmCamnFhVs0XVd2/IaI1E3MzvstJlWCvGbmiWn3lgwlSRCQmV+S5fdff1kyDqTVjeTmaiSmPPSLtPAuRyfqamCHqD90n8i7f9swBScLMAKDFpIg4uYYBwFTGUIQTIsd3XXhEeCkigHUlPssp1VUE8p3IY/Icx3dzRXsFAO+I9wbTkztjs00E+DA1o7dm3HtEDtdRhghRn2xZx3wifA2rByVqzTCPiKoZcQJ2YW2ZeCQoRB3VvXgSKCKAdSWexnclhikiUQ4R7+avZwXeS+/MhYgT2dBrRYRva2bxp6oS9Q1TRN44NOnYBzaX8XRO//1b1eF/IRINBfXrWNKhT0TknhnANJ2Yt/8zYC2juMtrbDCgIBwsTThZvenkNTosAvlO5DE8A80A69VpwdTb4/XECAQU/SxOZty9V0T45Ygs5j0zBAGUWicrWhtQUDXs4OQTee3QBABgXWejZ7/3C8EMq05HeI14dzH/Hz2vKWevFZ8vqvrrTWPE/c2nXW8iKSISw6MQCQUUsPF7q/26jMlPwvOJ4Sb1z2uzartp34xVw9V81HWGCFE38PaJvH5oEgCwaWULl6/HAyPUzNkNijExI0YRMRKs7Ski5ptDNnnjBnYDa1URIbOqxGQ5mFUVRbG9b8ZcKPB8YrhJ/fM8R6QcXqRppWLEDSzevd5SVYn6go3x8vKJvF5WRDatbOXy9XjgVhFJ6hkighWRfBGaZv0GirXTwkHF1Y0vg73mWM2N4j0cwZO6L0R4mFUB+1ki5vwSnmmGDS5i3o1kVW+eqKFgQL/ouPGJ5AoqhsuGV5qaIRYzLNjstYOTjlRPM5qm4bWyInJijzyKSGtDOV3VsUdEXKoqYIzvqpo9T2C6fKPHQw0B7K8W4T0cwRP5TuQx7InkJlkVsJ/9L+pJ4WZFtdceEcBoz7iJeR9MZqBppaKug8MWX4KQldUdcXQ3R5Erqnj5gDufyEAyg+FUFsGAguOWyVOI6OmqDlXSpMA9M4DzoQCmiPDwhwBAjCkiFlV43SNCZlX54OERAWC7NSMq5c5da8b7QqSzsTTCO+oi5r3PNDGjKP7uyiAIkSiKYsS9u/SJvHawpIYc3d2k38DIQHuCTdO5NauKUUTCwYA+sWJHedYVEU7XV7uKCK89NyKgQkR3EvNRRKybVcWMUrEiIm1zBl/TNF8VETetGTYxQ0ZVoh7g5RNhEzMnSmRUBcxbuZ3dnIge3wXMC0ZrRxER9ZrDA/lO5DE8klUBs0fEbmuGb3XK7gKSNvdRzOSLYIMrXplVAWOE182+mT4KMyPqCKaIvHJgwvZ+KzMyGlUB91u5Re6ZYcQdtMDTOb4eEX1qhhSR2oebWdXhTDfv6pQ5xZMZe4oIa8soivFL5gUdHDbw6q0ZMqoSdcD6JY3oTESRLah6e8UuqqpJOboLAB2N7hKXRbdmAGd7vaY5DwPYsQNomkbjuzLDxnfdFyI2p2ZYyh3n6pTNztvd0Mn6l42RkKc+Cxbz7sas2j9JighRP5R8IixPxFl7pnc0jVSmgGgogGOWNvE8nmvcBh0arRlxikgD28ArgSJixSNSUDVd8Y7S+K5caJpmmFU5Tc1Yb82IcTAzRSRlUxHxwx8CmKZm3HhEJphHhBQRoj5gPpHnHfpEmBpy3PJm6bZVd5ZvTsbTOUeL71JZLxSR0vesVhQRUblVvJDvRB6SLxpPcs+nZgpiFBHdI2JzBp8VLl5liDB47JuhMDOi3jhzfScA4MV9Y5h0EPxlGFVbOZ6KD23loMOCqtn2ugGGItIi0CPiJCbBT49IdlaSt3wv+/KdyEPMYTSuFRHb4TJixneba0wRMVozzvrBU9mC7odZRoUIUSds6ErgmO4m5IsaHv/9gO3Pl9UfApRuCtl1zK6JXdM0vS0tcmqmIVxuzdhRRHhPzYStr/MwB2jKGHFQ14VI3lQl8vOI+Btoxn75mDxplXTO2827DNaamZjJo2AjpZDBtu42x0LSLO0iCC+4eNMyAMAv3ui39XmFooq3+lgh0sr7WFzodHiDks4Z039CWzMR++O73HNEbLzm6Jt3JVRDgDovRJgiEgwoCLqMWbffmmEeEd6tmfLUzIyzqRmvX8zb4mEoCts3Y1+GPTxBW3eJ+uQjJ5QKkd+9M4IJGymkuwenkMmraIqGsK6zUdTxXOHUsMpa0uGgIjQvI+5g8R1vRSRqRxHJi3m94UV9FyKcjKqAg0CzvJhwGedTM/4UIqFgAK0NzvfN0MQMUa9s6Epg49ImFFQNj781aPnzWH7I8StauO654kmHnrhs75rAWtLNsbDQFkS87KVL++gRsbNWRObRXaDOC5EspwwRwOwRsTk1w92sanhE7GyGnMr405oB3PlEaGKGqGc+Wm7P/NxGe4Ytutsk0aK7uRihZvauCUk9Q0TsdaypfJ2csuHF4z01wzwiVm5+RXkSeVHXhUieU6oq4GJqhvv4bkldKKiaLSPVFMsR8aEQcTPCS6mqRD3D2jPP7BnBuMXfH6aInCSpPwQwxbzbNKvqm3cbxPlDACBRLnSmbKzS4D81w1ozpIjUNLz2zJi/hvXWjJgKtTESBFNb7UzOGK0Z7ytm46LjXBGhVFWiHlm3JIHjljWjqGr4v28tPD2TyRexcyAFANjU0yr4dM7RVVKbicvsmidaEUlEWQvcgUeEW46I9decLMfXOhHIeSqPyHFKVQUcTM0IqlAVRdFVETs+kamcPx4RwJBhnXlE2OZdUkSI+sTO9MxbfUkUVQ2diQiWS9zOdLqDKunB6C5gVkSsX2P1qRlfFBFqzUgLV7Mq69dZ3TUjsGfH7gYmbUzOpLP+eUTaHRrTNE1DH5lViTrn4nJ75tm9owuqiuZFdzLmSTCYWdXuzYnemhFciOgeERutGWNqxvtAM1FxEbyQ81QewQqRcMj9L6TtXTMCVzI3O1FEMv4pIp0Ot22OpnPIFVQoCtDdLO/dHUGIZE1nI45fwdoz80/PFIoq7n/xIADglNVtXh3PEZ0OzaqetWZi9syqqqrpmSNxzhHvOQsqvNGaIUVEOvTWjA9mVaNCFaeI2OlfTvmqiDhrzTB/yJJElEt7jSBqlYtPWA4A+MUbffN+zE9fPIBdgym0xsO4fMsqr47mCHZNGJ+2F3Sot2ZEm1VtKiLmwQE/FBGW+M17txkv5DyVR+R4ju/a9IgYPTv+PwJ934wNRcSvZFXAtPbbpjGNJmYIogRrzzy3dxQjFVSEiekcvvnEbgDADecfjdbyPhdZaY1HdNP9mI2wtqSeIyLarGrvZo9dXxWF3zXfzs2v/npDioh8GIWI+x+O/V0zYpbeAUBzg31FhBmpREualWAZIIfHZ2xt26SJGYIosaojjk0rW6BqwF8//KYeTcD49n+/g/HpPI7uTuDTm+VWQ4BS2nW7gxFe5hERGe9e+vql62S2oFpqjUyzeIRIiJs3hxSRRYKI1oyVJyVgCjSTxSPiY2tmZVsDIsEAsgVVj2y3wsHxaQA0MUMQAHDjhRsRDip49M0BXH//q3ox8s5gCv/6/H4AwK3/4z0IcbjeeYGermqnEGGKiODWjPk6mbbQnmGKSJxTvDtgmpqx5RGR82cv56k8wlBEeJpV7QWaifSIWN03kzNV9QlO/Us7hIIBrC3vvNgzNGX583YPlvIQju5uEnIugqglzj6qEz/8zCkIBxX84o1+XH//qygUVfztz3+PoqrhguO6cdaGTr+PaRlj34z1lq2xeVfsdSwcDOiKhBWfCDOq8rzRY685RVVb0EdTl+O7vb29+MIXvoC1a9eioaEB69evx6233opczn5OhEjyPBWRsL2pGSPQzH9FxFzR8wrbscuGrgQAe4XIzv5SIXLMUipECAIAPnRsN+683ChG/vDOZ/Hbd0YQCQZwy8XH+n08WzhrzbCpGbGKCGAv1IxdY0UoIsDCqkhdju/u3LkTqqrirrvuwltvvYVvfetb+OEPf4gvf/nLIh7OMVx3zYTs5YjINDUzUe6rJqIh32Tb9TYLkeFUFqPpHBSFFBGCMHPecUYxwvbK/M+z12J1h5ybduej00G6qjE1I17ZbbIR864rIhwVZ/MN9ELeRNnHd4X8tC666CJcdNFF+t/XrVuHXbt24c4778Ttt98u4iEd4dfUjKZpQqUyu1MzbGy2rVH8XcR86IrIsLVCZFc5pnpNRyMaON5lEMRi4LzjuvGDy0/B/7p3B7qbY7jmgxv8PpJt7O6byeSL+jXdG0XEerqqrohwVJwDAQWRUAC5grqgIqJbASQ1q3pmCJicnER7e3vVj8lms8hmjeo3mUwKPZNhVuUwNVMuRHJFFaqqVV2vbS5WhJhVbU7NTJTH49p8HOnbsMRQRDRNW9BZvnOg9Nw4htQQgqjI+cd14/mtH0I4FPAlqNAtbN+M1Zh3dr1TFCP5VCR2RnhFKCIAEGOFyAKKiG4FkFQR8aQ82rNnD+644w78yZ/8SdWP27ZtG1paWvS3np4eoefimqxqUjZyCxmHTO0bEU8MY9eMtUJEV0R8LETWLWmEogCTM3lLFx62uIv8IQQxPx2JqPC4c1EYO6istWaYJy4RDVW9EeSFnQ28IqZmAOurRWRXRGyd6uabb4aiKFXfdu7cOetzDh8+jIsuugiXXHIJrrrqqqpff+vWrZicnNTfDh48aP9/ZANmVo1yGd819+usPSkCChAO8v+FMaZmrLVmxsuKCDOH+UEsHERPWxyANZ8Ia80cu4wKEYJYjOitGYuJy0aYmTeFl75vxooikuU/NQOYskQWGJJgr0mymlVtfVe+9KUv4Yorrqj6MevWrdP/3NfXh3PPPRdnnnkm/umf/mnBrx+NRhGNRu0cyRU8PSKhgIKAAqgaKzTm/2XQM0RCQSGLp9gv4lSusGCbCCjFKANAa9zfO6cNXQkcGJvGnuEpnLG+Y96PK6qaPrp7zNJmr45HEISHsNaMVY+IEWbmTRtKBkWEKeoLtmZ0RUTO1oytn9iSJUuwZMkSSx97+PBhnHvuuTjllFPw4x//GIGAfJUYz0JEURREQ0HM5IsLGlYzAhfeAcYvoqaVipGF7hDGy3cc7T7HPm/oSuDJnUPYu4Aisn80jWxBRSwcwKr2uEenIwjCS1hrZipbQCZfXNDYn/IozIxhyyMiSBExYiOs2QFkVUSEnOrw4cM455xzsGrVKtx+++0YHh7GwMAABgYGRDycY7Icc0QA61ki2bzYcJlYOKj/n6y0Z4ypGZ8LkSXWRniZP+To7iYEPegFEwThPU3RkH4ds9KeSXoUZsaQSRGh8d0KPPHEE9izZw/27NmDlStXzvo3TbO+S0Q0hlmV1xIilv1vTRERWZ02N4QwMpWzVK1PlFszfppVAWB9l7V0VVaIbCSjKkEsWhRFQUcigv7JDMamclixwHJLdtMlpUdE0NSMZUXEg9ccNwg51RVXXAFN0yq+yQTPZFXA+jZEfeGdwH6dnckZtt3SzxwRANiwpFRYDCQzVVNhd7HRXfKHEMSihhnorWzmZtc6KT0iAnJEABseEcEqvFvkLI88gqdHBDCHmll0MAstRKxPzoxLML4LAC3xsJ6muHc4Pe/H7SJFhCDqAjuGVSNV1SuPSPlmz0ZrhnuOCFt8Z3V8t54UkVohx3kjoVWZzJPWDFNEFkj9U1VNj3j3c3yXsaHcnpnPsDqdK2D/WGnrLmWIEMTiplNPV7WuiHjVmtGTVS0kWDOzKvccEQs3v+Yk70WRI7LY0JNVuSki1sJlvJDJrO6bSWUKKKqllpnf47vAwlHvuwenoGmlPRRMPSEIYnFibOC1oIh4PL5rZ9eMrohwn5pZWBHJFVUwVwS1ZiREN6ty84hYbM2w8V2BiojVQoSFmTVGglI4qheanGH+EGrLEMTiR+7WjP1AMz8UkVkrRag1Ix857mZVi60ZDzwiTJ5cyCNiGFX9b8sAwIauUoExX2uGot0Jon5o19NVJWzNlG/20rmiripXQtM0YYqIFY+IWaHn9VrHGzlP5RH8zao2p2aEKiJsA+8Cikja/3h3M6w1s39sWv/5mNnZT4UIQdQLnQnrG3g9T1Y1FRWs0KhEtqCC1Sncc0RYxHuVqRmzUVVEkjcPqBABx0KEmVUthst44xGprogY8e5yFCLdzVEkoiEUVQ29o7MnZzRNw65ytPuxNLpLEIuejkbWmqmuiBRVTV+W6dVNVTQU0HeFVWvPpE0ekjjvHBELN7+yj+4C9V6I+NSa0WfKOVfHZlif1LIiIoFRFSiFGK3vquwTGZ7KYiydQ0ABjupO+HE8giA8hJlVR9K5qjlUfRMzyBVVRIIBLF8g+IwXiqIYPpEqhlUWZhYLB7gnQdtVRGRF3pN5QN6n1gxTKURKiFYVEeYRkUURAeY3rLL8kDUdjVJX9wRB8IEpIrmCWvXFfv9oaaS/p73B07UPCQtDAaIyRABrrzmyj+4CdV6I8B/ftTY1YyQAilMhrE7NTEzL5REBTCO8cwoR8ocQRH3REAnqyvFYlRHefeU27trORk/OxWChZtWKpDSbmOGcqgpYU0QMT6K8N291W4ioqoZ8sST1cV96t0COiBdRxJanZiRZeGdm3kJET1QlfwhB1At6e6aKYbV3pFSIrO7wthCxsm9mWqAiwpThaq85pIhIDFNDAD9bM+IUkWaLu2bG9YV3cnhEAKMQeXdkCqppLG7XINsxQ4oIQdQLVgyrrBBZ47UiooeazX/DlxaUIQJYzBFhcRESKyLezDlJiLkQ8TrQzAtFhH3tmXwR+aI67//RMKvKo4j0tDUgEgwgk1dxuGxC+/XOIeweLCkkFGZGEPVDp4V0VTZht9ZjRYSZVavd8E0LyhABLOaIFAyzrKzUbSGSL/APebE6NZP0sBABSr8k83lAxiU0q4aCAaztbMSuwRT+4PvPzOoNdzVFsao97uPpCILwkoUUkaKq4eDYDABgTae31wYrG3jTOXGKiO4RIUWkNmGKSDioIMDJZR210K8DjNaMyATAUDCAeCSI6VwRqUy+YiGiaZrempHJrAoAG5c1YddgCmPpHCLBALasa8c5x3Tho5uWcft5EQQhP+0LKCLm0d1lLd6M7jIseUSyHkzNWFBEZB7frd9CpMA3QwSw1prJFVRdMREdRdwUC5ULkcq/JEnJFt6Z+YsLjsHazka8Z3kLzlzfIUTWJAhCfjoaq6ersrbMqo64p6O7ACzliOiKiMipGQu7ZqgQkRDeqaqANbOqOdcjITiKuDkWxmAyO+/kDPOHxCNB6XI5etrjuP68o/0+BkEQPsO2bM+3b0Y3qnrsDwFMOSLVAs18VkT08V3JrvFm5C2RBJPlvHkXsOYRYepEYyQovHpnPpH50lWZP6RNIn8IQRCEmY4F9s3sGymFma312B8CWNvAa3hEBBQiJkVkvuTZWlBE5D2ZYPKcw8wAa7tmvAgzYzTpI7zzKCIShpkRBEGYYWbV+XJEWGvG6wwRwLjZqx7xzqZmRLRmSl9T02ZPgpoxckRIEZEOka2ZSltjGV7EuzMW2jcznmYL7+TyhxAEQTCYIjI+nZuVK8To9SlVFTAlq1Zdele6MRXhczOrHPMp8V5se3eLvCcTDO+Fd4C11owXo7uMhfbNkCJCEITstDdGEAkGKm7kLhRVHBwrtWa8DjMDrI3vMkVExPhuJBiAUu7wzxfzro/vkiIiHzkBfTO9NVPFwexFqipjoX0zerw7eUQIgpCUcDCA965qBQA89+7orH/rm8ggX9QQCQWwrDnm+dmMQLMqyaplj4gIs6qiKMYN8DyG1VoY35X3ZILJCTGrLuxg9iJVlbHQvhkj3p0KEYIg5OXM9Z0AgGf3zi5EdH9Ie9yXfCGzR2Q+syibmhExvguY9s3McwOcyZNZVVp4b94F7E3NeKGINC+giOjx7o3kESEIQl7O3NABAHh+7+gsnwgrRPxoywCGIqJqpXUalZgWqIgAxlbd+WLedUWEWjPyIcasWvpauaJa0VQFAEk9VdULj0h5amaehUxjEsa7EwRBzOXEla1oCAcxms5h91BKf/++Ef+MqkDJ98E8GvP5RNICp2aAhS0BNL4rMULMqqaKc75RKm+nZso5IjOVf0EmyKxKEEQNEAkFcNradgDAM3uM9oyfYWZAyaOxUJbIdFZcjghgRRGRf9dM/RYiAhURYH6fiEw5ImNp8ogQBFEbnLm+1J55bu+I/r79o+WJmQ7/FmE2VYl5zxVU/aZUWGtmAUXESFaV9+Ve3pMJRsSumVBAAfNLzZf976VZtdrUjKZpuiLSRh4RgiAkhxUiL7w7hkJRRaGo4oCPo7sMfYS3wnV2Jme8DjQIGN8FDKWDFJEaRESyammUqvrkjJfju/rUTCZ/hKM7lS2gUPaxkCJCEITsvGd5C5pjIaSyBbzZl8ThiRkUVA3RUABLfRjdZegjvBUUEeYPiQQDXF9rzOgx7/PliOhmVXlf7uU9mWBEtGaAhY1Dfigi+aJ2xCQPm5hpCMu38I4gCGIuwYCC09eVVJFn946gV2/LNPoyustIxOZPV9XDzAQZVYGFl63S+K7EZAWYVYGFR3i9TFZtjIR0R3dyjk+EZYiQUZUgiFrB8ImM6kbV1T76Q4DqHhE93l2QPwQwvB/zJ6vS9l1pEaaIhKqHy6T08V3xrZlAQNF/SeZOzjBFhPwhBEHUCmduKAWbbe8dw67B0hivX6O7jES1QkRgvDuDFRgLe0TkfbmX92SCYR4RnsmqAKrG7eYKqv6k8EIRKT1O5ckZincnCKLWOKorgc5EBJm8il++0Q/AX6MqYJhVKw0F6KO7AhbeMQwV/sibX03TyKwqM+I9IkcWIuZiICHwiWlmvskZtvCOChGCIGoFRVFwRjnufaLcXva7NWMoIkfGJOhhZj4pIubXIRrflRARS+9KX2/+1gwrBuKRIEKclZj5aG4wJmfMGIUItWYIgqgdmE+E4XdrpqnK+C6LdxcVZgZUV0TMhQgpIhIiYtcMUN2s6uXEDGO+fTP6wjsyqxIEUUOYC5FYOIDuJv9Gd4EFPCJZsfHuwEKKSKk4URQgHPRvsmgh6rcQEbB9F6juEfEyQ4Qxn0fEWHhHhQhBELXDqvY4VrQ2APB/dBdYwCPigSKiJ6tWmJphr0OxUBCKQoWIdOSKpTAv/uO787dmvBzdZTBFZO7UDDOr0sI7giBqCUVRdFXEb38IYG1qRqRHpFqOSC2EmQH1XIiUf0CizKqVZDIvR3cZ8ykizOjVToUIQRA1xufPXIN1SxrxqVN7/D6K4RGpUIh4MTVTLUekFsLMAMC7W3PJEDU101I2h07M5I74Nz88IvNNzYzRnhmCIGqU41e04MkvneP3MQAAiej8yapeTs1UVUQkNqoC9ayICDKrdpd3Hgwls0f8m5ebdxmVpmY0TTMCzUgRIQiCcIzuEfFJEWFqRyVFRPeIUGtGTkRs3wWAJU1RAMBgqlIhwloz3isiSVO1PkUL7wiCILjAPCKlwMrZxYAnHhE2NVNlfJcUEUnJM7OqMEUkc8S/+dOaYR4RoxAZT5cKolg4IGw1NUEQRD1gDqdku2UYnuaIVBnfld0jIvfpBCJKEekqKyJDlRSRrPfju0x96Z+cwWTZoMrCzMioShAE4Y5gQNF3ycz1iXiaI1JBEcnorRm5bzjrthDJCjKrMkVkLJ3Tix2GH4rIscuasbwlhonpPP7knpeQK6gmoyoVIgRBEG5hqkhqTsy7JzkibHyXFJHaQ9T4bls8rCfYDU/NVkWSM94rIrFwEP985WlIREN4/t0x3Pwfr2NsioyqBEEQvEjME/M+nROviESrjO/qHhEyq8qJPjXDuTWjKAq6ypHDg3N8In4oIgCwcWkzfnD5yQgGFPznK4fx/V/vAUCKCEEQBA+a5gk1Y56RRqHJqqw1c6QiwooTMqtKiiizKgB0NZd9InMKET+SVRnvP3oJvvbx4wEA746kAQDttPCOIAjCNYkKoWZFVcNMnrVmRCarll7DcgUVmqbN+jca35WYoqqhqIqJeAfmN6z6kaxq5rLNq/Bn56zX/07x7gRBEO7RPSKm1syMqVXSKDRZ1Shy5oaa0fiuxJhNpCIUEWZYNbdmSjPmpcf1QxFh/OUFx+DjJy0HAJzY0+LbOQiCIBYLerqqSRGZLv85oIg1i8ZMX3uuYbVWzKp1GfHuVSFiTlc173pJCKyOFyIQUPCtS0/CX330OHQmor6dgyAIYrHQVMGsms4Z/hCRm29DwQCCAQVFVUOmUEQLDMVd3zVD47vykS0akllIwArpSumqTLKLR4IICWgH2UFRFCpCCIIgOFFpAy/LEIkLnJhhxOaJea8VRUTu0wnCbFQVUalWSlf1a2KGIAiCEEuiwnLR6Zz4iRnGfIvvDI+I3C/1cp9OEKw1ExWkTFQyq7LWjJcZIgRBEIR4DEXEaMGzPTNeKCLzLb7Tx3epNSMfOUGpqoxK6ap+ju4SBEEQ4miqML6rb971UBHJHGFWLY/vkiIiH6ILkUrpqqSIEARBLE50RWSWWVX85l0Gey2bu/03S2ZVeWGpqmFBrZlK6arkESEIglicGLtmjhzfjXswJTmfIpIhs6q8iFZEAHO6KlNESk/KZipECIIgFhXmXTOapuGxNwdw93P7AXijiLDk1PkUEdm379blq6KoPTNmDMMqU0SoNUMQBLEYaSoHmk1M5/HJO5/FKwcmAJTa9J9470rhj8+SU4/0iNSGIlKfhYgHisjcdFW9NeNjmBlBEATBH6aI5IoqXjkwgYZwEF9831pc9f51nqz0iM2zgbdWxnfr8lVRL0QEKiJz01VTWaaI1OW3nCAIYtHSHAuhMxHFxHQOl23uwf/+4FHoKr8GeAFTRObmiGSoNSMv+aJ4RWRuuqphVqXWDEEQxGIiFAzgsevfB1XVPC1AGPMrItSakRYvWzMsXZXliDQ3UCFCEASx2PBzbcaCyaqSKyJyl0mCyHpgVu1unp2uaphV67L2IwiCIATBFI+sSRFRVc1IESdFRD4uPK4bR3cl0BIXp06wHBGWrko5IgRBEIQIjBwRoxBh06Hmf5eVunxV7GqOCe/jsXTVfFHD8FQWyZmSIuKFg5ogCIKoH3RFxNSayZpGeWVXRISfLpvN4qSTToKiKHj11VdFP5w0mNNVD41N608QUkQIgiAInlRSRJhRNaAAoQD/LfM8EV6I3HjjjVi+fLnoh5ESlq66dzitvy9BOSIEQRAER6IVzKrm0V1FqeNC5NFHH8Xjjz+O22+/XeTDSEt3WRHZOzwFAIhHgggJNMgSBEEQ9QdrvVRSRGRvywACPSKDg4O46qqr8PDDDyMej1v6nGw2i2w2q/89mUyKOp4nMEVkz1CpEKG2DEEQBMGbSkvvjFRVuY2qgCBFRNM0XHHFFfjTP/1TnHrqqZY/b9u2bWhpadHfenp6RBzPM1iWiFGIkFGVIAiC4EssdOTSO6aORMPyKyK2TnjzzTdDUZSqbzt37sQdd9yBVCqFrVu32jrM1q1bMTk5qb8dPHjQ1ufLBktXPTwxA4AUEYIgCII/0SqKSKwGFBFbr4xf+tKXcMUVV1T9mHXr1uHJJ5/Ec889h2h0dtLcqaeeissvvxx33313xc+NRqNHfE4t0z1nRJgUEYIgCII3TBHJFCp4RGpAEbFViCxZsgRLlixZ8OO++93v4qtf/ar+976+Plx44YV44IEHsGXLFvunrFFYuiqDFBGCIAiCN/rUTP7IqZm6NauuWrVq1t8TiQQAYP369Vi5cqWIh5QSliPCaKZChCAIguAMW3qXzhWgqhoCAUVXRGRPVQXqdNeMV7B0VQa1ZgiCIAjerGhtQDwSxMR0Hve+sB+AoY7UgiLiyQnXrFkDTdNw0kknefFw0mBOVwWAJgozIwiCIDjTFAvjpos2AgBue3QnDo1P0/guYdBl8omQR4QgCIIQwWdPX43T1rQhnSti63++YYzvkiJCdJsVEWrNEARBEAIIBBTc9oebEAkF8Nt3RvDgjkMADCOrzFAhIhhSRAiCIAgvWL8kgRvOPxoA8E45SJMUEWJWlggpIgRBEIRIvnj2WpywokX/ey3kiMh/whqHpasCpIgQBEEQYgkFA/jGH21CKFCa2KyFZFUqRARjVkSaSREhCIIgBHPssmbc/OGNaAgHsXltu9/HWRC6RRdMN3lECIIgCI/54vvW4cqz1iIYUBb+YJ+hV0bBLGtpQCigIBwMUCFCEARBeEYtFCEAFSLCaWkI44efOQXRcAChIHXCCIIgCMIMFSIecN5x3X4fgSAIgiCkhG7RCYIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDSpECIIgCILwDam372qaBgBIJpM+n4QgCIIgCKuw1232Ol4NqQuRVCoFAOjp6fH5JARBEARB2CWVSqGlpaXqxyialXLFJ1RVRV9fH5qamqAoit/H8Z1kMomenh4cPHgQzc3Nfh9n0ULfZ2+g77M30PfZG+j7PBtN05BKpbB8+XIEAtVdIFIrIoFAACtXrvT7GNLR3NxMT3QPoO+zN9D32Rvo++wN9H02WEgJYZBZlSAIgiAI36BChCAIgiAI36BCpIaIRqO49dZbEY1G/T7Kooa+z95A32dvoO+zN9D32TlSm1UJgiAIgljckCJCEARBEIRvUCFCEARBEIRvUCFCEARBEIRvUCFCEARBEIRvUCFS42SzWZx00klQFAWvvvqq38dZVPT29uILX/gC1q5di4aGBqxfvx633norcrmc30dbFHz/+9/HmjVrEIvFsGXLFrz44ot+H2lRsW3bNpx22mloampCV1cXPv7xj2PXrl1+H2vRc9ttt0FRFFx//fV+H6VmoEKkxrnxxhuxfPlyv4+xKNm5cydUVcVdd92Ft956C9/61rfwwx/+EF/+8pf9PlrN88ADD+CGG27ArbfeipdffhknnngiLrzwQgwNDfl9tEXD008/jauvvhrPP/88nnjiCeTzeVxwwQVIp9N+H23Rsn37dtx1113YtGmT30epLTSiZvnlL3+pbdy4UXvrrbc0ANorr7zi95EWPd/4xje0tWvX+n2Mmmfz5s3a1Vdfrf+9WCxqy5cv17Zt2+bjqRY3Q0NDGgDt6aef9vsoi5JUKqUdddRR2hNPPKF94AMf0K677jq/j1QzkCJSowwODuKqq67Cv/7rvyIej/t9nLphcnIS7e3tfh+jpsnlctixYwfOO+88/X2BQADnnXcennvuOR9PtriZnJwEAHr+CuLqq6/GxRdfPOt5TVhD6qV3RGU0TcMVV1yBP/3TP8Wpp56K3t5ev49UF+zZswd33HEHbr/9dr+PUtOMjIygWCyiu7t71vu7u7uxc+dOn061uFFVFddffz3OOussHH/88X4fZ9Fx//334+WXX8b27dv9PkpNQoqIRNx8881QFKXq286dO3HHHXcglUph69atfh+5JrH6fTZz+PBhXHTRRbjkkktw1VVX+XRygnDG1VdfjTfffBP333+/30dZdBw8eBDXXXcd7r33XsRiMb+PU5NQxLtEDA8PY3R0tOrHrFu3Dp/61Kfws5/9DIqi6O8vFosIBoO4/PLLcffdd4s+ak1j9fsciUQAAH19fTjnnHNw+umn4yc/+QkCAarf3ZDL5RCPx/Hggw/i4x//uP7+z3/+85iYmMAjjzzi3+EWIddccw0eeeQR/OY3v8HatWv9Ps6i4+GHH8YnPvEJBINB/X3FYhGKoiAQCCCbzc76N+JIqBCpQQ4cOIBkMqn/va+vDxdeeCEefPBBbNmyBStXrvTxdIuLw4cP49xzz8Upp5yCe+65hy4onNiyZQs2b96MO+64A0CpdbBq1Spcc801uPnmm30+3eJA0zRce+21eOihh/DUU0/hqKOO8vtIi5JUKoX9+/fPet+VV16JjRs34qabbqJWmAXII1KDrFq1atbfE4kEAGD9+vVUhHDk8OHDOOecc7B69WrcfvvtGB4e1v9t6dKlPp6s9rnhhhvw+c9/Hqeeeio2b96Mb3/720in07jyyiv9Ptqi4eqrr8Z9992HRx55BE1NTRgYGAAAtLS0oKGhwefTLR6ampqOKDYaGxvR0dFBRYhFqBAhiHl44oknsGfPHuzZs+eIAo+ERHdceumlGB4exle+8hUMDAzgpJNOwmOPPXaEgZVwzp133gkAOOecc2a9/8c//jGuuOIK7w9EEPNArRmCIAiCIHyDXHcEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfgGFSIEQRAEQfjG/wM+Mbg9yFnJtwAAAABJRU5ErkJggg==",
"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
}