{ "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", " \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: 125.25; Result: y = 1.98 * x + 1.02\n", "Step 2, Loss: 80.72; Result: y = 3.56 * x + 1.83\n", "Step 3, Loss: 52.16; Result: y = 4.83 * x + 2.49\n", "Step 4, Loss: 33.84; Result: y = 5.85 * x + 3.01\n", "Step 5, Loss: 22.10; Result: y = 6.66 * x + 3.42\n", "Step 6, Loss: 14.57; Result: y = 7.31 * x + 3.76\n", "Step 7, Loss: 9.74; Result: y = 7.83 * x + 4.03\n", "Step 8, Loss: 6.64; Result: y = 8.25 * x + 4.24\n", "Step 9, Loss: 4.66; Result: y = 8.59 * x + 4.41\n", "Step 10, Loss: 3.38; Result: y = 8.85 * x + 4.55\n", "Step 11, Loss: 2.56; Result: y = 9.07 * x + 4.66\n", "Step 12, Loss: 2.04; Result: y = 9.24 * x + 4.74\n", "Step 13, Loss: 1.71; Result: y = 9.38 * x + 4.81\n", "Step 14, Loss: 1.49; Result: y = 9.49 * x + 4.87\n", "Step 15, Loss: 1.35; Result: y = 9.58 * x + 4.91\n", "Step 16, Loss: 1.26; Result: y = 9.65 * x + 4.95\n", "Step 17, Loss: 1.21; Result: y = 9.71 * x + 4.98\n", "Step 18, Loss: 1.17; Result: y = 9.75 * x + 5.00\n", "Step 19, Loss: 1.15; Result: y = 9.79 * x + 5.02\n", "Step 20, Loss: 1.13; Result: y = 9.82 * x + 5.03\n" ] } ], "source": [ "# 定义模型\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", " # 也就是调用forward函数\n", " y_pred = model(x)\n", " # 计算损失函数\n", " loss = (y - y_pred).pow(2).mean()\n", " # 将上一次的梯度清零\n", " optimizer.zero_grad()\n", " # 计算损失函数的梯度\n", " loss.backward()\n", " # 迭代更新模型参数的估计值\n", " optimizer.step()\n", " print(f'Step {t + 1}, Loss: {loss: .2f}; Result: {model.string()}')" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Step 1, Loss: 125.25; Result: y = 1.98 * x + 1.02\n", "Step 2, Loss: 80.72; Result: y = 3.56 * x + 1.83\n", "Step 3, Loss: 52.16; Result: y = 4.83 * x + 2.49\n", "Step 4, Loss: 33.84; Result: y = 5.85 * x + 3.01\n", "Step 5, Loss: 22.10; Result: y = 6.66 * x + 3.42\n", "Step 6, Loss: 14.57; Result: y = 7.31 * x + 3.76\n", "Step 7, Loss: 9.74; Result: y = 7.83 * x + 4.03\n", "Step 8, Loss: 6.64; Result: y = 8.25 * x + 4.24\n", "Step 9, Loss: 4.66; Result: y = 8.59 * x + 4.41\n", "Step 10, Loss: 3.38; Result: y = 8.85 * x + 4.55\n", "Step 11, Loss: 2.56; Result: y = 9.07 * x + 4.66\n", "Step 12, Loss: 2.04; Result: y = 9.24 * x + 4.74\n", "Step 13, Loss: 1.71; Result: y = 9.38 * x + 4.81\n", "Step 14, Loss: 1.49; Result: y = 9.49 * x + 4.87\n", "Step 15, Loss: 1.35; Result: y = 9.58 * x + 4.91\n", "Step 16, Loss: 1.26; Result: y = 9.65 * x + 4.95\n", "Step 17, Loss: 1.21; Result: y = 9.71 * x + 4.98\n", "Step 18, Loss: 1.17; Result: y = 9.75 * x + 5.00\n", "Step 19, Loss: 1.15; Result: y = 9.79 * x + 5.02\n", "Step 20, Loss: 1.13; Result: y = 9.82 * x + 5.03\n" ] } ], "source": [ "# 利用代码实现PyTorch封装的梯度下降法\n", "model = Linear()\n", "for t in range(20):\n", " # 根据当前的参数估计值,得到模型的预测结果\n", " # 也就是调用forward函数\n", " y_pred = model(x)\n", " # 计算损失函数\n", " loss = (y - y_pred).pow(2).mean()\n", " # 计算损失函数的梯度\n", " loss.backward()\n", " with torch.no_grad():\n", " for param in model.parameters():\n", " # 迭代更新模型参数的估计值,等同于optimizer.step()\n", " param -= learning_rate * param.grad\n", " # 将梯度清零,等同于optimizer.zero_grad()\n", " param.grad = None\n", " print(f'Step {t + 1}, Loss: {loss: .2f}; Result: {model.string()}')" ] } ], "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 }