# Theano 实例:线性回归 ## 基本模型 在用 `theano` 进行线性回归之前,先回顾一下 `theano` 的运行模式。 `theano` 是一个符号计算的数学库,一个基本的 `theano` 结构大致如下: * 定义符号变量 * 编译用符号变量定义的函数,使它能够用这些符号进行数值计算。 * 将函数应用到数据上去 In [1]: ```py %matplotlib inline from matplotlib import pyplot as plt import numpy as np import theano from theano import tensor as T ``` ```py Using gpu device 0: GeForce GTX 850M ``` 简单的例子:$y = a \times b, a, b \in \mathbb{R}$ 定义 $a, b, y$: In [2]: ```py a = T.scalar() b = T.scalar() y = a * b ``` 编译函数: In [3]: ```py multiply = theano.function(inputs=[a, b], outputs=y) ``` 将函数运用到数据上: In [4]: ```py print multiply(3, 2) # 6 print multiply(4, 5) # 20 ``` ```py 6.0 20.0 ``` ## 线性回归 回到线性回归的模型,假设我们有这样的一组数据: In [5]: ```py train_X = np.linspace(-1, 1, 101) train_Y = 2 * train_X + 1 + np.random.randn(train_X.size) * 0.33 ``` 分布如图: In [6]: ```py plt.scatter(train_X, train_Y) plt.show() ``` ![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXQAAAEACAYAAACj0I2EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAGGBJREFUeJzt3X2MXFd5x/HfM3G2bElLtFnqAIlIGtEGSGRtnFK3ocpU7e4GWrnYFgLSFLdIGNS0gmgDxqQ0GxHVpGCB0jea0MSLVMMfpaGbAjtZXsawLaUlcYILCRA1WAlgk2XLm2LkpPv0j5ndnZ2dmb1vM/fOme9Husq83Llzrq/zzPFzn3OOubsAAP2vlHcDAADZIKADQCAI6AAQCAI6AASCgA4AgSCgA0AgMgnoZnaWmR0zs3uzOB4AIL6seuhvkfQ1SRS1A0BOUgd0M7tA0islfUiSpW4RACCRLHro75f0NknLGRwLAJBQqoBuZr8r6Xvufkz0zgEgV5ZmLhcz+wtJfyDpGUnPkvTzkj7m7q9v2Ie8OgAk4O6xOsqpeuju/k53v9DdL5b0WkmfbQzmDfsFu9188825t4Hz49w4v/C2JLKuQ6c3DgA52ZLVgdz9qKSjWR0PABAPI0VTKpfLeTehq0I+v5DPTeL8BlGqm6KRvsDMu/0dABAaM5P38qYoAKA4COgAEAgCOgAEgoAOAIEgoANAIAjoABAIAjoABIKADgCBIKADQCAI6AAQCAI6AASCgA4AgSCgA0AgCOgA+kqlUtHExB5NTOxRpVLJuzmFwvS5APpGpVLRrl17dfr0bZKk4eH9uueeGU1OTubcsuwlmT6XgA6gb0xM7NH8/E5Je+uvzGh8fFb33fexPJvVFcyHDgADjB46gMKqVCo6dOgOSdLU1D5JIuXS6TMEdABF1C5fLmldkA8xmEsEdAABGaR8eSvk0AFggG3JuwEA0MrU1D4tLOzV6dO158PD+zU1NZNvowqOlAuAwmq+KRpqvrwVcugAEAhy6AAKL+nQfYb8b44eOoCeSTp0f5CG/K/oecrFzJ4l6aikn5E0JOlf3P1A0z4EdACSkpciDmIJY5KAnqrKxd1/ama/6e5PmdkWSQtm9nJ3X0hzXABAfKlz6O7+VP3hkKSzJC2lPSaAME1N7dPw8H5JM5Jm6qWI+1bfb5cn3+xzqEmdQzezkqQHJF0i6e/c/e1N75NyAbCqXSniZnnyQSthzLVs0cyeI6ki6R3uXm14nYAOYFPr8+QVSdMaGXlSR478TfDBu5We59AbufsPzewTkq6UVG18b3p6evVxuVxWuVzO6msBBKeiWlC/TUtLtdkVQ69okaRqtapqtZrqGGmrXEYlPePuPzCzYdWuxC3u/pmGfeihA9jUWsrlYklv1iBVtLSSx8Ci50n6rJk9KOlLku5tDOYAENXk5KTuuWdGIyNP5t2UvsXAIgCFMoiDiFphLhcAQRi0ipZWCOgA+hIBfCMCOoC+Q4qlNQI6gL4ziPO0RMH0uQAwwAjoQB8JcU5w5mnJDikXoE+EnGvmpuhG5NCBgJFrHizk0AFggGU2OReA7pqa2qeFhb06fbr2vJZrnsm3USgUUi5AHyHXPDjIoQNAIMihA8AAI6ADyE2IdfV5IuUCIBch19VngRw6gL5BXX1n5NAB9FSclAnple6jDh1AIs0pk4WFvbrppj/V0aMPSFpfVtlu34WF/dTVZ4iUC4BENqZMblSpdJeWl98vaX1OvF16ZWpqH3X1bSRJudBDBzIUwsCf5Ofwb/VgXgvap09Lhw7d0fHzk5OTfflnVFQEdCAjrdIK/Va1EeccmqciKJW+qeXl1sdl2oIecfeubrWvAMI3Pr7bpcMueX077OPju/NuVixxz2Fubs7Hx3f7+Phuv/XWW314eGv984d9eHirz83Ntdy38XW0Vo+dseItPXQAbVQkfVBf/OIJXXFFWaOj521IwTSnTK688sqGdE2tZx9CGqpvxP0FiLuJHjoGxNzcXMceaj9YO4cpl0Yb/rv+nKL2tkP4M8mLEvTQCehAhkJIK8zNzfnIyCX1ILwxBTM2dlXkIB1CGiovSQI6KRcgQyFUbUxOTmr79m2an2/9/okTJ+s3TaNXs6A3COjAAFjJYy8unpK0pWU+vNFaVcp1km6sv3pcpdJhPf30syN/L9UtvcXAIiAQ7W4+rpUiXidpRtL7JG0+GVbjj8CPfvQjPfbYE/U68+OS7pR0e6zjNLcLnSUZWEQOHQhAp5uPa3nsxnz2nEs7fGTkkki5/o258CkfGbmkr+8VFJ16nUM3swslfVjSL0hySXe4++1pjgkgvkOH7oiR167U97tNS0vSrl1JBkBdru3bH2NmxIJJO9vi05JucPeXStoh6Xoze3H6ZgHIytTUPg0P75d0sWr58GlJK8G/Nip0JSWy+TFmJM3Uc+H7Vt9nJsViSNVDd/eTkk7WH//EzB6W9HxJD2fQNgARVCoVLS6eUql0w+rQ+8abj5OTk7rnnpl6PvyX9eijj+vHP473HY3HkNYGDa18f79PeRCMuDmadpukiySdkHRO0+vdTDMBA2197nzKS6XzfGzs6p4O9qHWvDuUVx26mZ0j6Z8kvcXdf9L8/vT09OrjcrmscrmcxdcCA685d768fLlGR2c3neGwXW8b+alWq6pWq6mOkbps0czOlvSvkj7l7h9o8b6n/Q4ArWW1jFua0kLWBu2Onq8pamam2l2S77v7DW32IaADXZJFMM3qGNSaZyuPgP5ySZ+X9BXVyhYl6YC7zzXsQ0AHuihtMGWx5mLq+YpF7r4gFprGgMuqd5r0OM3zx9BbHmBx76LG3USVCwKWVcVIu+OszN44NnaVj41dvToys92sjknawxS3xSSmz0XIijg1bVYle62OszZN7fo5yYeGzvWhoeduMsw/XnuK+Gc76JIEdGZbRF8IafBK1JTI2jS1s6pNqFXLcZ8580FJb1YW09eSnglM3F+AuJvooSMDRR28Ejdd0Sm10vz62NjVbRaZ2NH2zyJOe0i1FJtIuSBURQ3o7vHSFZ3Oo/k4G5eD2zzlEqc9Rf4zBSkXBKwICyW0S09ktUpRq+M0zsEi3V1fmOKjktR2pGdRVk0inZODuL8AcTfRQ0dG8rxx1+1qljx0sy1FOs9+pQQ9dFYsAiJIO/imsbd69dVX6OjRByTl33PtVi+awUrp9XxgEYDOKpWKDhx4tx566Gv15dukhYX1Q+vzTE0UJT2DjMTt0sfdRMoFAUg3YCebqpR+Eup59ZK4KQp0R9wpZyuViq699vqGOvLW4i0d1z+YojcfBHQgoqjpibVBUBfXX9mntVxyPhU6eSCd03tMrAVkbK3XPS1pv2qrNF6nUmlKY2N3r+bPG5eOa7dWZxqs8zl46KEDXTOpWqCe1sjIkzpy5B/brMN5XKXSlLZtu0wHD9Z67hMTeyQlv0ka0lQJiCFu0j3uJm6KIlBpZjxsN0ozq5uJjALtf0pwU5SUC9BBu7TFSg94fn6n5ud3ateuvavvr9wQHB+f1fj4bKye8fqbpLUe9sqNRWBTcX8B4m6ih44+1am3nLYH3O7YWfWsKRvsf6JsEUim1eCebpYUdirry2LOGsoGB1TcX4C4m+iho+CS9Ja7PQ8Ki01AzOUCxNdu3pGpqX3rKkWGh4szZB/hYy4XIEObpS0YOIOioYeO4G3Wk26u2W7uiQN5SNJDJ6AjaFGDdXPQl0Q6BbkioANNkszLTY8dRUAOHchAqDMgInwEdAQt7lqklUpF99//kKSdvWkgkCGG/qNw4swSuNm+cYbhr6RalpZeJelGdWMGRKCr4haux93EwCLEEGfATtzBPZsN2Fk/kGjOpR0+MnIJg3uQC+Ux9N/M7pL0O5K+5+6Xpz0eBkO7UsI4+es4+7abTnblOJK0uPj9hk9MSjqp7dtnyZ2jb2SRQ79b0l9J+nAGx8IAyGOu7lbB/8CBd+uRRx5dbcfQ0Fs1NPQ2nTlT+8ygrCyEcKQO6O7+BTO7KH1TMCg69azj3MSMe8Oz2YkTJ9e148wZaWzsTo2OztaP3/pHhiH/KCqqXFAocWYJbLWv1Hq1n1bB/4UvvFRLS+uPOTq6NVaNOisBoUgyGVhU76Hf2yqHbmZ+8803rz4vl8sql8upvxP9K+7Anag94s2O22o0aNwBREkGKgFRVKtVVavV1ee33HJL7IFFWVWyXCTpeJv3uncbGH0r6hSxUStZ5ubmfGTkktiLQ8Sdqpal3dArSlDlQkBHoUUJoGtBf0fXgy0rAaFXkgT0LMoWPyLpaknnmdnjkv7c3e9Oe1wgqrWbrOdrLRXSnSoVVgJCkWVR5fK6LBoCtBKvkmVStdGd0xoZeVJHjnSnSoV50FFUzLaIwks6n7m0cQpcZlJEv2D6XAysqBUshw7dQZUK+gLT56IQOvWou7WQRHMaZGJiT8vBS0DICOjIVKeBN83vHT36Wkln68yZ927Yt1vSji4FCi1uWUzcTZQtDpROZYYb3+temWGn8sK4tedAHpRH2SJQRJ3KC6lSQagI6MhMpVLR4uIplUo3aHm59lpjSqM53TE09Iik7s1uSODGoKHKBZlYnx8/rlLpsLZtu0wHDx7oyU1RIDSULSIXlUpF1157vZaW3qUsywGZphaDjLJF9Nxaz/ziLh2XaWqBqAjoSCXLeVQae+SLi9/vuLwcvXdgIwI6MhJtHpV2mnvkpdJU5H3pvQM1BHSksnGgzmOxg7m0cVm65eXjbatl4iwODQwSAjpS6d50spdr27aXbLq+J4A1VLmgEOLMgsiMiRgElC2ir8W50clNUYSOgA4AgUgS0EvdagwAoLcI6AAQCAI6AASCgA4AgSCgA0AgCOgAEAgCeuAqlYomJvZoYmKPKpVK3s0B0EUE9ICtjKicn9+p+fmd2rVrb2ZBPcoPBT8mQI/FXYQ07iYWic5NpwWb0+i0AHOcfQC0JxaJRi9Eme2QGRGB3iOgB2zj1LbZLsIMoFhSB3Qzu0bSBySdJelD7n5b6lYhE92a2jbKDwU/JkDvpZqcy8zOkvR1Sb8t6duS/kvS69z94YZ9PM13IJ5ezUIY5XuYERFIruezLZrZr0m62d2vqT9/hyS5+3sa9iGg90jUecIJtEDx5THb4gskPd7w/In6a+iCzcoA19+IrAX2lcDdeIxulTICyFfaHHqkrvf09PTq43K5rHK5nPJrB09WCyPHrT6hNw/0RrVaVbVaTXWMtCmXHZKmG1IuByQtN94YJeWSjYmJPZqf36mVQCzNaHx8Vvfd97HVfaKkXFodZ2zsTo2ObtXi4ilJWzQ6ep6mpvZJEku9ATlJknJJ20P/sqQXmdlFkr4j6TWSXpfymEgoSlVLc/XJ0NBb9dWvnq0zZ3ZI+ryk90mq/Qvg0ksvpZYc6COpArq7P2NmfyKpolrZ4j80VrggO1HLACcnJzsG3Oagv7i4TceO/ZGkWdWC+VrwPnHi3RmfBYBuYk3RPtKNfPZaCmZWUmMq5kadc84RPfXUT7W8/H5JpFyAXmKRaKyKGvzX8u7XSZpRrZd+XNKdkm6XdFyl0mFt23aZDh48QDAHeoSADknR69Eb9z906I7Vm6InTjyhpaV3qdWNU4lqF6AXCOiQFK0iJt7nb1SpdBepF6CH8qhyQYCab8CWSofrwZxqF6DICOgBSjsx1sZKmMt07Fg3WgogS6RcApVlRUzcnDyA9MihB6RoQ+6bb5yujCbNu11AqAjogShqj7io7QJCREAPRNoqlW4paruAEOUxfS4KYLNpdQEMiLirSsfdal+Bdubm5nx8fLePj+/2ubm51deGh7e6dNilwz48vHX1vVafj7pvFm3t1XcBg64eO+PF27gfiP0FBPS2OgXIVoG+lfHx3fXPe3077OPju7va5ijtApBOkoBOHXqOOi02sdmsiXkparsAMLCor1UqFS0unlKpdIOWl2uvxR1EBCAc3BTN0dTUPg0P71dtlsOZejDeF+mzKyWEx469UcvLb1CpNKWxsbtjlRFyMxUIC2WLOUs6gChtCSE15UCxMTlXH8orJx13sei0ijbyFQgRAb1PxZ2Aqzmg9lLzvwYWFvbyrwGgG+KWxcTdRNli10QtIWxVHnnrrbf2rKa816WVQAhE2WLvdTuV0On4UdM1rdIrR4/Orpsid2qKHjPQ7wjoKXQ7ldDt4/cqf592fnYAEcXt0sfdFHDKJW4qIe4oy6xSFUUYss8IUyAekXLpnUqlovvvf0jSzsj7r/W2j+szn/l9bdt2mQ4ePBC7lxw3zdO8AlEe6RVGmAI9EPcXIO6mAHvoaz3eKZdGI/V813rbcy5t7C1HnaSrlzczAeRHTM7VG+tTIXMu7fCRkUsiTqK1MY0yNnZV5Em6qBgBBkOSgE7KJbVJSSe1fftsx5TC2o3Bize8d+LEyciTdK2kTQCgGXO5JJBkDpaVPPbY2FkqlW5Y99kXvvCCrn43gMHAXC4Jxbkx2WqUZvPzOPOqMIweCF9P1xQ1s1dLmpZ0qaRfcfcH2uwXZECPKuokWARpAI16HdAvlbQs6e8lTRHQW2NhZQBJ9HS2RXd/ZOVLAQD546Zol8W9icmiEwCS6phyMbN5See3eOud7n5vfZ/PiZRLR1Hz4yw6AWBF5ikXdx9P16Sa6enp1cflclnlcjmLw/aNNLMidnPRCQDFUa1WVa1WUx0jq4FFHX9FGgN66KhWAZBEc2f3lltuiX2MxAHdzHZJul3SqKRPmNkxd39F0uOFIO10t0wzCyANBhZlpFKp6Nprr9fS0ruUpkSRHj4Aqcd16JG/YAAC+lrP/GJJb9ZaQL9RIyMf1/bt2wjOAGIhoOdkbfDQ+aoF89qc59KdqmWlqFgBEE9PBxahlUnV6s2ntWXL/+iZZ24XFSsAeoWBRRlYP3jopIaHH9Pll78472YBGDD00DPQaok3aWUGxdo+VKwA6DZy6F1ExQqApLgpCgCBSBLQyaEDQCAI6AAQCAI6AASCgA4AgSCgA0AgCOgAEAgCOgAEgoAOAIEgoANAIAjoABAIAjoABIKADgCBIKADQCAI6AAQCAI6AASCgA4AgSCgA0AgCOgAEAgCOgAEgoAOAIEgoANAIBIHdDN7r5k9bGYPmdk/m9lzsmwYACCeND30+yS91N23SfqGpAPZNKm/VKvVvJvQVSGfX8jnJnF+gyhxQHf3eXdfrj/9kqQLsmlSfwn9L1XI5xfyuUmc3yDKKof+BkmfzOhYAIAEtnR608zmJZ3f4q13uvu99X1uknTG3Y90oX0AgIjM3ZN/2OwPJb1R0m+5+0/b7JP8CwBggLm7xdm/Yw+9EzO7RtLbJF3dLpgnaRAAIJnEPXQz+6akIUlL9Ze+6O5/nFXDAADxpEq5AACKI/ORomb2ajP7qpn9n5ld0WG/b5nZV8zsmJn9Z9bt6IYY53aNmT1iZt80s/29bGMaZjZiZvNm9g0zu8/Mzm2zX19duyjXw8xur7//kJmN9bqNaWx2fmZWNrMf1q/XMTP7szzamYSZ3WVmp8zseId9+vnadTy/2NfO3TPdJF0q6ZckfU7SFR32e0zSSNbf380tyrlJOkvSo5IuknS2pAclvTjvtkc8v7+U9Pb64/2S3tPv1y7K9ZD0SkmfrD/+VUn/kXe7Mz6/sqTZvNua8Px+Q9KYpONt3u/baxfx/GJdu8x76O7+iLt/I+LufXXDNOK5vUzSo+7+LXd/WtJHJf1e91uXiZ2SZuqPZyS9qsO+/XLtolyP1fN29y9JOtfMtva2mYlF/fvWL9drHXf/gqT/7bBLP1+7KOcnxbh2eU7O5ZI+bWZfNrM35tiOrL1A0uMNz5+ov9YPtrr7qfrjU5La/Y/RT9cuyvVotU+/jHyOcn4u6dfrKYlPmtlLeta67uvnaxdFrGuXqGwxyoCjCK5y9++a2XMlzZvZI/Vfq1xlcG6Fvsvc4fxuanzi7t5hDEEhr10bUa9Hcy+o0NexQZR2PiDpQnd/ysxeIenjqqUOQ9Gv1y6KWNcuUUB39/GEjWs8xnfr/33SzO5R7Z+OuQeFDM7t25IubHh+oWq9hkLodH71mzPnu/tJM3uepO+1OUYhr10bUa5H8z4X1F/rB5uen7v/uOHxp8zsb81sxN2X1P/6+dptKu6163bKpWXux8x+1sx+rv742ZImJLW9i11Q7fJaX5b0IjO7yMyGJL1G0mzvmpXKrKS99cd7VesNrNOH1y7K9ZiV9HpJMrMdkn7QkHoquk3Pz8y2mpnVH79MtXLlEIK51N/XblOxr10X7truUi2ndVrSSUmfqr/+fEmfqD/+RdXuxj8o6b8lHcj7bnNW51Z//gpJX1et+qAvzq3e7hFJn1ZtOuT7JJ0bwrVrdT0kvUnSmxr2+ev6+w+pQ3VWEbfNzk/S9fVr9aCkf5e0I+82xzi3j0j6jqQz9f/33hDYtet4fnGvHQOLACAQLEEHAIEgoANAIAjoABAIAjoABIKADgCBIKADQCAI6AAQCAI6AATi/wEb9Cq85phjMgAAAABJRU5ErkJggg==) ### 定义符号变量 我们使用线性回归的模型对其进行模拟: $$\bar{y} = wx + b$$ 首先我们定义 $x, y$: In [7]: ```py X = T.scalar() Y = T.scalar() ``` 可以在定义时候直接给变量命名,也可以之后修改变量的名字: In [8]: ```py X.name = 'x' Y.name = 'y' ``` 我们的模型为: In [9]: ```py def model(X, w, b): return X * w + b ``` 在这里我们希望模型得到 $\bar{y}$ 与真实的 $y$ 越接近越好,常用的平方损失函数如下: $$C = |\bar{y}-y|^2$$ 有了损失函数,我们就可以使用梯度下降法来迭代参数 $w, b$ 的值,为此,我们将 $w$ 和 $b$ 设成共享变量: In [10]: ```py w = theano.shared(np.asarray(0., dtype=theano.config.floatX)) w.name = 'w' b = theano.shared(np.asarray(0., dtype=theano.config.floatX)) b.name = 'b' ``` 定义 $\bar y$: In [11]: ```py Y_bar = model(X, w, b) theano.pp(Y_bar) ``` Out[11]: ```py '((x * HostFromGpu(w)) + HostFromGpu(b))' ``` 损失函数及其梯度: In [12]: ```py cost = T.mean(T.sqr(Y_bar - Y)) grads = T.grad(cost=cost, wrt=[w, b]) ``` 定义梯度下降规则: In [13]: ```py lr = 0.01 updates = [[w, w - grads[0] * lr], [b, b - grads[1] * lr]] ``` ### 编译训练模型 每运行一次,参数 $w, b$ 的值就更新一次: In [14]: ```py train_model = theano.function(inputs=[X,Y], outputs=cost, updates=updates, allow_input_downcast=True) ``` ### 将训练函数应用到数据上 训练模型,迭代 100 次: In [15]: ```py for i in xrange(100): for x, y in zip(train_X, train_Y): train_model(x, y) ``` 显示结果: In [16]: ```py print w.get_value() # 接近 2 print b.get_value() # 接近 1 plt.scatter(train_X, train_Y) plt.plot(train_X, w.get_value() * train_X + b.get_value(), 'r') plt.show() ``` ```py 1.94257426262 1.00938093662 ``` ![](data:image/png;base64,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)