PyTorch实现MNIST手写数字识别:CNN模型搭建与训练避坑指南
简介这是一套基于Python与MNIST数据集实现的CNN手写数字识别项目面向高校毕业设计、课程设计与开发者项目实践。项目基于TensorFlow搭建卷积神经网络模型通过优化器训练并保存模型变量识别阶段复用已保存权重同时借助OpenCV完成灰度化、二值化、降噪与裁剪等图像预处理最终封装为ImgProcess库只需传入图片路径即可调用API完成数字识别整体流程清晰、易扩展。压缩包共68个文件约105.3MB以jpg样本图片、py源码、md项目文档为主另含模型检查点meta、data、checkpoint、index与txt说明等结构完整便于按需查阅和二次开发。目前已有129人浏览/学习该项目。资源包含严格测试过的源码、项目文档和使用教程无论是用于课题参考还是功能延申都能帮助快速跑通并理解从数据预处理、模型构建到训练识别的全链路实现。1. 第一个手写数字识别项目为什么我劝你先别急着自己发明轮子对于一个想用 Python 入门深度学习的开发者MNIST 手写数字识别几乎是最好的第一站它只有 7 万张 28×28 的灰度小图一张普通笔记本显卡就能在几十分钟内跑完一个完整的 CNN 卷积神经网络训练周期。很多人把这个项目当毕业设计或课程设计来做但真正有价值的不是那份源码本身而是你亲手把数据加载、模型搭建、训练评估这条链路跑通后获得的排错能力。这篇文章按我自己的落地顺序走先讲数据预处理再搭模型然后训练调参最后把模型做成一个能画数字的小 Demo每个步骤都给出可以直接抄走的代码和参数。2. 训练之前的功课环境、数据加载与预处理2.1 选 PyTorch 还是 TensorFlow课程设计里我一般这么定先说框架。这个题目只限定 Python CNN没限定框架但实际做毕业设计和课程设计时选错框架会让你多花一倍时间。我的默认选择是 PyTorch原因是动态图机制让报错信息更直观你在 forward 里 print 一个张量的 shape 就能立刻定位问题而 TensorFlow 的 Keras 接口虽然写起来更短但一旦涉及自定义训练循环和调试黑匣子感会很强。另外一个现实因素是 torchvision 提供了 MNIST 数据集的一键下载配合 DataLoader 几乎不用手写数据读取逻辑这对新手非常友好。如果你拿到的项目源码是 TensorFlow 1.x 写的那又是另一套故事——老代码里tf.placeholder、Session.run那套写法现在跑起来满是坑我一般会建议直接按 Pytorch 重写模型而不是去兼容旧版本。这不是说 TensorFlow 不好而是从「拿到源码 → 成功跑通 → 改成自己的项目」这条链路看PyTorch 的试错成本最低。环境方面深度学习课程设计多数不需要 GPUCPU 跑 MNIST 也就是一次训练几分钟的事。我通常建议装 Python 3.9、PyTorch 2.x再加 torchvision 和 matplotlib。安装命令就一条但要注意 PyTorch 的默认源在国外国内网络环境下手动配置国内镜像源能省去很多超时重试的时间。pip install torch torchvision matplotlib pillow -i https://pypi.tuna.tsinghua.edu.cn/simple这段命令里-i指定了清华 PyPI 镜像属于国内从业者最常见的做法核心目的是把下载源换成国内可达的镜像正常安装 PyTorch CPU 版约 200MB 左右网速正常时几分钟能完成。如果你使用的是 Anaconda也可以用conda install pytorch cpuonly -c pytorch但 conda 依赖解析较慢我一般两条都不排斥哪个环境先跑通用哪个。2.2 torchvision 加载 MNIST先解决下载问题torchvision 里加载 MNIST 的代码极短但很多人的第一个坑就出在这里.downloadTrue时程序卡在下载环节甚至报 404 错误——torchvision 下载 MNIST 会 404 是最近一年高频出现的热搜词原因是 MNIST 在 Yann LeCun 官网的原始文件地址变动频繁老版本 torchvision 的硬编码链接会失效。所以我的习惯是第一次先把数据文件手动准备好之后再用downloadFalse加载。你需要准备的其实是四个.gz压缩包训练集图像、训练集标签、测试集图像、测试集标签放到data/MNIST/raw目录下。torchvision 会自动识别这个目录结构不必自己写解压代码。from torchvision import datasets, transforms transform transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) train_dataset datasets.MNIST( root./data, trainTrue, transformtransform, downloadFalse ) test_dataset datasets.MNIST( root./data, trainFalse, transformtransform, downloadFalse )这里root是数据根目录trainTrue表示加载 6 万张训练图trainFalse加载 1 万张测试图。transform里的ToTensor()会把 PIL 图像或者 numpy 数组从 H×W×C 变成 C×H×W 的张量并将像素值从 0~255 缩放到 0~1Normalize((0.1307,), (0.3081,))是 MNIST 数据集的全局均值和标准差归一化后数据分布接近标准正态分布能明显加速收敛。这两个变换的顺序不能反先转张量再归一化否则维度不匹配会直接报错。如果手动下载不方便还有一个几乎零成本的临时办法换用datasets.MNIST的新参数downloadTrue配合新版本 torchvision新版本已经将下载源切到了内部镜像。但我依然建议你把下载好的文件备份一份因为后续每次重新创建环境都要重新下这个数据集的经典程度决定了它值得被你本地留存。2.3 数据增强要不要做MNIST 的特殊性CV 项目里数据增强几乎是标配但 MNIST 是个罕见的反例。像随机裁剪、水平翻转这类增强用在 CIFAR-10 上效果不错用在 MNIST 上反而有害——原因很直接把数字 6 水平翻转后看起来像 9把 7 翻转后完全不伦不类标签却没变等于强行给模型喂错误样本。MNIST 本身已经是 28×28 的小图而人的手写数字除了位置偏移和粗细变化外没有太多可增强的空间。我见过有人对 MNIST 做随机旋转 15 度结果测试集精度从 99% 掉到 97%。如果确实想提升泛化能力更推荐做的是随机仿射变换里的轻微平移把图像平移 1~2 个像素这也符合手写数字的真实分布——大多数人写字并不会严格居中。但课程设计阶段我建议不做任何数据增强先把基准模型跑明白再谈优化。这也是为什么这一节的结论能帮你避开一个常见的「越努力越翻车」操作。数据加载的最后一个细节是DataLoader的shuffle参数。训练集必须设置shuffleTrue否则模型每个 epoch 看到的样本顺序完全一致会学到样本间的排列顺序而不是数字本身测试集不需要 shuffle因为评估时不需要随机性。batch_size我一般取 64这个值对 MNIST 来说在训练速度和收敛稳定性之间比较平衡取 128 也可以但梯度会更平滑收敛稍微慢一点取 32 会让梯度噪声偏大新手调参时容易误判。3. 搭建 CNN 模型从 LeNet-5 到能拿出手的改进版3.1 为什么是 CNN计算一下全连接层的参数量在动手敲代码前我先算一笔账这笔账算完你就能理解这个项目为什么几乎必然用 CNN 而不是全连接网络。MNIST 每张图是 28×28 灰度图摊平就是 784 个像素。如果第一层就直接用全连接输入维度是 784假设隐藏层是 256 个神经元那这一层的权重参数就是 784×256256约 20 万个。再加一层 256 就是个 6 万参数的层两层全连接下来参数轻松破 50 万。在 7 万张训练图上这个模型能训但参数量远大于数据量过拟合几乎是必然的。CNN 解决这个问题的核心是局部连接和权值共享。一个 5×5 的卷积核只有 25 个权重但它在整张图上滑动时把这 25 个权重用在了所有位置上。MNIST 属于 LeNet-5 诞生的年代就是这个原因——手写数字的特征是局部的数字的弧线、拐角、端点都只跟邻近像素有关系不需要看整张图才能判断。这跟人脸识别不一样人脸需要把握五官之间的全局关系所以后来有了更深更宽的网络。池化层的作用则是下采样。2×2 最大池化把特征图边长缩小一半同时保留每个小区域内最显著的响应。它的好处有两个一是参数和计算量直接降到四分之一二是让特征对轻微的位置偏移更不敏感——手写数字笔画本来就有抖动池化恰好把这些抖动吸收掉。3.2 LeNet-5 的结构拆解每一层尺寸变化都得心里有数LeNet-5 是最经典的 MNIST CNN 结构1998 年由 Yann LeCun 提出到现在依然是这个项目最稳妥的起点。它的原始版本用的是 tanh 激活我们现在一般换成 ReLU效果更好。一个现代化的 LeNet-5 长这样输入是 1×28×28经过第一个 5×5 卷积得到 6 个通道此时输出尺寸为 6×24×24接着 ReLU 和 2×2 最大池化变成 6×12×12再经过第二个 5×5 卷积得到 16×8×8再池化变成 16×4×4最后把特征图展平成一维接三层全连接输出维度是 10对应 0~9 十个类别。每一层尺寸变化的规律很简单卷积后尺寸依赖 padding 和 kernel size池化后边长减半。MNIST 输入特别小所以很多人在这个项目里不给卷积加 padding让尺寸自然缩小如果加了 padding2第一层卷积后还是 28×28第二层卷积后是 14×14参数量不变但特征图更大理论上信息保留更多实际训练效果差别不大。课程设计里我建议不加 padding让结构更紧凑也更容易在答辩时讲清楚尺寸变化计算。第二个卷积层输出 16 个通道、4×4 的特征图展平后是 16×4×4256 个值这正好和第一个全连接层的输入维度对得上。这个 256 是怎么来的是答辩时老师最常问的问题建议你在源码注释里写清楚免得现场推导卡壳。3.3 代码实现一个能跑通并能到 99% 以上的 CNN下面这个模型是 LeNet-5 的 PyTorch 实现我加了一点现代改进激活函数用 ReLU最后一个全连接层前加了 Dropout。这段代码可以直接复制到项目里当成核心模型文件。import torch.nn as nn class CNNModel(nn.Module): def __init__(self): super(CNNModel, self).__init__() # 卷积部分提取局部特征 self.conv1 nn.Conv2d(in_channels1, out_channels6, kernel_size5) self.relu1 nn.ReLU() self.pool1 nn.MaxPool2d(kernel_size2, stride2) self.conv2 nn.Conv2d(in_channels6, out_channels16, kernel_size5) self.relu2 nn.ReLU() self.pool2 nn.MaxPool2d(kernel_size2, stride2) # 全连接部分把特征映射到10个类别 self.fc1 nn.Linear(in_features16 * 4 * 4, out_features120) self.relu3 nn.ReLU() self.dropout nn.Dropout(p0.5) self.fc2 nn.Linear(in_features120, out_features84) self.relu4 nn.ReLU() self.fc3 nn.Linear(in_features84, out_features10) def forward(self, x): x self.pool1(self.relu1(self.conv1(x))) x self.pool2(self.relu2(self.conv2(x))) x x.view(x.size(0), -1) # 展平变成 (batch_size, 256) x self.relu3(self.fc1(x)) x self.dropout(x) x self.relu4(self.fc2(x)) x self.fc3(x) return xview(x.size(0), -1)是把每个样本的特征图展平成向量-1表示自动推导该维度大小这里自动算出 256。Dropout(p0.5)只在训练时生效模型状态切到 eval() 后 Dropout 层会自动关闭所以评估时不用担心它干扰结果。前向传播的维度流转是1×28×28 → 6×24×24 → 6×12×12 → 16×8×8 → 16×4×4 → 256 → 120 → 84 → 10。这个模型的参数量大约 4.4 万个和全连接网络动辄几十万相比少了一个数量级但 MNIST 测试精度可以到 99% 左右。其原因就是 CNN 的归纳偏置跟手写数字这种局部特征密集的任务高度契合。如果你嫌这个结构太老想体现一点工作量常见的改进是把第一个卷积层输出通道从 6 改成 32、第二个从 16 改成 64配合 padding 保持尺寸参数量会增加但精度提升有限反而更容易过拟合。3.4 激活函数和 Dropout 的小建议ReLU 是这个项目里毫无争议的首选。Sigmoid 在深层网络里容易梯度消失MNIST 的网络虽然只有几层但用 Sigmoid 的收敛速度就是肉眼可见地比 ReLU 慢。你在答辩时可以提一句ReLU 对负值直接截断为零梯度在正区间恒为 1缓解了深层网络反向传播时的梯度衰减。Dropout 我一般只加在第一层全连接后面并且概率设为 0.5。卷积层的特征图本身已经通过池化做了降维再在卷积层加 Dropout 对 MNIST 这种小模型帮助不大。加在最后的全连接层则是性价比最高的位置因为这个位置的参数量占整个模型的比重最大最容易过拟合。另外有个容易被忽略的细节模型定义里的 Dropout 在训练和评估时行为不同这由model.train()和model.eval()控制如果忘了切状态训练完的模型在测试时精度会偏低这是新手最容易踩的隐藏坑。4. 训练主循环损失、优化器与指标怎么看4.1 训练代码epoch、batch、loss 的完整流程模型定义完下一步就是训练。训练这个环节看起来就十几行代码但里边的细节决定了你能不能稳定收敛。我给出最朴素也最可靠的一版训练循环没有提前停止没有学习率调度先把链路跑通。import torch.optim as optim device torch.device(cuda if torch.cuda.is_available() else cpu) model CNNModel().to(device) criterion nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) epochs 10 for epoch in range(epochs): model.train() total_loss 0.0 for images, labels in train_loader: images, labels images.to(device), labels.to(device) optimizer.zero_grad() outputs model(images) loss criterion(outputs, labels) loss.backward() optimizer.step() total_loss loss.item() avg_loss total_loss / len(train_loader) print(fEpoch {epoch1}/{epochs}, Loss: {avg_loss:.4f})这里的几个关键操作我逐个说明。optimizer.zero_grad()必须放在每次反向传播之前因为 PyTorch 的梯度默认会累积不清零的话上一批数据的梯度会加到本批上loss 曲线会异常震荡。criterion用的是CrossEntropyLoss它把 Softmax 和交叉熵合在了一步所以你模型最后一层输出的原始 logits 直接传给 loss 即可不需要自己在模型里加 Softmax。loss.backward()计算梯度optimizer.step()更新参数顺序不可调换。images.to(device)把数据搬到 GPU 或 CPUMNIST 训练集有 6 万张图batch_size64 时一个 epoch 大约 938 个 batch10 个 epoch 就是 9380 次参数更新。CPU 跑这 10 个 epoch 大约需要 5~10 分钟GPU 上是 1 分钟内的事。如果你用 CPU 发现每轮要几分钟是正常现象。4.2 优化器和学习率Adam 与 SGD 的取舍Adam 是这个项目的默认优化器学习率 0.001 几乎不需要调。Adam 的优点是自适应学习率对初始学习率不敏感哪怕你设成 0.01 它也能慢慢收敛只是后期可能会在最优解附近震荡。SGD 需要手动调学习率、动量收敛更慢但最终精度往往比 Adam 略高一点——在 MNIST 上这个差距约 0.1%完全感知不到。如果你想让训练过程更像「标准流程」可以在答辩时展示一份参数对照表说明你调过的几组参数。我自己平时会记录一张小表既方便自己复现也让项目文档更扎实参数推荐值备注epochs10从第 8 轮起 loss 几乎不降batch_size6432 偏慢128 略影响收敛optimizerAdam默认 betas 即可lr0.001调大至 0.01 会发散dropout0.5只加在第一个全连接层后Learning rate 是这个项目最典型的「玄学」参数我见过不少人把 lr 设成 0.1然后眼睁睁看着 loss 跳到 NaN。一个实用的检查方法是第一个 epoch 结束后如果 loss 比随机初始化时的 2.3 还高先怀疑 lr 过大。交叉熵损失在 10 分类下随机猜测时约等于 ln(10)2.302loss 明显高于这个数说明模型根本没在学大概率是学习率或者数据归一化出了问题。4.3 测试集和验证集别让精度数字骗了你MNIST 官方划分是 6 万训练 1 万测试。但你做课程设计时最好从 6 万里再切出 5000 张当验证集剩下的 55000 张当训练集。原因很简单如果你一直拿测试集调参测试集的精度就失去了可信度因为你已经间接地把测试集的信息用在了模型选择上。验证集则是用来观察训练过程的每个 epoch 结束后计算一下验证集精度看模型有没有过拟合。验证集划分用random_split就够注意先设置随机种子保证结果可复现from torch.utils.data import random_split total len(train_dataset) train_subset, val_subset random_split( train_dataset, [total - 5000, 5000], generatortorch.Generator().manual_seed(42) ) train_loader DataLoader(train_subset, batch_size64, shuffleTrue) val_loader DataLoader(val_subset, batch_size64, shuffleFalse)这里的原理是验证集和训练集必须来自同一分布随机切分能避免按顺序切分时可能引入的类别分布偏差。manual_seed(42)是固定随机数种子跑出来的结果完全可复现这在写实验报告的时候是刚需。评估时记得model.eval()并且整个循环包在with torch.no_grad():里关闭梯度计算以省内存并避免影响模型状态。这个细节卡了很多新手忘了model.eval()时 Dropout 还在随机丢弃同一批数据测两次结果不同就会怀疑模型是不是坏了。5. 常见问题与避坑从 404 到玄学收敛的 5 条记录5.1 现象torchvision 下载 MNIST 报 404 或卡住我见过最频繁的报错就是torchvision从官方源下载 MNIST 时返回 404或者下载到一半超时。原因已经提过原始数据集托管在外部服务器链接结构变化后老版本 torchvision 的固定地址失效加上国内访问该服务器时网络路径不稳定几乎没办法根治只能本地绕行。解决先手动把四个.gz文件下到本地放进data/MNIST/raw目录然后在代码里用downloadFalse。如果不想手动找文件还有一个更省事的方式用新版本 torchvision0.19 以上的downloadTrue它内部已经换用了可用的镜像源。判断自己 torchvision 版本用python -c import torchvision; print(torchvision.__version__)低于 0.17 的强烈建议直接升级而不是去折腾旧版下载逻辑。5.2 现象loss 在 0.6 左右不再下降精度停在 97%这个现象我遇到太多次了尤其在一些改动过的模型上。原因有三类一是学习率偏大导致在局部最优附近来回震荡二是模型结构里少了 ReLU 或者错用了 Pooling三是数据归一化忘了做像素值还在 0~255 的范围梯度数值太大把权重推到了异常区间。解决先确认transform里有Normalize没有就加上。再把 lr 调小一半观察 3 个 epoch如果 loss 开始继续下降就说明是学习率问题。最后检查模型结构里每个卷积后面是否都有激活函数连续两个卷积之间没有激活会让这部分退化成线性变换模型表达能力大幅下降。5.3 现象训练精度 99.5%但用自己写的数字图一张都识别不对这是典型的过拟合到数据集偏置或者推理预处理不一致。MNIST 的图像是黑底白字、数字居中、笔画粗且规整你拿手机拍的白纸黑字照片直接喂给模型分布完全不同识别率自然暴跌。解决把你的测试图片也处理成 28×28 灰度图做和训练一样的归一化并且尽量让数字居中。如果用的是自己画的图片可以用 PIL 预处理先转灰度convert(L)缩放到 28×28再用ToTensor和Normalize。这里最容易忽略的是灰度反转MNIST 数字是白色 255、背景黑色 0而扫描图片往往是白底黑字你要用255 - img把前景色反转否则模型看到的特征正好反过来精度直接崩到 10% 等于随机猜。5.4 现象单张图片预测时RuntimeError: Expected 4D input模型在训练时接收的输入是四维张量(batch, channel, height, width)但很多人做单张图推理时直接喂了一个三维张量(1, 28, 28)进去于是报维度错误。原因就是没有补 batch 维度。解决在图片张量上调用img.unsqueeze(0)增加一维变成(1, 1, 28, 28)。另外还要注意图片张量必须是浮点型并且已经归一化很多新手从 PIL 直接转来的是 uint8需要先.float()再除以 255。推理用的图要和训练用同一种预处理链这是这条坑的根子。5.5 现象数据路径包含中文名程序报找不到文件Windows 环境下 PyTorch 的 DataLoader 读取含中文的路径偶尔会报编码错误尤其当root./数据或当前用户名为中文时。原因是 Python 在部分 Windows 编码环境下对非 ASCII 路径处理不稳定。解决把项目和数据目录全部改成英文字符data、models、outputs这种命名在课程设计里足够清晰还能避免答辩换电脑时路径兼容性问题。如果你一定需要用中文路径可以在代码开头设置import os; os.environ[PYTHONUTF8] 1但这是补救手段不如直接改名省心。6. 把模型用起来性能验证与一个 Tkinter 手写板 Demo模型训练完最后一步要做两件事一是用测试集做一次干净的最终验证二是把模型打包成一个可以交互的东西。对毕业设计来说能演示比能跑通重要得多一个画板 Demo 能在答辩时直接抓住注意力。Tkinter 是 Python 自带 GUI 库不需要额外安装配合 PIL 就能做画板。核心思路是用 Canvas 捕获鼠标拖动的坐标把笔画画上去的同时把轨迹记录下来鼠标松开后把 Canvas 坐标系的图像转成 28×28 灰度图再走一遍训练时的预处理最后model.predict输出概率最高的数字。import torch from PIL import Image, ImageDraw def canvas_to_tensor(canvas, bbox): # canvas: Tkinter Canvas 对象 img Image.new(L, (400, 400), black) draw ImageDraw.Draw(img) # 从 bbox 中取出落在矩形内的事件坐标在 img 上画白色轨迹 for x1, y1, x2, y2 in bbox: draw.line([(x1, y1), (x2, y2)], fillwhite, width16) img img.resize((28, 28), Image.LANCZOS) img_tensor torch.tensor( list(img.getdata()), dtypetorch.float32 ).view(1, 28, 28) / 255.0 img_tensor (img_tensor - 0.1307) / 0.3081 return img_tensor.unsqueeze(0)这段代码把 400×400 画板缩放到 28×28除以 255 归一化到 0~1再做标准化和训练时的Normalize完全一致。注意这里不再做灰度反转因为画板背景设为黑色、画笔为白色方向和 MNIST 训练集一致。缩放用LANCZOS重采样可以保留边缘细节实测比默认的BILINEAR识别效果好一截这也是手写数字识别项目里一个容易被低估的细节。我自己的一个习惯是保留每一次训练后的模型文件和训练曲线图文件名带时间戳这样答辩时能准确说出「这个模型是在哪次实验之后定下来的」。遇到课程设计需要上交的源码包里项目文档我一般会附三样东西环境要求、代码结构说明、训练和推理的运行命令。这也是我做完几个类似项目后总结出的最省事的交付方式。希望这个项目能让你把 MNIST 和 CNN 这条路彻底走通真正把它变成自己的东西——希望帮到你。本文还有配套的精品资源点击获取

相关新闻

免费C++小游戏集合:源码解析、环境配置与调试实战

免费C++小游戏集合:源码解析、环境配置与调试实战

简介:一份收录了多种经典小游戏的C代码合集,面向初学编程的读者和游戏开发爱好者。通过阅读、运行和修改这些源码,可以系统巩固变量、循环、条件判断、函数、数组以及类与对象等C核心概念。压缩包内共117个文件,以115个cpp源文件为…

2026/10/11 14:11:21 阅读更多 →
Django+Python影城售票系统:从数据建模到并发锁座的完整实战

Django+Python影城售票系统:从数据建模到并发锁座的完整实战

做这个项目的人我见过不少,各种课设、毕设、还有想转行拿来做作品集的,但说实话,十个里有八个做的只是“换皮图书管理系统”——能增删改查电影和场次,再让用户注册登录,然后就没然后了。前阵子我帮人改造一个类似的模…

2026/10/11 14:11:21 阅读更多 →
@reach/router 程序化导航完全指南:navigate() API 用法与源码原理剖析

@reach/router 程序化导航完全指南:navigate() API 用法与源码原理剖析

前端 【免费下载链接】router 项目地址&#xff1a; https://gitcode.com/gh_mirrors/rou/router 点击查看 免费下载 本文以 reach/router 的 navigate 函数为核心&#xff0c;系统讲解在 React 应用中如何通过代码触发路由跳转&#xff08;而非依赖用户点击 <Link>&…

2026/10/11 14:10:20 阅读更多 →

最新新闻

现代机器人学课后答案:Grübler公式与自由度验算方法

现代机器人学课后答案:Grübler公式与自由度验算方法

简介&#xff1a;《现代机器人学》&#xff08;Modern Robotics: Mechanics, Planning, and Control&#xff09;官方配套课后习题答案&#xff0c;内容覆盖第2至第13章&#xff0c;涵盖自由度计算、运动学、动力学、路径规划与控制理论等核心主题。资源为单个PDF文件&#xff…

2026/10/11 15:04:53 阅读更多 →
贝叶斯网络入门:从DAG到后验概率推理与Python实践

贝叶斯网络入门:从DAG到后验概率推理与Python实践

简介&#xff1a;贝叶斯网络简介讲课稿是一份面向人工智能、机器学习初学者及课程教师的PPT教学资源&#xff0c;系统讲解贝叶斯网络如何用有向无环图表达变量依赖、以条件概率表量化不确定关系&#xff0c;并给出清晰的认知路径。内容从朱迪亚•佩尔1986年提出的背景展开&…

2026/10/11 15:04:53 阅读更多 →
Gatsby 嵌入 Twitter 推文与组件:gatsby-plugin-twitter 的配置、懒加载机制与版本演进解读

Gatsby 嵌入 Twitter 推文与组件:gatsby-plugin-twitter 的配置、懒加载机制与版本演进解读

前端静态站点Web框架 【免费下载链接】gatsby React-based framework with performance, scalability, and security built in. 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ga/gatsby 点击查看 免费下载 本文围绕 Gatsby 官方插件 gatsby-plugin-twitter 展开&…

2026/10/11 15:04:53 阅读更多 →
RESTful服务中Hibernate实战:事务边界与懒加载优化

RESTful服务中Hibernate实战:事务边界与懒加载优化

1. RESTful服务要用ORM&#xff0c;到底图什么&#xff1f; 先说个我观察到的现象。很多做REST接口的同学&#xff0c;一听到Hibernate就皱眉&#xff0c;觉得它重、慢、不好控制&#xff0c;宁愿手写JDBC或者直接用MyBatis。但如果你搞的是以业务逻辑为核心、实体关系复杂、需…

2026/10/11 15:04:53 阅读更多 →
MATLAB聚类分析实战:从K-means到DBSCAN的完整指南

MATLAB聚类分析实战:从K-means到DBSCAN的完整指南

简介&#xff1a;面向数据挖掘、模式识别与市场细分等应用场景的聚类分析专题课件&#xff0c;围绕系统聚类、快速聚类及MATLAB实现展开&#xff0c;讲解Q型与R型聚类、样品间距离度量、谱系聚类步骤&#xff0c;并结合pdist、linkage、dendrogram、cophenet、cluster等函数给出…

2026/10/11 15:04:53 阅读更多 →
华为无线解决方案报告书:从设计到交付的WLAN避坑指南

华为无线解决方案报告书:从设计到交付的WLAN避坑指南

简介&#xff1a;这是一份华为无线解决方案报告书&#xff0c;以某集团无线覆盖项目为背景&#xff0c;系统讲解无线局域网从设计到落地的完整思路&#xff0c;适合网络工程师、方案架构师及高校通信相关专业学生参考。报告重点涵盖网络设计原则、无线信号质量分析、总体架构、…

2026/10/11 15:03:52 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →