{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 最小二乘\n", "\n", "## 1. 最小二乘的基本原理\n", "\n", "最小二乘法(Least Squares)是一种数学优化技术,它通过最小化误差的平方和找到一组数据的最佳函数匹配, 最小二乘法通常用于曲线拟合、求解模型。很多其他的优化问题也可通过最小化能量或最大化熵用最小二乘形式表达。\n", "\n", "![ls_theory](images/least_squares.png)\n", "\n", "最小二乘原理的一般形式为:\n", "$$\n", "L = \\sum (V_{obv} - V_{target}(\\theta))^2\n", "$$\n", "其中\n", "* $V_{obv}$是观测的多组样本值\n", "* $V_{target}$是假设拟合函数的输出值\n", "* $\\theta$为构造模型的参数\n", "* $L$是目标函数\n", "\n", "如果通过调整模型参数$\\theta$,使得$L$下降到最小则表明,拟合函数与观测最为接近,也就是找到了最优的模型。\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1 示例\n", "\n", "假设我们有下面的一些观测数据,我们希望找到他们内在的规律。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAEGCAYAAABiq/5QAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/MnkTPAAAACXBIWXMAAAsTAAALEwEAmpwYAAAUHElEQVR4nO3da4xdV3nG8efBNjBc2knIKErGpI4EMgUiYjpCUEstTUgdLiVWSitoi1Ipwl96CVCZOEVV4Utj5IrLhzaSRQIWREAbLCcFioliI9SKpozjlBCClZRL8ODgQeBCwRTHfvvh7IntYc6c61577bP+PwnNnG17zjpnyLP3ede713JECABQjqc1PQAAQFoEPwAUhuAHgMIQ/ABQGIIfAAqztukB9OOiiy6KDRs2ND0MAGiVQ4cO/SAiZpYfb0Xwb9iwQfPz800PAwBaxfZ3VjpOqQcACkPwA0BhCH4AKAzBDwCFIfgBoDCt6OoBgBLsO7ygXfuP6HsnTurS6Slt37JRWzfNjv15CH4AyMC+wwu6Ze9DOnnqtCRp4cRJ3bL3IUkae/hT6gGADOzaf+Sp0F9y8tRp7dp/ZOzPRfADQAa+d+LkQMdHQfADQAYunZ4a6PgoCH4AyMD2LRs1tW7Necem1q3R9i0bx/5cTO4CQAaWJnDp6gGAgmzdNFtL0C9HqQcACkPwA0Bhag9+22tsH7b9merx5bbvt/2Y7U/ZfnrdYwAAnJXiiv8mSY+c8/h9kj4QES+Q9CNJNyYYAwCgUmvw214v6fWSPlw9tqSrJN1V/ZU9krbWOQYAwPnqvuL/oKR3STpTPX6epBMR8WT1+Kik+qewAQBPqa2d0/YbJB2PiEO2Xz3Ev98maZskXXbZZeMdHABkrO5VOuvs498s6Y22XyfpmZJ+RdKHJE3bXltd9a+XtLDSP46I3ZJ2S9Lc3FzUOE4AyEaKVTprK/VExC0RsT4iNkh6s6QDEfHHkg5KelP1126QdHddYwCAtkmxSmcTffw3S3qn7cfUqfnf3sAYACBLKVbpTLJkQ0R8UdIXq++/KekVKZ4XANrm0ukpLawQ8uNcpZM7dwEgIylW6WSRNgDISIpVOgl+AMhM3at0UuoBgMIQ/ABQGIIfAApD8ANAYQh+ACgMwQ8AhSH4AaAwBD8AFIbgB4DCEPwAUBiWbACQlbp3nwLBDyAjKXafGmQsk3oCIvgBZGO13adShm4/J6A2nxio8QPIRordp/rRa/vDpRPDwomTCp09Mew7vOIW4tkh+AFko9suU+PcfaofvU5AKfbFrRPBDyAbKXaf6kevE1Aun0yGRfADyMbWTbO69forNDs9JUuanZ7Srddfkbx23usElMsnk2ExuQsgK3XvPtXvGKTu2x9u37LxvMlfqZlPJsMi+AEUr1uHTrcTUIp9cetE8AMo2rD3DtT1ySRFmyg1fgBFy6lDJ1WbKMEPoGg5deikOglR6gFQtEunp7SwQsif26GT6i7dVCchrvgBFK1X62bKu3RTtYkS/ACK1uvegZRzAKluYKPUA6B4q3XopJwDSNUmSvADwCr6mQMYpxQ3sFHqAYBV5LJ+0DhxxQ8Aq2j7XborIfgBoIcc1g8aJ0o9AFAYgh8ACkPwA0BhCH4AKAzBDwCFoasHAMYg1UJu41DbFb/tZ9r+T9v/Zfth2++tjl9u+37bj9n+lO2n1zUGAEgh5UJu41Bnqef/JF0VES+TdKWka22/UtL7JH0gIl4g6UeSbqxxDABQu5w2c+lHbaWeiAhJ/1s9XFf9LyRdJemPquN7JL1H0m11jQMA6tbvQm65lINqndy1vcb2g5KOS7pX0n9LOhERT1Z/5aikFV+17W22523PLy4u1jlMABhJP+vo51QOqjX4I+J0RFwpab2kV0h60QD/dndEzEXE3MzMTF1DBICR9bOQW07loCRdPRFxwvZBSa+SNG17bXXVv15SnrMfANCnfhZyy2lv39qC3/aMpFNV6E9Jukadid2Dkt4k6ZOSbpB0d11jAIBUei3klnpd/9XUWeq5RNJB21+V9BVJ90bEZyTdLOmdth+T9DxJt9c4BgDIQk7r+tfZ1fNVSZtWOP5Nder9AFCMnNb1585dAEgkl3X9CX4AEyeXfvlcEfwAJspSv/xS6+RSv7wkwr/C6pwAJkpO/fK5IvgBTJSc+uVzRfADmCj9LJ9QOoIfwETJqV8+V0zuApgoOfXLD6vuriSCH8DEyaVffhgpupIIfqAB9Jk3K+f3f7WuJIIfaCn6zJuV+/ufoiuJyV0gMfrMm5X7+5+iK4ngBxKjz3xl+w4vaPPOA7p8x2e1eeeB2namyv39T9GVRKkHSCynddlzkbL8Msz7n3JOIEVXEsEPJLZ9y8bzQk6izzzFhOaSQd//JuYE6u5KotQDJLZ106xuvf4KzVZXmGvsp0KuiY23c5Cy/HLu+29Js9NTuvX6K7oGbe5zAsPgih9owFLIjHolmXNb4iBSl78GuaLOfU5gGFzxAw0Z9UpyqQSxcOKkQmdPHG381DCOCc26Jocnce0frviBhox6JZmyLl63QSY0V/qUI43+6ambSZyTIfiBhoxa3pi0EkQ/5ZduE63PWPu02k6Ck7D2z3IEP9CQUa8kS2wL7fYpZ/mxJeM6CbZ57Z+VUOMHGjJod8lyJS4/PGiQT/JJcBRc8QMNGuVKchJLEL10+5RzwbPW6eenzkxUHb5OBD/QYpNWguilW3nsb3/vJZLKOgmOguAH0Bq9PuUQ9P0h+AG0SmmfcurA5C4AFIbgB4DCEPwAUBhq/ECfJmVBNIDgB/qQ+z6twCAo9QB9mMQ12VEurviBPvRaEI0yENqk6xW/7c/Z3pBwLEC2VluTfZLWxUcZViv1fETSF2y/2/a6VAMCcrTagmijlIHq2jwEWE3XUk9E/LPtf5X0N5LmbX9M0plz/vz9CcYHZGG1pQLe8akHV/w3vVaSZMIYTelV4/+FpJ9Keoak5+qc4AdK022pgGHXxe/1SYE5A9Sla/DbvlbS+yXdI+nlEfGzZKMCWmTYDVW6fSJYuvLv9UmACWUMa7Ua/7sl/UFE7Bgm9G0/3/ZB21+3/bDtm6rjF9q+1/aj1dcLhh08kINhN1Tp9olgjd1zzoAJZYzCEVHPD7YvkXRJRDxg+7mSDknaKulPJf0wInba3iHpgoi4ebWfNTc3F/Pz87WME2jK8hq/1Pmk0G0bQUv61s7XS5I27zywYnlpdnpK/77jqlrGi/axfSgi5pYfr+0Grog4FhEPVN//RNIjkmYlXSdpT/XX9qhzMgCK0+2TwuwqraNLJm2jdaSV5Aau6n6ATZLul3RxRByr/ugJSRd3+TfbJG2TpMsuuyzBKFEn6tHd34OV3odecwajbLTO7wK1L9lg+zmSPi3p7RHx43P/LDp1phVrTRGxOyLmImJuZmam7mGiRtSjB3sP+pkzGHajdX4XkGq+4q9u/Pq0pDsjYm91+Pu2L4mIY9U8wPE6x4Dmrda2WMqV5qDvQa9dpobdaJ3fBaQag9+2Jd0u6ZFlN3vdI+kGSTurr3fXNQbkgXp0Pe/BMFsQ8ruAVO8V/2ZJb5X0kO0Hq2N/rU7g/5PtGyV9R9If1jgGjMkodeFR6tEp1Vn7zuU9yGUcaFZtwR8R/6ZOB9pKrq7reTF+qy0tIPUuNwx7g1NKgyyfMMwJ4ndeNKOP/8fjKx5PqQ2/C9SPZZnRU7e68Hv/5WH9/NSZnmE5bD06pX5r38Our3PwG4sDHa9LG34XqB/Bj5661X9/9LNTv3Ss20ThMPXolPqtfQ87OZpTbT333wXqR/Cjp2514W7aOFHYb+172ACftNo69wK0G1svoqduPePTUytv09DGMOu3L361DVnG8fPbgHsB2o/gR0/dbih6zxtfMjFh1u9Ca8MG+LALueWI/Yfbj1IP+rJaXXhSPvL3qn0vlTdOnjqtNbZOR2h2gNc8KbX1nOYrMByCHyOZlDDrZXk3z+mIp670S3j955q0+YoSUeoB+kB546xJmq8oFVf8QB8ob5zFvQDtR/ADfaC8cb5SSnyTilIP0AfKG5gkXPEDfaC8gUlC8AN96qe8wR2taAOCHxiTYRdwA1Kjxg+MCS2faAuCHxgTWj7RFpR60Go51dRp+URbcMWP1sptlUhaPtEWXPEjW72u5ofdFKUutHyiLQh+ZKmfDpkca+rc0Yo2oNSDLPXTITPspihA6Qh+ZKmfq3lq6sBwCH5kqZ+r+Una1QpIiRo/srR9y8bzavzSylfz1NSBwRH8yFKvDpl++vdz6vEHckLwD4gwSafb1Xw/HT+smwN0R41/ALndMFSnfYcXtHnnAV2+47PavPNAVq+xn44f1s0BuiP4B1BKmOR+guun4yfHHn8gFwT/AEoJk9xPcP10/NDjD3RH8A+glDDJ/QTXT/8+Pf5AdwT/AEoJk9xPcCv17//+b8xq1/4jT81JSKLHH+jCEdH0GHqam5uL+fn5pochqYyunuUdMVLnBJdrcLZtvEAqtg9FxNzy47RzDqiEG4batspkbqt0Arkj+BNp2yeFNp3gcp+TAHJDjT+B3Nsj2y73OQkgNwR/Arm3R7ZdKZPuwLhQ6kmAUkS92jYnATSN4E+ATbg76pznaNOcBNC02ko9tu+wfdz21845dqHte20/Wn29oK7nzwmlCOY5gJzUWeP/qKRrlx3bIem+iHihpPuqxxOPDUOY5wByUlupJyK+ZHvDssPXSXp19f0eSV+UdHNdY8hJ6aUI5jmAfKTu6rk4Io5V3z8h6eLEz4+G0HIJ5KOxds7orBXRdb0I29tsz9ueX1xcTDgy1IF5DiAfqYP/+7YvkaTq6/FufzEidkfEXETMzczMJBsg6sE8B5CP1O2c90i6QdLO6uvdiZ8fDSp9ngPIRZ3tnJ+Q9GVJG20ftX2jOoF/je1HJb2megwASKjOrp63dPmjq+t6TgBAb6zVAwCFIfgBoDATu1ZP29a/B4BUJjL4l2/Ft7QujCTCH0DxJrLUw7owANDdRAY/68IAQHcTGfysCwMA3U1k8LMuDAB0N5GTu2zFBwDdTWTwS6wLAwDdTGzwN437CADkiuCvAfcRAMjZRE7uNo37CADkrPgr/jpKMtxHACBnRV/xL5VkFk6cVOhsSWbf4YWRfi73EQDIWdHBX1dJhvsIAOSs6FJPXSUZ7iMAkLOig//S6SktrBDy4yjJcB8BgFwVXerZvmWj1q3xecfWrTElGQATrejglyRFj8cAMGGKDv5d+4/o1Jnzk/7UmaDfHsBEKzr46bcHUKKig59+ewAlKjr46bcHUKKi2znptwdQoqKDX6LfHkB5ii71AECJCH4AKAzBDwCFIfgBoDAEPwAUhuAHgMIQ/ABQGIIfAApD8ANAYQh+ACgMwQ8AhZnotXr2HV5gATYAWGZig3/f4QXdsvchnTx1WpK0cOKkbtn7kCQR/gCK1kipx/a1to/Yfsz2jjqeY9f+I0+F/pKTp06zrSKA4iUPfttrJP2DpNdKerGkt9h+8bifh20VAWBlTVzxv0LSYxHxzYj4haRPSrpu3E/CtooAsLImgn9W0nfPeXy0OnYe29tsz9ueX1xcHPhJ2FYRAFaWbTtnROyOiLmImJuZmRn432/dNKtbr79Cs9NTsqTZ6Sndev0VTOwCKF4TXT0Lkp5/zuP11bGxY1tFAPhlTVzxf0XSC21fbvvpkt4s6Z4GxgEARUp+xR8RT9r+c0n7Ja2RdEdEPJx6HABQqkZu4IqIz0n6XBPPDQCly3ZyFwBQD4IfAArjiGh6DD3ZXpT0nabH0ZCLJP2g6UE0iNdf9uuXeA9Gef2/FhG/1A/fiuAvme35iJhrehxN4fWX/fol3oM6Xj+lHgAoDMEPAIUh+PO3u+kBNIzXj9Lfg7G/fmr8AFAYrvgBoDAEPwAUhuDPlO3n2z5o++u2H7Z9U9NjaoLtNbYP2/5M02NJzfa07btsf8P2I7Zf1fSYUrL9jur/+1+z/Qnbz2x6THWzfYft47a/ds6xC23fa/vR6usFoz4PwZ+vJyX9VUS8WNIrJf1ZHVtUtsBNkh5pehAN+ZCkz0fEiyS9TAW9D7ZnJf2lpLmIeKk6Czq+udlRJfFRSdcuO7ZD0n0R8UJJ91WPR0LwZyoijkXEA9X3P1HnP/qiNhewvV7S6yV9uOmxpGb7VyX9lqTbJSkifhERJxodVHprJU3ZXivpWZK+1/B4ahcRX5L0w2WHr5O0p/p+j6Stoz4Pwd8CtjdI2iTp/oaHktoHJb1L0pmGx9GEyyUtSvpIVer6sO1nNz2oVCJiQdLfS3pc0jFJ/xMRX2h2VI25OCKOVd8/IeniUX8gwZ8528+R9GlJb4+IHzc9nlRsv0HS8Yg41PRYGrJW0ssl3RYRmyT9VGP4iN8WVR37OnVOgJdKerbtP2l2VM2LTv/9yD34BH/GbK9TJ/TvjIi9TY8nsc2S3mj725I+Kekq2x9vdkhJHZV0NCKWPuXdpc6JoBSvkfStiFiMiFOS9kr6zYbH1JTv275Ekqqvx0f9gQR/pmxbnfruIxHx/qbHk1pE3BIR6yNigzqTegciopgrvoh4QtJ3bW+sDl0t6esNDim1xyW90vazqv8WrlZBk9vL3CPphur7GyTdPeoPJPjztVnSW9W50n2w+t/rmh4UkvoLSXfa/qqkKyX9XbPDSaf6pHOXpAckPaROVk380g22PyHpy5I22j5q+0ZJOyVdY/tRdT4J7Rz5eViyAQDKwhU/ABSG4AeAwhD8AFAYgh8ACkPwA0BhCH5gQNXKqd+yfWH1+ILq8YaGhwb0heAHBhQR35V0m872U++UtDsivt3YoIAB0McPDKFaTuOQpDskvU3SldXSAkD21jY9AKCNIuKU7e2SPi/pdwl9tAmlHmB4r1VnyeCXNj0QYBAEPzAE21dKukad3dHesbR6ItAGBD8woGq1yNvU2SPhcUm71Nk0BGgFgh8Y3NskPR4R91aP/1HSr9v+7QbHBPSNrh4AKAxX/ABQGIIfAApD8ANAYQh+ACgMwQ8AhSH4AaAwBD8AFOb/AWkwKMckj29lAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "# 生成数据\n", "data_num = 50\n", "X = np.random.rand(data_num, 1)*10\n", "Y = X * 3 + 4 + 4*np.random.randn(data_num,1)\n", "\n", "# 画出数据的分布\n", "plt.scatter(X, Y)\n", "plt.xlabel(\"X\")\n", "plt.ylabel(\"Y\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.2 数学原理\n", "有$N$个观测数据为:\n", "$$\n", "\\mathbf{X} = \\{x_1, x_2, ..., x_N \\} \\\\\n", "\\mathbf{Y} = \\{y_1, y_2, ..., y_N \\}\n", "$$\n", "其中$\\mathbf{X}$为自变量,$\\mathbf{Y}$为因变量。\n", "\n", "我们希望找到一个模型能够解释这些数据,假设使用最简单的线性模型来拟合数据:\n", "$$\n", "y = ax + b\n", "$$\n", "那么问题就变成求解参数$a$, $b$能够使得模型输出尽可能和观测数据有比较小的误差。\n", "\n", "如何构建函数来评估模型输出与观测数据之间的误差是一个关键问题,这里我们使用观测数据与模型输出的平方和来作为评估函数(也被称为损失函数Loss function):\n", "$$\n", "L = \\sum_{i=1}^{N} \\{y_i - (a x_i + b)\\}^2 \\\\\n", "L = \\sum_{i=1}^{N} (y_i - a x_i - b)^2 \n", "$$\n", "\n", "使误差函数最小,那么我们就可以求出模型的参数:\n", "$$\n", "\\frac{\\partial L}{\\partial a} = -2 \\sum_{i=1}^{N} (y_i - a x_i - b) x_i \\\\\n", "\\frac{\\partial L}{\\partial b} = -2 \\sum_{i=1}^{N} (y_i - a x_i - b)\n", "$$\n", "\n", "即当偏微分为0时,误差函数为最小,因此我们可以得到:\n", "$$\n", "-2 \\sum_{i=1}^{N} (y_i - a x_i - b) x_i = 0 \\\\\n", "-2 \\sum_{i=1}^{N} (y_i - a x_i - b) = 0 \\\\\n", "$$\n", "\n", "将上式调整一下顺序可以得到:\n", "$$\n", "a \\sum x_i^2 + b \\sum x_i = \\sum y_i x_i \\\\\n", "a \\sum x_i + b N = \\sum y_i\n", "$$\n", "\n", "上式中$\\sum x_i^2$, $\\sum x_i$, $\\sum y_i$, $\\sum y_i x_i$都是已知的数据,而参数$a$, $b$是我们想要求得未知参数。通过求解二元一次方程组,我们即可求出模型的最优参数。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.3 求解程序" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = 2.985262, b = 3.577796\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "N = X.shape[0]\n", "\n", "S_X2 = np.sum(X*X)\n", "S_X = np.sum(X)\n", "S_XY = np.sum(X*Y)\n", "S_Y = np.sum(Y)\n", "\n", "A1 = np.array([[S_X2, S_X], \n", " [S_X, N]])\n", "B1 = np.array([S_XY, S_Y])\n", "\n", "# numpy.linalg模块包含线性代数的函数。\n", "# 使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。\n", "coeff = np.linalg.inv(A1).dot(B1)\n", "\n", "print('a = %f, b = %f' % (coeff[0], coeff[1]))\n", "\n", "x_min = np.min(X)\n", "x_max = np.max(X)\n", "y_min = coeff[0] * x_min + coeff[1]\n", "y_max = coeff[0] * x_max + coeff[1]\n", "\n", "plt.scatter(X, Y, label='original data')\n", "plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. 如何使用迭代的方法求出模型参数\n", "\n", "当数据比较多的时候,或者模型比较复杂,无法直接使用解析的方式求出模型参数。因此更为常用的方式是,通过迭代的方式逐步逼近模型的参数。\n", "\n", "### 2.1 梯度下降法\n", "在机器学习算法中,对于很多监督学习模型,需要对原始的模型构建损失函数,接下来便是通过优化算法对损失函数进行优化,以便寻找到最优的参数。在求解机器学习参数的优化算法中,使用较多的是基于梯度下降的优化算法(Gradient Descent, GD)。\n", "\n", "梯度下降法有很多优点,其中最主要的优点是,**在梯度下降法的求解过程中只需求解损失函数的一阶导数,计算的代价比较小,这使得梯度下降法能在很多大规模数据集上得到应用。**\n", "\n", "梯度下降法的含义是通过当前点的梯度方向寻找到新的迭代点。梯度下降法的基本思想可以类比为一个下山的过程。假设这样一个场景:\n", "* 一个人被困在山上,需要从山上下来(i.e. 找到山的最低点,也就是山谷)。\n", "* 但此时山上的浓雾很大,导致可视度很低。因此,下山的路径就无法全部确定,他必须利用自己周围的信息去找到下山的路径。\n", "* 这个时候,他就可以利用梯度下降算法来帮助自己下山。\n", " - 具体来说就是,以他当前的所处的位置为基准,寻找这个位置最陡峭的地方,然后朝着山的高度下降的地方走\n", " - 然后每走一段距离,都反复采用同一个方法,最后就能成功的抵达山谷。\n", "\n", "\n", "一般情况下,这座山最陡峭的地方是无法通过肉眼立马观察出来的,而是需要一个工具来测量;同时,这个人此时正好拥有测量出最陡峭方向的能力。所以,此人每走一段距离,都需要一段时间来测量所在位置最陡峭的方向,这是比较耗时的。那么为了在太阳下山之前到达山底,就要尽可能的减少测量方向的次数。这是一个两难的选择,如果测量的频繁,可以保证下山的方向是绝对正确的,但又非常耗时;如果测量的过少,又有偏离轨道的风险。所以需要找到一个合适的测量方向的频率,来确保下山的方向不错误,同时又不至于耗时太多!\n", "\n", "\n", "![gradient_descent](images/gradient_descent.png)\n", "\n", "如上图所示,得到了最优解。$x$,$y$表示的是$\\theta_0$和$\\theta_1$,$z$方向表示的是花费函数,很明显出发点不同,最后到达的收敛点可能不一样。当然如果是碗状的,那么收敛点就应该是一样的。\n", "\n", "对于最小二乘的损失函数\n", "$$\n", "L = \\sum_{i=1}^{N} (y_i - a x_i - b)^2\n", "$$\n", "\n", "我们更新的策略是:\n", "$$\n", "\\theta^1 = \\theta^0 - \\eta \\triangledown L(\\theta)\n", "$$\n", "其中$\\theta$代表了模型中的参数,例如$a$, $b$\n", "\n", "此公式的意义是:$L$是关于$\\theta$的一个函数,我们当前所处的位置为$\\theta_0$点,要从这个点走到L的最小值点,也就是山底。首先我们先确定前进的方向,也就是梯度的反向,然后走一段距离的步长,也就是$\\eta$,走完这个段步长,就到达了$\\theta_1$这个点!\n", "\n", "更新的策略是:\n", "\n", "$$\n", "a^1 = a^0 + 2 \\eta [ y - (ax+b)]*x \\\\\n", "b^1 = b^0 + 2 \\eta [ y - (ax+b)] \n", "$$\n", "\n", "下面就这个公式的几个常见的疑问:\n", "\n", "* **$\\eta$是什么含义?**\n", "$\\eta$在梯度下降算法中被称作为学习率或者步长,意味着我们可以通过$\\eta$来控制每一步走的距离,以保证不要步子跨的太大,错过了最低点。同时也要保证不要走的太慢,导致太阳下山了,还没有走到山下。所以$\\eta$的选择在梯度下降法中往往是很重要的。\n", "![gd_stepsize](images/gd_stepsize.png)\n", "\n", "* **为什么要梯度要乘以一个负号?**\n", "梯度前加一个负号,就意味着朝着梯度相反的方向前进!梯度的方向实际就是函数在此点上升最快的方向,而我们需要朝着下降最快的方向走,自然就是负的梯度的方向,所以此处需要加上负号。\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2.2 示例代码" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "epoch 0: loss = 961.232595, a = 3.042831, b = 1.277951\n", "epoch 100: loss = 780.212993, a = 3.110374, b = 3.224871\n", "epoch 200: loss = 797.359161, a = 2.879130, b = 3.475558\n", "epoch 300: loss = 845.492885, a = 2.799842, b = 3.518333\n", "epoch 400: loss = 835.064012, a = 2.813343, b = 3.517065\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import random\n", "\n", "n_epoch = 500 # epoch size\n", "a, b = 1, 1 # initial parameters\n", "epsilon = 0.001 # learning rate\n", "\n", "for i in range(n_epoch):\n", " data_idx = list(range(N))\n", " random.shuffle(data_idx)\n", " \n", " for j in data_idx:\n", " a = a + epsilon*2*(Y[j] - a*X[j] - b)*X[j]\n", " b = b + epsilon*2*(Y[j] - a*X[j] - b)\n", "\n", " L = 0\n", " for j in range(N):\n", " L = L + (Y[j]-a*X[j]-b)**2\n", " \n", " if i % 100 == 0:\n", " print(\"epoch %4d: loss = %f, a = %f, b = %f\" % (i, L, a, b))\n", " \n", "x_min = np.min(X)\n", "x_max = np.max(X)\n", "y_min = a * x_min + b\n", "y_max = a * x_max + b\n", "\n", "plt.scatter(X, Y, label='original data')\n", "plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n", "plt.legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. 如何可视化迭代过程" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "/* global mpl */\n", "window.mpl = {};\n", "\n", "mpl.get_websocket_type = function () {\n", " if (typeof WebSocket !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof MozWebSocket !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert(\n", " 'Your browser does not have WebSocket support. ' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.'\n", " );\n", " }\n", "};\n", "\n", "mpl.figure = function (figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = this.ws.binaryType !== undefined;\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById('mpl-warnings');\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent =\n", " 'This browser does not support binary websocket messages. ' +\n", " 'Performance may be slow.';\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = document.createElement('div');\n", " this.root.setAttribute('style', 'display: inline-block');\n", " this._root_extra_style(this.root);\n", "\n", " parent_element.appendChild(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message('supports_binary', { value: fig.supports_binary });\n", " fig.send_message('send_image_mode', {});\n", " if (fig.ratio !== 1) {\n", " fig.send_message('set_dpi_ratio', { dpi_ratio: fig.ratio });\n", " }\n", " fig.send_message('refresh', {});\n", " };\n", "\n", " this.imageObj.onload = function () {\n", " if (fig.image_mode === 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function () {\n", " fig.ws.close();\n", " };\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "};\n", "\n", "mpl.figure.prototype._init_header = function () {\n", " var titlebar = document.createElement('div');\n", " titlebar.classList =\n", " 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';\n", " var titletext = document.createElement('div');\n", " titletext.classList = 'ui-dialog-title';\n", " titletext.setAttribute(\n", " 'style',\n", " 'width: 100%; text-align: center; padding: 3px;'\n", " );\n", " titlebar.appendChild(titletext);\n", " this.root.appendChild(titlebar);\n", " this.header = titletext;\n", "};\n", "\n", "mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};\n", "\n", "mpl.figure.prototype._root_extra_style = function (_canvas_div) {};\n", "\n", "mpl.figure.prototype._init_canvas = function () {\n", " var fig = this;\n", "\n", " var canvas_div = (this.canvas_div = document.createElement('div'));\n", " canvas_div.setAttribute(\n", " 'style',\n", " 'border: 1px solid #ddd;' +\n", " 'box-sizing: content-box;' +\n", " 'clear: both;' +\n", " 'min-height: 1px;' +\n", " 'min-width: 1px;' +\n", " 'outline: 0;' +\n", " 'overflow: hidden;' +\n", " 'position: relative;' +\n", " 'resize: both;'\n", " );\n", "\n", " function on_keyboard_event_closure(name) {\n", " return function (event) {\n", " return fig.key_event(event, name);\n", " };\n", " }\n", "\n", " canvas_div.addEventListener(\n", " 'keydown',\n", " on_keyboard_event_closure('key_press')\n", " );\n", " canvas_div.addEventListener(\n", " 'keyup',\n", " on_keyboard_event_closure('key_release')\n", " );\n", "\n", " this._canvas_extra_style(canvas_div);\n", " this.root.appendChild(canvas_div);\n", "\n", " var canvas = (this.canvas = document.createElement('canvas'));\n", " canvas.classList.add('mpl-canvas');\n", " canvas.setAttribute('style', 'box-sizing: content-box;');\n", "\n", " this.context = canvas.getContext('2d');\n", "\n", " var backingStore =\n", " this.context.backingStorePixelRatio ||\n", " this.context.webkitBackingStorePixelRatio ||\n", " this.context.mozBackingStorePixelRatio ||\n", " this.context.msBackingStorePixelRatio ||\n", " this.context.oBackingStorePixelRatio ||\n", " this.context.backingStorePixelRatio ||\n", " 1;\n", "\n", " this.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband_canvas = (this.rubberband_canvas = document.createElement(\n", " 'canvas'\n", " ));\n", " rubberband_canvas.setAttribute(\n", " 'style',\n", " 'box-sizing: content-box; position: absolute; left: 0; top: 0; z-index: 1;'\n", " );\n", "\n", " // Apply a ponyfill if ResizeObserver is not implemented by browser.\n", " if (this.ResizeObserver === undefined) {\n", " if (window.ResizeObserver !== undefined) {\n", " this.ResizeObserver = window.ResizeObserver;\n", " } else {\n", " var obs = _JSXTOOLS_RESIZE_OBSERVER({});\n", " this.ResizeObserver = obs.ResizeObserver;\n", " }\n", " }\n", "\n", " this.resizeObserverInstance = new this.ResizeObserver(function (entries) {\n", " var nentries = entries.length;\n", " for (var i = 0; i < nentries; i++) {\n", " var entry = entries[i];\n", " var width, height;\n", " if (entry.contentBoxSize) {\n", " if (entry.contentBoxSize instanceof Array) {\n", " // Chrome 84 implements new version of spec.\n", " width = entry.contentBoxSize[0].inlineSize;\n", " height = entry.contentBoxSize[0].blockSize;\n", " } else {\n", " // Firefox implements old version of spec.\n", " width = entry.contentBoxSize.inlineSize;\n", " height = entry.contentBoxSize.blockSize;\n", " }\n", " } else {\n", " // Chrome <84 implements even older version of spec.\n", " width = entry.contentRect.width;\n", " height = entry.contentRect.height;\n", " }\n", "\n", " // Keep the size of the canvas and rubber band canvas in sync with\n", " // the canvas container.\n", " if (entry.devicePixelContentBoxSize) {\n", " // Chrome 84 implements new version of spec.\n", " canvas.setAttribute(\n", " 'width',\n", " entry.devicePixelContentBoxSize[0].inlineSize\n", " );\n", " canvas.setAttribute(\n", " 'height',\n", " entry.devicePixelContentBoxSize[0].blockSize\n", " );\n", " } else {\n", " canvas.setAttribute('width', width * fig.ratio);\n", " canvas.setAttribute('height', height * fig.ratio);\n", " }\n", " canvas.setAttribute(\n", " 'style',\n", " 'width: ' + width + 'px; height: ' + height + 'px;'\n", " );\n", "\n", " rubberband_canvas.setAttribute('width', width);\n", " rubberband_canvas.setAttribute('height', height);\n", "\n", " // And update the size in Python. We ignore the initial 0/0 size\n", " // that occurs as the element is placed into the DOM, which should\n", " // otherwise not happen due to the minimum size styling.\n", " if (fig.ws.readyState == 1 && width != 0 && height != 0) {\n", " fig.request_resize(width, height);\n", " }\n", " }\n", " });\n", " this.resizeObserverInstance.observe(canvas_div);\n", "\n", " function on_mouse_event_closure(name) {\n", " return function (event) {\n", " return fig.mouse_event(event, name);\n", " };\n", " }\n", "\n", " rubberband_canvas.addEventListener(\n", " 'mousedown',\n", " on_mouse_event_closure('button_press')\n", " );\n", " rubberband_canvas.addEventListener(\n", " 'mouseup',\n", " on_mouse_event_closure('button_release')\n", " );\n", " rubberband_canvas.addEventListener(\n", " 'dblclick',\n", " on_mouse_event_closure('dblclick')\n", " );\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband_canvas.addEventListener(\n", " 'mousemove',\n", " on_mouse_event_closure('motion_notify')\n", " );\n", "\n", " rubberband_canvas.addEventListener(\n", " 'mouseenter',\n", " on_mouse_event_closure('figure_enter')\n", " );\n", " rubberband_canvas.addEventListener(\n", " 'mouseleave',\n", " on_mouse_event_closure('figure_leave')\n", " );\n", "\n", " canvas_div.addEventListener('wheel', function (event) {\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " on_mouse_event_closure('scroll')(event);\n", " });\n", "\n", " canvas_div.appendChild(canvas);\n", " canvas_div.appendChild(rubberband_canvas);\n", "\n", " this.rubberband_context = rubberband_canvas.getContext('2d');\n", " this.rubberband_context.strokeStyle = '#000000';\n", "\n", " this._resize_canvas = function (width, height, forward) {\n", " if (forward) {\n", " canvas_div.style.width = width + 'px';\n", " canvas_div.style.height = height + 'px';\n", " }\n", " };\n", "\n", " // Disable right mouse context menu.\n", " this.rubberband_canvas.addEventListener('contextmenu', function (_e) {\n", " event.preventDefault();\n", " return false;\n", " });\n", "\n", " function set_focus() {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "};\n", "\n", "mpl.figure.prototype._init_toolbar = function () {\n", " var fig = this;\n", "\n", " var toolbar = document.createElement('div');\n", " toolbar.classList = 'mpl-toolbar';\n", " this.root.appendChild(toolbar);\n", "\n", " function on_click_closure(name) {\n", " return function (_event) {\n", " return fig.toolbar_button_onclick(name);\n", " };\n", " }\n", "\n", " function on_mouseover_closure(tooltip) {\n", " return function (event) {\n", " if (!event.currentTarget.disabled) {\n", " return fig.toolbar_button_onmouseover(tooltip);\n", " }\n", " };\n", " }\n", "\n", " fig.buttons = {};\n", " var buttonGroup = document.createElement('div');\n", " buttonGroup.classList = 'mpl-button-group';\n", " for (var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " /* Instead of a spacer, we start a new button group. */\n", " if (buttonGroup.hasChildNodes()) {\n", " toolbar.appendChild(buttonGroup);\n", " }\n", " buttonGroup = document.createElement('div');\n", " buttonGroup.classList = 'mpl-button-group';\n", " continue;\n", " }\n", "\n", " var button = (fig.buttons[name] = document.createElement('button'));\n", " button.classList = 'mpl-widget';\n", " button.setAttribute('role', 'button');\n", " button.setAttribute('aria-disabled', 'false');\n", " button.addEventListener('click', on_click_closure(method_name));\n", " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", "\n", " var icon_img = document.createElement('img');\n", " icon_img.src = '_images/' + image + '.png';\n", " icon_img.srcset = '_images/' + image + '_large.png 2x';\n", " icon_img.alt = tooltip;\n", " button.appendChild(icon_img);\n", "\n", " buttonGroup.appendChild(button);\n", " }\n", "\n", " if (buttonGroup.hasChildNodes()) {\n", " toolbar.appendChild(buttonGroup);\n", " }\n", "\n", " var fmt_picker = document.createElement('select');\n", " fmt_picker.classList = 'mpl-widget';\n", " toolbar.appendChild(fmt_picker);\n", " this.format_dropdown = fmt_picker;\n", "\n", " for (var ind in mpl.extensions) {\n", " var fmt = mpl.extensions[ind];\n", " var option = document.createElement('option');\n", " option.selected = fmt === mpl.default_extension;\n", " option.innerHTML = fmt;\n", " fmt_picker.appendChild(option);\n", " }\n", "\n", " var status_bar = document.createElement('span');\n", " status_bar.classList = 'mpl-message';\n", " toolbar.appendChild(status_bar);\n", " this.message = status_bar;\n", "};\n", "\n", "mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {\n", " // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n", " // which will in turn request a refresh of the image.\n", " this.send_message('resize', { width: x_pixels, height: y_pixels });\n", "};\n", "\n", "mpl.figure.prototype.send_message = function (type, properties) {\n", " properties['type'] = type;\n", " properties['figure_id'] = this.id;\n", " this.ws.send(JSON.stringify(properties));\n", "};\n", "\n", "mpl.figure.prototype.send_draw_message = function () {\n", " if (!this.waiting) {\n", " this.waiting = true;\n", " this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));\n", " }\n", "};\n", "\n", "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", " var format_dropdown = fig.format_dropdown;\n", " var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n", " fig.ondownload(fig, format);\n", "};\n", "\n", "mpl.figure.prototype.handle_resize = function (fig, msg) {\n", " var size = msg['size'];\n", " if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {\n", " fig._resize_canvas(size[0], size[1], msg['forward']);\n", " fig.send_message('refresh', {});\n", " }\n", "};\n", "\n", "mpl.figure.prototype.handle_rubberband = function (fig, msg) {\n", " var x0 = msg['x0'] / fig.ratio;\n", " var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;\n", " var x1 = msg['x1'] / fig.ratio;\n", " var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;\n", " x0 = Math.floor(x0) + 0.5;\n", " y0 = Math.floor(y0) + 0.5;\n", " x1 = Math.floor(x1) + 0.5;\n", " y1 = Math.floor(y1) + 0.5;\n", " var min_x = Math.min(x0, x1);\n", " var min_y = Math.min(y0, y1);\n", " var width = Math.abs(x1 - x0);\n", " var height = Math.abs(y1 - y0);\n", "\n", " fig.rubberband_context.clearRect(\n", " 0,\n", " 0,\n", " fig.canvas.width / fig.ratio,\n", " fig.canvas.height / fig.ratio\n", " );\n", "\n", " fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n", "};\n", "\n", "mpl.figure.prototype.handle_figure_label = function (fig, msg) {\n", " // Updates the figure title.\n", " fig.header.textContent = msg['label'];\n", "};\n", "\n", "mpl.figure.prototype.handle_cursor = function (fig, msg) {\n", " var cursor = msg['cursor'];\n", " switch (cursor) {\n", " case 0:\n", " cursor = 'pointer';\n", " break;\n", " case 1:\n", " cursor = 'default';\n", " break;\n", " case 2:\n", " cursor = 'crosshair';\n", " break;\n", " case 3:\n", " cursor = 'move';\n", " break;\n", " }\n", " fig.rubberband_canvas.style.cursor = cursor;\n", "};\n", "\n", "mpl.figure.prototype.handle_message = function (fig, msg) {\n", " fig.message.textContent = msg['message'];\n", "};\n", "\n", "mpl.figure.prototype.handle_draw = function (fig, _msg) {\n", " // Request the server to send over a new figure.\n", " fig.send_draw_message();\n", "};\n", "\n", "mpl.figure.prototype.handle_image_mode = function (fig, msg) {\n", " fig.image_mode = msg['mode'];\n", "};\n", "\n", "mpl.figure.prototype.handle_history_buttons = function (fig, msg) {\n", " for (var key in msg) {\n", " if (!(key in fig.buttons)) {\n", " continue;\n", " }\n", " fig.buttons[key].disabled = !msg[key];\n", " fig.buttons[key].setAttribute('aria-disabled', !msg[key]);\n", " }\n", "};\n", "\n", "mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {\n", " if (msg['mode'] === 'PAN') {\n", " fig.buttons['Pan'].classList.add('active');\n", " fig.buttons['Zoom'].classList.remove('active');\n", " } else if (msg['mode'] === 'ZOOM') {\n", " fig.buttons['Pan'].classList.remove('active');\n", " fig.buttons['Zoom'].classList.add('active');\n", " } else {\n", " fig.buttons['Pan'].classList.remove('active');\n", " fig.buttons['Zoom'].classList.remove('active');\n", " }\n", "};\n", "\n", "mpl.figure.prototype.updated_canvas_event = function () {\n", " // Called whenever the canvas gets updated.\n", " this.send_message('ack', {});\n", "};\n", "\n", "// A function to construct a web socket function for onmessage handling.\n", "// Called in the figure constructor.\n", "mpl.figure.prototype._make_on_message_function = function (fig) {\n", " return function socket_on_message(evt) {\n", " if (evt.data instanceof Blob) {\n", " var img = evt.data;\n", " if (img.type !== 'image/png') {\n", " /* FIXME: We get \"Resource interpreted as Image but\n", " * transferred with MIME type text/plain:\" errors on\n", " * Chrome. But how to set the MIME type? It doesn't seem\n", " * to be part of the websocket stream */\n", " img.type = 'image/png';\n", " }\n", "\n", " /* Free the memory for the previous frames */\n", " if (fig.imageObj.src) {\n", " (window.URL || window.webkitURL).revokeObjectURL(\n", " fig.imageObj.src\n", " );\n", " }\n", "\n", " fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n", " img\n", " );\n", " fig.updated_canvas_event();\n", " fig.waiting = false;\n", " return;\n", " } else if (\n", " typeof evt.data === 'string' &&\n", " evt.data.slice(0, 21) === 'data:image/png;base64'\n", " ) {\n", " fig.imageObj.src = evt.data;\n", " fig.updated_canvas_event();\n", " fig.waiting = false;\n", " return;\n", " }\n", "\n", " var msg = JSON.parse(evt.data);\n", " var msg_type = msg['type'];\n", "\n", " // Call the \"handle_{type}\" callback, which takes\n", " // the figure and JSON message as its only arguments.\n", " try {\n", " var callback = fig['handle_' + msg_type];\n", " } catch (e) {\n", " console.log(\n", " \"No handler for the '\" + msg_type + \"' message type: \",\n", " msg\n", " );\n", " return;\n", " }\n", "\n", " if (callback) {\n", " try {\n", " // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n", " callback(fig, msg);\n", " } catch (e) {\n", " console.log(\n", " \"Exception inside the 'handler_\" + msg_type + \"' callback:\",\n", " e,\n", " e.stack,\n", " msg\n", " );\n", " }\n", " }\n", " };\n", "};\n", "\n", "// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n", "mpl.findpos = function (e) {\n", " //this section is from http://www.quirksmode.org/js/events_properties.html\n", " var targ;\n", " if (!e) {\n", " e = window.event;\n", " }\n", " if (e.target) {\n", " targ = e.target;\n", " } else if (e.srcElement) {\n", " targ = e.srcElement;\n", " }\n", " if (targ.nodeType === 3) {\n", " // defeat Safari bug\n", " targ = targ.parentNode;\n", " }\n", "\n", " // pageX,Y are the mouse positions relative to the document\n", " var boundingRect = targ.getBoundingClientRect();\n", " var x = e.pageX - (boundingRect.left + document.body.scrollLeft);\n", " var y = e.pageY - (boundingRect.top + document.body.scrollTop);\n", "\n", " return { x: x, y: y };\n", "};\n", "\n", "/*\n", " * return a copy of an object with only non-object keys\n", " * we need this to avoid circular references\n", " * http://stackoverflow.com/a/24161582/3208463\n", " */\n", "function simpleKeys(original) {\n", " return Object.keys(original).reduce(function (obj, key) {\n", " if (typeof original[key] !== 'object') {\n", " obj[key] = original[key];\n", " }\n", " return obj;\n", " }, {});\n", "}\n", "\n", "mpl.figure.prototype.mouse_event = function (event, name) {\n", " var canvas_pos = mpl.findpos(event);\n", "\n", " if (name === 'button_press') {\n", " this.canvas.focus();\n", " this.canvas_div.focus();\n", " }\n", "\n", " var x = canvas_pos.x * this.ratio;\n", " var y = canvas_pos.y * this.ratio;\n", "\n", " this.send_message(name, {\n", " x: x,\n", " y: y,\n", " button: event.button,\n", " step: event.step,\n", " guiEvent: simpleKeys(event),\n", " });\n", "\n", " /* This prevents the web browser from automatically changing to\n", " * the text insertion cursor when the button is pressed. We want\n", " * to control all of the cursor setting manually through the\n", " * 'cursor' event from matplotlib */\n", " event.preventDefault();\n", " return false;\n", "};\n", "\n", "mpl.figure.prototype._key_event_extra = function (_event, _name) {\n", " // Handle any extra behaviour associated with a key event\n", "};\n", "\n", "mpl.figure.prototype.key_event = function (event, name) {\n", " // Prevent repeat events\n", " if (name === 'key_press') {\n", " if (event.key === this._key) {\n", " return;\n", " } else {\n", " this._key = event.key;\n", " }\n", " }\n", " if (name === 'key_release') {\n", " this._key = null;\n", " }\n", "\n", " var value = '';\n", " if (event.ctrlKey && event.key !== 'Control') {\n", " value += 'ctrl+';\n", " }\n", " else if (event.altKey && event.key !== 'Alt') {\n", " value += 'alt+';\n", " }\n", " else if (event.shiftKey && event.key !== 'Shift') {\n", " value += 'shift+';\n", " }\n", "\n", " value += 'k' + event.key;\n", "\n", " this._key_event_extra(event, name);\n", "\n", " this.send_message(name, { key: value, guiEvent: simpleKeys(event) });\n", " return false;\n", "};\n", "\n", "mpl.figure.prototype.toolbar_button_onclick = function (name) {\n", " if (name === 'download') {\n", " this.handle_save(this, null);\n", " } else {\n", " this.send_message('toolbar_button', { name: name });\n", " }\n", "};\n", "\n", "mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {\n", " this.message.textContent = tooltip;\n", "};\n", "\n", "///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////\n", "// prettier-ignore\n", "var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError(\"Constructor requires 'new' operator\");i.set(this,e)}function h(){throw new TypeError(\"Function is not a constructor\")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line\n", "mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Left button pans, Right button zooms\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\\nx/y fixes axis, CTRL fixes aspect\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n", "\n", "mpl.extensions = [\"eps\", \"jpeg\", \"pgf\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n", "\n", "mpl.default_extension = \"png\";/* global mpl */\n", "\n", "var comm_websocket_adapter = function (comm) {\n", " // Create a \"websocket\"-like object which calls the given IPython comm\n", " // object with the appropriate methods. Currently this is a non binary\n", " // socket, so there is still some room for performance tuning.\n", " var ws = {};\n", "\n", " ws.binaryType = comm.kernel.ws.binaryType;\n", " ws.readyState = comm.kernel.ws.readyState;\n", " function updateReadyState(_event) {\n", " if (comm.kernel.ws) {\n", " ws.readyState = comm.kernel.ws.readyState;\n", " } else {\n", " ws.readyState = 3; // Closed state.\n", " }\n", " }\n", " comm.kernel.ws.addEventListener('open', updateReadyState);\n", " comm.kernel.ws.addEventListener('close', updateReadyState);\n", " comm.kernel.ws.addEventListener('error', updateReadyState);\n", "\n", " ws.close = function () {\n", " comm.close();\n", " };\n", " ws.send = function (m) {\n", " //console.log('sending', m);\n", " comm.send(m);\n", " };\n", " // Register the callback with on_msg.\n", " comm.on_msg(function (msg) {\n", " //console.log('receiving', msg['content']['data'], msg);\n", " var data = msg['content']['data'];\n", " if (data['blob'] !== undefined) {\n", " data = {\n", " data: new Blob(msg['buffers'], { type: data['blob'] }),\n", " };\n", " }\n", " // Pass the mpl event to the overridden (by mpl) onmessage function.\n", " ws.onmessage(data);\n", " });\n", " return ws;\n", "};\n", "\n", "mpl.mpl_figure_comm = function (comm, msg) {\n", " // This is the function which gets called when the mpl process\n", " // starts-up an IPython Comm through the \"matplotlib\" channel.\n", "\n", " var id = msg.content.data.id;\n", " // Get hold of the div created by the display call when the Comm\n", " // socket was opened in Python.\n", " var element = document.getElementById(id);\n", " var ws_proxy = comm_websocket_adapter(comm);\n", "\n", " function ondownload(figure, _format) {\n", " window.open(figure.canvas.toDataURL());\n", " }\n", "\n", " var fig = new mpl.figure(id, ws_proxy, ondownload, element);\n", "\n", " // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n", " // web socket which is closed, not our websocket->open comm proxy.\n", " ws_proxy.onopen();\n", "\n", " fig.parent_element = element;\n", " fig.cell_info = mpl.find_output_cell(\"
\");\n", " if (!fig.cell_info) {\n", " console.error('Failed to find cell for figure', id, fig);\n", " return;\n", " }\n", " fig.cell_info[0].output_area.element.on(\n", " 'cleared',\n", " { fig: fig },\n", " fig._remove_fig_handler\n", " );\n", "};\n", "\n", "mpl.figure.prototype.handle_close = function (fig, msg) {\n", " var width = fig.canvas.width / fig.ratio;\n", " fig.cell_info[0].output_area.element.off(\n", " 'cleared',\n", " fig._remove_fig_handler\n", " );\n", " fig.resizeObserverInstance.unobserve(fig.canvas_div);\n", "\n", " // Update the output cell to use the data from the current canvas.\n", " fig.push_to_output();\n", " var dataURL = fig.canvas.toDataURL();\n", " // Re-enable the keyboard manager in IPython - without this line, in FF,\n", " // the notebook keyboard shortcuts fail.\n", " IPython.keyboard_manager.enable();\n", " fig.parent_element.innerHTML =\n", " '';\n", " fig.close_ws(fig, msg);\n", "};\n", "\n", "mpl.figure.prototype.close_ws = function (fig, msg) {\n", " fig.send_message('closing', msg);\n", " // fig.ws.close()\n", "};\n", "\n", "mpl.figure.prototype.push_to_output = function (_remove_interactive) {\n", " // Turn the data on the canvas into data in the output cell.\n", " var width = this.canvas.width / this.ratio;\n", " var dataURL = this.canvas.toDataURL();\n", " this.cell_info[1]['text/html'] =\n", " '';\n", "};\n", "\n", "mpl.figure.prototype.updated_canvas_event = function () {\n", " // Tell IPython that the notebook contents must change.\n", " IPython.notebook.set_dirty(true);\n", " this.send_message('ack', {});\n", " var fig = this;\n", " // Wait a second, then push the new image to the DOM so\n", " // that it is saved nicely (might be nice to debounce this).\n", " setTimeout(function () {\n", " fig.push_to_output();\n", " }, 1000);\n", "};\n", "\n", "mpl.figure.prototype._init_toolbar = function () {\n", " var fig = this;\n", "\n", " var toolbar = document.createElement('div');\n", " toolbar.classList = 'btn-toolbar';\n", " this.root.appendChild(toolbar);\n", "\n", " function on_click_closure(name) {\n", " return function (_event) {\n", " return fig.toolbar_button_onclick(name);\n", " };\n", " }\n", "\n", " function on_mouseover_closure(tooltip) {\n", " return function (event) {\n", " if (!event.currentTarget.disabled) {\n", " return fig.toolbar_button_onmouseover(tooltip);\n", " }\n", " };\n", " }\n", "\n", " fig.buttons = {};\n", " var buttonGroup = document.createElement('div');\n", " buttonGroup.classList = 'btn-group';\n", " var button;\n", " for (var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " /* Instead of a spacer, we start a new button group. */\n", " if (buttonGroup.hasChildNodes()) {\n", " toolbar.appendChild(buttonGroup);\n", " }\n", " buttonGroup = document.createElement('div');\n", " buttonGroup.classList = 'btn-group';\n", " continue;\n", " }\n", "\n", " button = fig.buttons[name] = document.createElement('button');\n", " button.classList = 'btn btn-default';\n", " button.href = '#';\n", " button.title = name;\n", " button.innerHTML = '';\n", " button.addEventListener('click', on_click_closure(method_name));\n", " button.addEventListener('mouseover', on_mouseover_closure(tooltip));\n", " buttonGroup.appendChild(button);\n", " }\n", "\n", " if (buttonGroup.hasChildNodes()) {\n", " toolbar.appendChild(buttonGroup);\n", " }\n", "\n", " // Add the status bar.\n", " var status_bar = document.createElement('span');\n", " status_bar.classList = 'mpl-message pull-right';\n", " toolbar.appendChild(status_bar);\n", " this.message = status_bar;\n", "\n", " // Add the close button to the window.\n", " var buttongrp = document.createElement('div');\n", " buttongrp.classList = 'btn-group inline pull-right';\n", " button = document.createElement('button');\n", " button.classList = 'btn btn-mini btn-primary';\n", " button.href = '#';\n", " button.title = 'Stop Interaction';\n", " button.innerHTML = '';\n", " button.addEventListener('click', function (_evt) {\n", " fig.handle_close(fig, {});\n", " });\n", " button.addEventListener(\n", " 'mouseover',\n", " on_mouseover_closure('Stop Interaction')\n", " );\n", " buttongrp.appendChild(button);\n", " var titlebar = this.root.querySelector('.ui-dialog-titlebar');\n", " titlebar.insertBefore(buttongrp, titlebar.firstChild);\n", "};\n", "\n", "mpl.figure.prototype._remove_fig_handler = function (event) {\n", " var fig = event.data.fig;\n", " if (event.target !== this) {\n", " // Ignore bubbled events from children.\n", " return;\n", " }\n", " fig.close_ws(fig, {});\n", "};\n", "\n", "mpl.figure.prototype._root_extra_style = function (el) {\n", " el.style.boxSizing = 'content-box'; // override notebook setting of border-box.\n", "};\n", "\n", "mpl.figure.prototype._canvas_extra_style = function (el) {\n", " // this is important to make the div 'focusable\n", " el.setAttribute('tabindex', 0);\n", " // reach out to IPython and tell the keyboard manager to turn it's self\n", " // off when our div gets focus\n", "\n", " // location in version 3\n", " if (IPython.notebook.keyboard_manager) {\n", " IPython.notebook.keyboard_manager.register_events(el);\n", " } else {\n", " // location in version 2\n", " IPython.keyboard_manager.register_events(el);\n", " }\n", "};\n", "\n", "mpl.figure.prototype._key_event_extra = function (event, _name) {\n", " var manager = IPython.notebook.keyboard_manager;\n", " if (!manager) {\n", " manager = IPython.keyboard_manager;\n", " }\n", "\n", " // Check for shift+enter\n", " if (event.shiftKey && event.which === 13) {\n", " this.canvas_div.blur();\n", " // select the cell after this one\n", " var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n", " IPython.notebook.select(index + 1);\n", " }\n", "};\n", "\n", "mpl.figure.prototype.handle_save = function (fig, _msg) {\n", " fig.ondownload(fig, null);\n", "};\n", "\n", "mpl.find_output_cell = function (html_output) {\n", " // Return the cell and output element which can be found *uniquely* in the notebook.\n", " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", " // IPython event is triggered only after the cells have been serialised, which for\n", " // our purposes (turning an active figure into a static one), is too late.\n", " var cells = IPython.notebook.get_cells();\n", " var ncells = cells.length;\n", " for (var i = 0; i < ncells; i++) {\n", " var cell = cells[i];\n", " if (cell.cell_type === 'code') {\n", " for (var j = 0; j < cell.output_area.outputs.length; j++) {\n", " var data = cell.output_area.outputs[j];\n", " if (data.data) {\n", " // IPython >= 3 moved mimebundle to data attribute of output\n", " data = data.data;\n", " }\n", " if (data['text/html'] === html_output) {\n", " return [cell, data, j];\n", " }\n", " }\n", " }\n", " }\n", "};\n", "\n", "// Register the function which deals with the matplotlib target/channel.\n", "// The kernel may be null if the page has been refreshed.\n", "if (IPython.notebook.kernel !== null) {\n", " IPython.notebook.kernel.comm_manager.register_target(\n", " 'matplotlib',\n", " mpl.mpl_figure_comm\n", " );\n", "}\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%matplotlib nbagg\n", "\n", "import matplotlib.pyplot as plt\n", "import matplotlib.animation as animation\n", "\n", "n_epoch = 300 # epoch size\n", "a, b = 1, 1 # initial parameters\n", "epsilon = 0.0001 # learning rate\n", "\n", "fig = plt.figure()\n", "imgs = []\n", "\n", "for i in range(n_epoch):\n", " data_idx = list(range(N))\n", " random.shuffle(data_idx)\n", " \n", " for j in data_idx[:10]:\n", " a = a + epsilon*2*(Y[j] - a*X[j] - b)*X[j]\n", " b = b + epsilon*2*(Y[j] - a*X[j] - b)\n", "\n", "\n", " if i<80 and i % 5 == 0:\n", " x_min = np.min(X)\n", " x_max = np.max(X)\n", " y_min = a * x_min + b\n", " y_max = a * x_max + b\n", "\n", " img = plt.scatter(X, Y, label='original data')\n", " img = plt.plot([x_min, x_max], [y_min, y_max], 'r', label='model')\n", " imgs.append(img)\n", " \n", "ani = animation.ArtistAnimation(fig, imgs)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. 如何使用批次更新的方法?\n", "\n", "如果有一些数据包含比较大的错误(异常数据),因此每次更新仅仅使用一个数据会导致不精确,同时每次仅仅使用一个数据来计算更新也导致计算效率比较低。\n", "\n", "\n", "* [梯度下降方法的几种形式](https://blog.csdn.net/u010402786/article/details/51188876)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. 如何拟合多项式函数?\n", "\n", "需要设计一个弹道导弹防御系统,通过观测导弹的飞行路径,预测未来导弹的飞行轨迹,从而完成摧毁的任务。按照物理学,可以得知模型为:\n", "$$\n", "y = at^2 + bt + c\n", "$$\n", "我们需要求解三个模型参数$a, b, c$。\n", "\n", "损失函数的定义为:\n", "$$\n", "L = \\sum_{i=1}^N (y_i - at_i^2 - bt_i - c)^2\n", "$$\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", "pa = -20\n", "pb = 90\n", "pc = 800\n", "\n", "t = np.linspace(0, 10) \n", "y = pa*t**2 + pb*t + pc + np.random.randn(np.size(t))*15\n", "\n", "\n", "plt.plot(t, y)\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.1 如何得到更新项?\n", "\n", "$$\n", "L = \\sum_{i=1}^N (y_i - at_i^2 - bt_i - c)^2\n", "$$\n", "\n", "\\begin{eqnarray}\n", "\\frac{\\partial L}{\\partial a} & = & - 2\\sum_{i=1}^N (y_i - at_i^2 - bt_i -c) t_i^2 \\\\\n", "\\frac{\\partial L}{\\partial b} & = & - 2\\sum_{i=1}^N (y_i - at_i^2 - bt_i -c) t_i \\\\\n", "\\frac{\\partial L}{\\partial c} & = & - 2\\sum_{i=1}^N (y_i - at_i^2 - bt_i -c)\n", "\\end{eqnarray}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.2 程序" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "epoch 0: loss = 2.59199e+07, a = -4.03101, b = 7.0103, c = 4.32798\n", "epoch 500: loss = 1.03254e+06, a = -31.3488, b = 241.561, c = 424.128\n", "epoch 1000: loss = 344061, a = -26.488, b = 176.47, c = 585.509\n", "epoch 1500: loss = 120771, a = -23.7191, b = 139.394, c = 677.407\n", "epoch 2000: loss = 48363.3, a = -22.1423, b = 118.28, c = 729.741\n", "epoch 2500: loss = 24884.4, a = -21.2443, b = 106.257, c = 759.543\n" ] }, { "data": { "image/png": "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KlVEPDxEJk7MGiGai/nx88X7bW8p/XZp4XWk4vsVZeDCgeI3yu+KI11V0ZA99uCvv0QefVTE01NiApBRD98qqd8vkR5zemSPr/B+21s6f9NZfN7z0Z9rDkWhn7+Li4s0atQo+/Xuu+9esez8+fNly5Yt2euvvfaaLF++PN8xnDx5UiZOnJjn940YMULef//9a5a71iyh//b8ee3nb4/EXxnYA5SyrVuAAbavvW3bPgWesC0/CXxqW+4NzLnWOf518s/MFPngAxE3N5HAQJG4uFwHKM34fYa0mNJCSo0slZ0gekf3lvSMdIcOplL5cPSoyJtvilSokDVN9TBXee2/d4rPcE8Jf6mSeA53yRpMNtxIn4F+4v/W/6fBdlZ5Sf4F9XeRl+mT+/fvL1FRUfk6X2727Nkj9erVy/P77JX8/+35HZX89wO+ZFUjfQd0BI4BbrYyLYBltuVlQAvbsputnLnaOf518t+2Letu/957RU6eFJFL7/BiE2Kl9dTWwuuI6xuuEv51uPi853PpfDWqWIv563vxf7OsxLSrIeLiIjH1S4v/UBeZ17GavPVgNSn9WtaI4oovINE96klGXKzTfuDnJflfbfR5flwpMb788stSp04dadCggbzwwgvy888/i4+PjwQEBEijRo1k586dl3wYVKtWTYYOHSqNGjWSZs2ayYYNG6RDhw5SvXp1mTRpkoiIJCUlSZs2baRJkyZSv359+fbbb0VEpFevXuLl5SWNGjWSF198UURERo8eLc2bN5cGDRrI8OHDs+MaOXKkBAUFSUhIiPTu3TvX5L9792654447pH79+vLqq69mX+P1nv9K5S5X6Mk/6/gMApKBRGAm4A/szLH/FmCzbXkzUCXHvl2Afy7HHAjEAXFVq1bN9WKvy6ZN/6jmGbd2nLi/6S68jpjXjfSO6i2WzZYC+WVWjnVJIrf9HuScHsN/tL90ntFJXF83wutInaeQoc/VF//3fJ3udyFn8hi0dJC0+qrVVV8NJzUU9zfdperYquL+prs0nNTwquUHLR10zRgur/aZPXu2HDt2TGrVqiWZtp/fSduN3OV3/pcn/08++URERJ577jlp0KCBnDlzRo4ePSo33XSTiIikpaXJ6dOnRUQkMTFRatSoIZmZmf+48162bJn85z//kczMTMnIyJBOnTrJqlWrJC4uTurXry9nz56V06dP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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "n_epoch = 3000 # epoch size\n", "a, b, c = 1.0, 1.0, 1.0 # initial parameters\n", "epsilon = 0.0001 # learning rate\n", "\n", "N = np.size(t)\n", "\n", "for i in range(n_epoch):\n", " for j in range(N):\n", " a = a + epsilon*2*(y[j] - a*t[j]**2 - b*t[j] - c)*t[j]**2\n", " b = b + epsilon*2*(y[j] - a*t[j]**2 - b*t[j] - c)*t[j]\n", " c = c + epsilon*2*(y[j] - a*t[j]**2 - b*t[j] - c)\n", "\n", " L = 0\n", " for j in range(N):\n", " L = L + (y[j] - a*t[j]**2 - b*t[j] - c)**2\n", " \n", " if i % 500 == 0:\n", " print(\"epoch %4d: loss = %10g, a = %10g, b = %10g, c = %10g\" % (i, L, a, b, c))\n", " \n", " \n", "y_est = a*t**2 + b*t + c \n", "\n", "\n", "plt.plot(t, y, 'r-', label='Real data')\n", "plt.plot(t, y_est, 'g-x', label='Estimated data')\n", "plt.legend()\n", "plt.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6. 如何使用sklearn求解线性问题?\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "X: (100, 1)\n", "Y: (100, 1)\n", "a = 2.825254, b = 5.366227\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "%matplotlib inline\n", "\n", "from sklearn import linear_model\n", "import numpy as np\n", "\n", "# load data\n", "# generate data\n", "data_num = 100\n", "X = np.random.rand(data_num, 1)*10\n", "Y = X * 3 + 4 + 8*np.random.randn(data_num,1)\n", "\n", "print(\"X: \", X.shape)\n", "print(\"Y: \", Y.shape)\n", "\n", "# create regression model\n", "regr = linear_model.LinearRegression()\n", "regr.fit(X, Y)\n", "\n", "a, b = np.squeeze(regr.coef_), np.squeeze(regr.intercept_)\n", "\n", "print(\"a = %f, b = %f\" % (a, b))\n", "\n", "x_min = np.min(X)\n", "x_max = np.max(X)\n", "y_min = a * x_min + b\n", "y_max = a * x_max + b\n", "\n", "plt.scatter(X, Y)\n", "plt.plot([x_min, x_max], [y_min, y_max], 'r')\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7. 如何使用sklearn拟合多项式函数?" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([800., 90., -20.])" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Fitting polynomial functions\n", "\n", "from sklearn.preprocessing import PolynomialFeatures\n", "from sklearn.linear_model import LinearRegression\n", "from sklearn.pipeline import Pipeline\n", "\n", "t = np.array([2, 4, 6, 8])\n", "\n", "pa = -20\n", "pb = 90\n", "pc = 800\n", "\n", "y = pa*t**2 + pb*t + pc\n", "\n", "model = Pipeline([('poly', PolynomialFeatures(degree=2)),\n", " ('linear', LinearRegression(fit_intercept=False))])\n", "model = model.fit(t[:, np.newaxis], y)\n", "model.named_steps['linear'].coef_\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 参考资料\n", "* [梯度下降法](https://blog.csdn.net/u010402786/article/details/51188876)\n", "* [如何理解最小二乘法?](https://blog.csdn.net/ccnt_2012/article/details/81127117)\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.9" } }, "nbformat": 4, "nbformat_minor": 2 }