1402 lines
200 KiB
Plaintext
1402 lines
200 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "b18bcd06",
|
|
"metadata": {},
|
|
"source": [
|
|
"<!-- HTML file automatically generated from DocOnce source (https://github.com/doconce/doconce/)\n",
|
|
"doconce format html exercisesweek41.do.txt -->\n",
|
|
"<!-- dom:TITLE: Exercises week 41 -->"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "7542d6aa",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Exercises week 41\n",
|
|
"**October 4-11, 2024**\n",
|
|
"\n",
|
|
"Date: **Deadline is Friday October 11 at midnight**"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "80943a15",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Overarching aims of the exercises this week\n",
|
|
"\n",
|
|
"The aim of the exercises this week is to get started with implementing\n",
|
|
"gradient methods of relevance for project 2. This exercise will also\n",
|
|
"be continued next week with the addition of automatic differentation.\n",
|
|
"Everything you develop here will be used in project 2.\n",
|
|
"\n",
|
|
"In order to get started, we will now replace in our standard ordinary\n",
|
|
"least squares (OLS) and Ridge regression codes (from project 1) the\n",
|
|
"matrix inversion algorithm with our own gradient descent (GD) and SGD\n",
|
|
"codes. You can use the Franke function or the terrain data from\n",
|
|
"project 1. **However, we recommend using a simpler function like**\n",
|
|
"$f(x)=a_0+a_1x+a_2x^2$ or higher-order one-dimensional polynomials.\n",
|
|
"You can obviously test your final codes against for example the Franke\n",
|
|
"function. Automatic differentiation will be discussed next week.\n",
|
|
"\n",
|
|
"You should include in your analysis of the GD and SGD codes the following elements\n",
|
|
"1. A plain gradient descent with a fixed learning rate (you will need to tune it) using the analytical expression of the gradients\n",
|
|
"\n",
|
|
"2. Add momentum to the plain GD code and compare convergence with a fixed learning rate (you may need to tune the learning rate), again using the analytical expression of the gradients.\n",
|
|
"\n",
|
|
"3. Repeat these steps for stochastic gradient descent with mini batches and a given number of epochs. Use a tunable learning rate as discussed in the lectures from week 39. Discuss the results as functions of the various parameters (size of batches, number of epochs etc)\n",
|
|
"\n",
|
|
"4. Implement the Adagrad method in order to tune the learning rate. Do this with and without momentum for plain gradient descent and SGD.\n",
|
|
"\n",
|
|
"5. Add RMSprop and Adam to your library of methods for tuning the learning rate.\n",
|
|
"\n",
|
|
"The lecture notes from weeks 39 and 40 contain more information and code examples. Feel free to use these examples.\n",
|
|
"\n",
|
|
"In summary, you should \n",
|
|
"perform an analysis of the results for OLS and Ridge regression as\n",
|
|
"function of the chosen learning rates, the number of mini-batches and\n",
|
|
"epochs as well as algorithm for scaling the learning rate. You can\n",
|
|
"also compare your own results with those that can be obtained using\n",
|
|
"for example **Scikit-Learn**'s various SGD options. Discuss your\n",
|
|
"results. For Ridge regression you need now to study the results as functions of the hyper-parameter $\\lambda$ and \n",
|
|
"the learning rate $\\eta$. Discuss your results.\n",
|
|
"\n",
|
|
"You will need your SGD code for the setup of the Neural Network and\n",
|
|
"Logistic Regression codes. You will find the Python [Seaborn\n",
|
|
"package](https://seaborn.pydata.org/generated/seaborn.heatmap.html)\n",
|
|
"useful when plotting the results as function of the learning rate\n",
|
|
"$\\eta$ and the hyper-parameter $\\lambda$ when you use Ridge\n",
|
|
"regression.\n",
|
|
"\n",
|
|
"We recommend reading chapter 8 on optimization from the textbook of [Goodfellow, Bengio and Courville](https://www.deeplearningbook.org/). This chapter contains many useful insights and discussions on the optimization part of machine learning."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "2095d197",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Code examples from week 39 and 40"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f428decb",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Code with a Number of Minibatches which varies, analytical gradient\n",
|
|
"\n",
|
|
"In the code here we vary the number of mini-batches."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"id": "ba38d454",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Own inversion\n",
|
|
"[[4.04881585]\n",
|
|
" [2.96745096]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.37175588 4.15690073]\n",
|
|
"theta from own gd\n",
|
|
"[[4.04881585]\n",
|
|
" [2.96745096]]\n",
|
|
"theta from own sdg\n",
|
|
"[[4.04015455]\n",
|
|
" [2.95745651]]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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fkP1ueeee/DNN9/gzTffxI0bNxAXF4dHHnkEL730kkuOi8gXqYQQwtOFICIiIvIU9hkiIiIiRWMwRERERIrGYIiIiIgUjcEQERERKRqDISIiIlI0BkNERESkaIrIM6TX63Hu3Dk0atTIYjp7IiIikh8hBK5fv47Y2Fj4+bmu/kYRwdC5c+eQkJDg6WIQERGRA/Lz8xEfH++y/SsiGGrUqBEAw8kMCwvzcGmIiIjIFiUlJUhISDDdx11FEcGQsWksLCyMwRAREZGXcXUXF3agJiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkVjMERERESKxmCIiIiIFI3BEBERESkagyEiIiJSNAZDREREpGgMhoiIiEjRGAwRERGRojEYIiIiIkXzeDC0ZcsWjBo1CrGxsVCpVFizZo3VbZ9++mmoVCosXrzYbeUjIiIi3+bxYKisrAydO3fG0qVL69xuzZo1+OmnnxAbG+umkhEREZESBHi6ACNGjMCIESPq3KagoABTpkzBd999B7Va7aaSERERkRJ4vGaoPnq9HhMmTMALL7yADh06eLo4RERE5GM8XjNUn9deew0BAQGYNm2aza+pqKhARUWF6XlJSYkrikZEREQ+QNY1Qz///DOWLFmC5cuXQ6VS2fy6BQsWIDw83PRISEhwYSmJiIjIm8k6GNq6dSuKiorQokULBAQEICAgAKdPn8bzzz+PxMREq6+bPXs2iouLTY/8/Hz3FZqIiIi8iqybySZMmIDBgwebLRs2bBgmTJiAxx57zOrrgoODERwc7OriERERkQ/weDBUWlqK48ePm57n5eXhl19+QUREBFq0aIHIyEiz7QMDAxEdHY127dq5u6hERETkgzweDO3atQvp6emm5zNmzAAATJw4EcuXL/dQqYiIiEgpPB4MpaWlQQhh8/anTp1yXWGIiIhIcWTdgZqIiIjI1RgMERERkaIxGCIiIiJFYzBEREREisZgiIiIiBSNwRAREREpGoMhIiIiUjQGQ0RERKRoDIaIiIhI0RgMERERkaIxGCIiIiJFYzBEREREisZgiIiIiBSNwRAREREpGoMhIiIiUjQGQ0RERKRoDIaIiIhI0RgMERERkaIxGCIiIiJFYzBEREREisZgiIiIiBSNwRAREREpGoMh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",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"filenames": {
|
|
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_5_1.png"
|
|
}
|
|
},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"%matplotlib inline\n",
|
|
"\n",
|
|
"# Importing various packages\n",
|
|
"from math import exp, sqrt\n",
|
|
"from random import random, seed\n",
|
|
"import numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"\n",
|
|
"n = 100\n",
|
|
"x = 2*np.random.rand(n,1)\n",
|
|
"y = 4+3*x+np.random.randn(n,1)\n",
|
|
"\n",
|
|
"X = np.c_[np.ones((n,1)), x]\n",
|
|
"XT_X = X.T @ X\n",
|
|
"theta_linreg = np.linalg.inv(X.T @ X) @ (X.T @ y)\n",
|
|
"print(\"Own inversion\")\n",
|
|
"print(theta_linreg)\n",
|
|
"# Hessian matrix\n",
|
|
"H = (2.0/n)* XT_X\n",
|
|
"EigValues, EigVectors = np.linalg.eig(H)\n",
|
|
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
|
|
"\n",
|
|
"theta = np.random.randn(2,1)\n",
|
|
"eta = 1.0/np.max(EigValues)\n",
|
|
"Niterations = 1000\n",
|
|
"\n",
|
|
"#while (iter <= Ni... or test)\n",
|
|
"for iter in range(Niterations):\n",
|
|
" gradients = 2.0/n*X.T @ ((X @ theta)-y)\n",
|
|
" theta -= eta*gradients\n",
|
|
"print(\"theta from own gd\")\n",
|
|
"print(theta)\n",
|
|
"\n",
|
|
"xnew = np.array([[0],[2]])\n",
|
|
"Xnew = np.c_[np.ones((2,1)), xnew]\n",
|
|
"ypredict = Xnew.dot(theta)\n",
|
|
"ypredict2 = Xnew.dot(theta_linreg)\n",
|
|
"\n",
|
|
"n_epochs = 50\n",
|
|
"M = 5 #size of each minibatch\n",
|
|
"m = int(n/M) #number of minibatches\n",
|
|
"t0, t1 = 5, 50\n",
|
|
"\n",
|
|
"def learning_schedule(t):\n",
|
|
" return t0/(t+t1)\n",
|
|
"\n",
|
|
"theta = np.random.randn(2,1)\n",
|
|
"\n",
|
|
"for epoch in range(n_epochs):\n",
|
|
"# Can you figure out a better way of setting up the contributions to each batch?\n",
|
|
" for i in range(m):\n",
|
|
" random_index = M*np.random.randint(m)\n",
|
|
" xi = X[random_index:random_index+M]\n",
|
|
" yi = y[random_index:random_index+M]\n",
|
|
" gradients = (2.0/M)* xi.T @ ((xi @ theta)-yi)\n",
|
|
" eta = learning_schedule(epoch*m+i)\n",
|
|
" theta = theta - eta*gradients\n",
|
|
"print(\"theta from own sdg\")\n",
|
|
"print(theta)\n",
|
|
"\n",
|
|
"plt.plot(xnew, ypredict, \"r-\")\n",
|
|
"plt.plot(xnew, ypredict2, \"b-\")\n",
|
|
"plt.plot(x, y ,'ro')\n",
|
|
"plt.axis([0,2.0,0, 15.0])\n",
|
|
"plt.xlabel(r'$x$')\n",
|
|
"plt.ylabel(r'$y$')\n",
|
|
"plt.title(r'Random numbers ')\n",
|
|
"plt.show()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "de04b41a",
|
|
"metadata": {},
|
|
"source": [
|
|
"In the above code, we have use replacement in setting up the\n",
|
|
"mini-batches. The discussion\n",
|
|
"[here](https://sebastianraschka.com/faq/docs/sgd-methods.html) may be\n",
|
|
"useful."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "77fc1cca",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Momentum based GD\n",
|
|
"\n",
|
|
"The stochastic gradient descent (SGD) is almost always used with a\n",
|
|
"*momentum* or inertia term that serves as a memory of the direction we\n",
|
|
"are moving in parameter space. This is typically implemented as\n",
|
|
"follows"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "441d1f36",
|
|
"metadata": {},
|
|
"source": [
|
|
"$$\n",
|
|
"\\mathbf{v}_{t}=\\gamma \\mathbf{v}_{t-1}+\\eta_{t}\\nabla_\\theta E(\\boldsymbol{\\theta}_t) \\nonumber\n",
|
|
"$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "47434945",
|
|
"metadata": {},
|
|
"source": [
|
|
"<!-- Equation labels as ordinary links -->\n",
|
|
"<div id=\"_auto1\"></div>\n",
|
|
"\n",
|
|
"$$\n",
|
|
"\\begin{equation} \n",
|
|
"\\boldsymbol{\\theta}_{t+1}= \\boldsymbol{\\theta}_t -\\mathbf{v}_{t},\n",
|
|
"\\label{_auto1} \\tag{1}\n",
|
|
"\\end{equation}\n",
|
|
"$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f3ea5060",
|
|
"metadata": {},
|
|
"source": [
|
|
"where we have introduced a momentum parameter $\\gamma$, with\n",
|
|
"$0\\le\\gamma\\le 1$, and for brevity we dropped the explicit notation to\n",
|
|
"indicate the gradient is to be taken over a different mini-batch at\n",
|
|
"each step. We call this algorithm gradient descent with momentum\n",
|
|
"(GDM). From these equations, it is clear that $\\mathbf{v}_t$ is a\n",
|
|
"running average of recently encountered gradients and\n",
|
|
"$(1-\\gamma)^{-1}$ sets the characteristic time scale for the memory\n",
|
|
"used in the averaging procedure. Consistent with this, when\n",
|
|
"$\\gamma=0$, this just reduces down to ordinary SGD as discussed\n",
|
|
"earlier. An equivalent way of writing the updates is"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "923628c8",
|
|
"metadata": {},
|
|
"source": [
|
|
"$$\n",
|
|
"\\Delta \\boldsymbol{\\theta}_{t+1} = \\gamma \\Delta \\boldsymbol{\\theta}_t -\\ \\eta_{t}\\nabla_\\theta E(\\boldsymbol{\\theta}_t),\n",
|
|
"$$"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "5c94031c",
|
|
"metadata": {},
|
|
"source": [
|
|
"where we have defined $\\Delta \\boldsymbol{\\theta}_{t}= \\boldsymbol{\\theta}_t-\\boldsymbol{\\theta}_{t-1}$."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f3f0e9c9",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Algorithms and codes for Adagrad, RMSprop and Adam\n",
|
|
"\n",
|
|
"The algorithms we have implemented are well described in the text by [Goodfellow, Bengio and Courville, chapter 8](https://www.deeplearningbook.org/contents/optimization.html).\n",
|
|
"\n",
|
|
"The codes which implement these algorithms are discussed after our presentation of automatic differentiation."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "92253eff",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Practical tips\n",
|
|
"\n",
|
|
"* **Randomize the data when making mini-batches**. It is always important to randomly shuffle the data when forming mini-batches. Otherwise, the gradient descent method can fit spurious correlations resulting from the order in which data is presented.\n",
|
|
"\n",
|
|
"* **Transform your inputs**. Learning becomes difficult when our landscape has a mixture of steep and flat directions. One simple trick for minimizing these situations is to standardize the data by subtracting the mean and normalizing the variance of input variables. Whenever possible, also decorrelate the inputs. To understand why this is helpful, consider the case of linear regression. It is easy to show that for the squared error cost function, the Hessian of the cost function is just the correlation matrix between the inputs. Thus, by standardizing the inputs, we are ensuring that the landscape looks homogeneous in all directions in parameter space. Since most deep networks can be viewed as linear transformations followed by a non-linearity at each layer, we expect this intuition to hold beyond the linear case.\n",
|
|
"\n",
|
|
"* **Monitor the out-of-sample performance.** Always monitor the performance of your model on a validation set (a small portion of the training data that is held out of the training process to serve as a proxy for the test set. If the validation error starts increasing, then the model is beginning to overfit. Terminate the learning process. This *early stopping* significantly improves performance in many settings.\n",
|
|
"\n",
|
|
"* **Adaptive optimization methods don't always have good generalization.** Recent studies have shown that adaptive methods such as ADAM, RMSPorp, and AdaGrad tend to have poor generalization compared to SGD or SGD with momentum, particularly in the high-dimensional limit (i.e. the number of parameters exceeds the number of data points). Although it is not clear at this stage why these methods perform so well in training deep neural networks, simpler procedures like properly-tuned SGD may work as well or better in these applications.\n",
|
|
"\n",
|
|
"Geron's text, see chapter 11, has several interesting discussions."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "08209015",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Using Automatic differentation with OLS\n",
|
|
"\n",
|
|
"We conclude the part on optmization by showing how we can make codes\n",
|
|
"for linear regression and logistic regression using **autograd**. The\n",
|
|
"first example shows results with ordinary leats squares."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"id": "f1f7d4aa",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Own inversion\n",
|
|
"[[3.37007195]\n",
|
|
" [3.48441798]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.32411274 4.30450049]\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"theta from own gd\n",
|
|
"[[3.37007195]\n",
|
|
" [3.48441798]]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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bgpPvr4dwVuu77KyMgBodBFWV13jHhUMnT59Gnq9vsFq9eHh4Q1WtTc4fvy42f1rampw+vTpRvexdExXs+e863vrrbdQUVGBCRMmGLd16dIFy5YtwxdffIGMjAwEBQVh8ODBOHjwoEPbby97zjsyMhIffPABsrKyoNPp0LlzZ9x0003YsmWLcR9v/75LSkrw9ddf46GHHjLZrvbv2x7ecH07gide3/bwhuu7qbzl+hZCYNq0aRgyZAh69OhhcT9XXeMesxxHXZIkmTwWQjTYZm3/+tttPaY72NvGjIwMzJkzB2vXrkVYWJhx+8CBAzFw4EDj48GDB+OGG27Au+++i3/84x+Oa3gT2XLenTt3RufOnY2P4+PjUVRUhDfffBNDhw6165juYm8bly1bhquuugpjx4412e4p37etvOX6tpenX9+28Kbr217ecn0/8cQT2L17N77//nur+7riGveonqG2bdvC19e3QbR38uTJBlGhQUREhNn9/fz80KZNm0b3sXRMV7PnvA1WrFiBBx98ECtXrsTw4cMb3dfHxwf9+/dXzV8STTnvugYOHGhyTt78fQsh8PHHH2PSpEkICAhodF+1fd/28Ibruyk8+fp2FE+7vpvCW67vJ598El988QWys7MRExPT6L6uusY9KhgKCAhA3759sWHDBpPtGzZswKBBg8y+Jj4+vsH+69evR79+/eDv79/oPpaO6Wr2nDcg/8V4//33Y/ny5Rg1apTV9xFCoKCgAJGRkU1usyPYe9715efnm5yTt37fgDxb49ChQ3jwwQetvo/avm97eMP1bS9Pv74dxdOu76bw9OtbCIEnnngCOp0OmzZtQseOHa2+xmXXuOJUa5XIzMwU/v7+4qOPPhJ79uwRaWlpokWLFsas+hkzZohJkyYZ9//9999F8+bNxdNPPy327NkjPvroI+Hv7y9WrVpl3OeHH34Qvr6+4u9//7vYu3ev+Pvf/y78/PzEtm3bXH5+lth63suXLxd+fn7ivffeEyUlJcafP//807jPnDlzxDfffCN+++03kZ+fLx544AHh5+cnfvrpJ5efnyW2nvc777wjVq9eLQ4cOCB++eUXMWPGDAFAZGVlGffxxu/b4N577xU33nij2WN6wvd97tw5kZ+fL/Lz8wUA8fbbb4v8/Hxx5MgRIYT3Xt+2nre3XN+2nre3XN+2nreBp1/fjz32mAgJCRE5OTkmv7cXLlww7uOua9zjgiEhhHjvvfdEhw4dREBAgLjhhhtMpuVNnjxZDBs2zGT/nJwc0adPHxEQECDi4uLEP//5zwbH/Pzzz0Xnzp2Fv7+/6NKli8nFpRa2nPewYcMEgAY/kydPNu6TlpYm2rdvLwICAkS7du3EyJEjxdatW114RsrYct7z588X11xzjQgKChKtW7cWQ4YMEevWrWtwTG/7voUQ4s8//xTNmjUTH3zwgdnjecL3bZg6ben31luvb1vP21uub1vP21uub3t+z73h+jZ3zgDE0qVLjfu46xqXLjeQiIiISJM8KmeIiIiIyNEYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIo+UkZGBoKAgFBcXG7c99NBD6NmzJ8rKytzYMiLyNFybjIg8khACvXv3RkJCAhYvXoz09HT861//wrZt2xAdHe3u5hGRB/FzdwOIiOwhSRJee+01jBs3DlFRUVi0aBFyc3MZCBGRzdgzREQe7YYbbsCvv/6K9evXY9iwYe5uDhF5IOYMEZHH+vbbb7Fv3z7o9XqEh4e7uzlE5KHYM0REHmnnzp1ITEzEe++9h8zMTDRv3hyff/65u5tFRB6IOUNE5HEOHz6MUaNGYcaMGZg0aRK6deuG/v37Y8eOHejbt6+7m0dEHoY9Q0TkUUpLSzF48GAMHToU//d//2fcPmbMGFRVVeGbb75xY+uIyBMxGCIiIiJNYwI1ERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNP+HyKTAN3zbiBYAAAAAElFTkSuQmCC",
|
|
"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.27227895 4.125757 ]\n",
|
|
"0 [-11.75978215] [-12.89770892]\n",
|
|
"1 [-0.06807123] [0.06136823]\n",
|
|
"2 [-0.06357887] [0.05731824]\n",
|
|
"3 [-0.05938299] [0.05353553]\n",
|
|
"4 [-0.05546402] [0.05000245]\n",
|
|
"5 [-0.05180367] [0.04670255]\n",
|
|
"6 [-0.04838489] [0.04362042]\n",
|
|
"7 [-0.04519174] [0.04074169]\n",
|
|
"8 [-0.04220931] [0.03805295]\n",
|
|
"9 [-0.03942371] [0.03554165]\n",
|
|
"10 [-0.03682195] [0.03319608]\n",
|
|
"11 [-0.03439189] [0.03100531]\n",
|
|
"12 [-0.0321222] [0.02895911]\n",
|
|
"13 [-0.0300023] [0.02704796]\n",
|
|
"14 [-0.0280223] [0.02526293]\n",
|
|
"15 [-0.02617297] [0.02359571]\n",
|
|
"16 [-0.02444569] [0.02203851]\n",
|
|
"17 [-0.0228324] [0.02058408]\n",
|
|
"18 [-0.02132557] [0.01922564]\n",
|
|
"19 [-0.01991819] [0.01795684]\n",
|
|
"20 [-0.0186037] [0.01677178]\n",
|
|
"21 [-0.01737595] [0.01566493]\n",
|
|
"22 [-0.01622922] [0.01463112]\n",
|
|
"23 [-0.01515818] [0.01366555]\n",
|
|
"24 [-0.01415781] [0.01276369]\n",
|
|
"25 [-0.01322347] [0.01192135]\n",
|
|
"26 [-0.01235079] [0.0111346]\n",
|
|
"27 [-0.0115357] [0.01039977]\n",
|
|
"28 [-0.0107744] [0.00971344]\n",
|
|
"29 [-0.01006335] [0.0090724]\n",
|
|
"theta from own gd\n",
|
|
"[[3.96547946]\n",
|
|
" [3.03112129]]\n",
|
|
"0 [-0.00939922] [0.00847367]\n",
|
|
"1 [-0.00877892] [0.00791445]\n",
|
|
"2 [-0.00801346] [0.00722437]\n",
|
|
"3 [-0.00725498] [0.00654058]\n",
|
|
"4 [-0.00654864] [0.00590379]\n",
|
|
"5 [-0.00590456] [0.00532314]\n",
|
|
"6 [-0.00532167] [0.00479764]\n",
|
|
"7 [-0.0047956] [0.00432337]\n",
|
|
"8 [-0.00432129] [0.00389577]\n",
|
|
"9 [-0.00389382] [0.00351039]\n",
|
|
"10 [-0.0035086] [0.00316311]\n",
|
|
"11 [-0.00316149] [0.00285017]\n",
|
|
"12 [-0.00284871] [0.0025682]\n",
|
|
"13 [-0.00256688] [0.00231412]\n",
|
|
"14 [-0.00231293] [0.00208517]\n",
|
|
"15 [-0.0020841] [0.00187888]\n",
|
|
"16 [-0.00187791] [0.00169299]\n",
|
|
"17 [-0.00169212] [0.0015255]\n",
|
|
"18 [-0.00152471] [0.00137458]\n",
|
|
"19 [-0.00137387] [0.00123858]\n",
|
|
"20 [-0.00123795] [0.00111605]\n",
|
|
"21 [-0.00111547] [0.00100563]\n",
|
|
"22 [-0.00100511] [0.00090614]\n",
|
|
"23 [-0.00090567] [0.00081649]\n",
|
|
"24 [-0.00081607] [0.00073571]\n",
|
|
"25 [-0.00073534] [0.00066293]\n",
|
|
"26 [-0.00066259] [0.00059734]\n",
|
|
"27 [-0.00059703] [0.00053824]\n",
|
|
"28 [-0.00053797] [0.00048499]\n",
|
|
"29 [-0.00048474] [0.00043701]\n",
|
|
"theta from own gd wth momentum\n",
|
|
"[[3.99839581]\n",
|
|
" [3.00144622]]\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.81818338]\n",
|
|
" [3.12840176]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.26024513 4.64291046]\n",
|
|
"0 [-16.3824865] [-20.20867716]\n",
|
|
"1 [9.71640303e-15] [1.05750493e-14]\n",
|
|
"2 [-2.05998413e-17] [-2.11570114e-16]\n",
|
|
"3 [6.96057795e-17] [1.90885733e-16]\n",
|
|
"4 [6.96057795e-17] [1.90885733e-16]\n",
|
|
"beta from own Newton code\n",
|
|
"[[3.81818338]\n",
|
|
" [3.12840176]]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# Using Newton's method\n",
|
|
"from random import random, seed\n",
|
|
"import numpy as np\n",
|
|
"import autograd.numpy as np\n",
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from autograd import grad\n",
|
|
"\n",
|
|
"def CostOLS(beta):\n",
|
|
" return (1.0/n)*np.sum((y-X @ beta)**2)\n",
|
|
"\n",
|
|
"n = 100\n",
|
|
"x = 2*np.random.rand(n,1)\n",
|
|
"y = 4+3*x+np.random.randn(n,1)\n",
|
|
"\n",
|
|
"X = np.c_[np.ones((n,1)), x]\n",
|
|
"XT_X = X.T @ X\n",
|
|
"beta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y)\n",
|
|
"print(\"Own inversion\")\n",
|
|
"print(beta_linreg)\n",
|
|
"# Hessian matrix\n",
|
|
"H = (2.0/n)* XT_X\n",
|
|
"# Note that here the Hessian does not depend on the parameters beta\n",
|
|
"invH = np.linalg.pinv(H)\n",
|
|
"EigValues, EigVectors = np.linalg.eig(H)\n",
|
|
"print(f\"Eigenvalues of Hessian Matrix:{EigValues}\")\n",
|
|
"\n",
|
|
"beta = np.random.randn(2,1)\n",
|
|
"Niterations = 5\n",
|
|
"\n",
|
|
"# define the gradient\n",
|
|
"training_gradient = grad(CostOLS)\n",
|
|
"\n",
|
|
"for iter in range(Niterations):\n",
|
|
" gradients = training_gradient(beta)\n",
|
|
" beta -= invH @ gradients\n",
|
|
" print(iter,gradients[0],gradients[1])\n",
|
|
"print(\"beta from own Newton code\")\n",
|
|
"print(beta)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "40292cf3",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Including Stochastic Gradient Descent with Autograd\n",
|
|
"In this code we include the stochastic gradient descent approach discussed above. Note here that we specify which argument we are taking the derivative with respect to when using **autograd**."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"id": "fa819b9d",
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Own inversion\n",
|
|
"[[3.6955259]\n",
|
|
" [3.2809076]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.31381731 4.50516278]\n",
|
|
"theta from own gd\n",
|
|
"[[3.6955259]\n",
|
|
" [3.2809076]]\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkMAAAHFCAYAAADxOP3DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABXSUlEQVR4nO3deXhTVfoH8O/tDoUWWmhpaQtF2aGALLIvw6IICLQVhRERR0VBBVEHOjqC4yDCoKKiMjj+wA1cmrIojorQAio4KEtBdi1QllLWFlq6Jef3R0zatEmzNMm9N/f7eZ482Htvbs5NGu/bc97zHkkIIUBERESkUX5yN4CIiIhITgyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiBRo1apVkCTJ/AgICEBMTAzuueceHDt2TLZ2zZ8/H5Ikyfb6anDixAlIkoQlS5bI3RQiclCA3A0gIttWrlyJdu3aoaSkBD/88AMWLFiAzMxMHD58GI0bN5a7eUREPoHBEJGCderUCT169AAADB48GHq9HvPmzcO6deswdepUmVtHciovLzf3GhJR3XCYjEhFTIHR+fPnzdtKSkrw1FNPoWvXrggPD0dERAT69OmD9evX13i+JEl47LHH8OGHH6J9+/aoX78+unTpgi+//LLGsRs3bkTXrl0RHByMxMREm8M+JSUlSEtLQ2JiIoKCgtC8eXPMmDEDV69etTiuZcuWGD16NL788kt069YN9erVQ/v27c2vvWrVKrRv3x6hoaHo1asXfv75Z7vvh2k4MTMzE48++iiaNGmCyMhIJCcn4+zZszWuff78+TXO0bJlS9x///01zrllyxY89NBDiIyMRFhYGO677z4UFRUhLy8PEyZMQKNGjRATE4Onn34a5eXlNc5rMBiwYMECJCQkICQkBD169MDmzZtrHHfs2DFMmjQJUVFRCA4ORvv27fHWW29ZHJOVlQVJkvDhhx/iqaeeQvPmzREcHIzjx4+juLgYTz/9NBITExESEoKIiAj06NEDa9assfv+EZER/6QgUpGcnBwAQJs2bczbSktLcfnyZTz99NNo3rw5ysrK8N133yE5ORkrV67EfffdZ3GOjRs3YteuXfjHP/6BBg0aYPHixRg/fjyOHDmCVq1aAQA2b96MsWPHok+fPvjkk0+g1+uxePFiiyAMAIQQGDduHDZv3oy0tDQMGDAA2dnZmDdvHnbs2IEdO3YgODjYfPy+ffuQlpaGZ599FuHh4XjhhReQnJyMtLQ0bN68GS+99BIkScKcOXMwevRo5OTkoF69enbflwcffBCjRo3C6tWrkZubi2eeeQb33nsvtmzZ4vJ7/eCDDyI5ORmffPIJ9uzZg7/97W+oqKjAkSNHkJycjIcffhjfffcdFi1ahNjYWMyePdvi+cuWLUOLFi2wdOlSGAwGLF68GCNHjsTWrVvRp08fAMDBgwfRt29fJCQk4JVXXkGzZs3wzTff4IknnsDFixcxb948i3OmpaWhT58+WL58Ofz8/BAVFYXZs2fjww8/xD//+U9069YNRUVFOHDgAC5duuTytRNpjiAixVm5cqUAIHbu3CnKy8vFtWvXxNdffy2aNWsmBg4cKMrLy20+t6KiQpSXl4u//OUvolu3bhb7AIjo6GhRWFho3paXlyf8/PzEwoULzdtuvfVWERsbK27cuGHeVlhYKCIiIkTV/218/fXXAoBYvHixxet8+umnAoBYsWKFeVuLFi1EvXr1xOnTp83b9u7dKwCImJgYUVRUZN6+bt06AUBs2LDBofdp+vTpFtsXL14sAIhz585ZXPu8efNqnKNFixZiypQpNc75+OOPWxw3btw4AUC8+uqrFtu7du0qbrnlFvPPOTk5AoDN92/YsGHmbbfddpuIi4sTBQUFFud87LHHREhIiLh8+bIQQojMzEwBQAwcOLBG+zt16iTGjRtXYzsROY7DZEQK1rt3bwQGBqJhw4a4/fbb0bhxY6xfv75Gnsjnn3+Ofv36oUGDBggICEBgYCDee+89HDp0qMY5hwwZgoYNG5p/jo6ORlRUFE6ePAkAKCoqwq5du5CcnIyQkBDzcQ0bNsSYMWMszmXqeak6zAQAd911F0JDQ2sMC3Xt2hXNmzc3/9y+fXsAxnyo+vXr19huapM9d955p8XPSUlJTj3fmtGjR1v8bGrTqFGjamy39jq23r9t27ZBr9ejpKQEmzdvxvjx41G/fn1UVFSYH3fccQdKSkqwc+dOi3OmpKTUeJ1evXrhv//9L+bOnYusrCzcuHHD5Wsm0ioGQ0QK9sEHH2DXrl3YsmULpk2bhkOHDmHixIkWx2RkZGDChAlo3rw5PvroI+zYsQO7du3CAw88gJKSkhrnjIyMrLEtODjYfBO9cuUKDAYDmjVrVuO46tsuXbqEgIAANG3a1GK7JElo1qxZjaGaiIgIi5+DgoJq3W6t/dZUvybT0FxdAgNn2mqtnbbev7KyMly/fh2XLl1CRUUF3nzzTQQGBlo87rjjDgDAxYsXLZ4fExNT45xvvPEG5syZg3Xr1mHIkCGIiIjAuHHjZC3BQKQ2zBkiUrD27dubk6aHDBkCvV6P//znP0hPT0dqaioA4KOPPkJiYiI+/fRTixpApaWlLr1m48aNIUkS8vLyauyrvi0yMhIVFRW4cOGCRUAkhEBeXh569uzpUhs8ITg42Op74qncGlvvX1BQEBo0aIDAwED4+/tj8uTJmDFjhtVzJCYmWvxsrcZTaGgoXnjhBbzwwgs4f/68uZdozJgxOHz4sHsuhsjHsWeISEUWL16Mxo0b4/nnn4fBYABgvEEGBQVZ3Cjz8vKsziZzhGk2V0ZGhkWPx7Vr1/DFF19YHDt06FAAxoCsKp1Oh6KiIvN+JWjZsiWys7Mttm3ZsgXXr1/3yOvZev8GDBgAf39/1K9fH0OGDMGePXuQlJSEHj161HhY68WrTXR0NO6//35MnDgRR44cQXFxsbsvi8gnsWeISEUaN26MtLQ0/PWvf8Xq1atx7733YvTo0cjIyMD06dORmpqK3NxcvPjii4iJiXF5qOTFF1/E7bffjuHDh+Opp56CXq/HokWLEBoaisuXL5uPGz58OG677TbMmTMHhYWF6Nevn3k2Wbdu3TB58mR3XXqdTZ48GX//+9/x/PPPY9CgQTh48CCWLVuG8PBwj7yev78/hg8fjtmzZ8NgMGDRokUoLCzECy+8YD7m9ddfR//+/TFgwAA8+uijaNmyJa5du4bjx4/jiy++cGg23K233orRo0cjKSkJjRs3xqFDh/Dhhx+iT58+FnlYRGQbgyEilXn88cexbNky/OMf/8DEiRMxdepU5OfnY/ny5fi///s/tGrVCnPnzsXp06ctbrzOGD58ONatW4fnnnsOd999N5o1a4bp06fjxo0bFueUJAnr1q3D/PnzsXLlSixYsABNmjTB5MmT8dJLL1lMq5fbM888g8LCQqxatQpLlixBr1698Nlnn2Hs2LEeeb3HHnsMJSUleOKJJ5Cfn4+OHTti48aN6Nevn/mYDh06YPfu3XjxxRfx3HPPIT8/H40aNULr1q3NeUP2/OlPf8KGDRvw2muvobi4GM2bN8d9992HZ5991iPXReSLJCGEkLsRRERERHJhzhARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJN00SdIYPBgLNnz6Jhw4ZWy9kTERGR8gghcO3aNcTGxsLPz3P9N5oIhs6ePYv4+Hi5m0FEREQuyM3NRVxcnMfOr4lgqGHDhgCMb2ZYWJjMrSEiIiJHFBYWIj4+3nwf9xRNBEOmobGwsDAGQ0RERCrj6RQXJlATERGRpjEYIiIiIk1jMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpskeDG3btg1jxoxBbGwsJEnCunXrbB47bdo0SJKEpUuXeq19RERE5NtkD4aKiorQpUsXLFu2rNbj1q1bh59++gmxsbFeahkRERFpQYDcDRg5ciRGjhxZ6zFnzpzBY489hm+++QajRo3yUsuIiIhIC2TvGbLHYDBg8uTJeOaZZ9CxY0e5m0NEREQ+RvaeIXsWLVqEgIAAPPHEEw4/p7S0FKWlpeafCwsLPdE0IiIi8gGK7hn65Zdf8Prrr2PVqlWQJMnh5y1cuBDh4eHmR3x8vAdbSURERGqm6GBo+/btyM/PR0JCAgICAhAQEICTJ0/iqaeeQsuWLW0+Ly0tDQUFBeZHbm6u9xpNREREqqLoYbLJkydj2LBhFttuu+02TJ48GVOnTrX5vODgYAQHB3u6eUREROQDZA+Grl+/juPHj5t/zsnJwd69exEREYGEhARERkZaHB8YGIhmzZqhbdu23m4qERER+SDZg6Gff/4ZQ4YMMf88e/ZsAMCUKVOwatUqmVpFREREWiF7MDR48GAIIRw+/sSJE55rDBEREWmOohOoiYiIiDyNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNkz0Y2rZtG8aMGYPY2FhIkoR169aZ95WXl2POnDno3LkzQkNDERsbi/vuuw9nz56Vr8FERETkU2QPhoqKitClSxcsW7asxr7i4mLs3r0bf//737F7925kZGTg6NGjuPPOO2VoKREREfkiSQgh5G6EiSRJWLt2LcaNG2fzmF27dqFXr144efIkEhISHDpvYWEhwsPDUVBQgLCwMDe1loiIiDzJW/fvAI+d2UMKCgogSRIaNWpk85jS0lKUlpaafy4sLPRCy4iIiEiNZB8mc0ZJSQnmzp2LSZMm1RohLly4EOHh4eZHfHy8F1tJREREaqKaYKi8vBz33HMPDAYD3n777VqPTUtLQ0FBgfmRm5vrpVYSERGR2qhimKy8vBwTJkxATk4OtmzZYnfcMDg4GMHBwV5qHREREamZ4oMhUyB07NgxZGZmIjIyUu4mERERkQ+RPRi6fv06jh8/bv45JycHe/fuRUREBGJjY5Gamordu3fjyy+/hF6vR15eHgAgIiICQUFBcjWbiIiIXKHXA9u3A+fOATExwIABgL+/rE2SfWp9VlYWhgwZUmP7lClTMH/+fCQmJlp9XmZmJgYPHuzQa3BqPRERqYICAwW3ysgAZs4ETp+u3BYXB7z+OpCcXONwb92/ZQ+GvIHBEBERKZ6TgYLqZGQAqalA9bBDkoz/pqfXuE5v3b9VM5uMiIjIZ5kChaqBEACcOWPcnpEhT7vcRa83BnrW+l9M22bNMh4nAwZDREREclJ4oOAW27fXDPSqEgLIzTUeJwMGQ0RERHJSeKDgFufOufc4N2MwREREJCeFBwpuERPj3uPcjMEQERGRnBQeKLjFgAHGZHBTsnR1kgTExxuPkwGDISIiIjkpPFBwC39/46w4oOZ1mn5eulS2MgIMhoiIiOSk8EDBbZKTjdPnmze33B4XZ3VavTexzhAREZESWKszFB9vDIR8oc6QiROFJVl00Y0YDBERkSr4egVqJ3nr/i372mRERET0B39/wMGlpsh9mDNEREREmsZgiIiIiDSNwRARERFpGnOGiIiIyDYNJHUzGCIiIiJLpgBo/Xrg44+BCxcq98XFGesi+dB0fwZDREREVMlavaOqzpwBUlNlL5ToTswZIiIiIqOMDGOgYysQAgBTecJZs4w9SD6AwRAREREZA5uZMyuDndoIAeTmGofSfACDISIiIjIGNrX1CFlz7pxn2uJlDIaIiIjItcAmJsb97ZABE6iJiIjIucBGkoyzygYM8Fx7vIg9Q0RERGQMbOLijIFObUz7ly71mXpDDIaIiIjIGNi8/rrxv2sLiOLifGpaPcBgiIiI1EivB7KygDVrjP/6yBRv2SUnGwOd5s0ttzdtapxKn5kJ5OT4VCAEMGeIiIjUxlpRQB+siiyb5GRg7FifX4KjKkkIRwoKqFthYSHCw8NRUFCAsLAwuZtDRESuMhUFrH7rMg3r+NjwjdZ56/7NYTIiIlKH2ooC+mBVZPIeBkNERKQO9ooC+lhVZPIeBkNERKQOjhYF9JGqyOQ9DIaIiEgdHC0K6CNVkcl7GAwREZE62CsKKElAfLzPVEUm72EwRERE6lBbUUAfrIpM3sNgiIiI1MNWUUBfqIrMQpKyYdFFIiJSF18sCihnIUm93rfeSxcwGCIiIvXx9wcGD5a7Fe5hq5DkmTPG7Z7s8XJXEOahgKq8uLzO53AEh8mIiIjkImchSVMQVr12kykIy8hw/DwtWwJDhgCTJhn/bdnS8edXU1pYio3zd2Fq6+24Oea6S+dwFpfjICIikktWljF4sCcz0709YXq9MWCxVcRSkow9RDk5tffwuGl5lBuXb+DrRfug+0yPL050QiHC/9hTCIDLcRAREfkuuQpJuqOadx17ta7nXcenM3/EhPgdaBqpR/Li3vj4RD8UIhyxfufwWOet+HJhtuPXVAeyB0Pbtm3DmDFjEBsbC0mSsG7dOov9QgjMnz8fsbGxqFevHgYPHoxff/1VnsYSERG5k1yFJN0RhLkQUBWcKsDH07bhuYi3MSNGh3feKIPudC8UoQES/E9jdvcs/LB8P3JLo/Fm9iAMmJ7kWDvrSPYE6qKiInTp0gVTp05FSkpKjf2LFy/Gq6++ilWrVqFNmzb45z//ieHDh+PIkSNo2LChDC0mIiJyE1MhyTNnrPewmIar3F1I0h1BmIMB1bU9x/D5+/7QbQxB6IUcvIKn8GdUBlFXg5ri4rRncdPSJyD5xTnWLjdTVM6QJElYu3Ytxo0bB8DYKxQbG4tZs2Zhzpw5AIDS0lJER0dj0aJFmDZtmkPnZc4QEREplinvBrAMiJzMu3GKKWfIXhBWW86Qg/lOQ/EdtmAoxiMD6UgFICyHpWq5Tm/dv2UfJqtNTk4O8vLyMGLECPO24OBgDBo0CD/++KPN55WWlqKwsNDiQUREpEhyFJJ0RzVvO8ujGCDhFOKRhcHoFnwQq4IfgVQ9EAI8P2vOAYoOhvLy8gAA0dHRFtujo6PN+6xZuHAhwsPDzY/4+HiPtpOIiFRMCZWfk5OBEyeMs8ZWrzb+m5Pj2YKLdQ3C/P2R/8jzEELAAMuAyAAJEoBfuj2II9+dxu6v8xFWegE2VpVzLGHbg2TPGXKEVC3qFELU2FZVWloaZs+ebf65sLCQARERaQurCjtGzsrP1clRSNKFat7HNp2A7pUTSN8ehV+KH8J4ROJ1zER8lTwgQ1QMAt55E+NN7+Ea26M5Ftw9a85Big6GmjVrBsDYQxRTJYkrPz+/Rm9RVcHBwQgODvZ4+4iIFElJN3glk7Pys5LYCcKEQeDgF79B9/pppO+Ixf6SNgBaAgD8oMeVRon4Ytj7mDD8Kpo0LAViYhBQPaCSa9acgxQdDCUmJqJZs2bYtGkTunXrBgAoKyvD1q1bsWjRIplbR0TkBc728PAG7xh7NXIkyZjDMnasJnvUhEFg3+dHkf7mOeh2xeNw2c0AbgYABKAcf4rch5TbizEurT2iOnazf0K5Zs05SPZg6Pr16zh+/Lj555ycHOzduxcRERFISEjArFmz8NJLL6F169Zo3bo1XnrpJdSvXx+TJk2SsdVERF7gbA8Pb/COc6ZGjq+sgWaHMAjsev8gdMsvIH13In6vaAugLQAgCKUYEbUPKWPKcGdaR0Tc1MO5k5sStlNTjb+H1mbN2UvY9iQhs8zMTAGgxmPKlClCCCEMBoOYN2+eaNasmQgODhYDBw4U+/fvd+o1CgoKBABRUFDggSsgIvIAnU4ISRLCeNuofEiS8aHT1XxOZmbN4609MjO9fTXKs3q1Y+/V6tVyt9Sj9OV6sf2tfWJWtywR73/a4tJDUCzGx+wQH0//Xlw9edU9L6jTCREXZ/kex8db/30W3rt/K6rOkKewzhARqYqr60atWWNcKNOe1auBiRPtt8GXE7DlWhNMASpKKrD97f1IX1mItQfb4pyhmXlfKK5jdHw2UlIljPxrZzRo1sD9DXDid8tb92/Zh8mIiKgaV4dw3JWkqoUEbIXnsLhbeXE5try2D7qPirH2SAdcFJV5PuEowJ2t9iPl7kCMeDoJ9SL6erYxcsyas4PBEBGR0ri6bpQ7bvBaScBWeg6LG5RcLcGmV7KhW1OGDb93xBVRmecTIV3GuJt/Req9IRg6uwuCGvSXsaXyYzBERKQ0rvbw1PUGr7UEbFPRQWu9YEuXqjLoK75YjK8XZyP9Mz2+PNkZ19DLvC9KuoDk9oeQMqUBBj3WGYH1faPXyx2YM0REpDR1XTfK2jBXfLz9G7xW82g8lR/lpbyra2evYePL+6HLkPDVmSQUI9S8r7nfOSR3OorUBxuh37RO8A9SVxDLnCEiIq2qaw+PC1WFAbg+POcopSZleyKHxcN5V1dPFmDDgv3QfRGIb/K6oBSVeT4tA3KR0uU3pD7SBL3u7wC/AHkKGQJQ7mdeDYMhIiIlqusQjis3eE9WCVZKUrYnbs7Vz3nhAnD33W7Pu7p45BLWLzyI9I0h2HyxC8pRmefTOjAHqT1OImV6NG65uzWkH34Dzu0Hvr8oXwCilM/cER6duK8QrDNERKpVUWGsC7R6tfHfigrPvlZcnPX6RqYaR/HxzrfBlZpJnmCtxk1cXN1e39o5/f1t1y1y8j08t++8ePuerWJo41+EP8otTtUx+Kh4fmCmyE4/Igx6g+eu0RVu+sxZZ8iNmDNEROQg02wywPrwnLO9Gq7WTHI3W7PkXL2u2s7piFryrnJ/OouMRceg29wI3xd2hoCfeV+3eoeQ0u88Up5MQLs7WjnWnrpcoyvc+Jl76/7NYIiIiCy5moBtjRKSsj0RkNk7pz3VCl/mbMtFxqKj+G3LKVwpCcE5xGA7BsAAf/QKPYDUQReR8kwrtBqcUPn6VYfm+vYFbrpJ/qATcOtnzgRqIiKSh6sJ2NZ4OinbEZ5Yh8zeOe2JicHRb3KQ/spJ6L6PRosbh/A6ZiIelee8FtIUJc8vQNO0hyyfay1YbdIEuHjR9ut5c601JXzmTmIwRERENblrhpUnk7Id5Ymb85kzLjVFQEJhcBMMvK0ZsssSASRiPDKQjlRIsByoaVh6EQ2fnQa0jazskbM1FFZbIFSVNwIQJXzmTvKzfwgREZGLTFWxTXkr1UmScQjOk8teuPvmnJFhLD7pJMMf4c7U0uXILmuHAJRjZMRP+KD+I5AgUOMdMgU8s2YZh8VqK4rpKG8EIEr4zJ3EYIiIiDzHVDMJqHlz9NayF+68OZt6Zuz0xAgAhmq32NOIwz1Yg4ro5lj14PfI/70IX+luoEHxhZqBkPlEVYa36jI0580ApLbPHDBe04MPer4dTmAwREREnmWqmdS8ueX2uDjvzHByV0DmYM+M4Y9+ngn4FIORiSlYiXlNluHH6R/jP7kjsSHvVkx5tz8aJzZybgjP1SEuOdZas/WZm8ybZ0xAz8jwTnvs4GwyIiLyDrmrEdd1lpyDs6TOoylm4zUYEhKROkHC7c8kITQq1PrBzsy8Ahw7tmlTY+FHE1dnArqDXg8sWGAMfqpzYMo/p9a7EYMhIiICULeAbM0aYNIku4f9cud8dHx/DkIahTjWHkfXoQMcO/b4ceDHH5WxBEYdyxp46/7NYTIiItIO0yy5iRON/zoQJJRcLcGGZ3/Cwqccm7HV/clBjgVCpvY4OoSnhPwrZzlT1kBGDIaIyPfo9cbhhzVrjP/q9XK3yDY1tVVDivKLkP7UDkxs8SOaNi7H2JduxXPnpiMXcTDYSnd2NUnZmZwqe8cCQIsWxuG0SZOM/7ZoIV9ujkpqDrHOEBH5FjUtDqmmtiqFI8NcLg6FFZ4uxMZFB5Ce4Yf/nk3CDfQx74vzP4uUzsdwrfuTkP7vaQCS9eVKXO2ZcabQpa1j168HUlJqHn/mjHG7Tuf93yu11Bzy6MpnCsGFWok0QikLgjpCTW1VCkcWIXVyodLLv18Rqx7cLsZE7xRBKLF4WmLASfF0j0yx8z/7hb5cX/trxMfL+5lVVAgRGWl7gVjAuN+TC/3aalcdFv/lQq1uxARqIg1QyoKgjlBTW5XCkUVIAdsLp0qSecjpwqGLWLfwIHRf1cfmS11QgUDzYW0Cc5Da8yRSH2uGrne3heRnY0hM7plx1W3eDAwbZv+4774Dhg71fHuqqsPiv1ybjIjIGZ5Yf8pT1NRWJaitvo8QxpvqzJmVP1shhEDJxKkYUy8BmQXdYMBA+EGPAdiOXgF70KGjhB7P3Y6OyW0h+SXab5O7litxl6wsx4/zdjBkynOyNiQs15T/ahgMEZFvUEmiplNtUEJblcCR4NFOZWYJQL2yQvQp+wqb0QNPBb2B56V/Iqz0AlABYB+AJ18B/FzI11JaL5ESuXPxXw/gbDIi8g1qSdR0pg1KaKsSuDEoTAtcgrz5y7GkfJYxEKrqzBnjcI4zM68yMoxDnlVnb8lRWdnRXio5e7NcKGvgLcwZIiLf4EzxOrn/J6ymtiqBo1WaHVW9QnNVzrz3juQxeWsISK8HoqOBS5dsHxMZCZw/r6rfKRZdJCJyhpoK0qmprUpgZ6FVAyScQhwuIcKx89kKhADHiwDay2MCKleb9wZ/f2DFitqPWbGCv1M2MBgiIt8h94KgzlBTW+Xm7w/x2lLjXOxqu0wFED8Iexwnuo5z32vaG5pTYmXl5GRjLaG4OMvtcXHy1BhSESZQE5FvUXiipgU1tVUGhgoDfvq/X6FbcQm6fb3QDel4HTMRj8og5EZoU+CVJXhu2uQ/horW2x4qkiSgSZPae4ZM7OVrKTUJnr9TLmEwRES+R2nTnmujprZ6gb5Mjx/+fQDp/7mKjANtcMbQ2bwvHxF4OnYNpt26F32G1Ue9Dq0QWvVGbxoqslaF2TTE9tZbwOzZ9vO17C2poeQkeP5OOY3BEBERyaqipAJZb2RD9/51ZBxqj3zRxbyvIQoxpsV+pEzwx+1/TUL9Jv0B9Ld9MtNQUfWaNhERwBNPGPf7+xsTn6U6LKlhymOqa1BFisDZZERE5HVl18uw+dV9SP+oBOuPd8AlEWne10i6irGtDiB1UhCGzU5yfAX4qvR6YMECY6L65cuV201rvwE1A6b4eOeKANahsjI5xlv3bwZDRETkFTcu38C3S7KR/kk5vsjpjAKEm/c1kS5ifNuDSLm3PobMTEJQg6C6vZgj097dkVtjbbFdZ4MqsonBkBsxGCIikkdRfhG+ejkbunSBL3OTUIQG5n3N/M4jpeNhpNwfhgHTOyMgxE2ZG95e+40VqD2Ga5MREZEqFZ4uxJcL9yN9rT++PpeEG+hj3hfvfwYpSceR+lBj9HmoE/wCot3fAG+v/caEZdVjMERERHV2+bcr2LDwV6R/EYRN+V1Qhn7mfa0CTiL1lhykPNIUPad0gOTXvJYzuYFSp72TYjEYIiLSEjcO6eT/egHrFh6C7uv62HKpCyqqzPJqF/QbUnrmIvXxGHS5qw0kvxbuugL7lDztnRSJwRARkVZYS/Y1za5yMNn37O48rH35CNI3hWHb1SQYMNC8LynkCFL6nEPqrDh0uPNmADe5+QIcxGnv5CQGQ0REWmBrdpVppfZapoGf/OE0Mv51HOlbIrDjWicINDPv617/IFIH5CPlqZZoPbwtgLYevAgHmdZ+q2stIdIMxc8mq6iowPz58/Hxxx8jLy8PMTExuP/++/Hcc8/Bz8+xpdU4m4yIZKGUWUYuzK46vvkkdEtyoNveFLuKOloc3qfBfqQMvoSUOTejZf84a2dUBk57Vz3OJvvDokWLsHz5crz//vvo2LEjfv75Z0ydOhXh4eGYOXOm3M0jIrLODUNSbuPg7KqTiz/Bh5ubI/2HGOwraQvAmOcjwYCB4dlIGVaA8XPaIK5nZ9vn8hRXAkuu00UOUnwwtGPHDowdOxajRo0CALRs2RJr1qzBzz//LHPLiIhsqMOQlEc4OGtq7t/88AkGAwD8UYEhEfuQensRxqW1R3Snrp5rnz11CSw57Z0c4Ng4k4z69++PzZs34+jRowCAffv24fvvv8cdd9whc8uIiKzQ6403bmsZCKZts2YZj/MWB2dNXUAT3NF0F967fzvOHy3EpkvdMe3jgYju1NTDDayFKbCs3rNlCiwzMozvZVYWsGaN8V9vvrfWKK09ZJfie4bmzJmDgoICtGvXDv7+/tDr9ViwYAEmTpxo8zmlpaUoLS01/1xYWOiNphIpl1JyV7TA2wX/HGDo0w/ljaIRdPU8JGv7AdwIjUJ6dnc0ahXhlTY5xF5gKUnAww8bF2A9c6Zyn1zDkYCyhkfJYYrvGfr000/x0UcfYfXq1di9ezfef/99LFmyBO+//77N5yxcuBDh4eHmR3x8vBdbTKQwGRnG5NkhQ4BJk4z/tmxp3E7up5CCf/oyPbKW7sXjSVsRX/8iJl59GwISDNXCISFJ8JMkhH7wjrICIcCxwPLSJctACLDsNfImR3qxvIE9U84TChcXFyeWLVtmse3FF18Ubdu2tfmckpISUVBQYH7k5uYKAKKgoMDTzSVSFp1OCEkSwnjbqHxIkvGh08ndQt+TmVnz/bb2yMx0+0uXFZWJbxf+LB5ut1VESfkWL9cQBeK1pgtEUcMoy3bExyvz96CiQojnnnPsvbT2kCTjtVVUeK+9cXHyt0enq9mOuDhlfsYOKCgo8Mr9W/HDZMXFxTWm0Pv7+8NgMNh8TnBwMIKDgz3dNCJlc2SIYdYs42wbDpm5j5cL/pUWluK7V7OhW12C9cc74rLobt7XWLqCcTcfQMqkEAybnYTgsL8B+jnKHzK1NtTkLG8PRypheFRpifsqovhgaMyYMViwYAESEhLQsWNH7NmzB6+++ioeeOABuZtGpGxK+J+zFnmh4N+Nyzfw9aJ90H2mxxcnOqEQPc37mkoXML7tIaROCcXgJ5IQWL9a0KX02VW2buiu8tb6Y3IPj/KPnzpRfDD05ptv4u9//zumT5+O/Px8xMbGYtq0aXj++eflbhqRe7k7yVnu/zlrWXKy8a9wa4m0Lhb8u553HV8tykZ6uoSvTndGEXqb98X45SGl4xGkPBCOAdM7wz9oYC1nUrDabuiu8tb6Y3Kvh8Y/fupE8cFQw4YNsXTpUixdulTuphB5jidmoMj9P2etc0PBv4JTBfhi4QHo1vvj63NdUIK+5n0J/qeR2vU4Uh6KRO+/dIRfQLNazqQS9m7oVcXFATduAJcvK2P9MbnXQ+MfP3Wi+GCIyOd5apxf7v85u5NaSwO4MCR16dhlrH/pV+g2hmDThS4oRz/zvpsDTyDllhNInR6F7ve2h+Sn4KUwXOHojfq554D584H1620PRwoBPPgg8Nln3vmdkXs9NP7xUzceTc9WCG9loxM5zdMzUEyzyarPKFPTbDIfmx1jTd7+fLF80lYxLOJn4Y9yi0ttH3Rc/H1Aptj76WFh0BvkbqpnuTITz9rvR2Sk8SHH74y19nhjxp7p/yXWZo/KMbvOTbx1/3Zqodbc3FxV1uzhQq2kWFlZxro/9mRmuj7Or+bFKm31mpn+0lbx7JgzP59DxstHofsuHNsLOsOAyh6DLiFHkNL3HFJmxqHDnTfL2Eovs7egrMnnnxt/L6o+z9RzeOyYsddIzt8ZuXoyTd8XwHrPlAq/L966fzsVDIWGhmL27NmYO3cuQkNDPdYod2MwRIq1Zo2xEKI9q1cDtVRdt0uNw0wurLSudCe+Pw3douPQZUVix3XLxU57hv6KlAEXkPJ0Im4e2kKmFirA558DEybUfkx8vPXP3Qd/Z5ym5j9+rFDkqvWbNm3Ck08+iffeew8LFizA1KlTPdUuIm3w1ji/0qdTW+Mjs2OObToB3SsnkL49Cr8UdwBQmefTt2E2Uv90GcnP3IwW/TraPokag1lXNXVgHTRbn7uP/M7UiRsS97XIqWCob9+++Omnn/DBBx/g2WefxRtvvIHXXnsNg331l4rI03wpydndVDw75uCG40hfehq6HTHILmkLoCUAwA96DGyUjZRhhRg/pw2a90iyfzKtrXVVl89dxb8zbqXGP35k5tLaZPfddx+OHj2KMWPGYNSoURg/fjyOHz/u7rYR+T7TDBSgclzfxBszUJRMRbNjhEFg76dH8Fz/LLQP/g0dx96MeZmDkV3SFv6owIjIn/HvP2/DuQOXkXmlGx77fBCa93Cg3UpZ68qb6vK5q+h3hpTFqZyhqoqLi7F7927odDq88cYbCAwMxIwZMzB//nw0bNjQ3e2sE+YMkeL52Di/W5jyP+z1msmU/yEMArvePwjd8gtI352I3ysq83yCUIrhUfuQOqYMd6Z1RMRNjZ1/Aa3mvziaRP3ZZ8Bdd1l/rkJ/Z8h5ikygXr58OXbt2oVdu3bh0KFD8Pf3R1JSEnr37o2uXbvi448/xtGjR7F27Vr06NHDY412FoMhUgUt5YU4SmGzYwwVBux49wDS372CjOybcEpfmf8TghsYGbMPKeP0GD23E8ITwuv2Yt6YaahU6ek1A53qbCVRK+x3hupGkcFQfHw8evfubX706NGjxoKoL730ElavXo0DBw64vbGuYjBEpGIy95pVlFRg+9v7oVtViIxf2+KcobLScyiuY3R8NlJSJYz8a2c0aNbAfS/srZmGSuRoIPjcc8DQoTX/cGBPq89QZDDkiPPnzyM2NhZ6vd6dp60TBkOkeOwVqp2X35/y4nJseW0fdB8VY+2RDrgompj3haEAdybuR+o9gRjxdBLqRdTzTCO03DPkaCBoYi2hnN8pn6DaYEgIgW3btmHQoEHuPG2dMBgiRdPabCGFKi0sxaYl+5C+ugwbfu+IK6IyzydCuoxxN/+KlD+HYOiTSQgOC67lTG6i5fwXRwNBEw6B+SzVBkNKxGCIFMuHKyyrQfHFYny9OBu6z/T44mRnXEPl/x+ipAtIbn8IKVMaYNBjnRFYP9D7DdRq/ou9QNAaXw4ONYzBkBsxGCJF0upsIZldO3sNG1/eD12GhK/OJKEYldX0m/udQ3Kno0h9sBH6TesE/yAFvO9azX+xFQja44vDhhqmyArURORGrJbrNVdPFuCLhfuRvj4Q3+R1QSn6mve18D+N1K7HkfJwJG59oCP8AhRWg0arFYWTk409X9UDQXt8vaAieQSDISK5sFqu85xIir145BLWLzwI3Vch+O5CF5Sjv3lf68AcpPY4iZTp0bhlUjtIfnFWz+GOdrjleVqtKFw1ENy8GfjnP+0/hwUVyQUMhojkwmq5znEg0TwvOx/rXj6M9K8bIOtKEvQwLmPiBz3uD/wId9x0BN3vaYPEv02EFJjosXa49XlaZwoEBwwAVq3i0jXkEcwZIpJLXWcLaWnqcC2J5kIAX936AhYduhPfF3aGqLLKUNd6h/Fs688w9uw7CLyYV/k8V4MQVxPemSjvHlpNKNcwJlC7EYMhUixX/+eupV4GO4nmBkg4jTgkIgcG+KNX6AGkDrqI5KcScdPVX9wXhLia8M5EeffSakK5RjEYciMGQ6Rozv7PXWu9DA7WnEnv9xp6/esuJPRpbtzg7iDE1SKIWi6e6Cla6hXVOM4mI9IKZ2YL6fXGwMna3zBCGG/ws2YZz6fym4MwCPy6/jiOPLsZKQ4cnzojGjAFQoD7Z+u5mvDORHn302pCOXkMgyEiJXD0f+4+Ph1fGAT2fnoE6cvyoPs5AUfKWmMQhiIFLswicncQ4mrCOxPliRSPwRCRmpw549hxKuplEAaB/638Fbp/X0T6nlbIqWgHoB0AIAilaBQVhKKipqhffBGSM7OI3B2EDBhgfB1nZzO5+jxv4rATaZyf/UOISBEyMoAnn3TsWIX3MujL9Ni+bB9mdduKFkFn0fvBTvjXrsHIqUhAPRQjOXYnVj/2Iy7klmLd+b4I/WA5JKAyL8rE9PPSpTVv3qYgpPpzqj43Pt7xIMTf35ig7mw7XH2et2RkGHOrhgwxLo46ZIjx54wMedpDJAehAQUFBQKAKCgokLspRK7R6YSQJCGMfQu1P+LjhaiokLvFNZTfKBebl+wWj3bcKpr55Vk0uQEKxT0JP4jPZ20XxRlfCbF6tRCZmZbXodMJERdX81p1Otsvanrfqr93pm21Pbe2czrbjro8z5Ns/V7V5f0hciNv3b85m4xI6ezNiqrus8+Au+6qfK6Mwx9l18uwZWk2dB8VY93RDrgompj3haMAd7baj9R7AjHimS4I2fKV/XIBrlyPJ6Zie7sCtSdwyj+pAKfWuxGDIVI1R6dmm5imaMtUi6jkagm+/dc+6D4px4acTrgqGpn3RUqXMK71QaROroc/zUpCUIMg4w5PlwtQUhDiKc5eI6f8kwpwaj0RGTmbDH3mjO3g4swZ43Y31yIqyi/C1//KRvpnAl+e6ozruNW8L9ovH8ntDyNlSgMMejwJASHVcnQ8VS5ACwGQiSuBL6f8E5kxGCJSOmeTofPyjENAHq5FVHi6EBsXHYBurYSvznTBDfQx74vzP4vkTseQ+mAj9H24E/yDBto+kSfKBWipQrergS+n/BOZMRgikpu9HgzTrChHc4YuX/ZYLaIrOVex4aUD0H0RiG/Pd0Ep+pr3JQacQkrX35EyrQl63d8BfgGxjp3U3T0UXu4Vk1VdetXUMOWfyEsYDBHJyZEeDNPU7BRH6jAD8HOwYoaDwcWFQxex/uVDSN9YD5svdUEF+pv3tQnMQWrPk0iZHo1uE9tB8ktw7LWrcmcPhb3gAAAeeQQYPRoICnK8jUpVl1410+9Vaqox8LG2Np6cU/6JvIh1hojkYurBqH4zM/VgVK3zkpwMfP65/RtTfLzjvT21BBfn9p7H2/dsxdCI3WjWoTEe+mAAvrnUAxUIRKfgY5g3KAv7M47hcElLLPhhMG75c3tIfjbq+djjznpA9oIDALhwwfh6vlBHp669asnJxp6y5s0tt8fF+VYPGpEdnE1GJAdXpzV//jkwYYL14wHjDWzsWOO57Q1/VDt37k9noXv5GHRbGuGHws4QVf5WuqXeIaT0P4+UJxPQdmQr56/XHlNgCFjvoXD0xrxmjbFwoCMkSf03fHfNCNNSsjmpitfu3x6tYqQQLLpIipOZ6VgBxczMms91pHifg8X0fss8KRbfkSl6he6vceitofvFv0Zlit8yT3rlLXFLUUJH31fTe6HQApUOq6gwvme2CnL6wjWSpnnr/s2cISI51GV4w9FV7iMigEuXamw788iLWPVOBHT3HsKeG+0BGPN8JBjQP2w/UoZeRfKc1oi/tZPz11UXjl5XbewlBVel8kVtATDvh8hNGAwRyaGuScO1rXJvYzaVACAuXcLjC6KxFsbn+qMCgxtnI+W26xif1g7Nkro41i5Pqe26HH2+KThwlNrr6Jjyfqwl4telyjaRhjBniNTHG/kNnn4NU86Qk3k9jp5XnD4Na+nIBkg4g+Z4JPJzJI8ux9i0DmjSNtLVq1CujAxg2jTg4kX7x/pKhWXm/ZAP4nIcbsRgyA41/U/UG8X0vFWwz11Jw38wVBhwOO19dFjygP2DfSUAqE1ZmfFzu3DB+n6uvUWkeN66f3NqvdZlZBh7KIYMMc7CGTLE+LMSpx07MxVdya9h4oZpzfoyPba9uQ8zu25FQvB5vLgkxLHXVvvQkCOCgoDly41BT/Vp+8ynIaIqVNEzdObMGcyZMwf//e9/cePGDbRp0wbvvfceunfv7tDz2TNkgycWx/RUL5M3VtiWaxVvJ9+zipIKZL2RDd3717H2cDucN0SZ943ERnyF0fZfUws9QyaeWLWeiLyCw2R/uHLlCrp164YhQ4bg0UcfRVRUFH777Te0bNkSN910k0PnYDBkhSdu/J4cXvLGCtsKXsW77HoZNr+6D+kflWD98Q64JCrzfBpJVzG21QGkTAzC8FkdEdK1nftzkdROTUPBRGTGVev/sGjRIsTHx2PlypXmbS1btpSvQb7C3YtjuroelKM3KW+ssK2wVbxvXL6Bb5dkQ/dpOTb83hkF6Gne10S6iHFtDiJ1cn0MmZmEoAaVS2RwqrUVdZ2lRkQ+TfE5Qxs2bECPHj1w1113ISoqCt26dcO7775b63NKS0tRWFho8aBq3Hnjd2Q9qFmzjMdV5Uy+kjdW2FbAKt5F+UX4fPYO3JPwI5pG6jFu4a348Pf+KEA4mvmdx/ROW7HllT04V9wI7x4eiNue7YGgBtXW2OISC0REzvFoSUc3CA4OFsHBwSItLU3s3r1bLF++XISEhIj333/f5nPmzZsn8EdZlaoPVqCuoi4VkN1xLgcrJJt5o9KuTNV8C3ILxMfTvxfjY3aIeiiyLMDsf1rM6pYltr+1T+jL9c5fT2amEKtXG/9lFWIiUhlvVaBWfM5QUFAQevTogR9//NG87YknnsCuXbuwY8cOq88pLS1FaWmp+efCwkLEx8czZ6gqd9a5cXQ9qNWrgYkTXc9XcvNUdKu88RoALv92BRsW/grdF0H4Nr8LyhBs3tcq4CRSuuUg9dGm6Dmlg+sLoBIRqRyn1v8hJiYGHTp0sNjWvn17nDp1yuZzgoODERYWZvGgakyVeoG6Tzt2dnjJmXylqrwx/OPB18j/9QJW3LsNtzX5GdE3N8DU9/rjy/xeKEMw2gb9jmf7ZWHPJ0dwvDQBi/83GL2mdmQgRETkBYpPoO7Xrx+OHDlise3o0aNo0aKFTC3yIe4q4+/IelDx8cbjAO+sy1UXbnyNs7vzsPblI0jfFIZtV5NgwEDzvs4hR5Ha5yxSZsahw5ibIPl5YDV4IiKyS/HB0JNPPom+ffvipZdewoQJE/C///0PK1aswIoVK+Rumm9wx43fkfWg7rmn8pzuXpdLrzdOi3dncFSH2UendpyBbtEx6LZE4MdrnSDQzLyve/2DSOmfj5TZLdDmtjYA2tStnUREVGeKzxkCgC+//BJpaWk4duwYEhMTMXv2bDz00EMOP591hrzkr38F/vUv6/skqXKYyZ35St5aOsOO37achG5JDtK3NcWuoo4W+/o02I+UwZeQ/MxNSBwY77U2eQXr9xCRB7HoohsxGPICZ5Oi3ZGo7IkK2k449OVv0C3NRfoPMdhX0rby5WHAgPBspA4rwPg5bRDX03NT8WWlkECUiHwXgyE3YjDkBa5Ub67LMgkyLJ0hDAL7M44h/Y2z0P0vDgdLbzbv80cFhkTsQ8ptRRg3tx2aJUXVciYFcraHR+ZAlIi0gRWoSV1cSYquS76Suyto2zqNQeCXjw5B904+0n9piePllXk+gSjD8Kb7kDKqBGP/1hGRrR1bK09xnO3hsVdkU5KMRTbHjuWQGRGpAoMhcg9Xk6JdTVT24NIZhgoDdr73K3TvXoJu7804qe8AwFjeIRgluL3ZPqSOq8DouZ3QqEXP2k+mdK4so+KlQJSIyFsYDJF72Jtebxq2Mk2vrys3L52hL9Pj+3f2I/29AmT82gZnDZ3N++qjCKPispGSLHDHnM5oGHurKy1WHld7eBS2hhsRUV0xGCL3qDq93hsLhLoh+CovLkfWG9nQfVCEtYfbI190Ne9riELc2XI/Uib447ZnklC/SR/3tFtJXO3hUcAabkRE7sRgiNzHXUUcHeFi8FVaWIrNr2Uj/eMSrD/eEZdFZZ5PY+kKxt50AKl/DsGw2UkIDuvnvvZWp4Qp6a728Hi7F5CIyMMYDJF7eaNCdNXXciD4unH5Br75VzbSP6nAFyc6oRCVeT5NpQsY3/YQUu4LxZCZSQis74UbuFKmpNclz8ubvYBERB7GqfWkflZ6Wa5fuIGvFmVDpwM25iahCA3Mh8f45SGl4xGkPBCOAdM7wz/IizdtJU1Jr2vxy7qURiAicgDrDLkRgyFtKDhVgC9fPoD0df74+lwXlKCeeV+C/2mkdDmO1Icj0fsvHeEXIMMaxTLURrKrrsUvlTDcR0Q+i3WGiKqycdO9dOwyNiz8FelfhuC7C0koQ2Wez00BJ5HaPQcpj0ahx+T2kPziZLwAKHNKel3zvOqwhhsRkVIwGCLlszIcc71+U7zi9wxevP4k9KjM82kf9BtSeuUi9fEYJKW2geTXQo4WW6fUKenezPMiIlIgBkOkbH8M4wghIFXZXL/4Iv6OOdiHm/B7SEek9D2HlJlx6HDnzQBukqu1tVPylHT28BCRhjFniBTr5LaTiLitJ0JLLsBaho8AUNE0BoHnctXRi1HXhOXq52JPDhH5OG/dv2XIIiWy7dimE3j59iz0DD2IKYNy0NBGIAQAEoDAC+eMQYEamKakA5UJyibOTEnPyDAGVUOGAJMmGf9t2dK4nYiInMZgyBfo9cZV49esMf6r18vdIqcc3HAcLw7NQpd6R9BmREukfTMYPxd3QHOccewEalr2wZSw3Ly55fa4OMem1Ztmf1VPxDatJcaAiIjIaRwmUzulFPBzgjAI7Pv8KHTLzkH3v3gcKqvM8fFHBf4UsQ+pI4tw19DLaPzAePsnzMxUX76LK8NcSpyaT0TkQawz5EY+GwwpqYCfHcIg8POHh5D+dj50uxPxW0XlLK9AlGFE1F6kjCrFnWkdEdk6wrjDnTk2zlJiTk5WlnFIzB41BodERFawzhDVVPUGHRXl2orjXmSoMGDHuweg+89l6PbdjFP6DgA6AABCcAO3x+xD6jg9Rs/thPCEXjVPINeyD0rtbVPq1HwiIpVjMKQWGRnAE08Ye0kcIUcBPwAVJRXY/vZ+6FYVIuPXtjhnSDLvC8V1jIrPRmqqhJF/7YwGzXrbP6E3F38FbPe2mXJy5OxtU/LUfCIiFeMwmRpkZAApKa49d/VqYOJE97anmvLicmS+no30D4qw7kh7XBBNzfvCUIA7E/cj5e5A3PZMEupF1KvlTLXwxrCVXg9ERwOXLlnfL3dOjpzDhkREMuAwGRnp9cDDD7v+fFd6CRwIPEoLS7FpyT7o1pRi/W+dcEV0N++LkC5j7M2/IvXPIRj6ZBKCw/q73n4TbxQFXLDAdiAEyNbbZsbV4omIPILBkNJlZdV+g7bF1EswYID9Y6uqJV+meODt+HpxNnSf6fHlyU4oRGWeT5R0AePbHULKfaEY/EQSAus7+bpy0+srawDZI2dOjreHDYmINIDBkNJt2eL8c1ztJbCRLyNOnwZSUvAXfIxPMMm8PdbvHFI6HUXKA+Ho/2hn+AcNdL6tSrF9O3D5smPHyp2Tw7XEiIjcisGQ0p065fxzXOkl0Ottzk6TABggYRHm4ie/fhjfLQepD0fi1gc6wi/AR5J1He3tiYx0vrfNE7iWGBGR2zAYUmI9maoSEhw77s9/BkaNcvkaCj7+EuG2ivkB8INAAnLx26bfIf3JgVo3auNob88TTyjr94OIiOpM28txqGGNpz/9ybHjpk41zhobPNjhm/X5AxewfNI2DIvYjelTrjn0HOl8nmPtUZsBA4w9atXXDKsqMhJ49lnvtYmIiLxCu8GQWtZ4GjzYeBOuTWSkw0Mmp3edwxspWzGo0V7EdI7Eo2sGYvOVW3AGcY61R+58GU+pbRFVkxUr2CtEROSDtBkM1ZIfAyGMj1mzlLHgqb+/8SZcGzs36RPfn8YrY7LQp+F+xPeKwcyMQdhW0BUCfugVegCLRmbhvW8Tau8ZkSQgPl4Z+TKeYmsR1fh4QKfjTC0iIh+lzaKLalzjycklIo5+kwPdqyeRvj0au2+0N2+XYEDfhgeQOvQKkv96MxL6VLnxm3rLAOs1bBS01plHKT2PjIhII1h00ZMcXdLC2nFy3SjtTKcWBoGDX/yG9KWnodsZi/0lbQAkAgD8oMegRtlIGV6I8XPbIvaWJNuvwRo2nKlFRKQx2gyGLlxw7Ti5F/CsdpMWBoG9aw5D91Ye0ncl4EjZzQBuBgAEoBxDI/ch5Y5ijJ3THlEduzn2GqxhQ0REGqPNYKhpU/vHVD9OIQt4CoPA/1b+Ct2/L0K3JxG/V7QD0A4AEIRSjIjah9Q7yzBmbkdE3NTDtRfxdM+It9YZY0BHREQO0GYwVD1B1t5x9hKuJcmYcD12rEduuIYKA35ccQDp715Bxv6bkavvZN5XD8UYGZuNlHF6jE7rjLC4XrWcSQG80bsmdw8eERGpijYTqE2rf9dSZBDx8ZWrf8uQcF1RUoFtb+2HblUhMg62Q54h2ryvAa5hVPx+pN4lYeScJIRGhbrlNT3OVu+aOxO0vfEaRETkFUyg9qSqq39biwUlyXJdL0eXaqjjAp5l18uwZWk2dB8VY93RDrgoKvN8wlGAO1vtR+o9gRjxTBeENOpbp9fyOm/0rtl7DQB46CEgPNyp4pREROTbtBkMAbZnTsXH15w55WihQRcKEpZcLcGmV7KRvroMG3I64aqozPOJlC5hXOuDSPlzCIbO7oKgBv2dPr9ibN9ee0+cEEBurvE4V3vX7L0GYFyMddgwDpsREZGZdoMhwPGZU6alGs6csd2TFBfncEHC4ovF+O+ifdB9bsCXJzvjGirzfKL98jG+3WGk3t8Agx5PQkCISoscVk9gdrScQV1615x5rpcT34mISLm0HQwBjs2cqjqsJknWCxJWHVaz4trZa9j48n6kZ0j475kkFKOPeV9zv3NI6XwUqQ82Qt+HO8E/aKDr16OEWVTWEpibNHHsuceOuf66zvTMeSHxnYiIVEKozEsvvSQAiJkzZzr8nIKCAgFAFBQU1O3FdToh4uJMC3YYH/Hxxu1WXP79inj/oe1iTPROEYwbFk9rGXBKPN0jU+x4d7/Ql+vr1q7a2hcXZ7N9HqHTCSFJlm1w9uFqeysqjNfr7OtnZrr1LSAiIvdw2/3bDlXNJtu1axcmTJiAsLAwDBkyBEuXLnXoeW7NRrfT83LxyCWse+kgdF+F4LuLXVGBQPO+NoE5SOlxEqkzotFtYjtIfrWskO4sJcyicmSWnj2mIUfTTD5n2VpSpDarVwMTJzr/WkRE5FGcTVbN9evX8ec//xnvvvsu/vnPf3rvha0FP9WG1fKy87F24WGkf9MAW68kQY/KPJ9OwceQ0vsMUmc2R8exN0PyS/RMG2Wsg2TmSAKzPXVNpLaVGF8bFxLfiYjId6gmGJoxYwZGjRqFYcOG2Q2GSktLUVpaav65sLDQtRetpXhfbvPeyFh0DLrNjfB9YWcIVOb5dKt3CKn9zyPlyQS0HdkaQGvXXt9R3pip5Yg6lhZw27lMifFZWcCECcYZZNY4mfhORES+SRXB0CeffILdu3dj165dDh2/cOFCvPDCC3V7URvDTuL0aSAlFTORjrWoHHa6NfQAUgZdRMozrdBqcHsA7eE1XqqDZJc7e1jqei5/f2DoUODdd60PmzmY+E5ERL7PT+4G2JObm4uZM2fio48+QkhIiEPPSUtLQ0FBgfmRm5vr3IvWMuwkARAAlmIWBjXcjaXjt+LUzrPYeb0Tntk4GK0GJzj3Wu7gwTpITjGVIJBs5EKZemKaN7d9DABERrqvt8Y0bFZ9CZa4OE6rJyIiACpYjmPdunUYP348/Kv89a7X6yFJEvz8/FBaWmqxzxpnErCEQeDEgo+R+Pxk+41z4/IbdWJKXLZXB8nVpGRn2EpgrprIDQApKbWfR6dzb6CihJIDRETkFCZQ/2Ho0KHYv3+/xbapU6eiXbt2mDNnjt1AyBHCILBnzWGkv3Ueup9b4JZyf6xx5ImeHnZylBvqILmNrQTmuLjKyt56vbH359Il6+fwRMK3I/WkiIhIkxQfDDVs2BCdOnWy2BYaGorIyMga251hqDDgf6sOQvfvi0jfexNOVFTm+bSAg4X/lDQLyZEgxJttqa2y9/bttgMhwHsJ30RERFBBMORO+jI9ti/bh/T/XEXGgdY4ra8MpuqhGHc034fUZIFRz/QC+rpv+Q2vcXR5EW+orSdGKQnfREREUGkwlJWV5dLz2kZdxgXRxfxzA1zDmBbZSLnLD7c/k4TQqMolMhQz7OQsNQwHKSXhm4iICCpIoHYHUwIWUIBGkgF3Jh5A6qQgDH8qCSGNapmhZq3OkLVV7b3JFxKBlZTwTUREiuWtBGpNBUPpz2ZizNy+CGoQ5PiTPRV8uHLeWopAqm6KuCOzztR2TURE5FYMhtzIW2+mw1wJapSw9pi7KbHnjYiIFIPBkBspKhhyJaixtwCqmoeVfGHYj4iIPILBkBu57c2s643b1aAmKwsYMsT++ZVSBJKIiMgNvBUMKX45DsXIyDAGMkOGAJMmGf9t2dK43VHOLKhaFaeiExEReQyDIUeYhraqBzJnzhi3OxoQuRrUcCo6ERGRxzAYsqeWRVvN22bNMh5nj6tBjSMLoMbHK68IJBERkQowGLLH1aEta1wNakxrj5mOqf4cQLlFIImIiBSOwZA97szXqUtQY1p7rHlzy+1xceqcVk9ERKQQqlyOw2OszRZzd75OXRZUVdLaY0RERD6CwZCJrUKIr75q/Nedi7bWJahRw9pjREREKsJgCLBdCPHMGeDuu4GnnwaWLHHvoq0MaoiIiBSBOUOOzBb75BPgs8+Yr0NEROSD2DPk6GyxJk2AEyeYr0NERORjGAw5M1uMQ1tEREQ+h8NkrO5MRESkaQyGWN2ZiIhI0xgMsbozERGRpjEYAtRV3VmvB7KygDVrjP86siYaERER2cQEahM1VHe2VRjy9deVFbARERGpiCSEtQI7vqWwsBDh4eEoKChAWFiY3M1xja3CkKahPKX1YBEREdWRt+7fHCZTA0cKQ86axSEzIiIiFzAYUgNHC0Nu3+69NhEREfkIBkNq4ExhSCIiInIKgyE1YGFIIiIij2EwpAYsDElEROQxDIbUgIUhiYiIPIbBkFqoqTAkERGRirDoopqooTAkERGRyjAYUht/f2DwYLlbQURE5DM4TEZERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpik+GFq4cCF69uyJhg0bIioqCuPGjcORI0fkbhYRERH5CMUHQ1u3bsWMGTOwc+dObNq0CRUVFRgxYgSKiorkbhoRERH5AEkIIeRuhDMuXLiAqKgobN26FQMHDnToOYWFhQgPD0dBQQHCwsI83EIiIiJyB2/dv1W3HEdBQQEAICIiwuYxpaWlKC0tNf9cWFjo8XYRERGROil+mKwqIQRmz56N/v37o1OnTjaPW7hwIcLDw82P+Ph4L7aSiIiI1ERVw2QzZszAxo0b8f333yMuLs7mcdZ6huLj4zlMRkREpCIcJqvm8ccfx4YNG7Bt27ZaAyEACA4ORnBwsJdaRkRERGqm+GBICIHHH38ca9euRVZWFhITE+VuEhEREfkQxQdDM2bMwOrVq7F+/Xo0bNgQeXl5AIDw8HDUq1dP5tYRERGR2ik+Z0iSJKvbV65cifvvv9+hc3BqPRERkfowZ+gPCo/ViIiISOVUNbWeiIiIyN0YDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaRqDISIiItI0BkNERESkaQyGiIiISNMYDBEREZGmMRgiIiIiTWMwRERERJrGYIiIiIg0jcEQERERaZpqgqG3334biYmJCAkJQffu3bF9+3a5m0REREQ+QBXB0KeffopZs2bh2WefxZ49ezBgwACMHDkSp06dkrtpREREpHKSEELI3Qh7br31Vtxyyy145513zNvat2+PcePGYeHChXafX1hYiPDwcBQUFCAsLMyTTSUiIiI38db9W/E9Q2VlZfjll18wYsQIi+0jRozAjz/+KFOriIiIyFcEyN0Aey5evAi9Xo/o6GiL7dHR0cjLy7P6nNLSUpSWlpp/LigoAGCMMImIiEgdTPdtTw9iKT4YMpEkyeJnIUSNbSYLFy7ECy+8UGN7fHy8R9pGREREnnPp0iWEh4d77PyKD4aaNGkCf3//Gr1A+fn5NXqLTNLS0jB79mzzz1evXkWLFi1w6tQpj76ZSlNYWIj4+Hjk5uZqKleK183r1gJeN69bCwoKCpCQkICIiAiPvo7ig6GgoCB0794dmzZtwvjx483bN23ahLFjx1p9TnBwMIKDg2tsDw8P19QvkUlYWBivW0N43drC69YWrV63n59nU5wVHwwBwOzZszF58mT06NEDffr0wYoVK3Dq1Ck88sgjcjeNiIiIVE4VwdDdd9+NS5cu4R//+AfOnTuHTp064auvvkKLFi3kbhoRERGpnCqCIQCYPn06pk+f7tJzg4ODMW/ePKtDZ76M183r1gJeN69bC3jdnr1uVRRdJCIiIvIUxRddJCIiIvIkBkNERESkaQyGiIiISNMYDBEREZGmqTIYevvtt5GYmIiQkBB0794d27dvr/X4rVu3onv37ggJCUGrVq2wfPnyGsfodDp06NABwcHB6NChA9auXeup5rvMmevOyMjA8OHD0bRpU4SFhaFPnz745ptvLI5ZtWoVJEmq8SgpKfH0pTjFmevOysqyek2HDx+2OM7XPu/777/f6nV37NjRfIwaPu9t27ZhzJgxiI2NhSRJWLdund3n+ML329nr9pXvt7PX7Svfb2ev21e+3wsXLkTPnj3RsGFDREVFYdy4cThy5Ijd53njO666YOjTTz/FrFmz8Oyzz2LPnj0YMGAARo4ciVOnTlk9PicnB3fccQcGDBiAPXv24G9/+xueeOIJ6HQ68zE7duzA3XffjcmTJ2Pfvn2YPHkyJkyYgJ9++slbl2WXs9e9bds2DB8+HF999RV++eUXDBkyBGPGjMGePXssjgsLC8O5c+csHiEhId64JIc4e90mR44csbim1q1bm/f54uf9+uuvW1xvbm4uIiIicNddd1kcp/TPu6ioCF26dMGyZcscOt5Xvt/OXrevfL+dvW4TtX+/nb1uX/l+b926FTNmzMDOnTuxadMmVFRUYMSIESgqKrL5HK99x4XK9OrVSzzyyCMW29q1ayfmzp1r9fi//vWvol27dhbbpk2bJnr37m3+ecKECeL222+3OOa2224T99xzj5taXXfOXrc1HTp0EC+88IL555UrV4rw8HB3NdEjnL3uzMxMAUBcuXLF5jm18HmvXbtWSJIkTpw4Yd6mhs+7KgBi7dq1tR7jK9/vqhy5bmvU+P2uypHr9pXvd1WufN6+8P0WQoj8/HwBQGzdutXmMd76jquqZ6isrAy//PILRowYYbF9xIgR+PHHH60+Z8eOHTWOv+222/Dzzz+jvLy81mNsndPbXLnu6gwGA65du1Zjsbvr16+jRYsWiIuLw+jRo2v8ZSmnulx3t27dEBMTg6FDhyIzM9NinxY+7/feew/Dhg2rUaVdyZ+3K3zh++0Oavx+14Wav9/u4Cvf74KCAgCodRFWb33HVRUMXbx4EXq9vsZq9dHR0TVWtTfJy8uzenxFRQUuXrxY6zG2zultrlx3da+88gqKioowYcIE87Z27dph1apV2LBhA9asWYOQkBD069cPx44dc2v7XeXKdcfExGDFihXQ6XTIyMhA27ZtMXToUGzbts18jK9/3ufOncN///tfPPjggxbblf55u8IXvt/uoMbvtyt84ftdV77y/RZCYPbs2ejfvz86depk8zhvfcdVsxxHVZIkWfwshKixzd7x1bc7e045uNrGNWvWYP78+Vi/fj2ioqLM23v37o3evXubf+7Xrx9uueUWvPnmm3jjjTfc1/A6cua627Zti7Zt25p/7tOnD3Jzc7FkyRIMHDjQpXPKxdU2rlq1Co0aNcK4ceMstqvl83aWr3y/XaX277czfOn77Spf+X4/9thjyM7Oxvfff2/3WG98x1XVM9SkSRP4+/vXiPby8/NrRIUmzZo1s3p8QEAAIiMjaz3G1jm9zZXrNvn000/xl7/8BZ999hmGDRtW67F+fn7o2bOnYv6SqMt1V9W7d2+La/Llz1sIgf/7v//D5MmTERQUVOuxSvu8XeEL3++6UPP3213U9v2uC1/5fj/++OPYsGEDMjMzERcXV+ux3vqOqyoYCgoKQvfu3bFp0yaL7Zs2bULfvn2tPqdPnz41jv/222/Ro0cPBAYG1nqMrXN6myvXDRj/Yrz//vuxevVqjBo1yu7rCCGwd+9exMTE1LnN7uDqdVe3Z88ei2vy1c8bMM7WOH78OP7yl7/YfR2lfd6u8IXvt6vU/v12F7V9v+tC7d9vIQQee+wxZGRkYMuWLUhMTLT7HK99xx1OtVaITz75RAQGBor33ntPHDx4UMyaNUuEhoaas+rnzp0rJk+ebD7+999/F/Xr1xdPPvmkOHjwoHjvvfdEYGCgSE9PNx/zww8/CH9/f/Hyyy+LQ4cOiZdfflkEBASInTt3ev36bHH2ulevXi0CAgLEW2+9Jc6dO2d+XL161XzM/Pnzxddffy1+++03sWfPHjF16lQREBAgfvrpJ69fny3OXvdrr70m1q5dK44ePSoOHDgg5s6dKwAInU5nPsYXP2+Te++9V9x6661Wz6mGz/vatWtiz549Ys+ePQKAePXVV8WePXvEyZMnhRC++/129rp95fvt7HX7yvfb2es2Ufv3+9FHHxXh4eEiKyvL4ve2uLjYfIxc33HVBUNCCPHWW2+JFi1aiKCgIHHLLbdYTMubMmWKGDRokMXxWVlZolu3biIoKEi0bNlSvPPOOzXO+fnnn4u2bduKwMBA0a5dO4svl1I4c92DBg0SAGo8pkyZYj5m1qxZIiEhQQQFBYmmTZuKESNGiB9//NGLV+QYZ6570aJF4qabbhIhISGicePGon///mLjxo01zulrn7cQQly9elXUq1dPrFixwur51PB5m6ZO2/q99dXvt7PX7Svfb2ev21e+3678nvvC99vaNQMQK1euNB8j13dc+qOBRERERJqkqpwhIiIiIndjMERERESaxmCIiIiINI3BEBEREWkagyEiIiLSNAZDREREpGkMhoiIiEjTGAwRERGRpjEYIiIiIk1jMERERESaxmCIiFRpzZo1CAkJwZkzZ8zbHnzwQSQlJaGgoEDGlhGR2nBtMiJSJSEEunbtigEDBmDZsmV44YUX8J///Ac7d+5E8+bN5W4eEalIgNwNICJyhSRJWLBgAVJTUxEbG4vXX38d27dvZyBERE5jzxARqdott9yCX3/9Fd9++y0GDRokd3OISIWYM0REqvXNN9/g8OHD0Ov1iI6Olrs5RKRS7BkiIlXavXs3Bg8ejLfeeguffPIJ6tevj88//1zuZhGRCjFniIhU58SJExg1ahTmzp2LyZMno0OHDujZsyd++eUXdO/eXe7mEZHKsGeIiFTl8uXL6NevHwYOHIh///vf5u1jx45FaWkpvv76axlbR0RqxGCIiIiINI0J1ERERKRpDIaIiIhI0xgMERERkaYxGCIiIiJNYzBEREREmsZgiIiIiDSNwRARERFpGoMhIiIi0jQGQ0RERKRpDIaIiIhI0xgMERERkaYxGCIiIiJN+38QUSereiPytAAAAABJRU5ErkJggg==",
|
|
"text/plain": [
|
|
"<Figure size 640x480 with 1 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"filenames": {
|
|
"image/png": "/Users/mhjensen/Teaching/MachineLearning/doc/LectureNotes/_build/jupyter_execute/exercisesweek41_22_1.png"
|
|
}
|
|
},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"theta from own sdg\n",
|
|
"[[3.6805151 ]\n",
|
|
" [3.33045013]]\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.98751068]\n",
|
|
" [2.92901115]]\n",
|
|
"Eigenvalues of Hessian Matrix:[0.28244905 4.61501312]\n",
|
|
"theta from own gd\n",
|
|
"[[3.98556236]\n",
|
|
" [2.93059014]]\n",
|
|
"theta from own sdg with momentum\n",
|
|
"[[4.01133846]\n",
|
|
" [2.92452609]]\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.99974365]\n",
|
|
" [3.0013839 ]\n",
|
|
" [3.99861193]]\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.99757634]\n",
|
|
" [2.9983289 ]\n",
|
|
" [3.99759503]]\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.99993596]\n",
|
|
" [3.00035483]\n",
|
|
" [3.99963172]]\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 0x1360ef5e0>]"
|
|
]
|
|
},
|
|
"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 0x135f8b1f0>"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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CIVCuP322xEKhbw+yryG/p7dgf6e3YH+nt2D/q7tIbVZlSAIgiCI+Q0pIgRBEARBeAYVIgRBEARBeAYVIgRBEARBeAYVIgRBEARBeAYVIhVOMpnE2rVroSgKXn75Za+PM6/Yt28frrnmGqxYsQK1tbVYtWoVbr/9dqRSKa+PNi+47777sGLFCoTDYaxbtw5/+tOfvD7SvGLz5s045ZRTEIlE0N7ejksvvRS7du3y+ljzns2bN0NRFNx0001eH6VioEKkwrnllluwePFir48xL9m5cydyuRy+/e1v4/XXX8fXvvY1fOtb38Ktt97q9dEqnsceeww33XQTbrvtNrz00ks488wzcfHFF+PAgQNeH23e8Mwzz+C6667D1q1b8dRTTyGTyeCCCy5APB73+mjzlm3btuGBBx7AiSee6PVRKgoa361gfvOb3+Dmm2/GT3/6Uxx33HF46aWXsHbtWq+PNa+56667cP/992Pv3r1eH6Wi2bBhA04++WTcf//92sdWr16NSy+9FJs3b/bwZPOXw4cPo729Hc888wzOOussr48z75icnMTJJ5+M++67D3feeSfWrl2Lr3/9614fqyIgRaRCGRgYwCc+8Ql8//vfR11dndfHqRrGx8fR0tLi9TEqmlQqhe3bt+OCCy6Y8fELLrgAzz77rEenmv+Mj48DAL1/BXHdddfhve99L84//3yvj1JxSL30jiiOqqq4+uqrce2112L9+vXYt2+f10eqCvbs2YN7770XX/nKV7w+SkUzNDSEbDaLjo6OGR/v6OhAf3+/R6ea36iqiptvvhlnnHEGjj/+eK+PM+949NFH8eKLL2Lbtm1eH6UiIUVEIu644w4oilL21wsvvIB7770XsVgMmzZt8vrIFYnZv2cjvb29uOiii3DZZZfh4x//uEcnn18oijLj96qqHvExgg/XX389duzYgUceecTro8w7enp6cOONN+Lhhx9GOBz2+jgVCXlEJGJoaAhDQ0NlP2f58uW4/PLL8atf/WrGRTubzcLv9+PKK6/EQw89JPqoFY3Zv2d2Uent7cU555yDDRs24Lvf/S58PqrfnZBKpVBXV4cf//jH+OAHP6h9/MYbb8TLL7+MZ555xsPTzT9uuOEGPP744/jjH/+IFStWeH2cecfjjz+OD37wg/D7/drHstksFEWBz+dDMpmc8WfEkVAhUoEcOHAAsVhM+31vby8uvPBC/OQnP8GGDRvQ2dnp4enmF4cOHcI555yDdevW4eGHH6YLCic2bNiAdevW4b777tM+tmbNGnzgAx8gsyonVFXFDTfcgJ///Od4+umncfTRR3t9pHnJxMQE9u/fP+NjH/vYx3Dsscfi05/+NLXCTEAekQpk6dKlM37f0NAAAFi1ahUVIRzp7e3F2WefjaVLl+Luu+/G4cOHtT9buHChhyerfG6++WZcddVVWL9+PU477TQ88MADOHDgAK699lqvjzZvuO666/DDH/4Qv/jFLxCJRDT/TWNjI2praz0+3fwhEokcUWzU19ejtbWVihCTUCFCECXYsmULdu/ejd27dx9R4JGQ6IyPfOQjGB4exhe+8AX09fXh+OOPxxNPPIFly5Z5fbR5AxuNPvvss2d8/MEHH8TVV1/t/oEIogTUmiEIgiAIwjPIdUcQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGdQIUIQBEEQhGf8P6ZyOHzGZunmAAAAAElFTkSuQmCC",
|
|
"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.18"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
} |