{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import torch\n", "\n", "# 固定随机种子,使得运行结果可以稳定复现\n", "torch.manual_seed(1024)\n", "# 产生训练用的数据\n", "x_origin = torch.linspace(100, 300, 200)\n", "# 将变量X归一化,否则梯度下降法很容易不稳定\n", "x = (x_origin - torch.mean(x_origin)) / torch.std(x_origin)\n", "epsilon = torch.randn(x.shape)\n", "y = 10 * x + 5 + epsilon" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# 为了使用PyTorch的高层封装函数,我们通过继承Module类来定义函数\n", "class Linear(torch.nn.Module):\n", " def __init__(self):\n", " \"\"\"\n", " 定义线性回归模型的参数:a, b\n", " \"\"\"\n", " super().__init__()\n", " self.a = torch.nn.Parameter(torch.zeros(()))\n", " self.b = torch.nn.Parameter(torch.zeros(()))\n", "\n", " def forward(self, x):\n", " \"\"\"\n", " 根据当前的参数估计值,得到模型的预测结果\n", " 参数\n", " ----\n", " x :torch.tensor,变量x\n", " 返回\n", " ----\n", " y_pred :torch.tensor,模型预测值\n", " \"\"\"\n", " return self.a * x + self.b\n", "\n", " def string(self):\n", " \"\"\"\n", " 输出当前模型的结果\n", " \"\"\"\n", " return f'y = {self.a.item():.2f} * x + {self.b.item():.2f}'" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Step 1, Loss: 101.19; Result: y = 3.12 * x + -1.99\n", "Step 2, Loss: 3.61; Result: y = 3.48 * x + -2.28\n", "Step 3, Loss: 4.00; Result: y = 3.22 * x + -1.97\n", "Step 4, Loss: 14.92; Result: y = 2.85 * x + -1.22\n", "Step 5, Loss: 25.90; Result: y = 2.68 * x + -0.23\n", "Step 6, Loss: 44.56; Result: y = 2.92 * x + 1.08\n", "Step 7, Loss: 60.46; Result: y = 3.74 * x + 2.61\n", "Step 8, Loss: 60.59; Result: y = 5.07 * x + 4.15\n", "Step 9, Loss: 47.31; Result: y = 6.73 * x + 5.52\n", "Step 10, Loss: 24.05; Result: y = 8.22 * x + 6.48\n", "Step 11, Loss: 14.43; Result: y = 9.36 * x + 5.75\n", "Step 12, Loss: 4.00; Result: y = 9.75 * x + 5.42\n", "Step 13, Loss: 1.48; Result: y = 9.88 * x + 5.28\n", "Step 14, Loss: 0.58; Result: y = 9.89 * x + 5.26\n", "Step 15, Loss: 1.48; Result: y = 9.89 * x + 5.20\n", "Step 16, Loss: 0.95; Result: y = 9.88 * x + 5.18\n", "Step 17, Loss: 1.03; Result: y = 9.88 * x + 5.17\n", "Step 18, Loss: 1.68; Result: y = 9.84 * x + 5.14\n", "Step 19, Loss: 0.55; Result: y = 9.86 * x + 5.15\n", "Step 20, Loss: 1.27; Result: y = 9.94 * x + 5.21\n" ] } ], "source": [ "# 定义每批次用到的数据量\n", "batch_size = 20\n", "# 定义模型\n", "model = Linear()\n", "# 确定最优化算法\n", "learning_rate = 0.1\n", "optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)\n", "\n", "for t in range(20):\n", " # 选取当前批次的数据,用于训练模型\n", " ix = (t * batch_size) % len(x)\n", " xx = x[ix: ix + batch_size]\n", " yy = y[ix: ix + batch_size]\n", " yy_pred = model(xx)\n", " # 计算当前批次数据的损失\n", " loss = (yy - yy_pred).pow(2).mean()\n", " # 将上一次的梯度清零\n", " optimizer.zero_grad()\n", " # 计算损失函数的梯度\n", " loss.backward()\n", " # 迭代更新模型参数的估计值\n", " optimizer.step()\n", " # 注意!loss记录的是模型在当前批次数据上的损失,该数值的波动较大\n", " print(f'Step {t + 1}, Loss: {loss: .2f}; Result: {model.string()}')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# 定义损失函数\n", "mse = lambda y, y_pred: (y - y_pred).pow(2).mean()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# 定义每批次用到的数据量\n", "batch_size = 20\n", "# 定义模型\n", "model = Linear()\n", "# 确定最优化算法\n", "learning_rate = 0.1\n", "optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)\n", "stats = {'batch_loss': [], 'total_loss': []}\n", "\n", "for t in range(20):\n", " # 选取当前批次的数据,用于训练模型\n", " ix = (t * batch_size) % len(x)\n", " xx = x[ix: ix + batch_size]\n", " yy = y[ix: ix + batch_size]\n", " # 计算当前批次数据的损失\n", " loss = mse(yy, model(xx))\n", " # 将上一次的梯度清零\n", " optimizer.zero_grad()\n", " # 计算损失函数的梯度\n", " loss.backward()\n", " # 迭代更新模型参数的估计值\n", " optimizer.step()\n", " # 预估模型在整个数据集上面的损失\n", " stats['batch_loss'].append(loss.item())\n", " stats['total_loss'].append(mse(y, model(x)).item())" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "# 创建一个图形框\n", "fig = plt.figure(figsize=(6, 6), dpi=80)\n", "# 在图形框里只画一幅图\n", "ax = fig.add_subplot(111)\n", "# 解决中文显示问题\n", "plt.rcParams['font.sans-serif'] = ['SimHei']\n", "plt.rcParams['axes.unicode_minus'] = False\n", "ax.set_xlabel('训练步数')\n", "ax.set_ylabel('模型损失')\n", "ax.plot(stats['batch_loss'], 'k', label='批次损失')\n", "ax.plot(stats['total_loss'], 'r-.', label='整体损失')\n", "legend = plt.legend(shadow=True)\n", "plt.savefig(\"sgd.png\", dpi=1200)\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }