{ "cells": [ { "cell_type": "code", "id": "initial_id", "metadata": { "collapsed": true, "ExecuteTime": { "end_time": "2026-03-15T06:40:53.937066295Z", "start_time": "2026-03-15T06:40:52.962818496Z" } }, "source": [ "import torch\n", "import numpy\n", "import pandas\n", "from sympy.physics.control.control_plots import matplotlib\n", "from torch.distributed.algorithms.ddp_comm_hooks.powerSGD_hook import batched_powerSGD_hook\n", "\n" ], "outputs": [], "execution_count": 1 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:53.993520411Z", "start_time": "2026-03-15T06:40:53.939990190Z" } }, "cell_type": "code", "source": "torch.randn(3,4,2)", "id": "3e141a42d342fa96", "outputs": [ { "data": { "text/plain": [ "tensor([[[ 0.5509, -1.6216],\n", " [ 0.1083, 0.4464],\n", " [ 1.8819, 0.4029],\n", " [-0.0733, 2.6961]],\n", "\n", " [[-2.0316, 0.7172],\n", " [-0.3774, 0.5248],\n", " [-0.0134, 0.3256],\n", " [ 0.3433, 0.1697]],\n", "\n", " [[ 1.1434, 0.6595],\n", " [ 0.2386, -0.6560],\n", " [ 1.3177, -0.6876],\n", " [-1.0916, -0.6199]]])" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 2 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.023331390Z", "start_time": "2026-03-15T06:40:53.996610811Z" } }, "cell_type": "code", "source": [ "X = torch.arange(12, dtype=torch.float32).reshape((3,4))\n", "Y = torch.tensor([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])\n", "torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)" ], "id": "8ae20ae68abbf32f", "outputs": [ { "data": { "text/plain": [ "(tensor([[ 0., 1., 2., 3.],\n", " [ 4., 5., 6., 7.],\n", " [ 8., 9., 10., 11.],\n", " [ 2., 1., 4., 3.],\n", " [ 1., 2., 3., 4.],\n", " [ 4., 3., 2., 1.]]),\n", " tensor([[ 0., 1., 2., 3., 2., 1., 4., 3.],\n", " [ 4., 5., 6., 7., 1., 2., 3., 4.],\n", " [ 8., 9., 10., 11., 4., 3., 2., 1.]]))" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 3 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.081323347Z", "start_time": "2026-03-15T06:40:54.028230344Z" } }, "cell_type": "code", "source": [ "a = torch.arange(3).reshape((3, 1))\n", "b = torch.arange(2).reshape((1, 2))\n", "a, b\n", "a+b" ], "id": "2960a1ded2cdd5a4", "outputs": [ { "data": { "text/plain": [ "tensor([[0, 1],\n", " [1, 2],\n", " [2, 3]])" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 4 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.538103014Z", "start_time": "2026-03-15T06:40:54.136512769Z" } }, "cell_type": "code", "source": "X[-1], X[1:3]\n", "id": "69c2ec23ab6ae97c", "outputs": [ { "data": { "text/plain": [ "(tensor([ 8., 9., 10., 11.]),\n", " tensor([[ 4., 5., 6., 7.],\n", " [ 8., 9., 10., 11.]]))" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 5 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.691375092Z", "start_time": "2026-03-15T06:40:54.563788479Z" } }, "cell_type": "code", "source": [ "A = X.numpy()\n", "B = torch.tensor(A)\n", "type(A), type(B)" ], "id": "b8d779a1bc7e4b1a", "outputs": [ { "data": { "text/plain": [ "(numpy.ndarray, torch.Tensor)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 6 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.732824469Z", "start_time": "2026-03-15T06:40:54.714530988Z" } }, "cell_type": "code", "source": [ "import os\n", "os.makedirs(os.path.join(\"..\",\"data\"),exist_ok=True)\n", "data_file = os.path.join(os.path.join(\"..\",\"data\",\"data.csv\"))\n", "with open(data_file, \"w\") as f:\n", " f.write('NumRooms,Alley,Price\\n') # 列名\n", " f.write('NA,Pave,127500\\n') # 每行表示一个数据样本\n", " f.write('2,NA,106000\\n')\n", " f.write('4,NA,178100\\n')\n", " f.write('NA,NA,140000\\n')\n", "\n" ], "id": "82be028b0f1dd1e3", "outputs": [], "execution_count": 7 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.811604177Z", "start_time": "2026-03-15T06:40:54.734220773Z" } }, "cell_type": "code", "source": [ "import pandas as pd\n", "data = pd.read_csv(data_file)\n", "print(data)\n" ], "id": "ddd789a2656899d1", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " NumRooms Alley Price\n", "0 NaN Pave 127500\n", "1 2.0 NaN 106000\n", "2 4.0 NaN 178100\n", "3 NaN NaN 140000\n" ] } ], "execution_count": 8 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.853161280Z", "start_time": "2026-03-15T06:40:54.813874506Z" } }, "cell_type": "code", "source": [ "inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]\n", "\n", "\n", "inputs = pd.get_dummies(inputs, dummy_na=True)\n", "print(inputs)\n", "inputs = inputs.fillna(inputs.mean())\n", "print(inputs)\n" ], "id": "e98fcc3bd4f067cf", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " NumRooms Alley_Pave Alley_nan\n", "0 NaN True False\n", "1 2.0 False True\n", "2 4.0 False True\n", "3 NaN False True\n", " NumRooms Alley_Pave Alley_nan\n", "0 3.0 True False\n", "1 2.0 False True\n", "2 4.0 False True\n", "3 3.0 False True\n" ] } ], "execution_count": 9 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.885351255Z", "start_time": "2026-03-15T06:40:54.855249881Z" } }, "cell_type": "code", "source": [ "X = torch.tensor(inputs.to_numpy(dtype=float))\n", "y = torch.tensor(outputs.to_numpy(dtype=float))\n", "X, y\n" ], "id": "8ff0f7b40f0e4996", "outputs": [ { "data": { "text/plain": [ "(tensor([[3., 1., 0.],\n", " [2., 0., 1.],\n", " [4., 0., 1.],\n", " [3., 0., 1.]], dtype=torch.float64),\n", " tensor([127500., 106000., 178100., 140000.], dtype=torch.float64))" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 10 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:54.918539225Z", "start_time": "2026-03-15T06:40:54.887053932Z" } }, "cell_type": "code", "source": [ "B=torch.tensor([[1,2,3],[2,0,4],[3,4,5]])\n", "B" ], "id": "91a6e0da442b95a0", "outputs": [ { "data": { "text/plain": [ "tensor([[1, 2, 3],\n", " [2, 0, 4],\n", " [3, 4, 5]])" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 11 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.091544877Z", "start_time": "2026-03-15T06:40:54.972764187Z" } }, "cell_type": "code", "source": "B==B.T", "id": "297e6a678fb19be7", "outputs": [ { "data": { "text/plain": [ "tensor([[True, True, True],\n", " [True, True, True],\n", " [True, True, True]])" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 12 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.318112438Z", "start_time": "2026-03-15T06:40:55.208719181Z" } }, "cell_type": "code", "source": [ "X=torch.arange(24).reshape(2,3,4)\n", "X" ], "id": "24e864b336beb58b", "outputs": [ { "data": { "text/plain": [ "tensor([[[ 0, 1, 2, 3],\n", " [ 4, 5, 6, 7],\n", " [ 8, 9, 10, 11]],\n", "\n", " [[12, 13, 14, 15],\n", " [16, 17, 18, 19],\n", " [20, 21, 22, 23]]])" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 13 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.396075402Z", "start_time": "2026-03-15T06:40:55.345582838Z" } }, "cell_type": "code", "source": [ "A = torch.arange(20, dtype=torch.float32).reshape(5, 4)\n", "B = A.clone() # 通过分配新内存,将A的一个副本分配给B\n", "A, A + B\n", "#A = torch.arange(20, dtype=torch.float32).reshape(5, 4)\n", "#B = A # 通过分配新内存,将A的一个副本分配给B\n", "id(A),id(B)" ], "id": "ee0905479b1dbc2b", "outputs": [ { "data": { "text/plain": [ "(140556050244048, 140556050244432)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 14 }, { "metadata": {}, "cell_type": "markdown", "source": "Hadamard乘积", "id": "136459f5efe765cf" }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.435745645Z", "start_time": "2026-03-15T06:40:55.410554891Z" } }, "cell_type": "code", "source": "A*B", "id": "f576b0df17cc0e98", "outputs": [ { "data": { "text/plain": [ "tensor([[ 0., 1., 4., 9.],\n", " [ 16., 25., 36., 49.],\n", " [ 64., 81., 100., 121.],\n", " [144., 169., 196., 225.],\n", " [256., 289., 324., 361.]])" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 15 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.547870490Z", "start_time": "2026-03-15T06:40:55.455797448Z" } }, "cell_type": "code", "source": [ "a=2\n", "X=torch.arange(24).reshape(2,3,4)\n", "a+X,(a*X).shape" ], "id": "b2373af1d7f2a45", "outputs": [ { "data": { "text/plain": [ "(tensor([[[ 2, 3, 4, 5],\n", " [ 6, 7, 8, 9],\n", " [10, 11, 12, 13]],\n", " \n", " [[14, 15, 16, 17],\n", " [18, 19, 20, 21],\n", " [22, 23, 24, 25]]]),\n", " torch.Size([2, 3, 4]))" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 16 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.646393885Z", "start_time": "2026-03-15T06:40:55.571643582Z" } }, "cell_type": "code", "source": [ "print(A)\n", "A_sum_axis0=A.sum(axis=0)\n", "A_sum_axis1=A.sum(axis=1)\n", "A_sum_axis0,A_sum_axis1" ], "id": "2b50246e1ca8a3bc", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[ 0., 1., 2., 3.],\n", " [ 4., 5., 6., 7.],\n", " [ 8., 9., 10., 11.],\n", " [12., 13., 14., 15.],\n", " [16., 17., 18., 19.]])\n" ] }, { "data": { "text/plain": [ "(tensor([40., 45., 50., 55.]), tensor([ 6., 22., 38., 54., 70.]))" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 17 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.715281021Z", "start_time": "2026-03-15T06:40:55.664043259Z" } }, "cell_type": "code", "source": [ "x=torch.arange(4,dtype=torch.float32)\n", "torch.mv(A,x)" ], "id": "3195464dfeb554ed", "outputs": [ { "data": { "text/plain": [ "tensor([ 14., 38., 62., 86., 110.])" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 18 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.752354225Z", "start_time": "2026-03-15T06:40:55.717824570Z" } }, "cell_type": "code", "source": [ "import time\n", "\n", "def showtime(func):\n", " def wrapper():\n", " start = time.time()\n", " result = func() # 执行原始函数\n", " end = time.time()\n", " print(f\"执行时间: {end - start:.6f}秒\")\n", " return result\n", " return wrapper # 返回包装函数\n", "\n", "@showtime\n", "def fun():\n", " print(\"I am silly\")\n", "\n", "fun()\n" ], "id": "ebda8c74ead3e42b", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am silly\n", "执行时间: 0.000183秒\n" ] } ], "execution_count": 19 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.822293071Z", "start_time": "2026-03-15T06:40:55.771678228Z" } }, "cell_type": "code", "source": "torch.norm(torch.ones((4, 9)))", "id": "3343cc0c01d0161c", "outputs": [ { "data": { "text/plain": [ "tensor(6.)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 20 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.831732982Z", "start_time": "2026-03-15T06:40:55.824867487Z" } }, "cell_type": "code", "source": [ "x =torch.arange(4.0,requires_grad=True)\n", "x.grad" ], "id": "674e2416e9417cfe", "outputs": [], "execution_count": 21 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.870751082Z", "start_time": "2026-03-15T06:40:55.832780649Z" } }, "cell_type": "code", "source": [ "y=2*torch.dot(x,x)\n", "y" ], "id": "66c0febebcf98cde", "outputs": [ { "data": { "text/plain": [ "tensor(28., grad_fn=)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 22 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.897976833Z", "start_time": "2026-03-15T06:40:55.872431759Z" } }, "cell_type": "code", "source": [ "y.backward()\n", "x.grad" ], "id": "825f2ce6c46ca4a8", "outputs": [ { "data": { "text/plain": [ "tensor([ 0., 4., 8., 12.])" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 23 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.913347196Z", "start_time": "2026-03-15T06:40:55.901720461Z" } }, "cell_type": "code", "source": [ "x.grad.zero_()\n", "y = x.sum()\n", "y.backward()\n", "x.grad\n" ], "id": "df399463515e9d3c", "outputs": [ { "data": { "text/plain": [ "tensor([1., 1., 1., 1.])" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 24 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:55.985375574Z", "start_time": "2026-03-15T06:40:55.929676346Z" } }, "cell_type": "code", "source": [ "# 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。\n", "# 本例只想求偏导数的和,所以传递一个1的梯度是合适的\n", "x.grad.zero_()\n", "y = x * x\n", "# 等价于y.backward(torch.ones(len(x)))\n", "print(y)\n", "y.sum().backward()\n", "x.grad" ], "id": "f9207619bd4b3de8", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([0., 1., 4., 9.], grad_fn=)\n" ] }, { "data": { "text/plain": [ "tensor([0., 2., 4., 6.])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 25 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.018025749Z", "start_time": "2026-03-15T06:40:55.987257926Z" } }, "cell_type": "code", "source": "torch.ones(len(x))", "id": "409c14c230570859", "outputs": [ { "data": { "text/plain": [ "tensor([1., 1., 1., 1.])" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 26 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.046029736Z", "start_time": "2026-03-15T06:40:56.019720336Z" } }, "cell_type": "code", "source": [ "x.grad.zero_()\n", "y=x*x\n", "u=y.detach()\n", "z=u*x\n", "z.sum().backward()\n", "x.grad==u" ], "id": "521b948fe0683b12", "outputs": [ { "data": { "text/plain": [ "tensor([True, True, True, True])" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 27 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.086132664Z", "start_time": "2026-03-15T06:40:56.049185612Z" } }, "cell_type": "code", "source": [ "x.grad.zero_()\n", "y.sum().backward()\n", "x.grad==2*x" ], "id": "b040beecf0632315", "outputs": [ { "data": { "text/plain": [ "tensor([True, True, True, True])" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 28 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.121364505Z", "start_time": "2026-03-15T06:40:56.091095688Z" } }, "cell_type": "code", "source": [ "from torch.distributions import multinomial\n", "fair_probs=torch.ones([6])\n", "fair_probs" ], "id": "4e6ec763dbea5aa3", "outputs": [ { "data": { "text/plain": [ "tensor([1., 1., 1., 1., 1., 1.])" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 29 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.150868516Z", "start_time": "2026-03-15T06:40:56.126763544Z" } }, "cell_type": "code", "source": "multinomial.Multinomial(1, fair_probs).sample()", "id": "f12d5e85bc6ab595", "outputs": [ { "data": { "text/plain": [ "tensor([0., 1., 0., 0., 0., 0.])" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 30 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.197988031Z", "start_time": "2026-03-15T06:40:56.152490623Z" } }, "cell_type": "code", "source": [ "counts = multinomial.Multinomial(10, fair_probs).sample((500,))\n", "\n", "cum_counts = counts.cumsum(dim=0)\n", "cum_counts.size()" ], "id": "b02f43376fd6f1fe", "outputs": [ { "data": { "text/plain": [ "torch.Size([500, 6])" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 31 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.313824234Z", "start_time": "2026-03-15T06:40:56.200143209Z" } }, "cell_type": "code", "source": [ "import matplotlib.pyplot as plt\n", "\n", "# 假设 estimates 是你的数据张量\n", "estimates = cum_counts / cum_counts.sum(dim=1, keepdims=True)\n", "\n", "# 设置图形大小 (等效于 d2l.set_figsize)\n", "plt.figure(figsize=(6, 4.5))\n", "\n", "# 绘制每条概率曲线\n", "for i in range(6):\n", " plt.plot(estimates[:, i].numpy(),\n", " label=f\"P(die={i + 1})\") # 使用 f-string 更简洁\n", "\n", "# 添加理论概率水平线\n", "plt.axhline(y=0.167, color='black', linestyle='dashed', label='Theoretical probability')\n", "\n", "# 设置坐标轴标签\n", "plt.xlabel('Groups of experiments')\n", "plt.ylabel('Estimated probability')\n", "\n", "# 添加图例\n", "plt.legend()\n", "\n", "# 显示图形\n", "plt.show()\n", "#plt.savefig('dice_probability.png', bbox_inches='tight')" ], "id": "8b80daa4edd0b066", "outputs": [ { "data": { "text/plain": [ "
" ], "image/png": "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" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 32 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.335068964Z", "start_time": "2026-03-15T06:40:56.317850591Z" } }, "cell_type": "code", "source": [ "import numpy as np\n", "class Timer:\n", " \"\"\"记录多次运行时间\"\"\"\n", " def __init__(self):\n", " self.times = []\n", " self.start()\n", " def start(self):\n", " \"\"\"启动计时器\"\"\"\n", " self.tik = time.time()\n", " def stop(self):\n", " \"\"\"停止计时器并将时间记录在列表中\"\"\"\n", " self.times.append(time.time() - self.tik)\n", " return self.times[-1]\n", " def avg(self):\n", " \"\"\"返回平均时间\"\"\"\n", " return sum(self.times) / len(self.times)\n", " def sum(self):\n", " \"\"\"返回时间总和\"\"\"\n", " return sum(self.times)\n", " def cumsum(self):\n", " \"\"\"返回累计时间\"\"\"\n", " return np.array(self.times).cumsum().tolist()" ], "id": "4bdbb4999907154a", "outputs": [], "execution_count": 33 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.450342214Z", "start_time": "2026-03-15T06:40:56.336961011Z" } }, "cell_type": "code", "source": [ "n = 10000\n", "a = torch.ones([n])\n", "b = torch.ones([n])\n", "c=torch.zeros(n)\n", "timer = Timer()\n", "for i in range(n):\n", " c[i]=a[i]+b[i]\n", "f'{timer.stop():.5f} sec'" ], "id": "c6f71622e2cc578a", "outputs": [ { "data": { "text/plain": [ "'0.03117 sec'" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 34 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.498587786Z", "start_time": "2026-03-15T06:40:56.454031052Z" } }, "cell_type": "code", "source": [ "timer.start()\n", "d=a+b\n", "f'{timer.stop():.5f} sec'" ], "id": "2578c79b1214a79f", "outputs": [ { "data": { "text/plain": [ "'0.00041 sec'" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 35 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.507308186Z", "start_time": "2026-03-15T06:40:56.500119417Z" } }, "cell_type": "code", "source": [ "import math\n", "def normal(x, mu, sigma):\n", " p = 1 / math.sqrt(2 * math.pi * sigma**2)\n", " return p * np.exp(-0.5 / sigma**2 * (x - mu)**2)" ], "id": "fd17fdbe38a5f79", "outputs": [], "execution_count": 36 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.533559761Z", "start_time": "2026-03-15T06:40:56.508247056Z" } }, "cell_type": "code", "source": [ "from matplotlib_inline import backend_inline\n", "def use_svg_display(): #@save\n", " \"\"\"使用svg格式在Jupyter中显示绘图\"\"\"\n", " backend_inline.set_matplotlib_formats('svg')\n", "def set_figsize(figsize=(3.5, 2.5)): #@save\n", " \"\"\"设置matplotlib的图表大小\"\"\"\n", " use_svg_display()\n", " plt.rcParams['figure.figsize'] = figsize\n", "def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):\n", " \"\"\"设置matplotlib的轴\"\"\"\n", " axes.set_xlabel(xlabel)\n", " axes.set_ylabel(ylabel)\n", " axes.set_xscale(xscale)\n", " axes.set_yscale(yscale)\n", " axes.set_xlim(xlim)\n", " axes.set_ylim(ylim)\n", " if legend:\n", " axes.legend(legend)\n", " axes.grid()\n", "def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,\n", "ylim=None, xscale='linear', yscale='linear',\n", "fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None):\n", " \"\"\"绘制数据点\"\"\"\n", " if legend is None:\n", " legend = []\n", " set_figsize(figsize)\n", " axes = axes if axes else plt.gca()\n", " # 如果X有一个轴,输出True\n", " def has_one_axis(X):\n", " return (hasattr(X, \"ndim\") and X.ndim == 1 or isinstance(X, list)\n", "and not hasattr(X[0], \"__len__\"))\n", " if has_one_axis(X):\n", " X = [X]\n", " if Y is None:\n", " X, Y = [[]] * len(X), X\n", " elif has_one_axis(Y):\n", " Y = [Y]\n", " if len(X) != len(Y):\n", " X = X * len(Y)\n", " axes.cla()\n", " for x, y, fmt in zip(X, Y, fmts):\n", " if len(x):\n", " axes.plot(x, y, fmt)\n", " else:\n", " axes.plot(y, fmt)\n", " set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)" ], "id": "82158a69cba14da0", "outputs": [], "execution_count": 37 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.625694875Z", "start_time": "2026-03-15T06:40:56.535032024Z" } }, "cell_type": "code", "source": [ "# 再次使用numpy进行可视化\n", "x = np.arange(-7, 7, 0.01)\n", "# 均值和标准差对\n", "params = [(0, 1), (0, 2), (3, 1)]\n", "plot(x, [normal(x, mu, sigma) for mu, sigma in params], xlabel='x',\n", "ylabel='p(x)', figsize=(4.5, 2.5),\n", "legend=[f'mean {mu}, std {sigma}' for mu, sigma in params])" ], "id": "f69ac10ebc3d13d8", "outputs": [ { "data": { "text/plain": [ "
" ], "image/svg+xml": "\n\n\n \n \n \n \n 2026-03-15T14:40:56.601846\n image/svg+xml\n \n \n Matplotlib v3.10.8, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 38 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.659870613Z", "start_time": "2026-03-15T06:40:56.640905156Z" } }, "cell_type": "code", "source": [ "#注意一下matmul做向量乘上矩阵的时候不用考虑转置的情况\n", "def synthetic_data(w, b, num_examples): #@save\n", " \"\"\"生成y=Xw+b+噪声\"\"\"\n", " X = torch.normal(0, 1, (num_examples, len(w)))\n", " y = torch.matmul(X, w) + b\n", " y += torch.normal(0, 0.01, y.shape)\n", " return X, y.reshape((-1, 1))\n" ], "id": "7ed837bdd2b3a26d", "outputs": [], "execution_count": 39 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.700642098Z", "start_time": "2026-03-15T06:40:56.665034974Z" } }, "cell_type": "code", "source": [ "true_w = torch.tensor([2, -3.4])\n", "true_b = 4.2\n", "features, labels = synthetic_data(true_w, true_b, 1000)" ], "id": "5ec2e204a6fd5cb2", "outputs": [], "execution_count": 40 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.766436205Z", "start_time": "2026-03-15T06:40:56.704907868Z" } }, "cell_type": "code", "source": [ "set_figsize()\n", "plt.scatter(features[:, (1)].detach().numpy(), labels.detach().numpy(), 1)" ], "id": "38213d46b3d9900d", "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "
" ], "image/svg+xml": "\n\n\n \n \n \n \n 2026-03-15T14:40:56.736997\n image/svg+xml\n \n \n Matplotlib v3.10.8, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 41 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.788076510Z", "start_time": "2026-03-15T06:40:56.778166680Z" } }, "cell_type": "code", "source": [ "w=torch.normal(0,0.01,size=(2,1),requires_grad=True)\n", "b=torch.zeros(1,requires_grad=True)\n", "def linreg(X, w, b):\n", " return torch.matmul(X,w)+b\n", "def squared_loss(y_hat,y):\n", " return (y_hat-y.reshape(y_hat.shape))**2/2\n", "def sgd(params,lr,batch_size):\n", " with torch.no_grad():\n", " for param in params:\n", " param-=lr*param.grad/batch_size\n", " param.grad.zero_()\n", "lr = 0.03\n", "num_epochs =20\n", "net = linreg\n", "loss = squared_loss" ], "id": "12166e1bc3ddd695", "outputs": [], "execution_count": 42 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.811093546Z", "start_time": "2026-03-15T06:40:56.788825920Z" } }, "cell_type": "code", "source": [ "import random\n", "def data_iter(batch_size, features, labels):\n", " num_examples = len(features)\n", " indices = list(range(num_examples))\n", " # 这些样本是随机读取的,没有特定的顺序\n", " random.shuffle(indices)\n", " for i in range(0, num_examples, batch_size):\n", " batch_indices = torch.tensor(\n", " indices[i: min(i + batch_size, num_examples)])\n", " yield features[batch_indices], labels[batch_indices]" ], "id": "f3b7ee9f326bc687", "outputs": [], "execution_count": 43 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:56.833447562Z", "start_time": "2026-03-15T06:40:56.813045993Z" } }, "cell_type": "code", "source": [ "batch_size =10\n", "for X,y in data_iter(batch_size, features, labels):\n", " print(X,'\\n',y)\n", " break" ], "id": "f386e12d65afff2e", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tensor([[-1.8455, -0.9126],\n", " [-0.0299, 1.6530],\n", " [-2.3513, 0.6457],\n", " [ 0.1707, 0.8342],\n", " [ 0.2096, -0.4362],\n", " [ 0.6160, 1.7403],\n", " [ 0.4242, 0.0484],\n", " [-1.4459, 0.7434],\n", " [ 0.5302, -0.5594],\n", " [-0.5957, -1.5179]]) \n", " tensor([[ 3.6056],\n", " [-1.4872],\n", " [-2.6965],\n", " [ 1.6980],\n", " [ 6.1001],\n", " [-0.4750],\n", " [ 4.9009],\n", " [-1.2270],\n", " [ 7.1486],\n", " [ 8.1680]])\n" ] } ], "execution_count": 44 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.028635227Z", "start_time": "2026-03-15T06:40:56.852110495Z" } }, "cell_type": "code", "source": [ "for epoch in range(num_epochs):\n", " for X, y in data_iter(batch_size, features, labels):\n", " l=loss(net(X, w, b), y)\n", " l.sum().backward()\n", " sgd([w,b],lr,batch_size)\n", " with torch.no_grad():\n", " train_l =loss(net(features, w, b), labels)\n", " print(f'epoch {epoch+1}, train loss: {float(train_l.mean()):3f}')" ], "id": "8888ab6adcec36f1", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "epoch 1, train loss: 0.030682\n", "epoch 2, train loss: 0.000100\n", "epoch 3, train loss: 0.000049\n", "epoch 4, train loss: 0.000049\n", "epoch 5, train loss: 0.000049\n", "epoch 6, train loss: 0.000049\n", "epoch 7, train loss: 0.000049\n", "epoch 8, train loss: 0.000049\n", "epoch 9, train loss: 0.000049\n", "epoch 10, train loss: 0.000049\n", "epoch 11, train loss: 0.000049\n", "epoch 12, train loss: 0.000049\n", "epoch 13, train loss: 0.000049\n", "epoch 14, train loss: 0.000049\n", "epoch 15, train loss: 0.000049\n", "epoch 16, train loss: 0.000049\n", "epoch 17, train loss: 0.000049\n", "epoch 18, train loss: 0.000049\n", "epoch 19, train loss: 0.000049\n", "epoch 20, train loss: 0.000049\n" ] } ], "execution_count": 45 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.085057122Z", "start_time": "2026-03-15T06:40:57.045310900Z" } }, "cell_type": "code", "source": [ "print(f'w的估计误差: {true_w - w.reshape(true_w.shape)}')\n", "print(f'b的估计误差: {true_b - b}')" ], "id": "8199439fa7f26309", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "w的估计误差: tensor([-0.0002, 0.0003], grad_fn=)\n", "b的估计误差: tensor([0.0002], grad_fn=)\n" ] } ], "execution_count": 46 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.146334186Z", "start_time": "2026-03-15T06:40:57.086581923Z" } }, "cell_type": "code", "source": [ "from torch.utils import data\n", "true_w = torch.tensor([2,-3.4])\n", "true_b = 4.2\n", "features,labels=synthetic_data(true_w, true_b, 1000)\n", "def load_array(data_arrays,batch_size,is_train=True):\n", " dataset = data.TensorDataset(*data_arrays)\n", " return data.DataLoader(dataset,batch_size,shuffle=is_train)\n", "batch_size = 10\n", "data_iter = load_array((features,labels),batch_size)" ], "id": "560d537dcbb5a335", "outputs": [], "execution_count": 47 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.187559751Z", "start_time": "2026-03-15T06:40:57.147857709Z" } }, "cell_type": "code", "source": [ "from torch import nn\n", "net = nn.Sequential(nn.Linear(2, 1))\n", "net[0].weight.data.normal_(0,0.001)\n", "net[0].bias.data.fill_(0)" ], "id": "c54fe059d6fd20de", "outputs": [ { "data": { "text/plain": [ "tensor([0.])" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 48 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.523547926Z", "start_time": "2026-03-15T06:40:57.191697380Z" } }, "cell_type": "code", "source": [ "loss = nn.MSELoss()\n", "trainer = torch.optim.SGD(net.parameters(), lr=0.01)\n", "num_epochs = 3\n", "for epoch in range(num_epochs):\n", " for X, y in data_iter:\n", " l = loss(net(X) ,y)\n", " trainer.zero_grad()\n", " l.backward()\n", " trainer.step()\n", " l = loss(net(features), labels)\n", " print(f'epoch {epoch + 1}, loss {l:f}')\n" ], "id": "e8a44851125b7cc6", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "epoch 1, loss 0.599957\n", "epoch 2, loss 0.011503\n", "epoch 3, loss 0.000325\n" ] } ], "execution_count": 49 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.637796611Z", "start_time": "2026-03-15T06:40:57.539577276Z" } }, "cell_type": "code", "source": [ "import torchvision\n", "from torchvision import transforms\n", "trans =transforms.ToTensor()\n", "mnist_train = torchvision.datasets.FashionMNIST(root=\"./data\",train=True,transform=trans,download=False)\n", "mnist_test = torchvision.datasets.FashionMNIST(root=\"./data\",train=False,transform=trans,download=False)\n" ], "id": "bd4e8a65ccd03177", "outputs": [], "execution_count": 50 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.669099255Z", "start_time": "2026-03-15T06:40:57.639295575Z" } }, "cell_type": "code", "source": [ "use_svg_display()\n", "len(mnist_train),len(mnist_test)" ], "id": "ed2c915af7f6a76a", "outputs": [ { "data": { "text/plain": [ "(60000, 10000)" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 51 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.717512337Z", "start_time": "2026-03-15T06:40:57.672873756Z" } }, "cell_type": "code", "source": "mnist_train[0][0].shape", "id": "4df1cbc292aa5981", "outputs": [ { "data": { "text/plain": [ "torch.Size([1, 28, 28])" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 52 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.739205016Z", "start_time": "2026-03-15T06:40:57.719179425Z" } }, "cell_type": "code", "source": [ "def get_fashion_mnist_labels(labels):\n", " text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',\n", "'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']\n", " return [text_labels[int(i)] for i in labels]\n" ], "id": "332f3d6da0bafbe8", "outputs": [], "execution_count": 53 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.764139878Z", "start_time": "2026-03-15T06:40:57.754725053Z" } }, "cell_type": "code", "source": [ "def show_images(imgs, num_rows, num_cols, titles=None, scale=1): #@save\n", " \"\"\"绘制图像列表\"\"\"\n", " figsize = (num_cols * scale, num_rows * scale)\n", " _, axes = plt.subplots(num_rows, num_cols, figsize=figsize)\n", " axes = axes.flatten()\n", " for i, (ax, img) in enumerate(zip(axes, imgs)):\n", " if torch.is_tensor(img):\n", " # 图片张量\n", " ax.imshow(img.numpy())\n", " else:\n", " # PIL图片\n", " ax.imshow(img)\n", " ax.axes.get_xaxis().set_visible(False)\n", " ax.axes.get_yaxis().set_visible(False)\n", " if titles:\n", " ax.set_title(titles[i])\n", " return axes" ], "id": "c83202fe9b0ab487", "outputs": [], "execution_count": 54 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:40:57.957479055Z", "start_time": "2026-03-15T06:40:57.765366722Z" } }, "cell_type": "code", "source": [ "X, y = next(iter(data.DataLoader(mnist_train, batch_size=18)))\n", "print(X.shape)\n", "show_images(X.reshape(18, 28, 28), 2, 9, titles=get_fashion_mnist_labels(y));" ], "id": "cf4abd8370d55416", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([18, 1, 28, 28])\n" ] }, { "data": { "text/plain": [ "
" ], "image/svg+xml": "\n\n\n \n \n \n \n 2026-03-15T14:40:57.897836\n image/svg+xml\n \n \n Matplotlib v3.10.8, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 55 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:00.262791420Z", "start_time": "2026-03-15T06:40:57.970609683Z" } }, "cell_type": "code", "source": [ "batch_size = 256\n", "def get_dataloader_workers():\n", " \"\"\"使用4个进程来读取数据\"\"\"\n", " return 4\n", "\n", "train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,\n", "num_workers=get_dataloader_workers())\n", "timer = Timer()\n", "for X, y in train_iter:\n", " continue\n", "f'{timer.stop():.2f} sec'" ], "id": "552769fbffc16142", "outputs": [ { "data": { "text/plain": [ "'2.26 sec'" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 56 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:00.481904106Z", "start_time": "2026-03-15T06:41:00.308644956Z" } }, "cell_type": "code", "source": [ "def load_data_fashion_mnist(batch_size, resize=None):\n", " \"\"\"下载Fashion-MNIST数据集,然后将其加载到内存中\"\"\"\n", " trans = [transforms.ToTensor()]\n", " if resize:\n", " trans.insert(0, transforms.Resize(resize))\n", " trans = transforms.Compose(trans)\n", " mnist_train = torchvision.datasets.FashionMNIST(\n", " root=\"./data\", train=True, transform=trans, download=False)\n", " mnist_test = torchvision.datasets.FashionMNIST(\n", " root=\"./data\", train=False, transform=trans, download=False)\n", " return (data.DataLoader(mnist_train, batch_size, shuffle=True,\n", " num_workers=get_dataloader_workers()),\n", " data.DataLoader(mnist_test, batch_size, shuffle=False,\n", " num_workers=get_dataloader_workers()))" ], "id": "aa81880abd86cae6", "outputs": [], "execution_count": 57 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.218194285Z", "start_time": "2026-03-15T06:41:00.632922086Z" } }, "cell_type": "code", "source": [ "train_iter, test_iter = load_data_fashion_mnist(32, resize=64)\n", "for X, y in train_iter:\n", " print(X.shape, X.dtype, y.shape, y.dtype)\n", " break" ], "id": "4248a103f745154", "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "torch.Size([32, 1, 64, 64]) torch.float32 torch.Size([32]) torch.int64\n" ] } ], "execution_count": 58 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.319582689Z", "start_time": "2026-03-15T06:41:02.252523696Z" } }, "cell_type": "code", "source": [ "from IPython import display\n", "batch_size = 256\n", "train_iter, test_iter = load_data_fashion_mnist(32)\n", "num_inputs = 784\n", "num_outputs = 10\n", "W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True)\n", "b = torch.zeros(num_outputs, requires_grad=True)\n", "X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])\n", "X.sum(0, keepdim=True), X.sum(1, keepdim=True)\n" ], "id": "94c52f0cca88ef48", "outputs": [ { "data": { "text/plain": [ "(tensor([[5., 7., 9.]]),\n", " tensor([[ 6.],\n", " [15.]]))" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 59 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.375197243Z", "start_time": "2026-03-15T06:41:02.320989852Z" } }, "cell_type": "code", "source": [ "def softmax(X):\n", " X_exp = torch.exp(X)\n", " partition = X_exp.sum(1, keepdim=True)\n", " return X_exp / partition # 这里应用了广播机制\n", "X = torch.normal(0, 1, (2, 5))\n", "X_prob = softmax(X)\n", "X_prob, X_prob.sum(1)" ], "id": "c4ab34373c5a664e", "outputs": [ { "data": { "text/plain": [ "(tensor([[0.4360, 0.2195, 0.2044, 0.0829, 0.0571],\n", " [0.0678, 0.3243, 0.2988, 0.0572, 0.2519]]),\n", " tensor([1.0000, 1.0000]))" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 60 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.400574302Z", "start_time": "2026-03-15T06:41:02.379951465Z" } }, "cell_type": "code", "source": [ "def net(X):\n", " return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b)" ], "id": "6eacc53b2b9738af", "outputs": [], "execution_count": 61 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.433540648Z", "start_time": "2026-03-15T06:41:02.402525751Z" } }, "cell_type": "code", "source": [ "y = torch.tensor([0, 2])\n", "y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])\n", "y_hat[[0, 1], y]" ], "id": "698449b4dafb545c", "outputs": [ { "data": { "text/plain": [ "tensor([0.1000, 0.5000])" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 62 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.473364236Z", "start_time": "2026-03-15T06:41:02.438405972Z" } }, "cell_type": "code", "source": [ "def cross_entropy(y_hat, y):\n", " return - torch.log(y_hat[range(len(y_hat)), y])\n", "cross_entropy(y_hat, y)" ], "id": "1720369fc8568c8c", "outputs": [ { "data": { "text/plain": [ "tensor([2.3026, 0.6931])" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 63 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.495413592Z", "start_time": "2026-03-15T06:41:02.475628534Z" } }, "cell_type": "code", "source": [ "def accuracy(y_hat, y): #@save\n", " \"\"\"计算预测正确的数量\"\"\"\n", " if len(y_hat.shape) > 1 and y_hat.shape[1] > 1:\n", " y_hat = y_hat.argmax(axis=1)\n", " cmp = y_hat.type(y.dtype) == y\n", " return float(cmp.type(y.dtype).sum())\n", "\n", "accuracy(y_hat, y)/len(y)" ], "id": "e65719500a64ed87", "outputs": [ { "data": { "text/plain": [ "0.5" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 64 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.505437086Z", "start_time": "2026-03-15T06:41:02.497345583Z" } }, "cell_type": "code", "source": [ "class Accumulator: #@save\n", " \"\"\"在n个变量上累加\"\"\"\n", " def __init__(self, n):\n", " self.data = [0.0] * n\n", " def add(self, *args):\n", " self.data = [a + float(b) for a, b in zip(self.data, args)]\n", " def reset(self):\n", " self.data = [0.0] * len(self.data)\n", " def __getitem__(self, idx):\n", " return self.data[idx]\n" ], "id": "f1eebb35ff2e9fea", "outputs": [], "execution_count": 65 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:02.526181989Z", "start_time": "2026-03-15T06:41:02.506819558Z" } }, "cell_type": "code", "source": [ "def evaluate_accuracy(net, data_iter): #@save\n", " \"\"\"计算在指定数据集上模型的精度\"\"\"\n", " if isinstance(net, torch.nn.Module):\n", " net.eval() # 将模型设置为评估模式\n", " metric = Accumulator(2) # 正确预测数、预测总数\n", " with torch.no_grad():\n", " for X, y in data_iter:\n", " metric.add(accuracy(net(X), y), y.numel())\n", " return metric[0] / metric[1]\n" ], "id": "bc2beb5f2d6afe7e", "outputs": [], "execution_count": 66 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:06.805858093Z", "start_time": "2026-03-15T06:41:02.527858694Z" } }, "cell_type": "code", "source": "evaluate_accuracy(net, test_iter)", "id": "65bcfb7e40c1a98b", "outputs": [ { "data": { "text/plain": [ "0.0498" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "execution_count": 67 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:06.843120784Z", "start_time": "2026-03-15T06:41:06.827746920Z" } }, "cell_type": "code", "source": [ "def train_epoch_ch3(net, train_iter, loss, updater): #@save\n", " \"\"\"训练模型一个迭代周期(定义见第3章)\"\"\"\n", " # 将模型设置为训练模式\n", " if isinstance(net, torch.nn.Module):\n", " net.train()\n", " # 训练损失总和、训练准确度总和、样本数\n", " metric = Accumulator(3)\n", " for X, y in train_iter:\n", " # 计算梯度并更新参数\n", " y_hat = net(X)\n", " l = loss(y_hat, y)\n", " if isinstance(updater, torch.optim.Optimizer):\n", " # 使用PyTorch内置的优化器和损失函数\n", " updater.zero_grad()\n", " l.mean().backward()\n", " updater.step()\n", " else:\n", " # 使用定制的优化器和损失函数\n", " l.sum().backward()\n", " updater(X.shape[0])\n", " metric.add(float(l.sum()), accuracy(y_hat, y), y.numel())\n", "# 返回训练损失和训练精度\n", " return metric[0] / metric[2], metric[1] / metric[2]" ], "id": "2faf1dcc6c023a53", "outputs": [], "execution_count": 68 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:06.897158404Z", "start_time": "2026-03-15T06:41:06.851017516Z" } }, "cell_type": "code", "source": [ "class Animator: #@save\n", " \"\"\"在动画中绘制数据\"\"\"\n", " def __init__(self, xlabel=None, ylabel=None, legend=None, xlim=None,\n", " ylim=None, xscale='linear', yscale='linear',\n", " fmts=('-', 'm--', 'g-.', 'r:'), nrows=1, ncols=1,\n", " figsize=(3.5, 2.5)):\n", " # 增量地绘制多条线\n", " if legend is None:\n", " legend = []\n", " use_svg_display()\n", " self.fig, self.axes = plt.subplots(nrows, ncols, figsize=figsize)\n", " if nrows * ncols == 1:\n", " self.axes = [self.axes, ]\n", " # 使用lambda函数捕获参数\n", " self.config_axes = lambda: set_axes(\n", " self.axes[0], xlabel, ylabel, xlim, ylim, xscale, yscale, legend)\n", " self.X, self.Y, self.fmts = None, None, fmts\n", " def add(self, x, y):\n", " # 向图表中添加多个数据点\n", " if not hasattr(y, \"__len__\"):\n", " y = [y]\n", " n = len(y)\n", " if not hasattr(x, \"__len__\"):\n", " x = [x] * n\n", " if not self.X:\n", " self.X = [[] for _ in range(n)]\n", " if not self.Y:\n", " self.Y = [[] for _ in range(n)]\n", " for i, (a, b) in enumerate(zip(x, y)):\n", " if a is not None and b is not None:\n", " self.X[i].append(a)\n", " self.Y[i].append(b)\n", " self.axes[0].cla()\n", " for x, y, fmt in zip(self.X, self.Y, self.fmts):\n", " self.axes[0].plot(x, y, fmt)\n", " self.config_axes()\n", " display.display(self.fig)\n", " display.clear_output(wait=True)\n" ], "id": "7cd5367ab43c5e5f", "outputs": [], "execution_count": 69 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:06.913685898Z", "start_time": "2026-03-15T06:41:06.898876289Z" } }, "cell_type": "code", "source": [ "def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater): #@save\n", " \"\"\"训练模型(定义见第3章)\"\"\"\n", " animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9],\n", " legend=['train loss', 'train acc', 'test acc'])\n", " for epoch in range(num_epochs):\n", " train_metrics = train_epoch_ch3(net, train_iter, loss, updater)\n", " test_acc = evaluate_accuracy(net, test_iter)\n", " animator.add(epoch + 1, train_metrics + (test_acc,))\n", " train_loss, train_acc = train_metrics\n", " assert train_loss < 0.5, train_loss\n", " assert train_acc <= 1 and train_acc > 0.7, train_acc\n", " assert test_acc <= 1 and test_acc > 0.7, test_acc" ], "id": "b02a143c75fad40", "outputs": [], "execution_count": 70 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:06.945935582Z", "start_time": "2026-03-15T06:41:06.916434775Z" } }, "cell_type": "code", "source": [ "lr = 0.1\n", "def updater(batch_size):\n", " return sgd([W, b], lr, batch_size)" ], "id": "6a97b70779276b61", "outputs": [], "execution_count": 71 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:41:54.907637364Z", "start_time": "2026-03-15T06:41:06.946861739Z" } }, "cell_type": "code", "source": [ "num_epochs = 10\n", "train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)" ], "id": "df3cceb72faee402", "outputs": [ { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001B[31m---------------------------------------------------------------------------\u001B[39m", "\u001B[31mKeyboardInterrupt\u001B[39m Traceback (most recent call last)", "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[72]\u001B[39m\u001B[32m, line 2\u001B[39m\n\u001B[32m 1\u001B[39m num_epochs = \u001B[32m10\u001B[39m\n\u001B[32m----> \u001B[39m\u001B[32m2\u001B[39m \u001B[43mtrain_ch3\u001B[49m\u001B[43m(\u001B[49m\u001B[43mnet\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtrain_iter\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtest_iter\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mcross_entropy\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mnum_epochs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mupdater\u001B[49m\u001B[43m)\u001B[49m\n", "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[70]\u001B[39m\u001B[32m, line 6\u001B[39m, in \u001B[36mtrain_ch3\u001B[39m\u001B[34m(net, train_iter, test_iter, loss, num_epochs, updater)\u001B[39m\n\u001B[32m 3\u001B[39m animator = Animator(xlabel=\u001B[33m'\u001B[39m\u001B[33mepoch\u001B[39m\u001B[33m'\u001B[39m, xlim=[\u001B[32m1\u001B[39m, num_epochs], ylim=[\u001B[32m0.3\u001B[39m, \u001B[32m0.9\u001B[39m],\n\u001B[32m 4\u001B[39m legend=[\u001B[33m'\u001B[39m\u001B[33mtrain loss\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mtrain acc\u001B[39m\u001B[33m'\u001B[39m, \u001B[33m'\u001B[39m\u001B[33mtest acc\u001B[39m\u001B[33m'\u001B[39m])\n\u001B[32m 5\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m epoch \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mrange\u001B[39m(num_epochs):\n\u001B[32m----> \u001B[39m\u001B[32m6\u001B[39m train_metrics = \u001B[43mtrain_epoch_ch3\u001B[49m\u001B[43m(\u001B[49m\u001B[43mnet\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mtrain_iter\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mloss\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mupdater\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 7\u001B[39m test_acc = evaluate_accuracy(net, test_iter)\n\u001B[32m 8\u001B[39m animator.add(epoch + \u001B[32m1\u001B[39m, train_metrics + (test_acc,))\n", "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[68]\u001B[39m\u001B[32m, line 10\u001B[39m, in \u001B[36mtrain_epoch_ch3\u001B[39m\u001B[34m(net, train_iter, loss, updater)\u001B[39m\n\u001B[32m 7\u001B[39m metric = Accumulator(\u001B[32m3\u001B[39m)\n\u001B[32m 8\u001B[39m \u001B[38;5;28;01mfor\u001B[39;00m X, y \u001B[38;5;129;01min\u001B[39;00m train_iter:\n\u001B[32m 9\u001B[39m \u001B[38;5;66;03m# 计算梯度并更新参数\u001B[39;00m\n\u001B[32m---> \u001B[39m\u001B[32m10\u001B[39m y_hat = \u001B[43mnet\u001B[49m\u001B[43m(\u001B[49m\u001B[43mX\u001B[49m\u001B[43m)\u001B[49m\n\u001B[32m 11\u001B[39m l = loss(y_hat, y)\n\u001B[32m 12\u001B[39m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(updater, torch.optim.Optimizer):\n\u001B[32m 13\u001B[39m \u001B[38;5;66;03m# 使用PyTorch内置的优化器和损失函数\u001B[39;00m\n", "\u001B[36mCell\u001B[39m\u001B[36m \u001B[39m\u001B[32mIn[61]\u001B[39m\u001B[32m, line 2\u001B[39m, in \u001B[36mnet\u001B[39m\u001B[34m(X)\u001B[39m\n\u001B[32m 1\u001B[39m \u001B[38;5;28;01mdef\u001B[39;00m\u001B[38;5;250m \u001B[39m\u001B[34mnet\u001B[39m(X):\n\u001B[32m----> \u001B[39m\u001B[32m2\u001B[39m \u001B[38;5;28;01mreturn\u001B[39;00m softmax(\u001B[43mtorch\u001B[49m\u001B[43m.\u001B[49m\u001B[43mmatmul\u001B[49m\u001B[43m(\u001B[49m\u001B[43mX\u001B[49m\u001B[43m.\u001B[49m\u001B[43mreshape\u001B[49m\u001B[43m(\u001B[49m\u001B[43m(\u001B[49m\u001B[43m-\u001B[49m\u001B[32;43m1\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mW\u001B[49m\u001B[43m.\u001B[49m\u001B[43mshape\u001B[49m\u001B[43m[\u001B[49m\u001B[32;43m0\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m)\u001B[49m\u001B[43m)\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mW\u001B[49m\u001B[43m)\u001B[49m + b)\n", "\u001B[31mKeyboardInterrupt\u001B[39m: " ] }, { "data": { "text/plain": [ "
" ], "image/svg+xml": "\n\n\n \n \n \n \n 2026-03-15T14:41:54.863039\n image/svg+xml\n \n \n Matplotlib v3.10.8, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 72 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:42:03.186617720Z", "start_time": "2026-03-15T06:42:01.659427155Z" } }, "cell_type": "code", "source": [ "def predict_ch3(net, test_iter, n=6): #@save\n", " \"\"\"预测标签(定义见第3章)\"\"\"\n", " for (X, y),i in zip(test_iter,range(1)):\n", " trues = get_fashion_mnist_labels(y)\n", " preds = get_fashion_mnist_labels(net(X).argmax(axis=1))\n", " titles = [true +'\\n' + pred for true, pred in zip(trues, preds)]\n", " show_images(\n", " X[0:n].reshape((n, 28, 28)), 1, n, titles=titles[0:n])\n", "\n", "predict_ch3(net, test_iter)\n" ], "id": "94f6177bfb40eece", "outputs": [ { "data": { "text/plain": [ "
" ], "image/svg+xml": "\n\n\n \n \n \n \n 2026-03-15T14:42:03.146128\n image/svg+xml\n \n \n Matplotlib v3.10.8, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" }, "metadata": {}, "output_type": "display_data", "jetTransient": { "display_id": null } } ], "execution_count": 73 }, { "metadata": { "ExecuteTime": { "end_time": "2026-03-15T06:42:05.791711771Z", "start_time": "2026-03-15T06:42:05.741066616Z" } }, "cell_type": "code", "source": [ "batch_size = 256\n", "train_iter, test_iter = load_data_fashion_mnist(batch_size)" ], "id": "4a0bfd0479ec7386", "outputs": [], "execution_count": 74 }, { "metadata": {}, "cell_type": "code", "source": [ "net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10))\n", "def init_weights(m):\n", " if type(m) == nn.Linear:\n", " nn.init.normal_(m.weight, std=0.01)\n", "\n", "net.apply(init_weights);\n", "loss = nn.CrossEntropyLoss(reduction='none')\n", "trainer = torch.optim.SGD(net.parameters(), lr=0.1)\n", "num_epochs = 10\n", "train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)" ], "id": "b9808d88f5e6827b", "outputs": [], "execution_count": null }, { "metadata": {}, "cell_type": "code", "source": "", "id": "c25dd146307f58e0", "outputs": [], "execution_count": null } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 5 }