├── README.md ├── dropout_gluon.ipynb ├── multilayer_perceptron_gluon.ipynb ├── softmax_regression_gluon.ipynb ├── multilayer_perceptron_from_scratch.ipynb ├── dropout_from_scratch.ipynb ├── utils.py ├── linear_regression_gluon.ipynb ├── regularization_gluon.ipynb └── regularization_from_scratch.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # gluon-practice-code 2 | 3 | 4 | 《动手学深度学习》 5 | 6 | 7 | ## References 8 | 9 | https://zh.gluon.ai/index.html 10 | -------------------------------------------------------------------------------- /dropout_gluon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2018-03-15T18:52:39.576686Z", 9 | "start_time": "2018-03-15T18:52:38.319857Z" 10 | }, 11 | "collapsed": true 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "import mxnet as mx\n", 16 | "from mxnet import nd\n", 17 | "from mxnet import gluon\n", 18 | "from mxnet import autograd\n", 19 | "from mxnet.gluon import nn\n", 20 | "from utils import load_data_fashion_mnist, accuracy, evaluate_accuracy" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "## 定义模型并添加丢弃层" 28 | ] 29 | }, 30 | { 31 | "cell_type": "code", 32 | "execution_count": 2, 33 | "metadata": { 34 | "ExecuteTime": { 35 | "end_time": "2018-03-15T18:52:39.590819Z", 36 | "start_time": "2018-03-15T18:52:39.578488Z" 37 | }, 38 | "collapsed": true 39 | }, 40 | "outputs": [], 41 | "source": [ 42 | "# 定义模型\n", 43 | "net = nn.Sequential()\n", 44 | "# 丢弃概率\n", 45 | "drop_prob1 = 0.2\n", 46 | "drop_prob2 = 0.5\n", 47 | "\n", 48 | "# 添加层\n", 49 | "with net.name_scope():\n", 50 | " # 将输入数据展开\n", 51 | " net.add(nn.Flatten())\n", 52 | " # 第一个全连接层\n", 53 | " net.add(nn.Dense(256, activation=\"relu\"))\n", 54 | " # 添加丢弃层\n", 55 | " net.add(nn.Dropout(drop_prob1))\n", 56 | " # 第二个全连接层\n", 57 | " net.add(nn.Dense(256, activation=\"relu\"))\n", 58 | " # 添加丢弃层\n", 59 | " net.add(nn.Dropout(drop_prob2))\n", 60 | " # 定义输出层\n", 61 | " net.add(nn.Dense(10))\n", 62 | "\n", 63 | "# 初始化模型参数\n", 64 | "net.initialize()" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "## 读取数据并训练" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 3, 77 | "metadata": { 78 | "ExecuteTime": { 79 | "end_time": "2018-03-15T18:52:54.018617Z", 80 | "start_time": "2018-03-15T18:52:39.592581Z" 81 | }, 82 | "collapsed": false 83 | }, 84 | "outputs": [ 85 | { 86 | "name": "stdout", 87 | "output_type": "stream", 88 | "text": [ 89 | "Epoch 0. Loss: 0.817475, Train acc 0.697349, Test acc 0.778145\n", 90 | "Epoch 1. Loss: 0.515098, Train acc 0.810831, Test acc 0.847456\n", 91 | "Epoch 2. Loss: 0.458402, Train acc 0.833450, Test acc 0.823918\n", 92 | "Epoch 3. Loss: 0.419452, Train acc 0.846554, Test acc 0.862079\n", 93 | "Epoch 4. Loss: 0.396483, Train acc 0.854067, Test acc 0.874499\n" 94 | ] 95 | } 96 | ], 97 | "source": [ 98 | "# 批数据大小\n", 99 | "batch_size = 256\n", 100 | "\n", 101 | "# 加载数据\n", 102 | "train_data, test_data = load_data_fashion_mnist(batch_size)\n", 103 | "\n", 104 | "# 优化\n", 105 | "trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.5})\n", 106 | "\n", 107 | "# 定义交叉熵损失\n", 108 | "softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()\n", 109 | "\n", 110 | "# 训练\n", 111 | "for epoch in range(5):\n", 112 | " # 训练损失\n", 113 | " train_loss = 0.0\n", 114 | " # 训练准确率\n", 115 | " train_acc = 0.0\n", 116 | " # 迭代训练\n", 117 | " for data, label in train_data:\n", 118 | " with autograd.record():\n", 119 | " # 计算输出\n", 120 | " output = net(data)\n", 121 | " # 计算损失\n", 122 | " loss = softmax_cross_entropy(output, label)\n", 123 | " # 梯度反向传播\n", 124 | " loss.backward()\n", 125 | " # 更新梯度\n", 126 | " trainer.step(batch_size)\n", 127 | " # 记录训练损失\n", 128 | " train_loss += nd.mean(loss).asscalar()\n", 129 | " # 记录训练准确率\n", 130 | " train_acc += accuracy(output, label)\n", 131 | " # 计算测试准确率\n", 132 | " test_acc = evaluate_accuracy(test_data, net)\n", 133 | " print(\"Epoch %d. Loss: %f, Train acc %f, Test acc %f\" % (epoch, train_loss / len(train_data), train_acc / len(train_data), test_acc))" 134 | ] 135 | } 136 | ], 137 | "metadata": { 138 | "kernelspec": { 139 | "display_name": "Python 2", 140 | "language": "python", 141 | "name": "python2" 142 | }, 143 | "language_info": { 144 | "codemirror_mode": { 145 | "name": "ipython", 146 | "version": 2 147 | }, 148 | "file_extension": ".py", 149 | "mimetype": "text/x-python", 150 | "name": "python", 151 | "nbconvert_exporter": "python", 152 | "pygments_lexer": "ipython2", 153 | "version": "2.7.13" 154 | } 155 | }, 156 | "nbformat": 4, 157 | "nbformat_minor": 2 158 | } 159 | -------------------------------------------------------------------------------- /multilayer_perceptron_gluon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2018-02-28T13:33:34.998857Z", 9 | "start_time": "2018-02-28T13:33:33.792138Z" 10 | }, 11 | "collapsed": true 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "# 导入mxnet\n", 16 | "import mxnet as mx\n", 17 | "\n", 18 | "# 设置随机种子\n", 19 | "mx.random.seed(2)\n", 20 | "\n", 21 | "from mxnet import gluon\n", 22 | "from mxnet import ndarray as nd\n", 23 | "from mxnet import autograd\n", 24 | "from mxnet import image\n", 25 | "from utils import load_data_fashion_mnist, accuracy, evaluate_accuracy" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "## 获取和读取数据" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": { 39 | "ExecuteTime": { 40 | "end_time": "2018-02-28T13:33:35.974855Z", 41 | "start_time": "2018-02-28T13:33:35.000780Z" 42 | }, 43 | "collapsed": true 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "# 批数据大小\n", 48 | "batch_size = 256\n", 49 | "\n", 50 | "# 获取训练数据和测试数据\n", 51 | "train_data, test_data = load_data_fashion_mnist(batch_size)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "## 定义模型" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "metadata": { 65 | "ExecuteTime": { 66 | "end_time": "2018-02-28T13:33:35.984171Z", 67 | "start_time": "2018-02-28T13:33:35.976520Z" 68 | }, 69 | "collapsed": false 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "# 按顺序堆叠网络层\n", 74 | "net = gluon.nn.Sequential()\n", 75 | "\n", 76 | "# name_scope作用, 方便管理参数名称\n", 77 | "with net.name_scope():\n", 78 | " net.add(gluon.nn.Flatten())\n", 79 | " net.add(gluon.nn.Dense(256, activation='relu'))\n", 80 | " net.add(gluon.nn.Dense(10))\n", 81 | "\n", 82 | "# 参数初始化\n", 83 | "net.initialize()" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "## Softmax和交叉熵损失函数" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": 4, 96 | "metadata": { 97 | "ExecuteTime": { 98 | "end_time": "2018-02-28T13:33:35.989919Z", 99 | "start_time": "2018-02-28T13:33:35.986808Z" 100 | }, 101 | "collapsed": true 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "# 定义交叉熵损失\n", 106 | "softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "## 优化" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 5, 119 | "metadata": { 120 | "ExecuteTime": { 121 | "end_time": "2018-02-28T13:33:35.995290Z", 122 | "start_time": "2018-02-28T13:33:35.991843Z" 123 | }, 124 | "collapsed": true 125 | }, 126 | "outputs": [], 127 | "source": [ 128 | "# 定义训练器和优化方法\n", 129 | "trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.1})" 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": {}, 135 | "source": [ 136 | "## 训练" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 6, 142 | "metadata": { 143 | "ExecuteTime": { 144 | "end_time": "2018-02-28T13:33:44.939392Z", 145 | "start_time": "2018-02-28T13:33:35.996900Z" 146 | }, 147 | "collapsed": false 148 | }, 149 | "outputs": [ 150 | { 151 | "name": "stdout", 152 | "output_type": "stream", 153 | "text": [ 154 | "Epoch 0. Loss: 0.819048, Train acc 0.728666, Test acc 0.768530\n", 155 | "Epoch 1. Loss: 0.550646, Train acc 0.808644, Test acc 0.823618\n", 156 | "Epoch 2. Loss: 0.488554, Train acc 0.829210, Test acc 0.845553\n", 157 | "Epoch 3. Loss: 0.457407, Train acc 0.839493, Test acc 0.842448\n", 158 | "Epoch 4. Loss: 0.438059, Train acc 0.845486, Test acc 0.852063\n" 159 | ] 160 | } 161 | ], 162 | "source": [ 163 | "# 定义迭代周期\n", 164 | "epochs = 5\n", 165 | "\n", 166 | "# 训练\n", 167 | "for epoch in range(epochs):\n", 168 | " # 训练损失\n", 169 | " train_loss = 0.0\n", 170 | " # 训练集准确率\n", 171 | " train_acc = 0.0\n", 172 | " # 迭代训练\n", 173 | " for data, label in train_data:\n", 174 | " # 记录梯度\n", 175 | " with autograd.record():\n", 176 | " # 计算输出\n", 177 | " output = net(data)\n", 178 | " # 计算损失\n", 179 | " loss = softmax_cross_entropy(output, label)\n", 180 | " # 反向传播求梯度\n", 181 | " loss.backward()\n", 182 | " # 梯度下降\n", 183 | " trainer.step(batch_size)\n", 184 | " # 总的训练损失\n", 185 | " train_loss += nd.mean(loss).asscalar()\n", 186 | " # 总的训练准确率\n", 187 | " train_acc += accuracy(output, label)\n", 188 | " \n", 189 | " # 测试集的准确率\n", 190 | " test_acc = evaluate_accuracy(test_data, net)\n", 191 | " \n", 192 | " print(\"Epoch %d. Loss: %f, Train acc %f, Test acc %f\" % (\n", 193 | " epoch, train_loss / len(train_data), train_acc / len(train_data), test_acc))" 194 | ] 195 | } 196 | ], 197 | "metadata": { 198 | "kernelspec": { 199 | "display_name": "Python 2", 200 | "language": "python", 201 | "name": "python2" 202 | }, 203 | "language_info": { 204 | "codemirror_mode": { 205 | "name": "ipython", 206 | "version": 2 207 | }, 208 | "file_extension": ".py", 209 | "mimetype": "text/x-python", 210 | "name": "python", 211 | "nbconvert_exporter": "python", 212 | "pygments_lexer": "ipython2", 213 | "version": "2.7.13" 214 | } 215 | }, 216 | "nbformat": 4, 217 | "nbformat_minor": 2 218 | } 219 | -------------------------------------------------------------------------------- /softmax_regression_gluon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2018-02-22T17:52:39.407763Z", 9 | "start_time": "2018-02-22T17:52:38.395884Z" 10 | }, 11 | "collapsed": true 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "# 导入mxnet\n", 16 | "import mxnet as mx\n", 17 | "\n", 18 | "# 设置随机种子\n", 19 | "mx.random.seed(2)\n", 20 | "\n", 21 | "from mxnet import gluon\n", 22 | "from mxnet import ndarray as nd\n", 23 | "from mxnet import autograd\n", 24 | "from mxnet import image" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "## 辅助函数" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": 2, 37 | "metadata": { 38 | "ExecuteTime": { 39 | "end_time": "2018-02-22T17:52:39.620736Z", 40 | "start_time": "2018-02-22T17:52:39.409482Z" 41 | }, 42 | "collapsed": true 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "from utils import load_data_fashion_mnist, accuracy, evaluate_accuracy" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "## 获取和读取数据" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": 3, 59 | "metadata": { 60 | "ExecuteTime": { 61 | "end_time": "2018-02-22T17:52:40.626754Z", 62 | "start_time": "2018-02-22T17:52:39.622405Z" 63 | }, 64 | "collapsed": false 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "# 批数据大小\n", 69 | "batch_size = 256\n", 70 | "\n", 71 | "# 获取训练数据和测试数据\n", 72 | "train_data, test_data = load_data_fashion_mnist(batch_size)" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "## 定义和初始化模型" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 4, 85 | "metadata": { 86 | "ExecuteTime": { 87 | "end_time": "2018-02-22T17:52:40.635311Z", 88 | "start_time": "2018-02-22T17:52:40.628431Z" 89 | }, 90 | "collapsed": false 91 | }, 92 | "outputs": [], 93 | "source": [ 94 | "# 定义一个空的模型\n", 95 | "net = gluon.nn.Sequential()\n", 96 | "\n", 97 | "# name_scope作用, 方便管理参数命名\n", 98 | "with net.name_scope():\n", 99 | " # 加入一个平铺层, 其会将输入数据平铺为batch_size*?维\n", 100 | " net.add(gluon.nn.Flatten())\n", 101 | " # 加入一个全连接层, 输出为10类\n", 102 | " net.add(gluon.nn.Dense(10))\n", 103 | "\n", 104 | "# 参数初始化\n", 105 | "net.initialize()" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "## Softmax和交叉熵损失函数" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": 5, 118 | "metadata": { 119 | "ExecuteTime": { 120 | "end_time": "2018-02-22T17:52:40.640735Z", 121 | "start_time": "2018-02-22T17:52:40.637242Z" 122 | }, 123 | "collapsed": true 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "# 定义交叉熵损失\n", 128 | "softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()" 129 | ] 130 | }, 131 | { 132 | "cell_type": "markdown", 133 | "metadata": {}, 134 | "source": [ 135 | "## 优化" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 6, 141 | "metadata": { 142 | "ExecuteTime": { 143 | "end_time": "2018-02-22T17:52:40.645888Z", 144 | "start_time": "2018-02-22T17:52:40.642635Z" 145 | }, 146 | "collapsed": true 147 | }, 148 | "outputs": [], 149 | "source": [ 150 | "# 定义训练器和优化方法\n", 151 | "trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.1})" 152 | ] 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "metadata": {}, 157 | "source": [ 158 | "## 训练" 159 | ] 160 | }, 161 | { 162 | "cell_type": "code", 163 | "execution_count": 7, 164 | "metadata": { 165 | "ExecuteTime": { 166 | "end_time": "2018-02-22T17:52:47.443043Z", 167 | "start_time": "2018-02-22T17:52:40.647739Z" 168 | }, 169 | "collapsed": false 170 | }, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "Epoch 0. Loss: 0.793821, Train acc 0.744107, Test acc 0.786659\n", 177 | "Epoch 1. Loss: 0.575076, Train acc 0.809879, Test acc 0.820112\n", 178 | "Epoch 2. Loss: 0.530560, Train acc 0.822583, Test acc 0.831731\n", 179 | "Epoch 3. Loss: 0.506161, Train acc 0.829728, Test acc 0.835837\n", 180 | "Epoch 4. Loss: 0.488752, Train acc 0.834769, Test acc 0.834135\n" 181 | ] 182 | } 183 | ], 184 | "source": [ 185 | "# 定义迭代周期\n", 186 | "epochs = 5\n", 187 | "\n", 188 | "# 训练\n", 189 | "for epoch in range(epochs):\n", 190 | " # 训练损失\n", 191 | " train_loss = 0.0\n", 192 | " # 训练集准确率\n", 193 | " train_acc = 0.0\n", 194 | " # 迭代训练\n", 195 | " for data, label in train_data:\n", 196 | " # 记录梯度\n", 197 | " with autograd.record():\n", 198 | " # 计算输出\n", 199 | " output = net(data)\n", 200 | " # 计算损失\n", 201 | " loss = softmax_cross_entropy(output, label)\n", 202 | " # 反向传播求梯度\n", 203 | " loss.backward()\n", 204 | " # 梯度下降\n", 205 | " trainer.step(batch_size)\n", 206 | " # 总的训练损失\n", 207 | " train_loss += nd.mean(loss).asscalar()\n", 208 | " # 总的训练准确率\n", 209 | " train_acc += accuracy(output, label)\n", 210 | " \n", 211 | " # 测试集的准确率\n", 212 | " test_acc = evaluate_accuracy(test_data, net)\n", 213 | " \n", 214 | " print(\"Epoch %d. Loss: %f, Train acc %f, Test acc %f\" % (\n", 215 | " epoch, train_loss / len(train_data), train_acc / len(train_data), test_acc))" 216 | ] 217 | } 218 | ], 219 | "metadata": { 220 | "kernelspec": { 221 | "display_name": "Python 2", 222 | "language": "python", 223 | "name": "python2" 224 | }, 225 | "language_info": { 226 | "codemirror_mode": { 227 | "name": "ipython", 228 | "version": 2 229 | }, 230 | "file_extension": ".py", 231 | "mimetype": "text/x-python", 232 | "name": "python", 233 | "nbconvert_exporter": "python", 234 | "pygments_lexer": "ipython2", 235 | "version": "2.7.13" 236 | } 237 | }, 238 | "nbformat": 4, 239 | "nbformat_minor": 2 240 | } 241 | -------------------------------------------------------------------------------- /multilayer_perceptron_from_scratch.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "ExecuteTime": { 8 | "end_time": "2018-02-27T18:17:57.578210Z", 9 | "start_time": "2018-02-27T18:17:56.281014Z" 10 | }, 11 | "collapsed": true 12 | }, 13 | "outputs": [], 14 | "source": [ 15 | "# 导入mxnet\n", 16 | "import mxnet as mx\n", 17 | "\n", 18 | "# 设置随机种子\n", 19 | "mx.random.seed(2)\n", 20 | "\n", 21 | "from mxnet import gluon\n", 22 | "from mxnet import ndarray as nd\n", 23 | "from mxnet import autograd\n", 24 | "from mxnet import image\n", 25 | "from utils import load_data_fashion_mnist, accuracy, evaluate_accuracy, SGD" 26 | ] 27 | }, 28 | { 29 | "cell_type": "markdown", 30 | "metadata": {}, 31 | "source": [ 32 | "## 数据获取" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 2, 38 | "metadata": { 39 | "ExecuteTime": { 40 | "end_time": "2018-02-27T18:17:58.698084Z", 41 | "start_time": "2018-02-27T18:17:57.580079Z" 42 | }, 43 | "collapsed": true 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "# 批数据大小\n", 48 | "batch_size = 256\n", 49 | "\n", 50 | "# 获取训练数据和测试数据\n", 51 | "train_data, test_data = load_data_fashion_mnist(batch_size)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "## 多层感知机" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 3, 64 | "metadata": { 65 | "ExecuteTime": { 66 | "end_time": "2018-02-27T18:17:58.710837Z", 67 | "start_time": "2018-02-27T18:17:58.699828Z" 68 | }, 69 | "collapsed": true 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "# 输入数据大小\n", 74 | "num_inputs = 28 * 28\n", 75 | "# 输出数据大小, 分为10类\n", 76 | "num_outputs = 10\n", 77 | "\n", 78 | "# 隐藏单元个数\n", 79 | "num_hidden = 256\n", 80 | "\n", 81 | "# 正态分布的标准差\n", 82 | "weight_scale = 0.01\n", 83 | "\n", 84 | "# 随机初始化输入层权重\n", 85 | "W1 = nd.random_normal(shape=(num_inputs, num_hidden), scale=weight_scale)\n", 86 | "b1 = nd.zeros(num_hidden)\n", 87 | "\n", 88 | "# 随机初始化隐藏层权重\n", 89 | "W2 = nd.random_normal(shape=(num_hidden, num_outputs), scale=weight_scale)\n", 90 | "b2 = nd.zeros(num_outputs)\n", 91 | "\n", 92 | "# 参数数组\n", 93 | "params = [W1, b1, W2, b2]\n", 94 | "\n", 95 | "# 需要计算梯度, 添加自动求导\n", 96 | "for param in params:\n", 97 | " param.attach_grad()" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "metadata": {}, 103 | "source": [ 104 | "## 激活函数" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "execution_count": 4, 110 | "metadata": { 111 | "ExecuteTime": { 112 | "end_time": "2018-02-27T18:17:58.716307Z", 113 | "start_time": "2018-02-27T18:17:58.712901Z" 114 | }, 115 | "collapsed": true 116 | }, 117 | "outputs": [], 118 | "source": [ 119 | "# 激活函数使用ReLU, relu(x)=max(x,0)\n", 120 | "def relu(X):\n", 121 | " return nd.maximum(X, 0)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "## 定义模型" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 5, 134 | "metadata": { 135 | "ExecuteTime": { 136 | "end_time": "2018-02-27T18:17:58.723268Z", 137 | "start_time": "2018-02-27T18:17:58.717841Z" 138 | }, 139 | "collapsed": false 140 | }, 141 | "outputs": [], 142 | "source": [ 143 | "def net(X):\n", 144 | " # 输入数据重排\n", 145 | " X = X.reshape((-1, num_inputs))\n", 146 | " # 计算激活值\n", 147 | " h1 = relu(nd.dot(X, W1) + b1)\n", 148 | " # 计算输出\n", 149 | " output = nd.dot(h1, W2) + b2\n", 150 | " return output" 151 | ] 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "metadata": {}, 156 | "source": [ 157 | "## Softmax和交叉熵损失函数" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 6, 163 | "metadata": { 164 | "ExecuteTime": { 165 | "end_time": "2018-02-27T18:17:58.727653Z", 166 | "start_time": "2018-02-27T18:17:58.724695Z" 167 | }, 168 | "collapsed": true 169 | }, 170 | "outputs": [], 171 | "source": [ 172 | "# 定义交叉熵损失\n", 173 | "softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "## 训练" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "execution_count": 7, 186 | "metadata": { 187 | "ExecuteTime": { 188 | "end_time": "2018-02-27T18:18:10.076855Z", 189 | "start_time": "2018-02-27T18:17:58.729198Z" 190 | }, 191 | "collapsed": false 192 | }, 193 | "outputs": [ 194 | { 195 | "name": "stdout", 196 | "output_type": "stream", 197 | "text": [ 198 | "Epoch 0. Loss: 1.042064, Train acc 0.630976, Test acc 0.776142\n", 199 | "Epoch 1. Loss: 0.601578, Train acc 0.788862, Test acc 0.815204\n", 200 | "Epoch 2. Loss: 0.525148, Train acc 0.816556, Test acc 0.835136\n", 201 | "Epoch 3. Loss: 0.486619, Train acc 0.829427, Test acc 0.833033\n", 202 | "Epoch 4. Loss: 0.459395, Train acc 0.836104, Test acc 0.835136\n" 203 | ] 204 | } 205 | ], 206 | "source": [ 207 | "# 定义迭代周期\n", 208 | "epochs = 5\n", 209 | "\n", 210 | "## 定义学习率\n", 211 | "learning_rate = 0.1\n", 212 | "\n", 213 | "# 训练\n", 214 | "for epoch in range(epochs):\n", 215 | " # 训练损失\n", 216 | " train_loss = 0.0\n", 217 | " # 训练集准确率\n", 218 | " train_acc = 0.0\n", 219 | " # 迭代训练\n", 220 | " for data, label in train_data:\n", 221 | " # 记录梯度\n", 222 | " with autograd.record():\n", 223 | " # 计算输出\n", 224 | " output = net(data)\n", 225 | " # 计算损失\n", 226 | " loss = softmax_cross_entropy(output, label)\n", 227 | " # 反向传播求梯度\n", 228 | " loss.backward()\n", 229 | " # 梯度下降\n", 230 | " SGD(params, learning_rate/batch_size)\n", 231 | " # 总的训练损失\n", 232 | " train_loss += nd.mean(loss).asscalar()\n", 233 | " # 总的训练准确率\n", 234 | " train_acc += accuracy(output, label)\n", 235 | " \n", 236 | " # 测试集的准确率\n", 237 | " test_acc = evaluate_accuracy(test_data, net)\n", 238 | " \n", 239 | " print(\"Epoch %d. Loss: %f, Train acc %f, Test acc %f\" % (\n", 240 | " epoch, train_loss / len(train_data), train_acc / len(train_data), test_acc))" 241 | ] 242 | } 243 | ], 244 | "metadata": { 245 | "kernelspec": { 246 | "display_name": "Python 2", 247 | "language": "python", 248 | "name": "python2" 249 | }, 250 | "language_info": { 251 | "codemirror_mode": { 252 | "name": "ipython", 253 | "version": 2 254 | }, 255 | "file_extension": ".py", 256 | "mimetype": "text/x-python", 257 | "name": "python", 258 | "nbconvert_exporter": "python", 259 | "pygments_lexer": "ipython2", 260 | "version": "2.7.13" 261 | } 262 | }, 263 | "nbformat": 4, 264 | "nbformat_minor": 2 265 | } 266 | -------------------------------------------------------------------------------- /dropout_from_scratch.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 丢弃法的概念\n", 8 | "\n", 9 | "在现代神经网络中,我们所指的丢弃法,通常是对输入层或者隐含层做以下操作:\n", 10 | "\n", 11 | "* 随机选择一部分该层的输出作为丢弃元素;\n", 12 | "* 把丢弃元素乘以0;\n", 13 | "* 把非丢弃元素拉伸。" 14 | ] 15 | }, 16 | { 17 | "cell_type": "markdown", 18 | "metadata": {}, 19 | "source": [ 20 | "## 丢弃法的实现" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 1, 26 | "metadata": { 27 | "ExecuteTime": { 28 | "end_time": "2018-03-14T19:00:58.525980Z", 29 | "start_time": "2018-03-14T19:00:57.353795Z" 30 | }, 31 | "collapsed": false 32 | }, 33 | "outputs": [], 34 | "source": [ 35 | "import mxnet as mx\n", 36 | "from mxnet import nd\n", 37 | "from mxnet import gluon\n", 38 | "from mxnet import autograd\n", 39 | "from utils import load_data_fashion_mnist, accuracy, evaluate_accuracy, SGD\n", 40 | "\n", 41 | "# 设置随机种子\n", 42 | "mx.random.seed(2)\n", 43 | "\n", 44 | "# 实现dropout\n", 45 | "def dropout(X, drop_probability):\n", 46 | " # 计算保留数据的比例\n", 47 | " keep_probability = 1 - drop_probability\n", 48 | " # 确保drop_probability的输入合法\n", 49 | " assert 0 <= keep_probability <= 1\n", 50 | " # 丢弃所有元素\n", 51 | " if keep_probability == 0:\n", 52 | " return X.zeros_like()\n", 53 | " # 随机生成一个相同纬度的矩阵, 根据随机值和keep_probability的对比确定是否丢弃该元素\n", 54 | " mask = nd.random.uniform(0, 1.0, X.shape, ctx=X.context) < keep_probability\n", 55 | " # 保证 E[dropout(X)] == X, 对剩下的数据进行缩放\n", 56 | " scale = 1 / keep_probability\n", 57 | " return mask * X * scale" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 2, 63 | "metadata": { 64 | "ExecuteTime": { 65 | "end_time": "2018-03-14T19:00:58.536105Z", 66 | "start_time": "2018-03-14T19:00:58.527911Z" 67 | }, 68 | "collapsed": false 69 | }, 70 | "outputs": [ 71 | { 72 | "data": { 73 | "text/plain": [ 74 | "\n", 75 | "[[ 0. 1. 2. 3.]\n", 76 | " [ 4. 5. 6. 7.]\n", 77 | " [ 8. 9. 10. 11.]\n", 78 | " [ 12. 13. 14. 15.]\n", 79 | " [ 16. 17. 18. 19.]]\n", 80 | "" 81 | ] 82 | }, 83 | "execution_count": 2, 84 | "metadata": {}, 85 | "output_type": "execute_result" 86 | } 87 | ], 88 | "source": [ 89 | "# 测试dropout\n", 90 | "A = nd.arange(20).reshape((5,4))\n", 91 | "dropout(A, 0.0)" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": 3, 97 | "metadata": { 98 | "ExecuteTime": { 99 | "end_time": "2018-03-14T19:00:58.543216Z", 100 | "start_time": "2018-03-14T19:00:58.537770Z" 101 | }, 102 | "collapsed": false 103 | }, 104 | "outputs": [ 105 | { 106 | "data": { 107 | "text/plain": [ 108 | "\n", 109 | "[[ 0. 0. 0. 0.]\n", 110 | " [ 0. 0. 0. 0.]\n", 111 | " [ 0. 0. 0. 0.]\n", 112 | " [ 0. 0. 0. 0.]\n", 113 | " [ 0. 0. 0. 0.]]\n", 114 | "" 115 | ] 116 | }, 117 | "execution_count": 3, 118 | "metadata": {}, 119 | "output_type": "execute_result" 120 | } 121 | ], 122 | "source": [ 123 | "dropout(A, 1.0)" 124 | ] 125 | }, 126 | { 127 | "cell_type": "code", 128 | "execution_count": 4, 129 | "metadata": { 130 | "ExecuteTime": { 131 | "end_time": "2018-03-14T19:00:58.550498Z", 132 | "start_time": "2018-03-14T19:00:58.544891Z" 133 | }, 134 | "collapsed": false 135 | }, 136 | "outputs": [ 137 | { 138 | "data": { 139 | "text/plain": [ 140 | "\n", 141 | "[[ 0. 2. 4. 0.]\n", 142 | " [ 8. 0. 12. 0.]\n", 143 | " [ 16. 18. 0. 0.]\n", 144 | " [ 0. 0. 0. 30.]\n", 145 | " [ 0. 34. 36. 0.]]\n", 146 | "" 147 | ] 148 | }, 149 | "execution_count": 4, 150 | "metadata": {}, 151 | "output_type": "execute_result" 152 | } 153 | ], 154 | "source": [ 155 | "dropout(A, 0.5)" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": { 161 | "ExecuteTime": { 162 | "end_time": "2018-03-14T18:45:50.346765Z", 163 | "start_time": "2018-03-14T18:45:50.341096Z" 164 | } 165 | }, 166 | "source": [ 167 | "## 丢弃法的本质\n", 168 | "\n", 169 | "一般来说,在集成学习里,我们可以对训练数据集有放回地采样若干次并分别训练若干个不同的分类器;测试时,把这些分类器的结果集成一下作为最终分类结果。事实上,丢弃法在模拟集成学习。丢弃法实质上是对每一个这样的数据集分别训练一个原神经网络子集的分类器。与一般的集成学习不同,这里每个原神经网络子集的分类器用的是同一套参数。因此丢弃法只是在模拟集成学习。使用丢弃法的神经网络实质上是对输入层和隐含层的参数做了正则化:学到的参数使得原神经网络不同子集在训练数据上都尽可能表现良好。" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "metadata": {}, 175 | "source": [ 176 | "## 数据获取" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": 5, 182 | "metadata": { 183 | "ExecuteTime": { 184 | "end_time": "2018-03-14T19:00:59.647771Z", 185 | "start_time": "2018-03-14T19:00:58.552220Z" 186 | }, 187 | "collapsed": false 188 | }, 189 | "outputs": [], 190 | "source": [ 191 | "# 批数据大小\n", 192 | "batch_size = 256\n", 193 | "\n", 194 | "# 加载数据\n", 195 | "train_data, test_data = load_data_fashion_mnist(batch_size)" 196 | ] 197 | }, 198 | { 199 | "cell_type": "markdown", 200 | "metadata": {}, 201 | "source": [ 202 | "## 含两个隐藏层的多层感知机" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": 6, 208 | "metadata": { 209 | "ExecuteTime": { 210 | "end_time": "2018-03-14T19:00:59.667827Z", 211 | "start_time": "2018-03-14T19:00:59.650044Z" 212 | }, 213 | "collapsed": true 214 | }, 215 | "outputs": [], 216 | "source": [ 217 | "# 模型输入大小\n", 218 | "num_inputs = 28 * 28\n", 219 | "\n", 220 | "# 模型输出大小\n", 221 | "num_outputs = 10\n", 222 | "\n", 223 | "# 第一个隐藏层节点数量\n", 224 | "num_hidden1 = 256\n", 225 | "\n", 226 | "# 第二个隐藏层节点数量\n", 227 | "num_hidden2 = 256\n", 228 | "\n", 229 | "# 随机数据时的标准差\n", 230 | "weight_scale = 0.01\n", 231 | "\n", 232 | "# 第一个隐藏层权重\n", 233 | "W1 = nd.random_normal(shape=(num_inputs, num_hidden1), scale=weight_scale)\n", 234 | "# 第一个隐藏层偏置\n", 235 | "b1 = nd.zeros(num_hidden1)\n", 236 | "\n", 237 | "# 第二个隐藏层权重\n", 238 | "W2 = nd.random_normal(shape=(num_hidden1, num_hidden2), scale=weight_scale)\n", 239 | "# 第二个隐藏层偏置\n", 240 | "b2 = nd.zeros(num_hidden2)\n", 241 | "\n", 242 | "# 输出层权重\n", 243 | "W3 = nd.random_normal(shape=(num_hidden2, num_outputs), scale=weight_scale)\n", 244 | "# 输出层偏置\n", 245 | "b3 = nd.zeros(num_outputs)\n", 246 | "\n", 247 | "# 参数数组\n", 248 | "params = [W1, b1, W2, b2, W3, b3]\n", 249 | "\n", 250 | "# 需要计算梯度, 添加自动求导\n", 251 | "for param in params:\n", 252 | " param.attach_grad()" 253 | ] 254 | }, 255 | { 256 | "cell_type": "markdown", 257 | "metadata": {}, 258 | "source": [ 259 | "## 定义包含丢弃层的模型" 260 | ] 261 | }, 262 | { 263 | "cell_type": "code", 264 | "execution_count": 7, 265 | "metadata": { 266 | "ExecuteTime": { 267 | "end_time": "2018-03-14T19:00:59.678013Z", 268 | "start_time": "2018-03-14T19:00:59.669321Z" 269 | }, 270 | "collapsed": true 271 | }, 272 | "outputs": [], 273 | "source": [ 274 | "# 第一个隐藏层的丢弃概率\n", 275 | "drop_prob1 = 0.2\n", 276 | "# 第二个隐藏层的丢弃概率\n", 277 | "drop_prob2 = 0.5\n", 278 | "\n", 279 | "# 定义网络\n", 280 | "def net(X):\n", 281 | " X = X.reshape((-1, num_inputs))\n", 282 | " # 第一层全连接\n", 283 | " h1 = nd.relu(nd.dot(X, W1) + b1)\n", 284 | " # 在第一层全连接后添加丢弃层\n", 285 | " h1 = dropout(h1, drop_prob1)\n", 286 | " # 第二层全连接\n", 287 | " h2 = nd.relu(nd.dot(h1, W2) + b2)\n", 288 | " # 在第二层全连接后添加丢弃层\n", 289 | " h2 = dropout(h2, drop_prob2)\n", 290 | " # 返回输出\n", 291 | " return nd.dot(h2, W3) + b3" 292 | ] 293 | }, 294 | { 295 | "cell_type": "markdown", 296 | "metadata": {}, 297 | "source": [ 298 | "## 训练" 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 8, 304 | "metadata": { 305 | "ExecuteTime": { 306 | "end_time": "2018-03-14T19:01:18.009627Z", 307 | "start_time": "2018-03-14T19:00:59.680273Z" 308 | }, 309 | "collapsed": false 310 | }, 311 | "outputs": [ 312 | { 313 | "name": "stdout", 314 | "output_type": "stream", 315 | "text": [ 316 | "Epoch 0. Loss: 1.221062, Train acc 0.528746, Test acc 0.754006\n", 317 | "Epoch 1. Loss: 0.598503, Train acc 0.774890, Test acc 0.813101\n", 318 | "Epoch 2. Loss: 0.499490, Train acc 0.818493, Test acc 0.840244\n", 319 | "Epoch 3. Loss: 0.457343, Train acc 0.832699, Test acc 0.835036\n", 320 | "Epoch 4. Loss: 0.426575, Train acc 0.846070, Test acc 0.849159\n" 321 | ] 322 | } 323 | ], 324 | "source": [ 325 | "# 定义交叉熵损失\n", 326 | "softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss()\n", 327 | "\n", 328 | "# 定义学习率\n", 329 | "learning_rate = 0.5\n", 330 | "\n", 331 | "# 训练\n", 332 | "for epoch in range(5):\n", 333 | " # 训练损失\n", 334 | " train_loss = 0.0\n", 335 | " # 训练准确率\n", 336 | " train_acc = 0.0\n", 337 | " # 迭代训练\n", 338 | " for data, label in train_data:\n", 339 | " with autograd.record():\n", 340 | " # 计算输出\n", 341 | " output = net(data)\n", 342 | " # 计算损失\n", 343 | " loss = softmax_cross_entropy(output, label)\n", 344 | " # 梯度反向传播\n", 345 | " loss.backward()\n", 346 | " # SGD更新梯度\n", 347 | " SGD(params, learning_rate / batch_size)\n", 348 | " # 记录训练损失\n", 349 | " train_loss += nd.mean(loss).asscalar()\n", 350 | " # 记录训练准确率\n", 351 | " train_acc += accuracy(output, label)\n", 352 | " # 计算测试准确率\n", 353 | " test_acc = evaluate_accuracy(test_data, net)\n", 354 | " print(\"Epoch %d. Loss: %f, Train acc %f, Test acc %f\" % (epoch, train_loss / len(train_data), train_acc / len(train_data), test_acc))" 355 | ] 356 | } 357 | ], 358 | "metadata": { 359 | "kernelspec": { 360 | "display_name": "Python 2", 361 | "language": "python", 362 | "name": "python2" 363 | }, 364 | "language_info": { 365 | "codemirror_mode": { 366 | "name": "ipython", 367 | "version": 2 368 | }, 369 | "file_extension": ".py", 370 | "mimetype": "text/x-python", 371 | "name": "python", 372 | "nbconvert_exporter": "python", 373 | "pygments_lexer": "ipython2", 374 | "version": "2.7.13" 375 | } 376 | }, 377 | "nbformat": 4, 378 | "nbformat_minor": 2 379 | } 380 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | 4 | from math import exp 5 | from mxnet import gluon 6 | from mxnet import autograd 7 | from mxnet import nd 8 | from mxnet import image 9 | from mxnet.gluon import nn 10 | import mxnet as mx 11 | import numpy as np 12 | from time import time 13 | import matplotlib.pyplot as plt 14 | 15 | class DataLoader(object): 16 | """similiar to gluon.data.DataLoader, but might be faster. 17 | 18 | The main difference this data loader tries to read more exmaples each 19 | time. But the limits are 1) all examples in dataset have the same shape, 2) 20 | data transfomer needs to process multiple examples at each time 21 | """ 22 | def __init__(self, dataset, batch_size, shuffle): 23 | self.dataset = dataset 24 | self.batch_size = batch_size 25 | self.shuffle = shuffle 26 | 27 | def __iter__(self): 28 | data = self.dataset[:] 29 | X = data[0] 30 | y = nd.array(data[1]) 31 | n = X.shape[0] 32 | if self.shuffle: 33 | idx = np.arange(n) 34 | np.random.shuffle(idx) 35 | X = nd.array(X.asnumpy()[idx]) 36 | y = nd.array(y.asnumpy()[idx]) 37 | 38 | for i in range(n//self.batch_size): 39 | yield (X[i*self.batch_size:(i+1)*self.batch_size], 40 | y[i*self.batch_size:(i+1)*self.batch_size]) 41 | 42 | def __len__(self): 43 | return len(self.dataset)//self.batch_size 44 | 45 | def load_data_fashion_mnist(batch_size, resize=None, root="~/.mxnet/datasets/fashion-mnist"): 46 | """download the fashion mnist dataest and then load into memory""" 47 | def transform_mnist(data, label): 48 | # transform a batch of examples 49 | if resize: 50 | n = data.shape[0] 51 | new_data = nd.zeros((n, resize, resize, data.shape[3])) 52 | for i in range(n): 53 | new_data[i] = image.imresize(data[i], resize, resize) 54 | data = new_data 55 | # change data from batch x height x weight x channel to batch x channel x height x weight 56 | return nd.transpose(data.astype('float32'), (0,3,1,2))/255, label.astype('float32') 57 | mnist_train = gluon.data.vision.FashionMNIST(root=root, train=True, transform=transform_mnist) 58 | mnist_test = gluon.data.vision.FashionMNIST(root=root, train=False, transform=transform_mnist) 59 | train_data = DataLoader(mnist_train, batch_size, shuffle=True) 60 | test_data = DataLoader(mnist_test, batch_size, shuffle=False) 61 | return (train_data, test_data) 62 | 63 | def try_gpu(): 64 | """If GPU is available, return mx.gpu(0); else return mx.cpu()""" 65 | try: 66 | ctx = mx.gpu() 67 | _ = nd.array([0], ctx=ctx) 68 | except: 69 | ctx = mx.cpu() 70 | return ctx 71 | 72 | def try_all_gpus(): 73 | """Return all available GPUs, or [mx.gpu()] if there is no GPU""" 74 | ctx_list = [] 75 | try: 76 | for i in range(16): 77 | ctx = mx.gpu(i) 78 | _ = nd.array([0], ctx=ctx) 79 | ctx_list.append(ctx) 80 | except: 81 | pass 82 | if not ctx_list: 83 | ctx_list = [mx.cpu()] 84 | return ctx_list 85 | 86 | def SGD(params, lr): 87 | for param in params: 88 | param[:] = param - lr * param.grad 89 | 90 | def accuracy(output, label): 91 | return nd.mean(output.argmax(axis=1)==label).asscalar() 92 | 93 | def _get_batch(batch, ctx): 94 | """return data and label on ctx""" 95 | if isinstance(batch, mx.io.DataBatch): 96 | data = batch.data[0] 97 | label = batch.label[0] 98 | else: 99 | data, label = batch 100 | return (gluon.utils.split_and_load(data, ctx), 101 | gluon.utils.split_and_load(label, ctx), 102 | data.shape[0]) 103 | 104 | def evaluate_accuracy(data_iterator, net, ctx=[mx.cpu()]): 105 | if isinstance(ctx, mx.Context): 106 | ctx = [ctx] 107 | acc = nd.array([0]) 108 | n = 0. 109 | if isinstance(data_iterator, mx.io.MXDataIter): 110 | data_iterator.reset() 111 | for batch in data_iterator: 112 | data, label, batch_size = _get_batch(batch, ctx) 113 | for X, y in zip(data, label): 114 | acc += nd.sum(net(X).argmax(axis=1)==y).copyto(mx.cpu()) 115 | n += y.size 116 | acc.wait_to_read() # don't push too many operators into backend 117 | return acc.asscalar() / n 118 | 119 | def train(train_data, test_data, net, loss, trainer, ctx, num_epochs, print_batches=None): 120 | """Train a network""" 121 | print("Start training on ", ctx) 122 | if isinstance(ctx, mx.Context): 123 | ctx = [ctx] 124 | for epoch in range(num_epochs): 125 | train_loss, train_acc, n, m = 0.0, 0.0, 0.0, 0.0 126 | if isinstance(train_data, mx.io.MXDataIter): 127 | train_data.reset() 128 | start = time() 129 | for i, batch in enumerate(train_data): 130 | data, label, batch_size = _get_batch(batch, ctx) 131 | losses = [] 132 | with autograd.record(): 133 | outputs = [net(X) for X in data] 134 | losses = [loss(yhat, y) for yhat, y in zip(outputs, label)] 135 | for l in losses: 136 | l.backward() 137 | train_acc += sum([(yhat.argmax(axis=1)==y).sum().asscalar() 138 | for yhat, y in zip(outputs, label)]) 139 | train_loss += sum([l.sum().asscalar() for l in losses]) 140 | trainer.step(batch_size) 141 | n += batch_size 142 | m += sum([y.size for y in label]) 143 | if print_batches and (i+1) % print_batches == 0: 144 | print("Batch %d. Loss: %f, Train acc %f" % ( 145 | n, train_loss/n, train_acc/m 146 | )) 147 | 148 | test_acc = evaluate_accuracy(test_data, net, ctx) 149 | print("Epoch %d. Loss: %.3f, Train acc %.2f, Test acc %.2f, Time %.1f sec" % ( 150 | epoch, train_loss/n, train_acc/m, test_acc, time() - start 151 | )) 152 | 153 | class Residual(nn.HybridBlock): 154 | def __init__(self, channels, same_shape=True, **kwargs): 155 | super(Residual, self).__init__(**kwargs) 156 | self.same_shape = same_shape 157 | with self.name_scope(): 158 | strides = 1 if same_shape else 2 159 | self.conv1 = nn.Conv2D(channels, kernel_size=3, padding=1, 160 | strides=strides) 161 | self.bn1 = nn.BatchNorm() 162 | self.conv2 = nn.Conv2D(channels, kernel_size=3, padding=1) 163 | self.bn2 = nn.BatchNorm() 164 | if not same_shape: 165 | self.conv3 = nn.Conv2D(channels, kernel_size=1, 166 | strides=strides) 167 | 168 | def hybrid_forward(self, F, x): 169 | out = F.relu(self.bn1(self.conv1(x))) 170 | out = self.bn2(self.conv2(out)) 171 | if not self.same_shape: 172 | x = self.conv3(x) 173 | return F.relu(out + x) 174 | 175 | def resnet18(num_classes): 176 | net = nn.HybridSequential() 177 | with net.name_scope(): 178 | net.add( 179 | nn.BatchNorm(), 180 | nn.Conv2D(64, kernel_size=3, strides=1), 181 | nn.MaxPool2D(pool_size=3, strides=2), 182 | Residual(64), 183 | Residual(64), 184 | Residual(128, same_shape=False), 185 | Residual(128), 186 | Residual(256, same_shape=False), 187 | Residual(256), 188 | nn.GlobalAvgPool2D(), 189 | nn.Dense(num_classes) 190 | ) 191 | return net 192 | 193 | def show_images(imgs, nrows, ncols, figsize=None): 194 | """plot a list of images""" 195 | if not figsize: 196 | figsize = (ncols, nrows) 197 | _, figs = plt.subplots(nrows, ncols, figsize=figsize) 198 | for i in range(nrows): 199 | for j in range(ncols): 200 | figs[i][j].imshow(imgs[i*ncols+j].asnumpy()) 201 | figs[i][j].axes.get_xaxis().set_visible(False) 202 | figs[i][j].axes.get_yaxis().set_visible(False) 203 | plt.show() 204 | 205 | def data_iter_random(corpus_indices, batch_size, num_steps, ctx=None): 206 | """Sample mini-batches in a random order from sequential data.""" 207 | # Subtract 1 because label indices are corresponding input indices + 1. 208 | num_examples = (len(corpus_indices) - 1) // num_steps 209 | epoch_size = num_examples // batch_size 210 | # Randomize samples. 211 | example_indices = list(range(num_examples)) 212 | random.shuffle(example_indices) 213 | 214 | def _data(pos): 215 | return corpus_indices[pos: pos + num_steps] 216 | 217 | for i in range(epoch_size): 218 | # Read batch_size random samples each time. 219 | i = i * batch_size 220 | batch_indices = example_indices[i: i + batch_size] 221 | data = nd.array( 222 | [_data(j * num_steps) for j in batch_indices], ctx=ctx) 223 | label = nd.array( 224 | [_data(j * num_steps + 1) for j in batch_indices], ctx=ctx) 225 | yield data, label 226 | 227 | def data_iter_consecutive(corpus_indices, batch_size, num_steps, ctx=None): 228 | """Sample mini-batches in a consecutive order from sequential data.""" 229 | corpus_indices = nd.array(corpus_indices, ctx=ctx) 230 | data_len = len(corpus_indices) 231 | batch_len = data_len // batch_size 232 | 233 | indices = corpus_indices[0: batch_size * batch_len].reshape(( 234 | batch_size, batch_len)) 235 | # Subtract 1 because label indices are corresponding input indices + 1. 236 | epoch_size = (batch_len - 1) // num_steps 237 | 238 | for i in range(epoch_size): 239 | i = i * num_steps 240 | data = indices[:, i: i + num_steps] 241 | label = indices[:, i + 1: i + num_steps + 1] 242 | yield data, label 243 | 244 | 245 | def grad_clipping(params, theta, ctx): 246 | """Gradient clipping.""" 247 | if theta is not None: 248 | norm = nd.array([0.0], ctx) 249 | for p in params: 250 | norm += nd.sum(p.grad ** 2) 251 | norm = nd.sqrt(norm).asscalar() 252 | if norm > theta: 253 | for p in params: 254 | p.grad[:] *= theta / norm 255 | 256 | 257 | def predict_rnn(rnn, prefix, num_chars, params, hidden_dim, ctx, idx_to_char, 258 | char_to_idx, get_inputs, is_lstm=False): 259 | """Predict the next chars given the prefix.""" 260 | prefix = prefix.lower() 261 | state_h = nd.zeros(shape=(1, hidden_dim), ctx=ctx) 262 | if is_lstm: 263 | state_c = nd.zeros(shape=(1, hidden_dim), ctx=ctx) 264 | output = [char_to_idx[prefix[0]]] 265 | for i in range(num_chars + len(prefix)): 266 | X = nd.array([output[-1]], ctx=ctx) 267 | if is_lstm: 268 | Y, state_h, state_c = rnn(get_inputs(X), state_h, state_c, *params) 269 | else: 270 | Y, state_h = rnn(get_inputs(X), state_h, *params) 271 | if i < len(prefix)-1: 272 | next_input = char_to_idx[prefix[i+1]] 273 | else: 274 | next_input = int(Y[0].argmax(axis=1).asscalar()) 275 | output.append(next_input) 276 | return ''.join([idx_to_char[i] for i in output]) 277 | 278 | 279 | def train_and_predict_rnn(rnn, is_random_iter, epochs, num_steps, hidden_dim, 280 | learning_rate, clipping_theta, batch_size, 281 | pred_period, pred_len, seqs, get_params, get_inputs, 282 | ctx, corpus_indices, idx_to_char, char_to_idx, 283 | is_lstm=False): 284 | """Train an RNN model and predict the next item in the sequence.""" 285 | if is_random_iter: 286 | data_iter = data_iter_random 287 | else: 288 | data_iter = data_iter_consecutive 289 | params = get_params() 290 | 291 | softmax_cross_entropy = gluon.loss.SoftmaxCrossEntropyLoss() 292 | 293 | for e in range(1, epochs + 1): 294 | # If consecutive sampling is used, in the same epoch, the hidden state 295 | # is initialized only at the beginning of the epoch. 296 | if not is_random_iter: 297 | state_h = nd.zeros(shape=(batch_size, hidden_dim), ctx=ctx) 298 | if is_lstm: 299 | state_c = nd.zeros(shape=(batch_size, hidden_dim), ctx=ctx) 300 | train_loss, num_examples = 0, 0 301 | for data, label in data_iter(corpus_indices, batch_size, num_steps, 302 | ctx): 303 | # If random sampling is used, the hidden state has to be 304 | # initialized for each mini-batch. 305 | if is_random_iter: 306 | state_h = nd.zeros(shape=(batch_size, hidden_dim), ctx=ctx) 307 | if is_lstm: 308 | state_c = nd.zeros(shape=(batch_size, hidden_dim), ctx=ctx) 309 | with autograd.record(): 310 | # outputs shape:(batch_size, vocab_size) 311 | if is_lstm: 312 | outputs, state_h, state_c = rnn(get_inputs(data), state_h, 313 | state_c, *params) 314 | else: 315 | outputs, state_h = rnn(get_inputs(data), state_h, *params) 316 | # Let t_ib_j be the j-th element of the mini-batch at time i. 317 | # label shape:(batch_size * num_steps) 318 | # label = [t_0b_0, t_0b_1, ..., t_1b_0, t_1b_1, ..., ]. 319 | label = label.T.reshape((-1,)) 320 | # Concatenate outputs: 321 | # shape: (batch_size * num_steps, vocab_size). 322 | outputs = nd.concat(*outputs, dim=0) 323 | # Now outputs and label are aligned. 324 | loss = softmax_cross_entropy(outputs, label) 325 | loss.backward() 326 | 327 | grad_clipping(params, clipping_theta, ctx) 328 | SGD(params, learning_rate) 329 | 330 | train_loss += nd.sum(loss).asscalar() 331 | num_examples += loss.size 332 | 333 | if e % pred_period == 0: 334 | print("Epoch %d. Training perplexity %f" % (e, 335 | exp(train_loss/num_examples))) 336 | for seq in seqs: 337 | print(' - ', predict_rnn(rnn, seq, pred_len, params, 338 | hidden_dim, ctx, idx_to_char, char_to_idx, get_inputs, 339 | is_lstm)) 340 | print() 341 | -------------------------------------------------------------------------------- /linear_regression_gluon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 创建数据集" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "ExecuteTime": { 15 | "end_time": "2018-02-06T19:02:40.761222Z", 16 | "start_time": "2018-02-06T19:02:39.491082Z" 17 | }, 18 | "collapsed": true 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "# 导入mxnet\n", 23 | "import random\n", 24 | "import mxnet as mx\n", 25 | "\n", 26 | "# 导入mxnet的gluon, ndarray, autograd\n", 27 | "from mxnet import gluon\n", 28 | "from mxnet import autograd\n", 29 | "from mxnet import ndarray as nd\n", 30 | "\n", 31 | "# 设置随机种子\n", 32 | "mx.random.seed(1)\n", 33 | "random.seed(1)\n", 34 | "\n", 35 | "# 训练数据的维度\n", 36 | "num_inputs = 2\n", 37 | "\n", 38 | "# 训练数据的样本数量\n", 39 | "num_examples = 1000\n", 40 | "\n", 41 | "# 实际的权重w\n", 42 | "true_w = [2, -3.4]\n", 43 | "\n", 44 | "# 实际的偏置b\n", 45 | "true_b = 4.2\n", 46 | "\n", 47 | "# 随机生成均值为0, 方差为1, 服从正态分布的训练数据X, \n", 48 | "X = nd.random_normal(shape=(num_examples, num_inputs))\n", 49 | "\n", 50 | "# 根据X, w, b生成对应的输出y\n", 51 | "y = true_w[0] * X[:, 0] + true_w[1] * X[:, 1] + true_b \n", 52 | "\n", 53 | "# 给y加上随机噪声\n", 54 | "y += 0.01 * nd.random_normal(shape=y.shape)" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "## 数据展示" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 2, 67 | "metadata": { 68 | "ExecuteTime": { 69 | "end_time": "2018-02-06T19:02:41.230757Z", 70 | "start_time": "2018-02-06T19:02:40.762933Z" 71 | }, 72 | "collapsed": false 73 | }, 74 | "outputs": [ 75 | { 76 | "data": { 77 | "image/png": "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\nXl22tgYu+AAAAABJRU5ErkJggg==\n", 78 | "text/plain": [ 79 | "" 80 | ] 81 | }, 82 | "metadata": {}, 83 | "output_type": "display_data" 84 | } 85 | ], 86 | "source": [ 87 | "%matplotlib inline\n", 88 | "import matplotlib.pyplot as plt\n", 89 | "\n", 90 | "# 绘制数据的散点图 \n", 91 | "plt.scatter(X[:, 1].asnumpy(), y.asnumpy())\n", 92 | "plt.show()" 93 | ] 94 | }, 95 | { 96 | "cell_type": "markdown", 97 | "metadata": {}, 98 | "source": [ 99 | "## 数据读取" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 3, 105 | "metadata": { 106 | "ExecuteTime": { 107 | "end_time": "2018-02-06T19:02:41.236814Z", 108 | "start_time": "2018-02-06T19:02:41.232498Z" 109 | }, 110 | "collapsed": false 111 | }, 112 | "outputs": [], 113 | "source": [ 114 | "# 训练时的批数据大小\n", 115 | "batch_size = 10\n", 116 | "\n", 117 | "# 创建数据集\n", 118 | "dataset = gluon.data.ArrayDataset(X, y)\n", 119 | "\n", 120 | "# 读取数据\n", 121 | "data_iter = gluon.data.DataLoader(dataset, batch_size, shuffle=True)" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 4, 127 | "metadata": { 128 | "ExecuteTime": { 129 | "end_time": "2018-02-06T19:02:41.245468Z", 130 | "start_time": "2018-02-06T19:02:41.238256Z" 131 | }, 132 | "collapsed": false 133 | }, 134 | "outputs": [ 135 | { 136 | "name": "stdout", 137 | "output_type": "stream", 138 | "text": [ 139 | "\n", 140 | "[[-2.11255503 0.61242002]\n", 141 | " [ 2.18546367 -0.48856559]\n", 142 | " [ 0.91085583 0.38985687]\n", 143 | " [-0.56097323 1.44421673]\n", 144 | " [ 0.31765923 -1.75729597]\n", 145 | " [-0.57738042 2.03963804]\n", 146 | " [-0.91808975 0.64181799]\n", 147 | " [-0.20269176 0.21012937]\n", 148 | " [-0.22549874 0.19895147]\n", 149 | " [ 1.42844415 0.06982213]]\n", 150 | " \n", 151 | "[ -2.11691356 10.22533131 4.70613146 -1.82755637 10.82125568\n", 152 | " -3.88111711 0.17608714 3.07074499 3.06542921 6.82972908]\n", 153 | "\n" 154 | ] 155 | } 156 | ], 157 | "source": [ 158 | "# 查看数据\n", 159 | "for data, label in data_iter:\n", 160 | " print data, label\n", 161 | " break" 162 | ] 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "metadata": {}, 167 | "source": [ 168 | "## 定义模型" 169 | ] 170 | }, 171 | { 172 | "cell_type": "code", 173 | "execution_count": 5, 174 | "metadata": { 175 | "ExecuteTime": { 176 | "end_time": "2018-02-06T19:02:41.250556Z", 177 | "start_time": "2018-02-06T19:02:41.247275Z" 178 | }, 179 | "collapsed": false 180 | }, 181 | "outputs": [], 182 | "source": [ 183 | "# 定义一个空的模型\n", 184 | "net = gluon.nn.Sequential()\n", 185 | "\n", 186 | "# 加入一个Dense层\n", 187 | "net.add(gluon.nn.Dense(1))" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "## 初始化模型参数" 195 | ] 196 | }, 197 | { 198 | "cell_type": "code", 199 | "execution_count": 6, 200 | "metadata": { 201 | "ExecuteTime": { 202 | "end_time": "2018-02-06T19:02:41.255395Z", 203 | "start_time": "2018-02-06T19:02:41.251992Z" 204 | }, 205 | "collapsed": true 206 | }, 207 | "outputs": [], 208 | "source": [ 209 | "net.initialize()" 210 | ] 211 | }, 212 | { 213 | "cell_type": "markdown", 214 | "metadata": {}, 215 | "source": [ 216 | "## 定义损失函数" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 7, 222 | "metadata": { 223 | "ExecuteTime": { 224 | "end_time": "2018-02-06T19:02:41.260791Z", 225 | "start_time": "2018-02-06T19:02:41.257514Z" 226 | }, 227 | "collapsed": true 228 | }, 229 | "outputs": [], 230 | "source": [ 231 | "square_loss = gluon.loss.L2Loss()" 232 | ] 233 | }, 234 | { 235 | "cell_type": "markdown", 236 | "metadata": { 237 | "ExecuteTime": { 238 | "end_time": "2018-02-06T18:12:42.920568Z", 239 | "start_time": "2018-02-06T18:12:42.917424Z" 240 | } 241 | }, 242 | "source": [ 243 | "## 优化" 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": 8, 249 | "metadata": { 250 | "ExecuteTime": { 251 | "end_time": "2018-02-06T19:02:41.265893Z", 252 | "start_time": "2018-02-06T19:02:41.262365Z" 253 | }, 254 | "collapsed": true 255 | }, 256 | "outputs": [], 257 | "source": [ 258 | "trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': 0.01})" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "## 训练" 266 | ] 267 | }, 268 | { 269 | "cell_type": "code", 270 | "execution_count": 9, 271 | "metadata": { 272 | "ExecuteTime": { 273 | "end_time": "2018-02-06T19:02:41.867845Z", 274 | "start_time": "2018-02-06T19:02:41.267689Z" 275 | }, 276 | "collapsed": false 277 | }, 278 | "outputs": [ 279 | { 280 | "name": "stdout", 281 | "output_type": "stream", 282 | "text": [ 283 | "Epoch 0, average loss: 7.403182\n", 284 | "Epoch 1, average loss: 0.854247\n", 285 | "Epoch 2, average loss: 0.099864\n", 286 | "Epoch 3, average loss: 0.011887\n", 287 | "Epoch 4, average loss: 0.001479\n" 288 | ] 289 | } 290 | ], 291 | "source": [ 292 | "# 定义训练的迭代周期\n", 293 | "epochs = 5\n", 294 | "\n", 295 | "# 训练\n", 296 | "for epoch in xrange(epochs):\n", 297 | " # 总的loss\n", 298 | " total_loss = 0\n", 299 | " for data, label in data_iter:\n", 300 | " # 记录梯度\n", 301 | " with autograd.record():\n", 302 | " # 计算预测值\n", 303 | " output = net(data)\n", 304 | " # 计算loss\n", 305 | " loss = square_loss(output, label)\n", 306 | " # 根据loss进行反向传播计算梯度\n", 307 | " loss.backward()\n", 308 | " # 更新权重, batch_size用来进行梯度平均\n", 309 | " trainer.step(batch_size)\n", 310 | " # 计算总的loss\n", 311 | " total_loss += nd.sum(loss).asscalar()\n", 312 | " \n", 313 | " print \"Epoch %d, average loss: %f\" % (epoch, total_loss/num_examples)" 314 | ] 315 | }, 316 | { 317 | "cell_type": "markdown", 318 | "metadata": {}, 319 | "source": [ 320 | "## 参考资料\n", 321 | "\n", 322 | "* ArrayDataset \n", 323 | "[https://mxnet.incubator.apache.org/api/python/gluon/data.html#mxnet.gluon.data.ArrayDataset](https://mxnet.incubator.apache.org/api/python/gluon/data.html#mxnet.gluon.data.ArrayDataset) \n", 324 | "\n", 325 | "* DataLoader \n", 326 | "[https://mxnet.incubator.apache.org/api/python/gluon/data.html?highlight=dataload#mxnet.gluon.data.DataLoader](https://mxnet.incubator.apache.org/api/python/gluon/data.html?highlight=dataload#mxnet.gluon.data.DataLoader) \n", 327 | "\n", 328 | "* Sequential \n", 329 | "[https://mxnet.incubator.apache.org/api/python/gluon/gluon.html?highlight=gluon.nn.sequential#mxnet.gluon.nn.Sequential](https://mxnet.incubator.apache.org/api/python/gluon/gluon.html?highlight=gluon.nn.sequential#mxnet.gluon.nn.Sequential) \n", 330 | "\n", 331 | "* L2Loss \n", 332 | "[https://mxnet.incubator.apache.org/api/python/gluon/loss.html?highlight=l2loss#mxnet.gluon.loss.L2Loss](https://mxnet.incubator.apache.org/api/python/gluon/loss.html?highlight=l2loss#mxnet.gluon.loss.L2Loss) \n", 333 | "\n", 334 | "* Trainer \n", 335 | "[https://mxnet.incubator.apache.org/api/python/gluon/gluon.html?highlight=trainer#mxnet.gluon.Trainer](https://mxnet.incubator.apache.org/api/python/gluon/gluon.html?highlight=trainer#mxnet.gluon.Trainer) " 336 | ] 337 | } 338 | ], 339 | "metadata": { 340 | "kernelspec": { 341 | "display_name": "Python 2", 342 | "language": "python", 343 | "name": "python2" 344 | }, 345 | "language_info": { 346 | "codemirror_mode": { 347 | "name": "ipython", 348 | "version": 2 349 | }, 350 | "file_extension": ".py", 351 | "mimetype": "text/x-python", 352 | "name": "python", 353 | "nbconvert_exporter": "python", 354 | "pygments_lexer": "ipython2", 355 | "version": "2.7.13" 356 | } 357 | }, 358 | "nbformat": 4, 359 | "nbformat_minor": 2 360 | } 361 | -------------------------------------------------------------------------------- /regularization_gluon.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 高维线性回归数据集" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "ExecuteTime": { 15 | "end_time": "2018-03-09T17:58:23.343726Z", 16 | "start_time": "2018-03-09T17:58:22.330109Z" 17 | }, 18 | "collapsed": true 19 | }, 20 | "outputs": [], 21 | "source": [ 22 | "# 导入mxnet\n", 23 | "import random\n", 24 | "import mxnet as mx\n", 25 | "\n", 26 | "# 设置随机种子\n", 27 | "random.seed(2)\n", 28 | "mx.random.seed(2)\n", 29 | "\n", 30 | "from mxnet import gluon\n", 31 | "from mxnet import ndarray as nd\n", 32 | "from mxnet import autograd\n", 33 | "\n", 34 | "\n", 35 | "# 训练数据数量\n", 36 | "num_train = 20\n", 37 | "\n", 38 | "# 测试数据数量\n", 39 | "num_test = 100\n", 40 | "\n", 41 | "# 输入数据特征维度\n", 42 | "num_inputs = 200\n", 43 | "\n", 44 | "# 实际权重\n", 45 | "true_w = nd.ones((num_inputs, 1)) * 0.01\n", 46 | "\n", 47 | "# 实际偏置\n", 48 | "true_b = 0.05\n", 49 | "\n", 50 | "# 生成数据\n", 51 | "X = nd.random_normal(shape=(num_train + num_test, num_inputs))\n", 52 | "y = nd.dot(X, true_w) + true_b\n", 53 | "\n", 54 | "# 添加随机噪声\n", 55 | "y += 0.01 * nd.random_normal(shape=y.shape)\n", 56 | "\n", 57 | "# 训练数据和测试数据\n", 58 | "X_train, X_test = X[:num_train, :], X[num_train:, :]\n", 59 | "y_train, y_test = y[:num_train], y[num_train:]" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "## 定义训练和测试" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 2, 72 | "metadata": { 73 | "ExecuteTime": { 74 | "end_time": "2018-03-09T17:58:23.606426Z", 75 | "start_time": "2018-03-09T17:58:23.345665Z" 76 | }, 77 | "collapsed": true 78 | }, 79 | "outputs": [], 80 | "source": [ 81 | "%matplotlib inline\n", 82 | "import matplotlib as mpl\n", 83 | "mpl.rcParams['figure.dpi']= 120\n", 84 | "import matplotlib.pyplot as plt\n", 85 | "import numpy as np\n", 86 | "\n", 87 | "# 批数据大小\n", 88 | "batch_size = 1\n", 89 | "\n", 90 | "# 创建数据集\n", 91 | "dataset_train = gluon.data.ArrayDataset(X_train, y_train)\n", 92 | "\n", 93 | "# 读取数据\n", 94 | "data_iter = gluon.data.DataLoader(dataset_train, batch_size, shuffle=True)\n", 95 | "\n", 96 | "# 损失函数\n", 97 | "square_loss = gluon.loss.L2Loss()\n", 98 | "\n", 99 | "# 测试\n", 100 | "def test(net, X, y):\n", 101 | " return square_loss(net(X), y).mean().asscalar()\n", 102 | "\n", 103 | "# 训练\n", 104 | "def train(weight_decay):\n", 105 | " # 定义训练的迭代周期\n", 106 | " epochs = 10\n", 107 | " # 定义学习率\n", 108 | " learning_rate = 0.005\n", 109 | " # 定义网络\n", 110 | " net = gluon.nn.Sequential()\n", 111 | " with net.name_scope():\n", 112 | " net.add(gluon.nn.Dense(1))\n", 113 | " #net.collect_params().initialize(mx.init.Normal(sigma=1))\n", 114 | " # 初始化网络参数\n", 115 | " net.initialize(mx.init.Normal(sigma=1))\n", 116 | " # SGD训练, 使用权重衰减代替L2正则化\n", 117 | " trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': learning_rate, 'wd': weight_decay})\n", 118 | " # 训练损失\n", 119 | " train_loss = []\n", 120 | " # 测试损失\n", 121 | " test_loss = []\n", 122 | " for epoch in range(epochs):\n", 123 | " for data, label in data_iter:\n", 124 | " # 记录梯度\n", 125 | " with autograd.record():\n", 126 | " # 计算预测值\n", 127 | " output = net(data)\n", 128 | " # 计算损失\n", 129 | " loss = square_loss(output, label)\n", 130 | " # 反向传播\n", 131 | " loss.backward()\n", 132 | " # 更新权重\n", 133 | " trainer.step(batch_size)\n", 134 | " # 训练损失\n", 135 | " train_loss.append(test(net, X_train, y_train))\n", 136 | " # 测试损失\n", 137 | " test_loss.append(test(net, X_test, y_test))\n", 138 | " # 绘制图像\n", 139 | " plt.plot(train_loss)\n", 140 | " plt.plot(test_loss)\n", 141 | " plt.legend(['train','test'])\n", 142 | " plt.show()\n", 143 | " return ('learned w[:10]:', net[0].weight.data()[:,:10], '\\nlearned b:', net[0].bias.data())" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "## 训练模型并观察过拟合" 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 3, 156 | "metadata": { 157 | "ExecuteTime": { 158 | "end_time": "2018-03-09T17:58:24.118988Z", 159 | "start_time": "2018-03-09T17:58:23.608613Z" 160 | }, 161 | "collapsed": false 162 | }, 163 | "outputs": [ 164 | { 165 | "data": { 166 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhIAAAFkCAYAAAB1rtL+AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzt3Xl8VPW9//HXZ7KRBBKRHQUBEaQiYEJBpagVBakKKFdr\nLBXltuCC+ov24ULtLYtVa1uCuN9bvajUUJdWLLXgbq3rlUDViiwKomwVkCRACCT5/v44M5iEJGQm\nMzkzyfv5eMxjMud8c85nPIa88znfc8acc4iIiIhEIuB3ASIiIpK4FCREREQkYgoSIiIiEjEFCRER\nEYmYgoSIiIhETEFCREREIqYgISIiIhFTkBAREZGIKUiIiIhIxBQkREREJGJhBwkzG2lmz5vZJjOr\nMrNxdYwZYGaLzWyXme02s/fM7Ohq69PM7H4z225mpWb2jJl1buqbERERkeYVSUciE1gJXA0c8kEd\nZnYs8CbwCXAacCIwB9hXbdg84FxgYnBMd+DZCGoRERERH1lTPrTLzKqACc6556stKwT2O+cm1/M9\nWcDXwCXOuT8Hl/UHVgEnO+fej7ggERERaVZRnSNhZobXaVhrZkvNbJuZvWtm46sNywWSgVdCC5xz\nq4GNwCnRrEdERERiKznK2+sMtAVuBn4O3ASMBf5kZmc4594EuuJ1LEpqfe+24LpDmFkHYAywgZqn\nSERERKRhbYBewDLn3I5obzzaQSLU4XjOOTc/+PWHZnYqcCXe3IlIjAH+0NTiREREWrEfAU9Ge6PR\nDhLbgQq8+Q7VrQJGBL/eCqSaWVatrkSX4Lq6bABYuHAhAwYMiF614pv8/HwKCgr8LkOiSMe0ZdHx\nbDlWrVrFpEmTIPi7NNqiGiSccwfM7P+A/rVW9QO+CH69HC9sjAKqT7bsCbxTz6b3AQwYMICcnJxo\nliw+yc7O1rFsYXRMWxYdzxYpJlMDwg4SZpYJ9AUsuKiPmQ0GdjrnvgR+AywyszeB1/DmSJwHnA7g\nnCsxs0eAuWb2DVAKzAfe0hUbIiIiiSWSjsRQvIDggo/fBZc/Bkxxzj1nZlcCM4B7gNXAhc656t2G\nfKASeAZIA5YC10T0DkRERMQ3YQcJ59wbHOayUefcAmBBA+vLgWuDDxEREUlQCfVZGxUVflcg0ZKX\nl+d3CRJlOqYti46nNFZCBYlt2/yuQKJF/0i1PDqmLYuOpzRWtC//jKlNm/yuQEREQjZu3Mj27dv9\nLkOAjh070rNnT1/2rSAhIiJh27hxIwMGDGDv3r1+lyJARkYGq1at8iVMJFSQ2LzZ7wpERARg+/bt\n7N27VzcKjAOhG05t375dQeJwvvrK7wpERKQ63ShQEmqypU5tiIiIxBcFCREREYlYQgWJXbtg926/\nqxAREZGQhAoSAOvX+12BiIiIhCRckPj8c78rEBERiVyvXr2YMmWK32VETUIFibQ0BQkREYm9d955\nh1mzZlFSUhL1bQcCAczs8AMTREJd/tm9u05tiIhI7L399tvMnj2bK664gqysrKhue/Xq1QQCCfV3\nfIMS6p0cdZQ6EiIiEnvOuUaPKy8vD2vbKSkpJCUlRVJWXEq4IKGOhIiIxNKsWbO46aabAG8+QyAQ\nICkpiS+++IJAIMB1113Hk08+ycCBA2nTpg3Lli0D4Le//S0jRoygY8eOZGRkMHToUJ599tlDtl97\njsRjjz1GIBDg7bff5oYbbqBz5860bduWCy+8kB07djTPm26ChDq1cdRRsHgxOAct6PSSiIjEkYkT\nJ7JmzRoWLVrEPffcQ4cOHTAzOnXqBMArr7zCU089xfTp0+nYsSO9evUCYP78+YwfP55Jkyaxf/9+\nFi1axMUXX8ySJUsYO3bswe3XNz/i2muv5cgjj2TmzJls2LCBgoICpk+fTmFhYczfc1MkXJDYt887\nvXHssX5XIyIiLdHAgQPJyclh0aJFjB8//pDPr1izZg0ff/wx/fv3r7F87dq1pKWlHXw9ffp0Tjrp\nJObOnVsjSNSnU6dOLF269ODryspK7r33XkpLS2nXrl0T31XsJFSQOP54yMiAAQNg7Fi48074znf8\nrkpERA5n71749NPY7iP0OyLWzjjjjENCBFAjROzatYuKigpGjhzJokWLDrtNM2Pq1Kk1lo0cOZJ5\n8+bxxRdfMHDgwKYXHiMJFSS6doXPPoM//hF+8Qt47DH49a/9rkpERA7n008hNze2+1i+HJrj88NC\npzJqW7JkCb/61a9YuXJljQmYjb1Co0ePHjVet2/fHoBvvvkmskKbSUIFCfDCxPXXw+9/D2Vlflcj\nIiKNcfzx3i/6WO+jOaSnpx+y7M0332T8+PGcccYZPPjgg3Tr1o2UlBQeffTRRs9xqO9KjsZeQeKX\nhAsSIenpChIiIokiI6N5ugXREu4No/70pz+Rnp7OsmXLSE7+9lfrI488Eu3S4k5CXf5ZnYKEiIjE\nSmZmJuDNdWiMpKQkzIyKioqDyzZs2MDixYtjUl88SeggsW+f31WIiEhLlJubi3OOGTNmsHDhQv74\nxz+yd+/eesefe+657NmzhzFjxvDwww8ze/ZsTj75ZI477rhG7a++0xfxfloDdGpDRETkEEOHDuX2\n22/noYceYtmyZTjn+OyzzzCzOk97fP/73+fRRx/lrrvuIj8/n969e3P33Xezfv16Pvzwwxpj69pG\nfadSEuEzOSwR0o6Z5QDLly9fTk7wJNull8LWrfDqq/7WJiLSGhUVFZGbm0v1f5fFH4c7FqH1QK5z\nrija+0/YUxtt2qgjISIi4reEDRI6tSEiIuK/hA4SmmwpIiLir7CDhJmNNLPnzWyTmVWZ2bgGxj4U\nHHNdreVpZna/mW03s1Ize8bMOodThzoSIiIi/oukI5EJrASuBuqdqWlmFwDDgU11rJ4HnAtMBE4D\nugOHftZqAxQkRERE/Bf25Z/OuaXAUgCr57oUMzsKuAcYA7xQa10WMAW4xDn3RnDZFcAqMxvmnHu/\nMXUoSIiIiPgv6nMkguHiceBu59yqOobk4gWYV0ILnHOrgY3AKY3dj67aEBER8V8sJlveAux3zt1X\nz/quwfUltZZvC65rlPR0qKyEAwcirFJERESaLKp3tjSzXOA64KRobjckPz+f7OxsADZv9pY98UQe\nU6bkxWJ3IiIiCaWwsPCQTxstLi6O6T6jfYvs7wGdgC+rTZ9IAuaa2f9zzvUBtgKpZpZVqyvRJbiu\nXgUFBQfv2vX88zB+PJx3XpTfgYiISILKy8sjL6/mH9fV7mwZE9E+tfE4MAgYXO2xGbgbb+IlwHKg\nAhgV+iYz6w/0BN5p7I5CHweveRIiIiL+CbsjYWaZQF8g1HLoY2aDgZ3OuS+Bb2qNPwBsdc6tBXDO\nlZjZI3hdim+AUmA+8FZjr9gAb7IlKEiIiIj4KZKOxFBgBV5nwQG/A4qAWfWMr+teE/nAEuAZ4HW8\nrsXEcIpQR0JERGLlnXfeYdasWZSU1L4uIHruvPNOFi9eHLPtN5ewg4Rz7g3nXMA5l1TrMaWe8X2c\nc/NrLSt3zl3rnOvonGvnnLvIOffvcOpQkBARkVh5++23mT17Nrt27YrZPu64447WGSTiRShI6PM2\nREQk2pyr98bNUkvCBwl1JEREJJpmzZrFTTfdBECvXr0IBAIkJSWxceNGABYuXMjQoUPJyMigQ4cO\n5OXl8dVXX9XYxrp165g4cSLdunUjPT2dHj16kJeXR2lpKQCBQIC9e/eyYMECAoEAgUCAKVPqbOzH\nvWhf/tlsFCRERCQWJk6cyJo1a1i0aBH33HMPHTp0AKBTp0786le/4r/+67+45JJL+OlPf8rXX3/N\n/PnzOf3001mxYgVZWVkcOHCA0aNHc+DAAa677jq6du3Kpk2bWLJkCbt27aJdu3YsXLiQ//zP/2T4\n8OFMnToVgGOPPdbPtx2xhA0SumpDRERiYeDAgeTk5LBo0SLGjx9Pz549Adi4cSMzZ87kjjvu4Oab\nbz44/sILL2TIkCE88MAD3HLLLXzyySds2LCBZ599lgsuuODguNtuu+3g15deeinTpk2jT58+XHrp\npc335mIgYYNEWhqYKUiIiCSCvQf28un2T2O6j+M7Hk9GSkbMtv/ss8/inOOiiy5ix44dB5d37tyZ\n4447jtdee41bbrnl4B2Yly5dyjnnnEN6qIXeQiVskDDzuhKabCkiEv8+3f4puf8du7srAiyfupyc\nbjkx2/66deuoqqqib9++h6wzM1JTUwFvXsWNN97I3LlzWbhwISNHjmTcuHFMmjSJrKysmNXnl4QN\nEqCPEhcRSRTHdzye5VOXx3wfsVRVVUUgEGDp0qUEAodeq9C2bduDX//mN7/h8ssvZ/Hixbz44otc\nd9113HXXXbz77rt07949pnU2NwUJERGJuYyUjJh2C6Kt2udFHXTsscfinKNXr151diVqO+GEEzjh\nhBOYMWMG7777LqeeeioPPfQQs2fPrncfiShhL/8E79SGgoSIiERbZmYmQI0bUl144YUEAgFmzar7\nRs47d+4EoLS0lMrKyhrrTjjhBAKBAOXl5TX2EcsbXjUXdSRERERqyc3NxTnHjBkzuOSSS0hJSeH8\n88/n9ttvZ8aMGaxfv54JEybQrl07Pv/8c5577jmmTZvGDTfcwKuvvsr06dO56KKL6NevHxUVFTz+\n+OMkJyczceLEGvt4+eWXKSgooHv37vTu3Zthw4b5+K4joyAhIiJSy9ChQ7n99tt56KGHWLZsGVVV\nVaxfv56bb76Z/v37U1BQcPAURY8ePTjnnHMYN24cAIMHD+acc85hyZIlbNq0iYyMDAYPHszSpUtr\nBIW5c+cybdo0fvGLX1BWVsbkyZMVJJpberqu2hARkdiYMWMGM2bMOGT5hAkTmDBhQr3f16tXL/7n\nf/7nsNvv168fr732WpNqjAcJPUdCHQkRERF/KUiIiIhIxBI6SOiqDREREX8ldJBQR0JERMRfChIi\nIiISsYQPErpqQ0RExD8JHyTUkRAREfGPgoSIiIhELKFvSKWrNkRE/LVq1Sq/S2j1/D4GCR0k1JEQ\nEfFHx44dycjIYNKkSX6XIkBGRgYdO3b0Zd8JHyQqK6GiApIT+p2IiCSWnj17smrVKrZv3+53KYIX\n7Hr27OnLvhP61296uvdcVgbt2vlbi4hIa9OzZ0/ffnlJ/Ej4yZag0xsiIiJ+Segg0aaN96wgISIi\n4o+EDhLqSIiIiPhLQUJEREQiFnaQMLORZva8mW0ysyozG1dtXbKZ/drMPjSz3cExj5lZt1rbSDOz\n+81su5mVmtkzZtY53FpCQUK3yRYREfFHJB2JTGAlcDXgaq3LAIYAs4CTgAuA/sDiWuPmAecCE4HT\ngO7As+EWoo6EiIiIv8K+/NM5txRYCmBmVmtdCTCm+jIzmw68Z2ZHO+e+MrMsYApwiXPujeCYK4BV\nZjbMOfd+Y2tRkBAREfFXc8yROAKvc7Er+DoXL8C8EhrgnFsNbAROCWfDumpDRETEXzENEmaWBtwF\nPOmc2x1c3BXYH+xeVLctuK7R1JEQERHxV8zubGlmycDTeN2Iq6Oxzfz8fLKzs2stzaOsLC8amxcR\nEUlohYWFFBYW1lhWXFwc033GJEhUCxE9gDOrdSMAtgKpZpZVqyvRJbiuXgUFBeTk5NRYlpGhqzZE\nREQA8vLyyMur+cd1UVERubm5Mdtn1E9tVAsRfYBRzrlvag1ZDlQAo6p9T3+gJ/BOuPvTJ4CKiIj4\nJ+yOhJllAn2B0BUbfcxsMLAT2IJ3GecQ4Dwgxcy6BMftdM4dcM6VmNkjwFwz+wYoBeYDb4VzxUZI\nmzYKEiIiIn6J5NTGUOA1vLkPDvhdcPljePePOD+4fGVwuQVffx/4e3BZPlAJPAOk4V1Oek0Etagj\nISIi4qNI7iPxBg2fEjns6RLnXDlwbfDRJAoSIiIi/knoz9oAL0hosqWIiIg/WkSQUEdCRETEHwoS\nIiIiErGEDxK6akNERMQ/CR8k1JEQERHxj4KEiIiIRKxFBAldtSEiIuKPhA8SGRmwZ4/fVYiIiLRO\nCR8kOnSAHTv8rkJERKR1Svgg0bkz7NwJBw74XYmIiEjrk/BBolMn71ldCRERkeaX8EGic2fv+d//\n9rcOERGR1khBQkRERCKmICEiIiIRS/ggkZnpXQKqICEiItL8Ej5IgNeVUJAQERFpfi0iSHTqBF9/\n7XcVIiIirU+LCBLqSIiIiPhDQUJEREQipiAhIiIiEVOQEBERkYi1mCCxezeUlfldiYiISOvSIoJE\n6PM2dOWGiIhI82oRQUJ3txQREfGHgoSIiIhErEUEidCpDQUJERGR5tUigkRqKhxxhIKEiIhIcws7\nSJjZSDN73sw2mVmVmY2rY8xsM9tsZnvN7CUz61trfZqZ3W9m282s1MyeMbPOTXkjnTtrsqWIiEhz\ni6QjkQmsBK4GXO2VZnYzMB2YCgwD9gDLzCy12rB5wLnAROA0oDvwbAS1HNSpkzoSIiIizS053G9w\nzi0FlgKYmdUx5HpgjnNuSXDMZcA2YALwlJllAVOAS5xzbwTHXAGsMrNhzrn3I3kjuimViIhI84vq\nHAkz6w10BV4JLXPOlQDvAacEFw3FCzDVx6wGNlYbEzYFCRERkeYX7cmWXfFOd2yrtXxbcB1AF2B/\nMGDUNyZsChIiIiLNr0VctQHfBgl3yKwNERERiZWw50gcxlbA8LoO1bsSXYAV1cakmllWra5El+C6\neuXn55OdnV1jWV5eHnl5eXTuDPv3Q2kpZGU19W2IiIgknsLCQgoLC2ssKy4ujuk+oxoknHPrzWwr\nMAr4ECA4uXI4cH9w2HKgIjjmz8Ex/YGewDsNbb+goICcnJw614Xubvn00zBlCtQ5DVRERKQFC/1x\nXV1RURG5ubkx22ck95HINLPBZjYkuKhP8HWP4Ot5wG1mdr6ZnQg8DnwFLIaDky8fAeaa2Rlmlgs8\nCrwV6RUbAKecAuPGwU9+AsOHwyefRLolERERaaxI5kgMxTtNsRxvYuXvgCJgFoBz7m7gXuBhvKs1\n0oGxzrn91baRDywBngFeBzbj3VMiYmlpsHgxvP467NoFP/4xVFY2ZYsiIiJyOGEHCefcG865gHMu\nqdZjSrUxM51z3Z1zGc65Mc65dbW2Ue6cu9Y519E51845d5FzLirXXJx+Ojz2GBQVwSOPRGOLIiIi\nUp8Wc9VGdaecApddBjNmwM6dflcjIiLScrXIIAFw113eVRwzZ/pdiYiISMvVYoNEt25w1VXw1FN+\nVyIiItJytdggATBsGGzbBlsbvDuFiIiIRKpFB4khwQtU//lPf+sQERFpqVp0kOjdG9q1g5Ur/a5E\nRESkZWrRQSIQgEGD1JEQERGJlRYdJMA7vaGOhIiISGy0+CAxeDCsXg1lZX5XIiIi0vK0+CAxZAhU\nVcHHH/tdiYiISMvT4oPEwIHeXAnNkxAREYm+Fh8k0tOhf3/NkxAREYmFFh8kwDu9oY6EiIhI9LWK\nIDF4sBckXn0VHnwQ1q71uyIREZGWIdnvAppDbi6UlsKoUd7rzEy47z6YPBnM/K1NREQkkbWKjsSZ\nZ8JLL8GqVbBrF1x8MVxxBdx4o9+ViYiIJLZW0ZEIBOCss759/eij0KsXzJkDt94KnTr5VpqIiEhC\naxUdibpcfbV3WuPJJ/2uREREJHG12iDRsSOcfz4sWOB3JSIiIomr1QYJ8CZbrlypS0NFREQi1aqD\nxNix3vyIxx7zuxIREZHE1KqDREoKTJoECxfCgQN+VyMiIpJ4WnWQADjnHPj6a/jyS78rERERSTyt\nPkhkZHjP5eX+1iEiIpKIWn2QSEvznvfv97cOERGRRNTqg0RqqvesjoSIiEj4Wn2QUEdCREQkcq0+\nSKgjISIiErmoBwkzC5jZHDP73Mz2mtk6M7utjnGzzWxzcMxLZtY32rU0hjoSIiIikYtFR+IWYBpw\nNXA8cBNwk5lNDw0ws5uB6cBUYBiwB1hmZqkxqKdB6kiIiIhELhaf/nkKsNg5tzT4eqOZXYoXGEKu\nB+Y455YAmNllwDZgAvBUDGqqlzoSIiIikYtFR+JtYJSZHQdgZoOBEcALwde9ga7AK6FvcM6VAO/h\nhZBmpY6EiIhI5GLRkbgLyAI+NbNKvLDyc+fcouD6roDD60BUty24rlmFgoQ6EiIiIuGLRZD4IXAp\ncAnwCTAEuMfMNjvnnmjKhvPz88nOzq6xLC8vj4kXT+T51c/z+obXmTRoEicffXKjtxkIQHKyOhIi\nIpL4CgsLKSwsrLGsuLg4pvuMRZC4G7jTOfd08PW/zKwXcCvwBLAVMKALNbsSXYAVDW24oKCAnJyc\nGsteWPsCR889mq/3fk2njE7c/3/3c16/87h37L30OqJXowpOS1NHQkREEl9eXh55eXk1lhUVFZGb\nmxuzfcZijkQGUFlrWVVoX8659XhhYlRopZllAcPx5lc0mnOOW16+heM6HMdHV33Elhu38OSFT7Ji\nywomPzcZ51yjtpOaqo6EiIhIJGLRkfgLcJuZfQX8C8gB8oHfVxszLzhmHbABmAN8BSwOZ0fvfPUO\nH/37I5ZNWsbAzgMByDsxjw4ZHRizcAzPfPIMF51w0WG3o46EiIhIZGLRkZgOPAPcjzdH4m7gQeC/\nQgOcc3cD9wIP412tkQ6Mdc6F9ev8oQ8eok/7PpzV56way0cfO5px/cfxs5d+RtmBsjq/d/f+3ews\n2wmoIyEiIhKpqAcJ59we59wNzrnezrlM59xxzrlfOucqao2b6Zzr7pzLcM6Ncc6tC2c/O/bu4Kl/\nPcW03GkE7NC38bvRv2NL6RZufPFGVm9fjXOO0vJSVmxZwfV/u57uv+vOgPsHsHbHWnUkREREIhSL\nUxvNYsHKBTgcVwy5os71fY/sy8wzZvLzV3/Ogx88SGpSKvsrvbTQMaMj04dN58+f/pnRC0eTmvUW\n5eXdm7N8ERGRFiHhgoRzjkUfL+LOf9zJxAET6ZTZqd6xM0bO4OrvXs37m97nk68/oXNmZ3pm92Ro\n96G0SW7DlUOvZMSjI9h6+mj+Xf5n4LjmeyMiIiItQEIFiXe/fJcbP7qR1ze8zsQBEykYU3DY7zmi\nzRGMPnY0o48dfci6ntk9eXHSi5z02/N4uu0gct6aTf4p+SQHEuo/i4iIiG8S6mPEr3nhGnaW7WTp\nj5byzMXP0KVtlyZvc0CnAXz3/z7kuOKruPnlmznxwRN59pNnG33pqIiISGuWUEHi9+N+z8ppKxnT\nd0xUt5uenMnATXP5YOoHHJN9DP/x9H/wH0//h8KEiIjIYSRUkDip20mYWdS3G7pqI6dbDksnLeWJ\nC57gT6v+xF/W/CXq+xIREWlJEipIxEpqas3LP3904o8Yfexoblh2A+UVusGEiIhIfRQk8DoS1W9I\nZWYUjClgw64NzHt3nn+FiYiIxDkFCQ7tSAB8p9N3mD5sOnP+PocH/+9BKqoq6v5mERGRVkxBgkM7\nEiFzvj+HCwdcyDUvXMPABwZStKWo+YsTERGJYwoS1N2RAGiX1o7HL3ic5VOXk5GSwQ/+8AO+2PVF\n8xcoIiISpxQkqL8jEXJSt5NYOmkpGSkZnPvkuRTvK26+4kREROKYggT1dySq65zZmb9e+lc2lW7i\npIdP4toXruX1Da83S30iIiLxSkGCw3ckQgZ0GsCrl73K2X3O5q9r/8qZj53Jup1hfWipiIhIi6Ig\nQeM6EiEndTuJh89/mI+u+oi05DQWf7o4tsWJiIjEMQUJGt+RqC4zNZOz+5zN4tUKEiIi0nopSBBe\nR6K68f3H89aXb7F97/boFyUiIpIAFCTwgkR5OYT7GV3n9TsP5xxL1iyJaL/OOfZV7GP73u1UuaqI\ntiEiIuKnZL8LiAdpad5zRQWkpDT++7q07cLJR5/M4tWLuXzI5Q2OXbNjDX9b+zdeWf8KRVuKKN1f\nyu79uw8GiDN6ncGySctITUqN8F2IiIg0PwUJvI4EeF2JcIIEeKc3Zv99Nu9vep+HP3iYL4q/oE/7\nPvTI6kFSIImyA2X8de1fWbF1BalJqYzoMYLJgyfTPr09bVPbkpmSSVlFGdNfmM7PXvwZ88fOj/4b\nFBERiREFCb7tSEQyT2Jc/3Hc8sotDP/9cHpk9eC7R32XDzZ/cHASZsACfK/n9/j5yJ8z9rixZKRk\n1LmdiqoKrnnhGgZ1GcT5/c6nXVq7eseKiIjECwUJanYkwnV8x+O548w76N2+NxMHTCQlKcyWRtBV\nQ6/ivU3v8dO//PTgsrP6nMU1372GET1GUF5ZTmVVJekp6bRNbauQISIicUFBgqZ1JMyMW0fe2uQa\nzIxHxj3ClCFTKC4vZkvpFhb8cwEX/PGCOsef3edsrhp6Fcd1OI61O9byZcmXlJSXsHv/btKS0shM\nzeTUHqcyoscIzKzJ9YmIiNRFQYKmdSSiKTmQzOm9Tj/4etrQaazcupINuzaQlpR2cM7Flt1bWLBy\nARc+deHBsW2S25Cdlk1maib7K/dTUl5CSXkJJx99MlcMuYLstGxSk1JJTUolJSmFTSWb+NfX/2LP\n/j0MP3o4Od1y2LZ7G2t2rGFn2U72VeyjrKLs4HPZAe/rDukd6NO+D0dnHU1WWhbt0toRMO/in7ID\nZZSUl7CvYt/BukIhZs/+Pezat4s9B/ZQ5aoIWIAeWT3o3b437du0Jy05jTbJbUhLSiM1KRWHwzlH\nlauiylXh8L52wUtrzAzDCFiAPQf2sG33Nnbt21VjeWMe1bdV/evQ/qvXEfo6YIGD/x1TAimkJKUc\n/H4Ax7eX/xhGu7R2B99jbdW/r/Z/Mz+4cC9daur+aL79teT3Bs37/vTeEkdyIPa/5hUkaFpHItaG\ndB3CkK5DDll+5dAr+XDbhxTvK6Zfh350zuxc4xdQlavib2v/xt1v3820JdPq3HbvI3rTJrkNDy1/\n6OCylEAKR6YfSXpKOunJ6bRJbkOb5Dakp3hff/z1xzy/5vmw752REkihfXp7MlMySQokcaDyAJtK\nN1FRVRHWdkREpPFuOPkGftTpRzHdh4IE8dORCNegLoPqXRewAOf2O5dz+53L/sr9NR7lFeV0zOhI\nZmomAN++LLNWAAASoklEQVSUfcPH//6Y7u26c8wRxzQqwe6v3E9peSml+0sP/uWekZJBu9R2tElu\nc3Bc6K/45EDyIX9pV1RVsKlkEyXlJZRXlrOvYh/7Kvaxv3J/ja6CWbWva3ULwOvGdMnswpHpRwLU\n6GCEHpVVlTgclVWV3mtXWaPjUL1Wh8OwGt2N0NdmRpWr4kDlAQ5UHTj4XJ8qV0VpeSm79u1if+W3\nSbX6Xz21/9qqva65OxR1dUliur9mfH8t+b1B874/vbfEcHzH42FLbPehIEF8dySiIXRKoz7t09sz\n8piRYW+zQ0YHOmR0iLiu5EAyxxxxTMTfLyIih1e0pSim29edLUncjoSIiIjfYhIkzKy7mT1hZtvN\nbK+Z/dPMcmqNmW1mm4PrXzKzvrGopTFaekdCREQkVqIeJMzsCOAtoBwYAwwAbgS+qTbmZmA6MBUY\nBuwBlpmZL/eHVkdCREQkMrGYI3ELsNE595Nqy76oNeZ6YI5zbgmAmV0GbAMmAE/FoKYGqSMhIiIS\nmVic2jgf+MDMnjKzbWZWZGYHQ4WZ9Qa6Aq+EljnnSoD3gFNiUM9hqSMhIiISmVgEiT7AVcBqYDTw\nIDDfzH4cXN8VcHgdiOq2Bdc1O3UkREREIhOLUxsB4H3n3C+Cr/9pZgOBK4EnmrLh/Px8srOzayzL\ny8sjLy+vKZslKQnM1JEQEZHEVlhYSGFhYY1lxcXFMd1nLILEFmBVrWWrgND9nLcCBnShZleiC7Ci\noQ0XFBSQk5PT0JCImHldCXUkREQkkdX1x3VRURG5ubkx22csTm28BfSvtaw/wQmXzrn1eGFiVGil\nmWUBw4G3Y1BPo6SmqiMhIiISrlh0JAqAt8zsVrwrMIYDPwF+Wm3MPOA2M1sHbADmAF8Bi2NQT6Oo\nIyEiIhK+qAcJ59wHZnYBcBfwC2A9cL1zblG1MXebWQbwMHAE8CYw1jnn269ydSRERETCF5PP2nDO\nvQC8cJgxM4GZsdh/JNSREBERCZ8+ayNIHQkREZHwKUgEqSMhIiISPgWJIHUkREREwqcgEaSOhIiI\nSPgUJILUkRAREQmfgkSQOhIiIiLhU5AIUkdCREQkfAoSQepIiIiIhE9BIkgdCRERkfApSASpIyEi\nIhI+BYkgdSRERETCpyARpI6EiIhI+BQkgtSREBERCZ+CRJA6EiIiIuFTkAhSR0JERCR8ChJB6kiI\niIiET0EiSB0JERGR8ClIBKkjISIiEj4FiaDUVKis9B4iIiLSOAoSQWlp3rO6EiIiIo2nIBGUmuo9\na56EiIhI4ylIBKkjISIiEj4FiSB1JERERMKnIBGkjoSIiEj4FCSC1JEQEREJn4JEkDoSIiIi4VOQ\nCFJHQkREJHwKEkHqSIiIiIQv5kHCzG4xsyozm1tr+Wwz22xme83sJTPrG+taGqKOhIiISPhiGiTM\n7LvAVOCftZbfDEwPrhsG7AGWmVlqLOtpiDoSIiIi4YtZkDCztsBC4CfArlqrrwfmOOeWOOc+Bi4D\nugMTYlXP4agjISIiEr5YdiTuB/7inHu1+kIz6w10BV4JLXPOlQDvAafEsJ4GqSMhIiISvuRYbNTM\nLgGGAEPrWN0VcMC2Wsu3Bdf5Qh0JERGR8EU9SJjZ0cA84Czn3IFobjs/P5/s7Oway/Ly8sjLy2vy\ntkNBQh0JERFJVIWFhRQWFtZYVlxcHNN9xqIjkQt0AorMzILLkoDTzGw6cDxgQBdqdiW6ACsa2nBB\nQQE5OTnRrxgwg5QUdSRERCRx1fXHdVFREbm5uTHbZyzmSLwMnIh3amNw8PEB3sTLwc65z4GtwKjQ\nN5hZFjAceDsG9TRaWhpsq33CRUREROoV9Y6Ec24P8En1ZWa2B9jhnFsVXDQPuM3M1gEbgDnAV8Di\naNcTjrw8uOsu+P73vYeIiIg0LCaTLevgarxw7m4zywAeBo4A3gTGOud8naFw332wYQNMmAD/+Aec\neKKf1YiIiMS/ZrlFtnPuTOfcDbWWzXTOdXfOZTjnxjjn1jVHLQ1JTYVnnoFevWDKFL+rERERiX/6\nrI1asrLg1lvhgw9g40a/qxEREYlvChJ1GDvWu4Jjsa8zNkREROKfgkQdsrPhzDMVJERERA5HQaIe\n48fD66/DN9/4XYmIiEj8UpCox7hxUFkJf/2r35WIiIjELwWJehx1FAwbBs8953clIiIi8UtBogHj\nx8PSpbBvn9+ViIiIxCcFiQaccw7s2eNdCioiIiKHUpBowKBBkJkJb73ldyUiIiLxSUGiAcnJcPLJ\n8LavHyUmIiISvxQkDuPUU70g4dzhx4qIiLQ2ChKHMWIEbN8Oa9f6XYmIiEj8UZA4jJNPBjOd3hAR\nEamLgsRhZGfDwIGacCkiIlIXBYlGCM2TEBERkZoUJBrh1FPhk0/0uRsiIiK1KUg0wogR3vM77/hb\nh4iISLxRkGiEPn3gmGPg6af9rkRERCS+KEg0ghlceSUUFnqXgoqIiIhHQaKRfvIT7/mRR/ytQ0RE\nJJ4oSDRSx46QlwcPPACVlX5XIyIiEh8UJMIwfTps3AhLlvhdiYiISHxQkAhDbq53p8uHH/a7EhER\nkfigIBGmiy6C116Dffv8rkRERMR/ChJhOussL0ToTpciIiIKEmEbOBA6d4aXX/a7EhEREf8pSIQp\nEIBRoxQkREREIAZBwsxuNbP3zazEzLaZ2Z/NrF8d42ab2WYz22tmL5lZ32jXEitnnw0ffKDP3hAR\nEYlFR2IkcC8wHDgLSAFeNLP00AAzuxmYDkwFhgF7gGVmlhqDeqJu1ChwDl591e9KRERE/BX1IOGc\n+4Fz7gnn3Crn3EfA5UBPILfasOuBOc65Jc65j4HLgO7AhGjXEws9e0K/fjq9ISIi0hxzJI4AHLAT\nwMx6A12BV0IDnHMlwHvAKc1QT1ScdZaChIiISEyDhJkZMA/4h3Puk+DirnjBYlut4duC6xLCGWfA\nunXw9dd+VyIiIuKfWHckHgC+A1wS4/00u549vectW/ytQ0RExE/Jsdqwmd0H/AAY6Zyr/ut2K2BA\nF2p2JboAKxraZn5+PtnZ2TWW5eXlkZeXF5Waw9E12DvZuhUGDWr23YuIiByisLCQwsLCGsuKi4tj\nuk9zzkV/o16IGA+c7pz7vI71m4HfOOcKgq+z8ELFZc65p+sYnwMsX758OTk5OVGvNxLl5dCmDSxY\nAJMn+12NiIhI3YqKisjNzQXIdc4VRXv7Ue9ImNkDQB4wDthjZl2Cq4qdc6FPqJgH3GZm64ANwBzg\nK2BxtOuJlbQ0aN/e60iIiIi0VrE4tXEl3mTK12stvwJ4HMA5d7eZZQAP413V8SYw1jm3Pwb1xEy3\nbpojISIirVvUg4RzrlETOJ1zM4GZ0d5/c+raVR0JERFp3fRZG02gICEiIq2dgkQT6NSGiIi0dgoS\nTaCOhIiItHYKEk3QtSuUlMDevX5XIiIi4g8FiSbo1s17VldCRERaKwWJJqh+d0sREZHWSEGiCUId\nCU24FBGR1kpBognat4eUFHUkRESk9VKQaAIz7/SGOhIiItJaKUg0Ubdu6kiIiEjrpSDRRLqXhIiI\ntGYKEk2ku1uKiEhrpiDRROpIiIhIa6Yg0URdu8K2bVBZ6XclIiIizU9Boom6dfNCxI4dflciIiLS\n/BQkmkh3txQRkdZMQaKJQkFCEy5FRKQ1UpBoolCQWLHC3zpERET8oCDRRGlpMG0a3HYbLF7sdzUi\nIiLNK9nvAlqC+++H7dvhhz+EO++EI4+EQACSkiA5GU477dvOhYiISEuiIBEFSUnwhz/AxRfDDTfU\nvX7sWLj6ajjnHO8zOkRERFoCndqIkrQ079RGRQXs3w/79sHevd49Ju67z7uq4wc/gO99D55/HoqK\nYO1aqKryu3IREZHIKUhEWVKS99HiaWmQng6dO8OVV8L778PSpVBeDuPHQ24u9OsH3bt7cyz+9S+/\nKxcREQmfTm00EzMYMwZGj4bPPoOSEu8mVi++CIsWwcsvw6efeiFEREQkUShINDMz6Nv329dnnw0/\n/jEMGQL/+78wdap/tYmIiIRLpzbiwKBB3hUfc+Z4cytEREQShYJEnJg1y7s75kMP+V2JiIhI4ylI\nxIl+/eDyy+FnP4NOnaBnT5g8GV54Afbs8bu66CssLPS7BIkyHdOWRcdTGsvXIGFm15jZejMrM7N3\nzey7ftbjt7lzoaDAuxfFJZd4V3qcey60bQtHHAE5OXD99fDcc7Bzp9/VNo3+kWp5dExbFh1PaSzf\nJlua2Q+B3wFTgfeBfGCZmfVzzm33qy4/ZWXBtdd++/rXv4aPPoIPP4TNm2HVKvjLX2D+fG/S5uDB\ncPzx0K4dZGSAczUfEybAWWf5935ERKTl8/OqjXzgYefc4wBmdiVwLjAFuNvHuuKGmTcRc9Cgmss3\nbIA33oDXXoONG2HdOigr88aHHnv2wIMPwgMPePepEBERiQVfgoSZpQC5wB2hZc45Z2YvA6f4UVMi\n6dXLe0yeXP+YykrIz/duhvXWW3D00d+GjEAA2rf35mH06OE9d+7sLRcREQmHXx2JjkASsK3W8m1A\n/zrGtwFYtWpVjMtqWSZP9m5w9dRTXrCoftqjuNi7y2ZIcrI3D+PII707cgYC3rKkJO8Reh26a2dq\nqveckvJtQIGaz/V9DfDhh8Vcf30RKSnetlJTvf1E+jkkh/u+htZHuu5wYrXPeP1v9PnnxcybVxS1\nmlrif6NIxGq7h/PFF8X893+Hdzwl/nTpArt3H/zd2SYW+zDnXCy22/BOzboBm4BTnHPvVVv+a+A0\n59wptcZfCvyheasUERFpUX7knHsy2hv1qyOxHagEutRa3gXYWsf4ZcCPgA2AbtkkIiLSeG2AXni/\nS6POl44EgJm9C7znnLs++NqAjcB859xvfClKREREwuLnVRtzgQVmtpxvL//MABb4WJOIiIiEwbcg\n4Zx7ysw6ArPxTmmsBMY45772qyYREREJj2+nNkRERCTx6c4BIiIiEjEFCREREYlYQgQJfbhXYjKz\nX5pZVa3HJ7XGzDazzWa218xeMrO+ftUrNZnZSDN73sw2BY/duDrGNHj8zCzNzO43s+1mVmpmz5hZ\n5+Z7FxJyuONpZv9bx8/rC7XG6HjGCTO71czeN7MSM9tmZn82s351jIv5z2jcB4lqH+71S+Ak4J94\nH+7V0dfCpLE+xptM2zX4+F5ohZndDEzH++C2YcAevGOb6kOdcqhMvEnQVwOHTKZq5PGbh/cZOhOB\n04DuwLOxLVvq0eDxDPobNX9e82qt1/GMHyOBe4HhwFlACvCimaWHBjTbz6hzLq4fwLvAPdVeG/AV\ncJPftelx2GP3S6CogfWbgfxqr7OAMuBiv2vX45BjVQWMC+f4BV+XAxdUG9M/uK1hfr+n1vyo53j+\nL/CnBr5HxzOOH3gfPVEFfK/asmb5GY3rjkS1D/d6JbTMee9UH+6VOI4LtlI/M7OFZtYDwMx64/3F\nU/3YlgDvoWMb9xp5/IbiXWJefcxqvBvP6RjHpzOCbfJPzewBMzuy2rpcdDzj2RF4naad0Lw/o3Ed\nJGj4w726Nn85EqZ3gcuBMcCVQG/g72aWiXf8HDq2iaoxx68LsD/4j1d9YyR+/A24DDgTuAk4HXgh\neNdh8I6ZjmccCh6jecA/nHOheWjN9jPq550tpYVzzlW/r/vHZvY+8AVwMfCpP1WJSF2cc09Ve/kv\nM/sI+Aw4A3jNl6KksR4AvgOM8GPn8d6RCPfDvSSOOeeKgTVAX7zjZ+jYJqrGHL+tQKqZZTUwRuKU\nc2493r/BoVn+Op5xyMzuA34AnOGc21JtVbP9jMZ1kHDOHQCWA6NCy4ItnFHA237VJZExs7Z4/yht\nDv4jtZWaxzYLbwayjm2ca+TxWw5U1BrTH+gJvNNsxUpEzOxooAMQ+uWk4xlngiFiPPB959zG6uua\n82c0EU5t6MO9EpSZ/Qb4C97pjKOAWcABYFFwyDzgNjNbh/cR8XPwrshZ3OzFyiGCc1n64v1VA9DH\nzAYDO51zX3KY4+ecKzGzR4C5ZvYNUArMB95yzr3frG9GGjyewccv8S772xoc92u8DuIy0PGMN2b2\nAN7lueOAPWYW6jwUO+f2Bb9unp9Rvy9ZaeRlLVcH/yOU4aWkoX7XpEejjlth8H/aMrxZwE8CvWuN\nmYl3idJevH+w+vpdtx4Hj83peJeBVdZ6PNrY4wek4V3rvj34j9TTQGe/31trfDR0PIE2wFK8ELEP\n+Bx4EOik4xmfj3qOZSVwWa1xMf8Z1Yd2iYiISMTieo6EiIiIxDcFCREREYmYgoSIiIhETEFCRERE\nIqYgISIiIhFTkBAREZGIKUiIiIhIxBQkREREJGIKEiIiIhIxBQkRERGJmIKEiIiIROz/A/aGOaOf\nr/aGAAAAAElFTkSuQmCC\n", 167 | "text/plain": [ 168 | "" 169 | ] 170 | }, 171 | "metadata": {}, 172 | "output_type": "display_data" 173 | }, 174 | { 175 | "data": { 176 | "text/plain": [ 177 | "('learned w[:10]:', \n", 178 | " [[ 1.04817235 -0.02568591 0.86764944 0.29322273 0.01006198 -0.56152564\n", 179 | " 0.38436413 -0.3084037 -2.32450151 0.03733355]]\n", 180 | " , '\\nlearned b:', \n", 181 | " [ 0.79914868]\n", 182 | " )" 183 | ] 184 | }, 185 | "execution_count": 3, 186 | "metadata": {}, 187 | "output_type": "execute_result" 188 | } 189 | ], 190 | "source": [ 191 | "train(0)" 192 | ] 193 | }, 194 | { 195 | "cell_type": "markdown", 196 | "metadata": {}, 197 | "source": [ 198 | "## 使用Gluon的正则化" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 4, 204 | "metadata": { 205 | "ExecuteTime": { 206 | "end_time": "2018-03-09T17:58:24.653507Z", 207 | "start_time": "2018-03-09T17:58:24.120722Z" 208 | }, 209 | "collapsed": false 210 | }, 211 | "outputs": [ 212 | { 213 | "data": { 214 | "image/png": "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\ng2aWEbQtD53PxqwlXk/TJojs72ijDhLU/HCvrMiXI3U0C/gpMAr4OdANeMfMmuGdP4fObbSqzflr\nB+wu/8OrujbSeLwGXAh8D7geGA68ageerJWFzmejVH6O7gbec85VzEOL2O+on3e2lBjnnAu+r/sX\nZjYbKAbOARb4U5WIHIpz7tmgt1+a2efA18AI4G1fipLaehDoBxznx8Ebe49EXR/uJY2Yc64EWAT0\nxDt/hs5ttKrN+VsLNDGz9BraSCPlnFuG92dwxSx/nc9GyMzuB04BRjjn1gRtitjvaKMOEs65PUAR\nMLJiXXkXzkjgA7/qkvoxszS8P5RWl/8htZbK5zYdbwayzm0jV8vzVwTsrdKmN9AZ+DBixUq9mFlH\nIBOo+MtJ57ORKQ8RY4ATnXMrgrdF8nc0GoY29HCvKGVmdwKv4A1ndAAmAnuAKeVN7gZuMrMleI+I\nvwXvipypES9WDlI+l6Un3r9qALqb2SBgk3PuGw5z/pxzW83sUeAuM9sMbAPuBd53zs2O6JeRGs9n\n+fJ7vMv+1pa3+xNeD+IM0PlsbMzsQbzLc0cD282souehxDm3q/znyPyO+n3JSi0va7mq/D/CTryU\nlO93TVpqdd4Ky/9HuxNvFvDTQLcqbW7Gu0RpB94fWD39rlvL/nMzHO8ysH1Vlsdqe/6AZLxr3TeU\n/yH1b6Ct398tHpeazieQAkzHCxG7gKXAQ0Abnc/GuVRzLvcBF1ZpF/bfUT20S0REROqtUc+REBER\nkcZNQUJERETqTUFCRERE6k1BQkREROpNQUJERETqTUFCRERE6k1BQkREROpNQUJERETqTUFCRERE\n6k1BQkREROpNQUJERETq7f8DeBel9sPT1IYAAAAASUVORK5CYII=\n", 215 | "text/plain": [ 216 | "" 217 | ] 218 | }, 219 | "metadata": {}, 220 | "output_type": "display_data" 221 | }, 222 | { 223 | "data": { 224 | "text/plain": [ 225 | "('learned w[:10]:', \n", 226 | " [[ 0.00107634 -0.00052574 0.00450234 -0.00110544 -0.00683913 -0.00181657\n", 227 | " -0.00530634 0.00512847 -0.00742552 -0.00058494]]\n", 228 | " , '\\nlearned b:', \n", 229 | " [ 0.00449433]\n", 230 | " )" 231 | ] 232 | }, 233 | "execution_count": 4, 234 | "metadata": {}, 235 | "output_type": "execute_result" 236 | } 237 | ], 238 | "source": [ 239 | "train(5)" 240 | ] 241 | }, 242 | { 243 | "cell_type": "markdown", 244 | "metadata": { 245 | "ExecuteTime": { 246 | "end_time": "2018-03-09T18:02:11.051312Z", 247 | "start_time": "2018-03-09T18:02:11.048104Z" 248 | } 249 | }, 250 | "source": [ 251 | "## 可用权重衰减代替L2正则化的原因 \n", 252 | "\n", 253 | "![推导](https://discuss.gluon.ai/uploads/default/optimized/2X/e/e95646511afc71bf614ba6abdb99bd056ee79ea9_1_690x438.png)\n", 254 | "\n", 255 | "注:图片来自Gluon社区。" 256 | ] 257 | } 258 | ], 259 | "metadata": { 260 | "kernelspec": { 261 | "display_name": "Python 2", 262 | "language": "python", 263 | "name": "python2" 264 | }, 265 | "language_info": { 266 | "codemirror_mode": { 267 | "name": "ipython", 268 | "version": 2 269 | }, 270 | "file_extension": ".py", 271 | "mimetype": "text/x-python", 272 | "name": "python", 273 | "nbconvert_exporter": "python", 274 | "pygments_lexer": "ipython2", 275 | "version": "2.7.13" 276 | } 277 | }, 278 | "nbformat": 4, 279 | "nbformat_minor": 2 280 | } 281 | -------------------------------------------------------------------------------- /regularization_from_scratch.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## 高维线性回归\n", 8 | "\n", 9 | "使用线性函数$y = 0.05 + \\sum_{i = 1}^p 0.01x_i + \\text{noise}$生成数据样本,噪音服从均值0和标准差为0.01的正态分布。" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": { 16 | "ExecuteTime": { 17 | "end_time": "2018-03-08T19:07:59.135941Z", 18 | "start_time": "2018-03-08T19:07:58.166912Z" 19 | }, 20 | "collapsed": true 21 | }, 22 | "outputs": [], 23 | "source": [ 24 | "# 导入mxnet\n", 25 | "import random\n", 26 | "import mxnet as mx\n", 27 | "\n", 28 | "# 设置随机种子\n", 29 | "random.seed(2)\n", 30 | "mx.random.seed(2)\n", 31 | "\n", 32 | "from mxnet import gluon\n", 33 | "from mxnet import ndarray as nd\n", 34 | "from mxnet import autograd" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "## 生成数据集" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": 2, 47 | "metadata": { 48 | "ExecuteTime": { 49 | "end_time": "2018-03-08T19:07:59.143688Z", 50 | "start_time": "2018-03-08T19:07:59.137902Z" 51 | }, 52 | "collapsed": true 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "# 训练数据数量\n", 57 | "num_train = 20\n", 58 | "\n", 59 | "# 测试数据数量\n", 60 | "num_test = 100\n", 61 | "\n", 62 | "# 输入数据特征维度\n", 63 | "num_inputs = 200\n", 64 | "\n", 65 | "# 实际权重\n", 66 | "true_w = nd.ones((num_inputs, 1)) * 0.01\n", 67 | "\n", 68 | "# 实际偏置\n", 69 | "true_b = 0.05" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": 3, 75 | "metadata": { 76 | "ExecuteTime": { 77 | "end_time": "2018-03-08T19:07:59.152808Z", 78 | "start_time": "2018-03-08T19:07:59.146220Z" 79 | }, 80 | "collapsed": true 81 | }, 82 | "outputs": [], 83 | "source": [ 84 | "# 生成数据\n", 85 | "X = nd.random_normal(shape=(num_train + num_test, num_inputs))\n", 86 | "y = nd.dot(X, true_w) + true_b\n", 87 | "\n", 88 | "# 添加随机噪声\n", 89 | "y += 0.01 * nd.random_normal(shape=y.shape)\n", 90 | "\n", 91 | "# 训练数据和测试数据\n", 92 | "X_train, X_test = X[:num_train, :], X[num_train:, :]\n", 93 | "y_train, y_test = y[:num_train], y[num_train:]" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 4, 99 | "metadata": { 100 | "ExecuteTime": { 101 | "end_time": "2018-03-08T19:07:59.161134Z", 102 | "start_time": "2018-03-08T19:07:59.154329Z" 103 | }, 104 | "collapsed": true 105 | }, 106 | "outputs": [], 107 | "source": [ 108 | "# 批数据大小\n", 109 | "batch_size = 1\n", 110 | "\n", 111 | "# 通过yield进行数据读取\n", 112 | "def data_iter(num_examples):\n", 113 | " # 产生样本的索引\n", 114 | " idx = list(range(num_examples))\n", 115 | " # 将索引随机打乱\n", 116 | " random.shuffle(idx)\n", 117 | " # 迭代一个epoch\n", 118 | " for i in range(0, num_examples, batch_size):\n", 119 | " # 依次取出样本的索引, 这种实现方式在num_examples/batch_size不能整除时也适用\n", 120 | " j = nd.array(idx[i:min((i + batch_size), num_examples)])\n", 121 | " # 根据提供的索引取元素\n", 122 | " yield nd.take(X, j), nd.take(y, j)" 123 | ] 124 | }, 125 | { 126 | "cell_type": "markdown", 127 | "metadata": {}, 128 | "source": [ 129 | "## 初始化模型参数" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "execution_count": 5, 135 | "metadata": { 136 | "ExecuteTime": { 137 | "end_time": "2018-03-08T19:07:59.168063Z", 138 | "start_time": "2018-03-08T19:07:59.162812Z" 139 | }, 140 | "collapsed": true 141 | }, 142 | "outputs": [], 143 | "source": [ 144 | "def init_params():\n", 145 | " # 随机初始化权重w\n", 146 | " w = nd.random_normal(shape=(num_inputs, 1))\n", 147 | " # 偏置b初始化为0\n", 148 | " b = nd.zeros((1,))\n", 149 | " # w, b放入list里\n", 150 | " params = [w, b]\n", 151 | "\n", 152 | " # 需要计算反向传播, 添加自动求导\n", 153 | " for param in params:\n", 154 | " param.attach_grad()\n", 155 | " return params" 156 | ] 157 | }, 158 | { 159 | "cell_type": "markdown", 160 | "metadata": {}, 161 | "source": [ 162 | "## $L_2$ 范数正则化\n", 163 | "\n", 164 | "在训练时最小化函数为:$\\text{loss} + \\lambda \\sum_{p \\in \\textrm{params}}\\|p\\|_2^2。$" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 6, 170 | "metadata": { 171 | "ExecuteTime": { 172 | "end_time": "2018-03-08T19:07:59.172969Z", 173 | "start_time": "2018-03-08T19:07:59.169671Z" 174 | }, 175 | "collapsed": true 176 | }, 177 | "outputs": [], 178 | "source": [ 179 | "# L2范数\n", 180 | "def L2_penalty(w, b):\n", 181 | " return ((w**2).sum() + b ** 2) / 2" 182 | ] 183 | }, 184 | { 185 | "cell_type": "markdown", 186 | "metadata": {}, 187 | "source": [ 188 | "## 定义训练和测试" 189 | ] 190 | }, 191 | { 192 | "cell_type": "code", 193 | "execution_count": 7, 194 | "metadata": { 195 | "ExecuteTime": { 196 | "end_time": "2018-03-08T19:07:59.436628Z", 197 | "start_time": "2018-03-08T19:07:59.174882Z" 198 | }, 199 | "collapsed": false 200 | }, 201 | "outputs": [], 202 | "source": [ 203 | "%matplotlib inline\n", 204 | "import matplotlib as mpl\n", 205 | "mpl.rcParams['figure.dpi']= 120\n", 206 | "import matplotlib.pyplot as plt\n", 207 | "import numpy as np\n", 208 | "\n", 209 | "\n", 210 | "# 定义网络\n", 211 | "def net(X, w, b):\n", 212 | " return nd.dot(X, w) + b\n", 213 | "\n", 214 | "# 损失函数\n", 215 | "def square_loss(yhat, y):\n", 216 | " return (yhat - y.reshape(yhat.shape)) ** 2 / 2\n", 217 | "\n", 218 | "# 梯度下降\n", 219 | "def sgd(params, lr, batch_size):\n", 220 | " for param in params:\n", 221 | " param[:] = param - lr * param.grad / batch_size\n", 222 | "\n", 223 | "# 测试\n", 224 | "def test(net, params, X, y):\n", 225 | " return square_loss(net(X, *params), y).mean().asscalar()\n", 226 | "\n", 227 | "# 训练\n", 228 | "def train(_lambda):\n", 229 | " # 定义训练的迭代周期\n", 230 | " epochs = 10\n", 231 | " # 定义学习率\n", 232 | " learning_rate = 0.005\n", 233 | " # 初始化参数\n", 234 | " w, b = params = init_params()\n", 235 | " # 训练损失\n", 236 | " train_loss = []\n", 237 | " # 测试损失\n", 238 | " test_loss = []\n", 239 | " for epoch in range(epochs):\n", 240 | " for data, label in data_iter(num_train):\n", 241 | " # 记录梯度\n", 242 | " with autograd.record():\n", 243 | " # 计算预测值\n", 244 | " output = net(data, *params)\n", 245 | " # 计算loss\n", 246 | " loss = square_loss(output, label) + _lambda * L2_penalty(*params)\n", 247 | " # 反向传播\n", 248 | " loss.backward()\n", 249 | " # 更新梯度\n", 250 | " sgd(params, learning_rate, batch_size)\n", 251 | " # 训练损失\n", 252 | " train_loss.append(test(net, params, X_train, y_train))\n", 253 | " # 测试损失\n", 254 | " test_loss.append(test(net, params, X_test, y_test))\n", 255 | " \n", 256 | " # 绘制损失图像\n", 257 | " plt.plot(train_loss)\n", 258 | " plt.plot(test_loss)\n", 259 | " plt.legend(['train', 'test'])\n", 260 | " plt.show()\n", 261 | " return 'learned w[:10]:', w[:10].T, 'learned b:', b" 262 | ] 263 | }, 264 | { 265 | "cell_type": "markdown", 266 | "metadata": {}, 267 | "source": [ 268 | "# 观察过拟合" 269 | ] 270 | }, 271 | { 272 | "cell_type": "code", 273 | "execution_count": 8, 274 | "metadata": { 275 | "ExecuteTime": { 276 | "end_time": "2018-03-08T19:08:00.050410Z", 277 | "start_time": "2018-03-08T19:07:59.438408Z" 278 | }, 279 | "collapsed": false 280 | }, 281 | "outputs": [ 282 | { 283 | "data": { 284 | "image/png": "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\nNljoAAAAAElFTkSuQmCC\n", 285 | "text/plain": [ 286 | "" 287 | ] 288 | }, 289 | "metadata": {}, 290 | "output_type": "display_data" 291 | }, 292 | { 293 | "data": { 294 | "text/plain": [ 295 | "('learned w[:10]:', \n", 296 | " [[ 1.04817176 -0.02568593 0.86764956 0.29322267 0.01006179 -0.56152576\n", 297 | " 0.38436398 -0.30840367 -2.32450151 0.03733355]]\n", 298 | " , 'learned b:', \n", 299 | " [ 0.79914856]\n", 300 | " )" 301 | ] 302 | }, 303 | "execution_count": 8, 304 | "metadata": {}, 305 | "output_type": "execute_result" 306 | } 307 | ], 308 | "source": [ 309 | "train(0)" 310 | ] 311 | }, 312 | { 313 | "cell_type": "markdown", 314 | "metadata": {}, 315 | "source": [ 316 | "## 使用正则化" 317 | ] 318 | }, 319 | { 320 | "cell_type": "code", 321 | "execution_count": 9, 322 | "metadata": { 323 | "ExecuteTime": { 324 | "end_time": "2018-03-08T19:08:00.683766Z", 325 | "start_time": "2018-03-08T19:08:00.052185Z" 326 | }, 327 | "collapsed": false 328 | }, 329 | "outputs": [ 330 | { 331 | "data": { 332 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAhIAAAFkCAYAAAB1rtL+AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAAPYQAAD2EBqD+naQAAIABJREFUeJzt3Xl8VNX9//HXZ5KQEEKAhCWEfQm7oEkEXBAsbXEF1GpN\ntVqt1dqiLbZfq/zsAtpqtRWXqrWttlVr0LoURQXrUlwRCSourAJBVlkDsoQl5/fHncAkkJBlZm5m\n5v38fu9jMveeufcz3gbenHPuveacQ0RERKQhAn4XICIiIrFLQUJEREQaTEFCREREGkxBQkRERBpM\nQUJEREQaTEFCREREGkxBQkRERBpMQUJEREQaTEFCREREGkxBQkRERBqs3kHCzEaY2XNmtsbMKsxs\nbMi2ZDP7vZktMLOvgm3+aWYdq+0j1czuM7NNZrbDzJ4ys/bh+EIiIiISPQ3pkWgBfAj8CKj+oI50\n4FhgMnAccA7QF5herd1dwJnAecApQC7wdANqERERER9ZYx7aZWYVwHjn3HO1tCkE3gO6OedWm1km\nsBG40Dn3bLBNX2AhMNw5N7fBBYmIiEhURWOORGu8nottwfcFQDLwamUD59xiYBVwQhTqERERkTBJ\njuTOzSwVuA143Dn3VXB1DrDXObe9WvMNwW1H2k82MAZYCeyJTLUiIiJxKQ3oDsxyzm0O984jFiTM\nLBn4N15vxI8aubsxwL8aXZSIiEjiugh4PNw7jUiQCAkRXYCvhfRGAKwHmplZZrVeiQ7BbUeyEuCx\nxx6jf//+EahYom3ixIlMnTrV7zIkjHRO44vOZ/xYuHAhF198MQT/Lg23sAeJkBDREzjVObe1WpMS\nYD8wGgidbNkVeLeG3e4B6N+/P/n5+eEuWXzQqlUrncs4o3MaX3Q+41JEpgbUO0iYWQugN2DBVT3N\nbAiwBViHdxnnscBZQIqZdQi22+Kc2+ec225mDwF3mtlWYAdwD/C2rtgQERGJLQ3pkSgEXseb++CA\nPwbX/xPv/hFnB9d/GFxvwfenAm8E100EDgBPAanATODHDahFREREfFTvIOGcm03tl40e9ZJS51w5\ncE1wERERkRilZ22IL4qKivwuQcJM5zS+6HxKXSlIiC/0h1T80TmNLzqfUlcRvSGViIjEr1WrVrFp\n0ya/yxCgbdu2dO3a1ZdjK0iIiEi9rVq1iv79+7Nr1y6/SxEgPT2dhQsX+hImFCRERKTeNm3axK5d\nu3SjwCag8oZTmzZtUpAQEZHYohsFiiZbioiISIMpSIiIiEiDKUiIiIhIgylIiIiISIMpSIiIiERR\n9+7dufzyy/0uI2wUJERERKp59913mTx5Mtu3bw/7vgOBAGZ29IYxQpd/ioiIVPPOO+8wZcoULrvs\nMjIzM8O678WLFxMIxM+/4+Pnm4iIiISJc67O7crLy+u175SUFJKSkhpSVpOkICEiIhJi8uTJXH/9\n9YA3nyEQCJCUlERpaSmBQIBrr72Wxx9/nEGDBpGWlsasWbMA+MMf/sBJJ51E27ZtSU9Pp7CwkKef\nfvqw/VefI/HPf/6TQCDAO++8w3XXXUf79u3JyMjg3HPPZfPmzdH50o2goQ0REZEQ5513HkuWLGHa\ntGncfffdZGdnY2a0a9cOgFdffZUnn3ySCRMm0LZtW7p37w7APffcw7hx47j44ovZu3cv06ZN44IL\nLmDGjBmcfvrpB/df0/yIa665hqysLH7zm9+wcuVKpk6dyoQJEyguLo74d24MBQkREZEQgwYNIj8/\nn2nTpjFu3LjDnl+xZMkSPvnkE/r27Vtl/dKlS0lNTT34fsKECRx33HHceeedVYJETdq1a8fMmTMP\nvj9w4AD33nsvO3bsoGXLlo38VpGjICEiIhG3axcsWhTZY/TrB+npkT0GwKhRow4LEUCVELFt2zb2\n79/PiBEjmDZt2lH3aWZceeWVVdaNGDGCu+66i9LSUgYNGtT4wiNEQUJERCJu0SIoKIjsMUpKIBrP\nD6scyqhuxowZ/Pa3v+XDDz+sMgGzrldodOnSpcr7Nm3aALB169aGFRolChIiIhJx/fp5f9FH+hjR\n0Lx588PWvfnmm4wbN45Ro0bxwAMP0LFjR1JSUnj44YfrPMehpis56noFiV8UJEREJOLS06PTWxAu\n9b1h1DPPPEPz5s2ZNWsWycmH/mp96KGHwl1ak6PLP0VERKpp0aIF4M11qIukpCTMjP379x9ct3Ll\nSqZPnx6R+poSBQkREZFqCgoKcM4xadIkHnvsMZ544gl27dpVY/szzzyTnTt3MmbMGB588EGmTJnC\n8OHDycvLq9Pxahq+aOrDGqChDRERkcMUFhZyyy238Oc//5lZs2bhnOPzzz/HzI447HHqqafy8MMP\nc9tttzFx4kR69OjB7bffzooVK1iwYEGVtkfaR01DKbHwTA6LhbRjZvlASUlJCfmxNMgmIhKn5s+f\nT0FBAfpz2X9HOxeV24EC59z8cB9fQxsiIiLSYAoSIiIi0mAKEiIiItJgChIiIiLSYAoSIiIi0mAK\nEiIiItJgChIiIiLSYAoSIiIi0mAKEiIiItJgMRUktu5u2s9kFxERSTQxFSQWblrodwkiIiISIqaC\nxGcbP/O7BBEREQmhICEiIlLNu+++y+TJk9m+fXvEjnHrrbcyffr0iO0/WhQkREREqnnnnXeYMmUK\n27Zti9gxfve73ylIRNvGnRtZt2Od32WIiEicc875XULMiKkgAVCyrsTvEkREJI5NnjyZ66+/HoDu\n3bsTCARISkpi1apVADz22GMUFhaSnp5OdnY2RUVFrF69uso+li1bxnnnnUfHjh1p3rw5Xbp0oaio\niB07dgAQCATYtWsX//jHPwgEAgQCAS6//PLoftEwSa7vB8xsBPB/QAHQERjvnHuuWpspwBVAa+Bt\n4Grn3LKQ7anAncC3gVRgFvAj59yXtR27dVpr5q2dx1l9zqpv2SIiInVy3nnnsWTJEqZNm8bdd99N\ndnY2AO3ateO3v/0tv/rVr7jwwgv5wQ9+wMaNG7nnnnsYOXIkH3zwAZmZmezbt49vfvOb7Nu3j2uv\nvZacnBzWrFnDjBkz2LZtGy1btuSxxx7j+9//PsOGDePKK68EoFevXn5+7YZzztVrAU4DpgDjgAPA\n2GrbfwFsAc4CBgH/AT4HmoW0eQBYCYwEjgPeAd6s5Zj5gDvh5hPcmf8604mIiL9KSkoc4EpKSvwu\nJSL+8Ic/uEAg4EpLSw+uKy0tdcnJye62226r0vbTTz91KSkp7tZbb3XOOffhhx86M3PPPPNMrcfI\nyMhwl112WaNrPdq5qNwO5Lt6/p1fl6XePRLOuZnATAAzsyM0+Qlws3NuRrDNJcAGYDzwpJllApcD\nFzrnZgfbXAYsNLOhzrm5NR17QNsBzFg7A+ccRz60iIg0Rbv27WLRpkURPUa/tv1IT0mP2P6ffvpp\nnHOcf/75bN68+eD69u3bk5eXx+uvv84NN9xAq1atAJg5cyannXYazZs3j1hNTUG9g0RtzKwHkAO8\nWrnOObfdzN4DTgCeBAqDxw1ts9jMVgXb1Bwk2g3goQ0PsWbHGjpndg5n6SIiEkGLNi2i4C8FET1G\nyZUl5HfMj9j+ly1bRkVFBb179z5sm5nRrFkzwJtX8bOf/Yw777yTxx57jBEjRjB27FguvvhiMjMz\nI1afX8IaJPBChMPrgQi1IbgNoAOw1zlX/eLc0DZHNLD9QADmrZ2nICEiEkP6te1HyZWRnSzfr22/\niO6/oqKCQCDAzJkzCQQOv1YhIyPj4M933HEH3/ve95g+fTovv/wy1157Lbfddhtz5swhNzc3onVG\nW7iDRET97qbfkbopletnXc/DbR8GoKioiKKiIp8rExGR2qSnpEe0tyDcjjR83qtXL5xzdO/e/Yi9\nEtUNHDiQgQMHMmnSJObMmcOJJ57In//8Z6ZMmVLjMRqruLiY4uLiKuvKysrCfpxQ4Q4S6wHD63UI\n7ZXoAHwQ0qaZmWVW65XoENxWo6lTp/Kbxb+h/EA5z138XG1NRUREGqxFixYAbNu2ja5duwJw7rnn\ncuONNzJ58mQeffTRwz6zZcsWsrKy2LFjB+np6SQlJR3cNnDgQAKBAOXl5VWOEe4bXh3pH9fz58+n\noCByw0phDRLOuRVmth4YDSwACE6uHAbcF2xWAuwPtnk22KYv0BV492jHKMwt5O737taESxERiZiC\nggKcc0yaNIkLL7yQlJQUzj77bG655RYmTZrEihUrGD9+PC1btmT58uX85z//4aqrruK6667jtdde\nY8KECZx//vn06dOH/fv388gjj5CcnMx5551X5RivvPIKU6dOJTc3lx49ejB06FAfv3XDNOQ+Ei2A\n3ng9DwA9zWwIsMU59wVwF3CTmS3Du8TzZmA1MB0OTr58CLjTzLYCO4B7gLdru2KjUmFuIVt2b2Hl\ntpX0aNOjvuWLiIgcVWFhIbfccgt//vOfmTVrFhUVFaxYsYJf/OIX9O3bl6lTpx4coujSpQunnXYa\nY8eOBWDIkCGcdtppzJgxgzVr1pCens6QIUOYOXNmlaBw5513ctVVV/HLX/6S3bt3c+mllyZGkMC7\n6uJ1vEmVDvhjcP0/gcudc7ebWTrwIN4Nqd4ETnfO7Q3Zx0S8e1A8hXdDqpnAj+ty8IKOXvfMvLXz\nFCRERCRiJk2axKRJkw5bP378eMaPH1/j57p3785f//rXo+6/T58+vP76642qsSmo9y2ynXOznXMB\n51xSteXykDa/cc7lOufSnXNjXMhdLYPby51z1zjn2jrnWjrnzndHuatlpQ4ZHeiS2YV5a+fVt3QR\nEREJs5h71gZ4wxvz1ilIiIiI+C1mg0TJ2hIqXIXfpYiIiCS0mA0SZeVlfL7lc79LERERSWgxGSRC\nJ1yKiIiIf2IySGSnZ9OjdQ/eX/u+36WIiIgktJgMEgD5HfP5YP0HR28oIiIiERNTQcK5Qz/nd8zn\ng3Uf4EJXioiISFTF1EO7Vq6EytuFH5dzHGXlZazYtoKebXr6WpeISKJauHCh3yUkPL/PQUwFiTlz\noPI25ZVPkZu/br6ChIhIlLVt25b09HQuvvhiv0sRID09nbZt2/py7JgKEu+GPNKrQ0YHclvm8sG6\nD/jWgG/5V5SISALq2rUrCxcuZNOmTX6XInjBrvIppdEWU0GipATKyyE11Xuf3zGf+evn+1uUiEiC\n6tq1q29/eUnTEVOTLffsgbffPvT+uJzjKFlbogmXIiIiPompIJGVBbNmHXqf3zGfjbs2snbHWv+K\nEhERSWAxFSSGD4eXXz70vnLCpe4nISIi4o+YChInnAAffggbNnjvu2R2Iat5FvPXaZ6EiIiIH2Iq\nSAwe7L1+9JH3ambehEsFCREREV/EVJDIyYGUFFi69NC6/Jx8StaV+FeUiIhIAoupIJGcDD17wrJl\nh9YV5hayevtqNny1wb/CREREElRMBQmAvLyqPRKFuYWAHikuIiLih5gLEr17V+2R6N66O9nNsxUk\nREREfBBzQSIvD5Yvh/37vfdmRmFuIfPWKUiIiIhEW8wFid69Yd8++OKLQ+uOzz2e99e8rztcioiI\nRFnMBYm8PO+1+jyJDTs3sGbHGn+KEhERSVAxFyS6dDn8ElBNuBQREfFHzAWJI10C2imzEx0zOvL+\nmvf9K0xERCQBxVyQAG+eRGiPBKAJlyIiIj6IySCRl1e1RwKCQWLtPE24FBERiaKYDBK9e1e9BBS8\nKze27N7Cym0rfatLREQk0cRkkMjLO/wS0IHtBwKwaNMin6oSERFJPDEZJHr39l5D50l0zuxMalIq\nS7csPfKHREREJOxiMkh07epdAho6TyJgAXpl9WLpZgUJERGRaInJIJGc7A1vfPpp1fV5WXnqkRAR\nEYmimAwSAMcfD++9V3WdgoSIiEh0xWyQGDYMPvoIdu8+tC4vO4+V21ay98Be/woTERFJIDEbJIYP\n9y7/nD//0Lq8rDwqXAUrtq7wrzAREZEEErNB4phjoHnzqsMbvbO8yzk0vCEiIhIdMRskkpOhoADm\nzDm0rlNmJ9KS01i2ZVnNHxQREZGwidkgAd7wRmiPRMAC9M7qrUtARUREoiSmg8SwYbBqFaxbd2id\nrtwQERGJnpgOEsOHe6+hvRIKEiIiItET9iBhZgEzu9nMlpvZLjNbZmY3HaHdFDNbG2zzXzPrXd9j\nde4MubnVgkR2HqvKVlG+v7xxX0RERESOKhI9EjcAVwE/AvoB1wPXm9mEygZm9gtgAnAlMBTYCcwy\ns2b1PdiwYVUnXFZeArp86/LGfAcRERGpg0gEiROA6c65mc65Vc65Z4CX8QJDpZ8ANzvnZjjnPgEu\nAXKB8fU92PDh8P77cOCA916XgIqIiERPJILEO8BoM8sDMLMhwEnAi8H3PYAc4NXKDzjntgPv4YWQ\nehk2DHbuPPTcjdyWuaSnpLNk85JGfg0RERE5muQI7PM2IBNYZGYH8MLK/3POTQtuzwEcsKHa5zYE\nt9VLQQEEAt48icGDwcw4Luc43lvz3tE/LCIiIo0SiR6JbwPfAS4EjgMuBf7PzL4bgWORkeHd5TJ0\nwuXIbiN5o/QNnHOROKSIiIgERaJH4nbgVufcv4PvPzWz7sCNwKPAesCADlTtlegAfFDbjidOnEir\nVq2qrCsqKmLYsCLefvvQupHdR/K7t37Hok2L6N+uf6O+jIiISKwoLi6muLi4yrqysrKIHjMSQSId\nOFBtXQXB3g/n3AozWw+MBhYAmFkmMAy4r7YdT506lfz8/MPW79kDf/0rbN8OmZlwYpcTSbIkZpfO\nVpAQEZGEUVRURFFRUZV18+fPp6CgIGLHjMTQxvPATWZ2hpl1M7NzgInAMyFt7gq2OdvMjgEeAVYD\n0xtywGHDwDnv6g2AjGYZFOYWMrt0dmO+h4iIiBxFJILEBOApvN6Fz/CGOh4AflXZwDl3O3Av8CDe\n1RrNgdOdc3sbcsB+/byeiOrzJGavnK15EiIiIhEU9iDhnNvpnLvOOdfDOdfCOZfnnPu1c25/tXa/\ncc7lOufSnXNjnHMNfmRnIABDh1YNEqO6j2LdV+t0PwkREZEIiulnbYSqvMNlZQfESV1PImABZq/U\n8IaIiEikxFWQ+PJL72mgAJmpmeR3zNc8CRERkQiKmyDRtav3uiHkgtKR3UYyu1TzJERERCIlboJE\ny5be644dh9aN7DaS1dtXs2LbCn+KEhERiXNxEyQyMrzXr746tG5EtxEYpnkSIiIiERI3QeJIPRKt\n01ozJGcI/yv9ny81iYiIxLu4CRJpaZCUVDVIwKH7SYiIiEj4xU2QMPOGN0KHNsC7n0RpWSml20r9\nKUxERCSOxU2QAG94o3qPxIiuIwB0GaiIiEgExH2QyE7P5pj2x2h4Q0REJALiKkgcaWgDDt1PQkRE\nRMIrroLEkXokAEZ2H8nnWz9nzfY10S9KREQkjiVEkDixy4kAvLfmvcM3ioiISIPFVZCoaWgjt2Uu\nnVp24v0170e/KBERkTgWV0Giph4JgOM7Hc/ctXOjW5CIiEicS5ggMTR3KPPWzqPCVUS3KBERkTgW\nV0GipqENgKGdhrK9fDtLNi+JblEiIiJxLK6CRG09EgW5BQDMXaPhDRERkXCJuyCxcydUHGH0onVa\na/pm91WQEBERCaO4ChKVjxLfufPI24d2Gsr7a3XlhoiISLjEVZA40qPEQx2fezwfrv+QvQf2Rq8o\nERGROJZQQWJop6HsPbCXBRsWRK8oERGROBZXQaJyaKOmKzeG5AwhJZDCW6veil5RIiIicSyugsTR\neiTSktM4u+/Z3Dv3XvYd2Be9wkREROJUQgUJgF+P/DXLty7n0QWPRqcoERGROBaXQaKmoQ2AwR0G\nc17/87jljVvUKyEiItJIcRUk0tPBrPYeCYBfjfwVK7atUK+EiIhII8VVkDDzJlweLUgM7jCY8f3G\n86e5f4pOYSIiInEqroIEeMMbtQ1tVDqt12ks2LCA3ft2R74oERGROBV3QaIuPRLgPXvjgDuge0qI\niIg0QtwFidoe3BXqmPbHkBJIYd7aeZEvSkREJE7FZZCoy9BGanIqgzsMZt46BQkREZGGirsgUdeh\nDYCCjgWUrC2JbEEiIiJxLO6CRF2HNgAKcwv5dOOn7Nq3K7JFiYiIxKm4DBJ1GdoAb8Jlhavgw/Uf\nRrYoERGROBV3QaI+QxuD2g+iWVIzDW+IiIg0UNwFifoMbTRLasaQDkM04VJERKSB4jJI1HVoA7wJ\nl7oEVEREpGHiLkhkZHhBwrm6tS/MLWThxoV8tbce6UNERESAOAwSLVtCRQXsquOFGCd1PQmHY/bK\n2ZEtTEREJA7FZZCAug9v9M3uS4/WPXhh6QuRK0pERCRORSRImFmumT1qZpvMbJeZfWRm+dXaTDGz\ntcHt/zWz3uE4dkaG91rXCZdmxpl5Z/Li0hdxdR0PERERESACQcLMWgNvA+XAGKA/8DNga0ibXwAT\ngCuBocBOYJaZNWvs8St7JOoaJADO7HMmpWWlfLbxs8YeXkREJKEkR2CfNwCrnHNXhKwrrdbmJ8DN\nzrkZAGZ2CbABGA882ZiD13doA2BU91E0T27OC0tfYGD7gY05vIiISEKJxNDG2cA8M3vSzDaY2Xwz\nOxgqzKwHkAO8WrnOObcdeA84obEHr+/QBkBachqje47mxaUvNvbwIiIiCSUSQaIncDWwGPgm8ABw\nj5l9N7g9B3B4PRChNgS3NUpDhjYAzsw7k7dWvcW2PdsaW4KIiEjCiMTQRgCY65z7ZfD9R2Y2CPgh\n8Ghjdjxx4kRatWpVZV1RURFFRUUH31f2SNRnaAPgjLwzOOAO8PLnL3PBwAsaU6aIiIgviouLKS4u\nrrKurKwsoseMRJBYByystm4hcG7w5/WAAR2o2ivRAfigth1PnTqV/Pz82poQCECLFvXvkejaqisD\n2w1k1rJZChIiIhKTqv/jGmD+/PkUFBRE7JiRGNp4G+hbbV1fghMunXMr8MLE6MqNZpYJDAPeCUcB\nLVvC1q1Hb1fdmF5jmPX5LF0GKiIiUkeRCBJTgeFmdqOZ9TKz7wBXAH8KaXMXcJOZnW1mxwCPAKuB\n6eEooKAAZjfgRpXf7PVN1uxYo8tARURE6ijsQcI5Nw84BygCPgb+H/AT59y0kDa3A/cCD+JdrdEc\nON05tzccNYwdC2+9BVu21O9zp3Q7hdSkVF7+/OVwlCEiIhL3InJnS+fci865wc65dOfcQOfcw0do\n8xvnXG6wzRjn3LJwHf+ss+DAAXjppfp9rnlKc07pdgqzPp8VrlJERETiWtw9awMgNxcKC+G55+r/\n2TG9xjC7dDZ79u8Jf2EiIiJxJi6DBHjDGy+9BHvrOVjyzV7fZM/+PbxZ+mZkChMREYkjcR0kduyo\n/6TLQe0H0TGjo+ZJiIiI1EHcBonBg6Fr1/oPb5gZo3uOZnZpAy77EBERSTBxGyTM4OyzYcYMqO9t\nIQa2G8iSzUt0PwkREZGjiNsgAXDGGbByJSxeXL/P5WXlUVZexsZdGyNSl4iISLyI6yAxahSkptb/\nMtC87DwAlm5eGv6iRERE4khcB4n0dC9MvFjPp4P3zuoNwNItChIiIiK1iesgAXD66fDGG/V7Gmh6\nSjqdWnZSj4SIiMhRJESQ2LsXXn+9fp/Ly85Tj4SIiMhRxH2QyMuDnj3rP0+iT1YfBQkREZGjiPsg\nYeb1Srz0Uv0uA83LzmPp5qW6BFRERKQWcR8kwAsSK1fC0np0MORl5bFz307Wf7U+YnWJiIjEuoQI\nEiNGQCBQv9tlH7wEVMMbIiIiNUqIIJGZCccd5129UVc92/TEMJZsXhK5wkRERGJcQgQJgJEj6xck\n0pLT6Na6my4BFRERqUXCBIlTToFVq6C0tO6fycvSJaAiIiK1SZggcfLJ3mt9eiUUJERERGqXMEEi\nOxsGDar/hMtlW5ZR4SoiV5iIiEgMS5ggAd7wRn16JAa0G8Ce/Xv49MtPI1eUiIhIDEu4ILF0Kaxb\nV7f2o7qPIrt5No8ueDSyhYmIiMSohAsSUPdeiWZJzSgaVMRjCx5jf8X+yBUmIiISoxIqSHTsCJ06\nwYIFdf/M9479Huu+Wsd/P/9v5AoTERGJUQkVJAC6doXVq+vePr9jPoPaD+IfH/0jYjWJiIjEqoQL\nEp071y9ImBmXDrmU/yz6D1t3b41cYSIiIjEo4YJEly71CxIAFw++mAMVB3ji0yciU5SIiEiMSrgg\n0bkzfPFF/R4pnpORw6k9TuXfn/07coWJiIjEoIQMErt3w9Z6jlJcMOAC/rfyf3y588vIFCYiIhKD\nEi5IdOnivdZ3eOOc/udgGM8sfCb8RYmIiMSohAsSnTt7r/UNEm3T22p4Q0REpJqECxI5ORAIePMk\n6kvDGyIiIlUlXJBITvZuTFXfHgk4NLzx7MJnw1+YiIhIDEq4IAENuwQUvOGNr/X4Go9/8nj4ixIR\nEYlBCRkk6ntTqlBX5F/BG6Vv8NH6j8JblIiISAxK2CDRkDkSAOf2P5cumV24+727w1uUiIhIDErI\nIFE5tFGfm1JVSg4k8+Pjf8zjHz+uSZciIpLwEjJIdO4MO3dCWVnDPv+Dgh8QsAAPznswvIWJiIjE\nmIQNEtDweRJZzbO4dMil3D/vfvYd2Be+wkRERGJMQgaJyrtbNnSeBMCVBVey/qv1zC6dHZ6iRERE\nYlBCBonKm1I1tEcC4NicY+nWqhvTF00PX2EiIiIxJiGDREqKFyYaEyTMjLF9xzJ98XRcQ2ZtioiI\nxIGIBwkzu8HMKszszmrrp5jZWjPbZWb/NbPeka4lVGPuJVFpfL/xfLH9Cz5Y/0F4ihIREYkxEQ0S\nZnY8cCXwUbX1vwAmBLcNBXYCs8ysWSTrCdWlS+PmSACM6DqC1mmt+c+i/4SnKBERkRgTsSBhZhnA\nY8AVwLZqm38C3Oycm+Gc+wS4BMgFxkeqnuq6d4flyxu3j5SkFM7qcxbTF2uehIiIJKZI9kjcBzzv\nnHstdKWZ9QBygFcr1znntgPvASdEsJ4qBgzwgsSuXY3bz7i+41iwYQErtq4IT2EiIiIxJCJBwswu\nBI4FbjxmeuMUAAAbMElEQVTC5hzAARuqrd8Q3BYVgwZ5d7ZcuLBx+xnTawypSanqlRARkYSUHO4d\nmlln4C7g6865sN6taeLEibRq1arKuqKiIoqKiuq9rwEDvNdPP4WCgobX1DK1JaN7jmb64un8dPhP\nG74jERGRRiouLqa4uLjKurKG3sa5jsIeJIACoB0w38wsuC4JOMXMJgD9AAM6ULVXogNQ6+UPU6dO\nJT8/PyxFZmRAt25ekGiscX3HcfULV7N512ay07Mbv0MREZEGONI/rufPn09BY/7FfBSRGNp4BTgG\nb2hjSHCZhzfxcohzbjmwHhhd+QEzywSGAe9EoJ4aDRoUniAxtu9YnHO8sPSFxu9MREQkhoQ9SDjn\ndjrnPgtd8C7v3Oycq5yRcBdwk5mdbWbHAI8Aq4GoTjQYOBA++aTx+8nJyGFY52G6DFRERBJOtO5s\nWeXWj86524F7gQfxrtZoDpzunNsbpXoAL0iUlsJXXzV+X+P7jmfW57PYvW9343cmIiISI6ISJJxz\nX3POXVdt3W+cc7nOuXTn3Bjn3LJo1BJq0CDv9bPPGr+vcf3GsWvfLl5Z/krjdyYiIhIjEvJZG5X6\n9QOz8Axv9Gvbj77ZfXl20bON35mIiEiMSOggkZ4OPXuGZ8IlwEXHXMS0T6axcefG8OxQRESkiUvo\nIAHePIlwBYkfHf8jzIz73r8vPDsUERFp4hI+SAwaFJ6hDYDs9GyuOO4K7p17Lzv37gzPTkVERJqw\nhA8SAwfCmjXw5Zfh2d/EEyZStqeMhz94ODw7FBERacISPkiMHg2tWsGkSeHZX/fW3blw0IX88d0/\nsvdAVK9mFRERibqEDxIdOsDvfw8PPQSvvx6efd5w8g2sKlvF3+b/LTw7FBERaaISPkgA/OAHMGIE\nXHkl7A7D/aQGtR/EJUMuYcrsKXy1Nwx3uxIREWmiFCSAQAD+8hdYuRIeeSQ8+5w8ajJb92xl6rtT\nw7NDERGRJkhBIqhfP+jYEb74Ijz769a6GxOOn8Ad79yh+0qIiEjcUpAIkZUFW7eGb3+TRkwiOZDM\n5c9dToWrCN+ORUREmggFiRBZWbBlS/j2l52ezb/O/RcvLHmBKbOnhG/HIiIiTYSCRIg2bcLbIwFw\net7pTDl1CpNnT+b5xc+Hd+ciIiI+U5AIEe4eiUqTRkzirD5ncdWMq9hRviP8BxAREfGJgkSISAWJ\ngAW474z72LpnK7e+dWv4DyAiIuITBYkQkRjaqNS1VVeuP/F6/vjuH1m+dXlkDiIiIhJlChIhKq/a\nqIjQBRbXn3Q97Vu05//++3+ROYCIiEiUKUiEaNMGnIOyssjsv0WzFvz+67/nmYXP8PqKMN2PW0RE\nxEcKEiGysrzXSA1vABQNKuLELify01k/ZX/F/sgdSEREJAoUJEJUBolITLisZGbcNeYuFmxYoId6\niYhIzFOQCNGmjfcayR4JgOM7Hc/3jv0eN712E1t3R/hgIiIiEaQgESIaPRKVfve137H3wF5ufPXG\nyB9MREQkQhQkQrRsCUlJ0QkSHVt25NbRt/JgyYO8UfpG5A8oIiISAQoSIcwiey+J6q4+/mpO6HwC\nVz5/JXv274nOQUVERMJIQaKaSN3d8kgCFuBvY//G8q3L+e0bv43OQUVERMJIQaKaaPZIAAxoN4BJ\nIyZx29u38fGGj6N3YBERkTBQkKgmmj0SlW48+UbysvK44vkrOFBxILoHFxERaQQFiWratIl+kEhN\nTuVvY//G+2ve577374vuwUVERBpBQaKayudtRNuJXU7kR8f/iEmvTmLp5qXRL0BERKQBFCSq8WNo\no9JtX7+NnIwcLn72YvYd2OdPESIiIvWgIFFNtCdbhspolsG/zv0XJWtLuPmNm/0pQkREpB4UJKrJ\nyoJdu2CPT7d1GNZ5GL8a+St+++ZveXvV2/4UISIiUkcKEtVE63kbtZk0YhLDOw/n4mcvZnv5dv8K\nEREROQoFiWqi8Sjxo0kOJPPoOY+yeddmrnnpGv8KEREROQoFiWqi+eCu2vRs05M/nfEnHvnoEZ74\n5Al/ixEREamBgkQ1lUMbfgcJgO8O/i4XDLyAH77wQ1ZvX+13OSIiIodRkKimKcyRqGRmPHDmA7RI\nacGl/7mUClfhd0kiIiJVKEhUk5oK6elNo0cCIKt5Fv8c/09eW/Ead825y+9yREREqlCQOAK/7m5Z\nk9E9R3Pd8Ou44ZUbeGvVW36XIyIicpCCxBH4eXfLmtz69Vs5scuJnPPEOazcttLvckRERIAIBAkz\nu9HM5prZdjPbYGbPmlmfI7SbYmZrzWyXmf3XzHqHu5aG8uPBXUfTLKkZT1/wNJmpmZxdfDY7ynf4\nXZKIiEhEeiRGAPcCw4CvAynAy2bWvLKBmf0CmABcCQwFdgKzzKxZBOqpt6Y2tFEpOz2b54ueZ1XZ\nKr7zzHf0yHEREfFd2IOEc+4M59yjzrmFzrmPge8BXYGCkGY/AW52zs1wzn0CXALkAuPDXU9DZGXB\npk1+V3FkA9oN4IlvPcGLS1/kxldv9LscERFJcNGYI9EacMAWADPrAeQAr1Y2cM5tB94DTohCPUfV\noQN8+aXfVdTstN6ncec37+SOd+7gLyV/8bscERFJYMmR3LmZGXAX8JZz7rPg6hy8YLGhWvMNwW2+\n69ABNmwA58DM72qO7Nph17JsyzKumnEV5fvLuWaYbqUtIiLRF9EgAdwPDABOivBxwqpDBygvh7Iy\naN3a72qOzMy45/R7SEtO49qZ17K9fDv/75T/53dZIiKSYCIWJMzsT8AZwAjn3LqQTesBAzpQtVei\nA/BBbfucOHEirVq1qrKuqKiIoqKisNRcKSfYL7JhQ9MNEuCFidu/cTuZqZnc9PpNpCWn8bMTf+Z3\nWSIi4pPi4mKKi4urrCsrK4voMSMSJIIhYhww0jm3KnSbc26Fma0HRgMLgu0z8a7yuK+2/U6dOpX8\n/PxIlFxFhw7e64YN0LdvxA/XKGbGL0f+kj379/Dz//6c1mmt+X7+9/0uS0REfHCkf1zPnz+fgoKC\nGj7ReGEPEmZ2P1AEjAV2mlnwr2XKnHN7gj/fBdxkZsuAlcDNwGpgerjraYjQIBErbvnaLWzbs40r\nZ1xJuxbtGNt3rN8liYhIAojEVRs/BDKB/wFrQ5YLKhs4527Hu9fEg3hXazQHTnfO7Y1APfXWujU0\naxZbQcLMuPeMexnXdxwXPXMRH2/42O+SREQkAUTiPhIB51zSEZZHqrX7jXMu1zmX7pwb45xbFu5a\nGsrM65VYv97vSuonYAEePedRemf15uzis/lyZxO+hlVEROKCnrVRg8pLQGNNi2YteO7C59izfw9n\n/OsMyvZEdpKNiIgkNgWJGsRqkADo0qoLMy+eyfKtyzn9X6fruRwiIhIxChI1iOUgAXBszrG8/N2X\n+XTjp5zx+Bls3d0EHx4iIiIxT0GiBrEeJAAKcwuZdfEsPtv4GSc9fBKl20r9LklEROKMgkQNcnK8\nyZbO+V1J4wzvPJx3v/8u5QfKGf7QcErWlvhdkoiIxBEFiRpU3iZ7+3a/K2m8Ptl9ePf779K1VVdG\n/mMkLy590e+SREQkTihI1CAWb0pVm/Yt2vP6pa/z9Z5fZ2zxWD01VEREwkJBogbxFiQA0lPSefqC\np7m68GqumnEVk16dRIWr8LssERGJYZF++mfMCn1wVzxJCiRxz+n30L11d37+35+zYtsKHhr7EOkp\n6X6XJiIiMUg9EjWovE12rN3dsi7MjJ+d+DP+ff6/eW7xc5zw0Al8vuVzv8sSEZEYpCBRAzNo3z7+\neiRCfWvAt5jz/Tns3LuTwr8W8sQnT/hdkoiIxBgFiVrEw70kjuaYDscw78p5fKPnN7jw6Qv59lPf\nZtOuTX6XJSIiMUJBohY5OfEfJABap7XmyfOfZNp503hl+SsMun8Qzy9+3u+yREQkBihI1CIReiRC\nfXvQt/nk6k8ozC1k7LSxXD79craXx8GNNEREJGIUJGoRi48Sb6yOLTvyfNHzPDT2IZ767CmOeeAY\nXlvxmt9liYhIE6UgUYvKHolYv012fZkZlx93OQuuXkCvNr0Y/chorn3pWnbt2+V3aSIi0sQoSNQi\nJwf27IEvvvC7En90b92dVy55hXtOu4e/zf8bx/75WN5a9ZbfZYmISBOiIFGLk0+Gjh3hpJNg/ny/\nq/FHwAJcM+waPvzhh2SnZzPi7yP4wXM/YMvuLX6XJiIiTYCCRC06dYL33/fCxMknw0MPJd4wR6U+\n2X1467K3uP+M+/n3Z/+mz719uHvO3ew9sNfv0kRExEcKEkfRqRPMng3f+Q5ccQWMG5dYV3KESgok\ncfXxV7Pwxws5p985XPfydfS/rz9PfvokLlETlohIglOQqIPmzeFvf4P//AfmzIELLvC7In91bNmR\nv479Kwt+uIAB7Qbw7ae+zfCHhvNm6Zt+lyYiIlGmIFEP48bBHXfAG2/AunV+V+O/ge0H8nzR87x2\nyWscqDjAKf84hXHTxrFw40K/SxMRkShRkKins8+GpCSvd0I8p/Y4lbk/mEvxecUs2LCAgfcP5NtP\nfZuPN3zsd2kiIhJhChL1lJUFo0bBs8/6XUnTErAAFw66kEU/XsQDZz7Ae6vfY/CfB3PuE+cyf12C\nXvIiIpIAFCQa4Jxz4PXXYetWvytpelKTU7mq8CqWXrOUh8c+zMdffkzBXwoY89gYZi2bpUmZIiJx\nRkGiAcaPh/374YUX/K6k6UpJSuGy4y5j4Y8X8vi5j7Np1yZO+9dpHPPAMTz8wcPs2b/H7xJFRCQM\nFCQaoFMnGDpUwxt1kRxIpuiYIub9YB7/u/R/9MrqxRXPXUHXqV254ZUbWLZlmd8liohIIyhINNA5\n58DMmYn3UK+GMjNGdh/J9Auns2jCIi4cdCEPljxI3r15jH5kNE988gTl+8v9LlNEROpJQaKBLrsM\nWrWCc8+Fcv39Vy99svtwz+n3sPa6tTwy/hH2HdjHhU9fSOepnfn5yz9n0aZFfpcoIiJ1pCDRQB06\neJeAzp8PP/xh4t46uzGapzTnu0O+yxuXvcFnP/qM7w7+Ln//8O/0v68/hX8p5A/v/IEvyhL0iWki\nIjFCQaIRhg717nj5j3/Ak0/6XU1s69+uP3eOuZM1163hyW89SbfW3bjptZvoeldXTvn7Kfxp7p9Y\nVbbK7zJFRKQai4XL8cwsHygpKSkhPz/f73IOM2oUNGsGL7/sdyXxpWxPGdMXT6f4k2JeWf4K+yv2\nc1zOcYzrO45x/cYxpMMQzMzvMkVEmrT58+dTUFAAUOCcC/uNfdQjEQYXXQSvvqqJl+HWKq0Vlwy5\nhJcueolN/7eJ4vOK6du2L3fOuZPjHjyOHnf34NqXruXV5a+y78A+v8sVEUlI6pEIg61bIScHfv97\n+OlP/a4m/u09sJfZK2czffF0pi+ezurtq2md1prTep/Gqd1PZVT3UeRl5am3QkSEyPdIKEiEyTnn\nwBdfwLx5fleSWJxzfLD+A6Yvms6Ly15k/rr5VLgKcjJyGNltpLd0H0n/tv0VLEQkIUU6SCSHe4eJ\n6qKL4PzzYfFi6NvX72oSh5mR3zGf/I75TD51MtvLt/P2qreZXTqb2aWzuXbmteyv2E/b9LYM6zSM\noZ2GMqzTMI7vdDxZzbP8Ll9EJOYpSITJWWdBZiY89hjcfLPf1SSuzNRMTs87ndPzTgfgq71f8e4X\n7/LmqjeZu2Yud825i617vIek5GXlMbTTUI7PPZ5jc45lcIfBtGnexs/yRURijoJEmKSlwaWXwh13\nwJgxcPLJflckABnNMvhGr2/wjV7fALyhkM+3fs57q99j7pq5zF07l6c+e4ryA95dxbpkdmFIzhCG\ndBjC4A6DGdxhML3a9CIlKcXPryEi0mQpSITRHXfAxx/D2WfDW2/BwIF+VyTVmRm9s3rTO6s3Fw2+\nCID9FftZsnkJH63/iI82eMvDHzzMuq/WAd7zQnq26Unf7L7e0rYv/dr2o292X9qmt9XcCxFJaAoS\nYZSa6t3tcuRIGDHCu7/EscfCj38M2dl+Vyc1SQ4kM6DdAAa0G0DRMUUH12/cuZFPvvyExZsXs3jT\nYhZtXsTTC59m5baVOLxJym3S2tC3bV96tulJt1bd6N66+8Gla6uupCWn+fW1RESiQkEizFq1glmz\n4A9/gA8/9HopXnsNXnkFkvVf+6Di4mKKioqO3tBH7Vq049Qep3Jqj1OrrN+zfw/Ltixj8abFXsjY\nvJiV21by1qq3WL19NRWu4mDbnIycg8GiS2YXclvmVlk6ZnSkeUrzaH+1iIiFcyp1p/MpdeXrX21m\n9mPg50AO8BFwjXPufT9rCocOHbwAAfDmm3DqqXDDDV64EE8s/yGVlpzGoPaDGNR+0GHb9h3Yx+rt\nq1m5bSWlZaWs3LaSldtWsmLbCt5f8z5rd6xl9/7dVT7TJq3NwWDRKbMTuRm5dGzZkXbp7Wib3rbK\nkpqcGq2vWW+xfE7lcDqfUle+BQkz+zbwR+BKYC4wEZhlZn2cc5v8qivcRozwAsTEiZCUBL17e70W\nrVsf/pqmXvCYl5KUQo82PejRpscRtzvnKCsvY+2OtUdcFm9azOsrXmftjrXsqzj8bp0ZzTIOCxdt\nm7clq3kWrdJa0TqtNa1Sg69prQ7+nJmaSVIgKdJfX0QSkJ89EhOBB51zjwCY2Q+BM4HLgdt9rCvs\nfvITWLIEHnwQtm+v+UmhzZodOWB07gzHHONN3uzWDdq3h4Bubh6TzIzWaa1pndaaAe0G1NjOOceO\nvTvYtGtTrUvptlJK1pawefdmyvaUHbz65EgymmUcDBqVoaNls5ZkNMugRUoLWjRrQYuUFt77I/zc\nolmLg23TU9JJS05TOBERf4KEmaUABcDvKtc555yZvQKc4EdNkWQG99/vLRUVsGMHlJXBtm1Hf922\nzZtrcffdhwJIs2bQpQt07XroNXTp0gUyMvz9ztI4ZkZmaiaZqZn0bNOzzp8r319OWXkZ2/Zso2xP\n2VF/3rhrIyu3reSrvV+xc99Odu7dyc59O9m1b1edjpccSKZ5cnPSktPYsXwHfe7tQ1pyGmnJaTRP\naX7w54NLkrc+NSmVlKQUmiU1IyWQEvafkyyJpEASyYFkkixJV9aIRJBfPRJtgSRgQ7X1G4Aj3Rcy\nDWDhwoURLiv6WrTwlk6dam+3ezeUlsKGDd7Dwdavh3Xr4IMPYOZM2Lixak9HZqa3pKV5V5NULpXv\nk5K8Xg0zb6np59q2VfaKBAJVf67LPj/7rIwbbphf588frY6aPlO5JKYkICu4QHpwyT1S0wCQGlyA\nClfB3oo97K3YTXlw2XtgN+VuN+UHdrPP7WFfxV72uXL27dvLvvJy5ux7nu5fnuCtq9jLnopydrCX\n/RVb2VdRzj6313ut2Mt+V84Bt//gst/tO/hzhTsQkf8aAUsiQMB7tSQCFiBAEkYgGDaSSLIAVtkG\nr40RXG9JXjsCIdsCmBkH/88CGN7/6AIEMAALEAg+H9F7DXj/uyQQ/IyF7KfaOirbBcAI7vPQ/r1X\nC+7z0Ccq91OpMkgdWmcHfz70+2HBxds6b8mnnH/zz0L3UuXz3v+H7KeGdtVDXJXPWMj+QrYf2mYh\nnzn4ZQ7/DofVUN2Rt1gtn6hxb7X8gVLTlpqOU+vxazhO7TUfrl+nzmRxsKcyIgPovjxrw8w6AmuA\nE5xz74Ws/z1winPuhGrtvwP8K7pVioiIxJWLnHOPh3unfvVIbAIOAB2qre8AHOlh3LOAi4CVwJ6I\nViYiIhJf0oDueH+Xhp1vT/80sznAe865nwTfG7AKuMc5d4cvRYmIiEi9+HnVxp3AP8yshEOXf6YD\n//CxJhEREakH34KEc+5JM2sLTMEb0vgQGOOc2+hXTSIiIlI/vg1tiIiISOzTbY1ERESkwRQkRERE\npMFiIkiY2Y/NbIWZ7TazOWZ2vN81ydGZ2a/NrKLa8lm1NlPMbK2Z7TKz/5pZb7/qlarMbISZPWdm\na4LnbuwR2tR6/sws1czuM7NNZrbDzJ4ys/bR+xZS6Wjn08z+foTf1xertdH5bCLM7EYzm2tm281s\ng5k9a2Z9jtAu4r+jTT5IhDzc69fAcXhPCZ0VnKgpTd8neJNpc4LLyZUbzOwXwAS8B7cNBXbindtm\nPtQph2uBNwn6R8Bhk6nqeP7uwnuGznnAKXg31nw6smVLDWo9n0EvUfX3tfrjP3U+m44RwL3AMODr\nQArwspk1r2wQtd9R51yTXoA5wN0h7w1YDVzvd21ajnrufg3Mr2X7WmBiyPtMYDdwgd+1aznsXFUA\nY+tz/oLvy4FzQtr0De5rqN/fKZGXGs7n34FnavmMzmcTXvAePVEBnByyLiq/o026RyLk4V6vVq5z\n3jeNy4d7xam8YFfq52b2mJl1ATCzHnj/4gk9t9uB99C5bfLqeP4K8S4xD22zGO/GczrHTdOoYDf5\nIjO738yyQrYVoPPZlLXG62naAtH9HW3SQYLaH+6VE/1ypJ7mAN8DxgA/BHoAb5hZC7zz59C5jVV1\nOX8dgL3BP7xqaiNNx0vAJcDXgOuBkcCLdujJWjnofDZJwXN0F/CWc65yHlrUfkf9vLOlxDnnXOh9\n3T8xs7lAKXABsMifqkTkSJxzT4a8/dTMPgY+B0YBr/tSlNTV/cAA4CQ/Dt7UeyTq+3AvacKcc2XA\nEqA33vkzdG5jVV3O33qgmZll1tJGmijn3Aq8P4MrZ/nrfDZBZvYn4AxglHNuXcimqP2ONukg4Zzb\nB5QAoyvXBbtwRgPv+FWXNIyZZeD9obQ2+IfUeqqe20y8Gcg6t01cHc9fCbC/Wpu+QFfg3agVKw1i\nZp2BbKDyLyedzyYmGCLGAac651aFbovm72gsDG3o4V4xyszuAJ7HG87oBEwG9gHTgk3uAm4ys2V4\nj4i/Ge+KnOlRL1YOE5zL0hvvXzUAPc1sCLDFOfcFRzl/zrntZvYQcKeZbQV2APcAbzvn5kb1y0it\n5zO4/Brvsr/1wXa/x+tBnAU6n02Nmd2Pd3nuWGCnmVX2PJQ55/YEf47O76jfl6zU8bKWHwX/I+zG\nS0mFftekpU7nrTj4P9rdeLOAHwd6VGvzG7xLlHbh/YHV2++6tRw8NyPxLgM7UG15uK7nD0jFu9Z9\nU/APqX8D7f3+bom41HY+gTRgJl6I2AMsBx4A2ul8Ns2lhnN5ALikWruI/47qoV0iIiLSYE16joSI\niIg0bQoSIiIi0mAKEiIiItJgChIiIiLSYAoSIiIi0mAKEiIiItJgChIiIiLSYAoSIiIi0mAKEiIi\nItJgChIiIiLSYAoSIiIi0mD/H7GdpflyLA3VAAAAAElFTkSuQmCC\n", 333 | "text/plain": [ 334 | "" 335 | ] 336 | }, 337 | "metadata": {}, 338 | "output_type": "display_data" 339 | }, 340 | { 341 | "data": { 342 | "text/plain": [ 343 | "('learned w[:10]:', \n", 344 | " [[ 0.00107633 -0.00052574 0.00450233 -0.00110545 -0.0068391 -0.00181657\n", 345 | " -0.00530632 0.00512845 -0.00742549 -0.00058495]]\n", 346 | " , 'learned b:', \n", 347 | " [ 0.00449432]\n", 348 | " )" 349 | ] 350 | }, 351 | "execution_count": 9, 352 | "metadata": {}, 353 | "output_type": "execute_result" 354 | } 355 | ], 356 | "source": [ 357 | "train(5)" 358 | ] 359 | } 360 | ], 361 | "metadata": { 362 | "kernelspec": { 363 | "display_name": "Python 2", 364 | "language": "python", 365 | "name": "python2" 366 | }, 367 | "language_info": { 368 | "codemirror_mode": { 369 | "name": "ipython", 370 | "version": 2 371 | }, 372 | "file_extension": ".py", 373 | "mimetype": "text/x-python", 374 | "name": "python", 375 | "nbconvert_exporter": "python", 376 | "pygments_lexer": "ipython2", 377 | "version": "2.7.13" 378 | } 379 | }, 380 | "nbformat": 4, 381 | "nbformat_minor": 2 382 | } 383 | --------------------------------------------------------------------------------