<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="https://wuguangzheng.top/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <atom:link href="https://wuguangzheng.top/rss.xml" rel="self" type="application/rss+xml"/>
    <title>又菜又爱学的博客</title>
    <link>https://wuguangzheng.top/</link>
    <description>记录技术学习和生活思考的个人博客</description>
    <language>zh-CN</language>
    <pubDate>Sat, 14 Mar 2026 14:33:19 GMT</pubDate>
    <lastBuildDate>Sat, 14 Mar 2026 14:33:19 GMT</lastBuildDate>
    <generator>@vuepress/plugin-feed</generator>
    <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
    <copyright>© 2026 wugz. All rights reserved.</copyright>
    <image>
      <title>又菜又爱学的博客</title>
      <url>https://wuguangzheng.top/./planet.svg</url>
      <link>https://wuguangzheng.top/</link>
    </image>
    <item>
      <title>AI 时代机器学习入门：手写数字分类实战</title>
      <link>https://wuguangzheng.top/blog/x852e0h7/</link>
      <guid>https://wuguangzheng.top/blog/x852e0h7/</guid>
      <source url="https://wuguangzheng.top/rss.xml">AI 时代机器学习入门：手写数字分类实战</source>
      <description>这篇文章带你了解AI时代机器学习入门的超简单方法，通过实战手写数字分类，展示调参、GPU自动调用、更换神经网络等操作的核心流程。</description>
      <pubDate>Sat, 14 Mar 2026 14:32:20 GMT</pubDate>
      <content:encoded><![CDATA[
<h2>40万手写数据实战99.67%准确率，新手也能一键上手</h2>
<p>当下AI浪潮席卷而来，很多朋友想入门机器学习，却总被“复杂的公式”“难懂的模型原理”“繁琐的硬件配置”劝退，觉得这是“大神专属”的技能。但实际体验下来，<strong>机器学习入门的核心从来不是造轮子，而是站在巨人的肩膀上做尝试</strong>——主流框架早已把复杂的底层逻辑封装完毕，调用GPU、调整参数、更换神经网络，本质上只是改几个数字、换一行代码的事。</p>
<p>我近期用PyTorch做了一次手写数字分类实战，基于40万张手写数字数据集，用ResNet18模型训练，全程仅做了基础的参数调整和GPU自动调用，最终跑出了<strong>99.67%的测试准确率</strong>，整个过程没有复杂的操作，甚至新手也能跟着复刻。这也印证了一个结论：<strong>AI时代，机器学习入门的门槛早已大幅降低，勇敢动手尝试，你就已经赢在了起点</strong>。</p>
<p>这篇文章就以这次手写数字分类实战为核心，和大家聊聊机器学习入门那些“超简单”的核心操作，打消你的顾虑，让你敢上手、会上手。</p>
<h3>先破局：机器学习入门，真的不用怕“复杂”</h3>
<p>很多人对机器学习的恐惧，来源于“觉得要先吃透所有原理才能动手”。但实际的工业界和入门实战中，<strong>我们更多是使用现成的框架、现成的模型，核心工作是调参、适配数据、选择合适的网络结构</strong>，而非从0到1写一个神经网络。</p>
<p>就像这次手写数字分类，我全程用的是PyTorch框架，调用了经典的ResNet18模型，没有手写一行卷积层代码；GPU是自动识别调用，不用手动配置显卡驱动和环境；调参就是改几个超参数的数字，更换模型就是换一行调用代码——整个过程的核心是“尝试”，而非“死磕原理”。</p>
<p><strong>入门的关键，是先动手做一个能跑通的项目，在实战中理解逻辑，而非纸上谈兵</strong>。当你能轻松跑通一个手写数字分类项目，再去深究模型原理、参数背后的逻辑，会事半功倍。</p>
<h3>实战落地：40万手写数据，99.67%准确率的简单实现</h3>
<p>先和大家简单说下这次实战的基础情况，让大家有个直观认知：</p>
<ul>
<li>
<p>数据集：402953张手写数字图片，按9:1拆分为训练集和测试集，标签映射为0-9的数字分类；</p>
</li>
<li>
<p>硬件：普通的RTX3080显卡，无需高端算力；</p>
</li>
<li>
<p>模型：直接调用PyTorch内置的ResNet18模型，仅修改输出层并添加Dropout防过拟合；</p>
</li>
<li>
<p>训练结果：9轮训练触发早停，最高测试准确率99.67%，模型泛化能力拉满，无过拟合、无欠拟合。</p>
</li>
</ul>
<p>整个实战的代码核心逻辑不到200行，其中最关键的<strong>GPU调用、调参、更换网络</strong>，加起来不到10行代码——这就是当下机器学习入门的真实状态：框架做了所有重活，我们只需要做简单的“选择和调整”。</p>
<p>接下来，重点和大家聊三个最核心的操作，也是机器学习入门的“基本功”，看完你会发现，原来这么简单！</p>
<h3>核心操作1：调用GPU？一行代码，全自动识别</h3>
<p>很多人觉得“用GPU训练模型”需要复杂的硬件配置、环境调试，其实在PyTorch中，<strong>调用GPU只需要一行代码，框架会自动识别你的电脑是否有可用的GPU，没有则自动切换到CPU</strong>，完全不用手动干预。</p>
<p>核心代码就这一行：</p>
<div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-python"><span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">cuda</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375"> if</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">cuda</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">is_available</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375"> else</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">cpu</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>后续只需要把模型和数据放到这个<code>device</code>上即可，比如：</p>
<div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-python"><span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 模型放到GPU/CPU</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 数据放到GPU/CPU</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>这次实战中，我的RTX3080显卡被自动识别，40万数据的单轮训练仅需4分钟左右，效率拉满；就算你的电脑没有独立显卡，把代码直接运行在CPU上，也能正常训练，只是速度稍慢，完全不影响项目跑通。</p>
<p><strong>总结</strong>：GPU调用无需手动配置，一行代码全自动，新手无脑用就行。</p>
<h3>核心操作2：调参？本质就是改几个数字，试错就好</h3>
<p>调参是机器学习实战中最核心的工作之一，但入门阶段的调参，<strong>完全不需要复杂的调优算法，就是修改几个超参数的数字，根据训练结果试错即可</strong>，甚至可以理解为“改数字，看效果”。</p>
<p>这次手写数字分类实战中，我用到的核心超参数就这几个，全部是直接定义的数字，想调整直接改就行：</p>
<div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-python"><span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">epochs </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 10</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 训练轮数</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">batch_size </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 256</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 批次大小</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">lr </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 5e-4</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 学习率</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">weight_decay </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 5e-5</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 权重衰减</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">dropout_prob </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # Dropout概率，防过拟合</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>比如学习率<code>lr</code>，如果训练时损失下降太慢，就把数字调大一点（比如改成1e-3）；如果损失波动太大、不收敛，就调小一点（比如改成3e-4）；Dropout概率如果模型过拟合，就调大一点（比如0.6），欠拟合就调小一点（比如0.3）。</p>
<p>这次实战中，我把学习率设为5e-4，Dropout设为0.5，batch_size设为256，仅通过这几个简单的数字调整，就实现了模型的快速收敛和高准确率。<strong>入门阶段的调参，没有固定答案，核心是大胆试错，看训练日志的损失和准确率变化，慢慢找到合适的数值</strong>。</p>
<p>甚至可以说，<strong>调参是机器学习入门最有趣的部分</strong>，你会发现改一个小小的数字，模型的效果可能会有天翻地覆的变化，这种“掌控感”，会让你快速找到入门的乐趣。</p>
<h3>核心操作3：换神经网络？一行代码，轻松切换</h3>
<p>很多朋友觉得“设计神经网络”是一件很难的事，其实入门阶段，我们完全不需要自己设计，<strong>PyTorch等框架内置了大量经典的预训练模型（ResNet、VGG、AlexNet等），想更换模型，只需要改一行调用代码就行</strong>。</p>
<p>这次实战中，我用的是ResNet18模型，核心调用代码：</p>
<div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-python"><span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> models</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">resnet18</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">weights</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">None</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 调用ResNet18</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果想换成更深的ResNet34，只需要把代码改成：</p>
<div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-python"><span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> models</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">resnet34</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">weights</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">None</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 调用ResNet34</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果想换成更简单的VGG16，就是：</p>
<div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-python"><span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> models</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">vgg16</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">weights</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">None</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 调用VGG16</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>更换模型后，仅需要根据模型的输出特征数，微调一下最后的全连接层即可，核心逻辑完全不变。这次实战中，我只用了基础的ResNet18，就跑出了99.67%的准确率，足以见得<strong>现成的经典模型，完全能满足入门阶段的所有实战需求</strong>。</p>
<p><strong>总结</strong>：入门阶段不用纠结“如何设计神经网络”，先学会调用现成的经典模型，能根据任务需求切换网络，就是合格的入门者了。</p>
<h3>实战复盘：简单的操作，也能做出顶尖的效果</h3>
<p>看完核心操作，再回头看这次实战的训练日志，更能感受到“简单操作”的力量：</p>
<ul>
<li>
<p>40万张图片的超大数据集，框架自动加载、拆分，无需手动处理数据格式；</p>
</li>
<li>
<p>GPU自动加速，训练效率拉满，单轮训练仅4分钟；</p>
</li>
<li>
<p>简单调参后，模型训练损失持续下降，测试准确率稳定在99%+，Dropout完美抑制过拟合；</p>
</li>
<li>
<p>早停机制自动终止无效训练，最终跑出99.67%的超高准确率，模型泛化能力极强。</p>
</li>
</ul>
<p>整个训练过程没有任何复杂的操作，所有核心步骤都是“调用框架、改数字、换代码”，但最终的效果却堪比专业的实战项目——这就是AI时代机器学习的魅力：<strong>框架把复杂的工作做了，我们只需要做简单的选择和尝试，就能做出不错的成果</strong>。</p>
<h3>写给所有想入门的人：AI时代，勇敢尝试就是最大的收获</h3>
<p>很多朋友迟迟不敢入门机器学习，无非是怕“学不会”“做不出来效果”“搞不懂硬件和模型”。但通过这次手写数字分类的实战，我想和大家说：<strong>AI时代，机器学习的入门门槛已经低到超乎你的想象</strong>。</p>
<ul>
<li>
<p>不用懂复杂的数学公式，先会调用框架就行；</p>
</li>
<li>
<p>不用会设计神经网络，先会用现成的模型就行；</p>
</li>
<li>
<p>不用会配置GPU，框架自动识别就行；</p>
</li>
<li>
<p>不用会复杂的调参算法，先会改数字试错就行。</p>
</li>
</ul>
<p>入门的关键，从来不是“一次性吃透所有知识”，而是<strong>勇敢地动手写第一行代码，跑通第一个项目</strong>。当你能成功跑通一个手写数字分类项目，看到自己的模型跑出90%、95%甚至99%的准确率时，那种成就感会驱动你去深究背后的原理，去学习更高级的调参方法、模型设计思路。</p>
<p>AI时代，机器学习不再是少数人的“专属技能”，而是每个人都可以尝试的“通用工具”。就像这次手写数字分类，40万数据的实战，全程都是简单的操作，却能做出顶尖的效果——这不仅是框架的力量，更是“勇敢尝试”的力量。</p>
<h3>最后：附核心精简代码，动手跑起来！</h3>
<p>为了让大家能直接上手，这里附上本次手写数字分类的核心精简代码，复制到本地，修改数据集路径，就能直接运行，新手也能轻松跑通：</p>
<div class="language-python line-numbers-mode" data-highlighter="shiki" data-ext="python" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-python"><span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torch</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">nn </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">as</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> nn</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">optim </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">as</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> optim</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torchvision </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> models</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">utils</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">data </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> Dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> DataLoader</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">from</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> PIL</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375"> import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> Image</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> re</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> pathlib </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> Path</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> os</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> sklearn</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model_selection </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> train_test_split</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># 进度条库</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">from</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> tqdm </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">import</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> tqdm</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># 🔥 超参数配置（RTX3080 + Windows 专属）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">cuda</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375"> if</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">cuda</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">is_available</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375"> else</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">cpu</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">epochs </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 10</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">min_delta </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.01</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">batch_size </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 256</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">lr </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 5e-4</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">weight_decay </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 5e-5</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">patience </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 5</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">dropout_prob </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # ✨ 新增Dropout概率超参数（可根据过拟合程度调整：0.3~0.7）</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">root_dir </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676"> r</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#AB5E3F;--shiki-dark:#C4704F">E:/project/machine_learning/by_field</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # by_field数据集根目录</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ✅ 数据预处理（黑字白底+轻微倾斜，适配手写数字）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">train_transform </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">Compose</span><span style="--shiki-light:#999999;--shiki-dark:#666666">([</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">RandomRotation</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">degrees</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> fill</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=(</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">255</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 255</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 255</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> expand</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">False</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 轻微倾斜，白色填充</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">RandomCrop</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">128</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> padding</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">2</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 减小padding，避免裁掉数字</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">RandomHorizontalFlip</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">p</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">0</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 手写数字禁用翻转</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">ToTensor</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(),</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">Normalize</span><span style="--shiki-light:#999999;--shiki-dark:#666666">((</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#999999;--shiki-dark:#666666"> (</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">))</span></span>
<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666">])</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">test_transform </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">Compose</span><span style="--shiki-light:#999999;--shiki-dark:#666666">([</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">ToTensor</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(),</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    transforms</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">Normalize</span><span style="--shiki-light:#999999;--shiki-dark:#666666">((</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#999999;--shiki-dark:#666666"> (</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">))</span></span>
<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666">])</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ✅ 自定义数据集（核心适配by_field：仅读digit文件夹+按子文件夹编号映射标签）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># 标签规则：digit子文件夹30→0、31→1、32→2、…、39→9</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">class</span><span style="--shiki-light:#2E8F82;--shiki-dark:#5DA994"> CustomMNISTDataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665">Dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">    def</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> __init__</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> root_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> transform</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">None</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">        self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">root_dir </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> root_dir</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">        self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">transform </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> transform</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">        self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#999999;--shiki-dark:#666666"> []</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">        self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">labels </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#999999;--shiki-dark:#666666"> []</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">        # 递归遍历：所有层级下的digit文件夹 → 仅读取digit的直接子文件夹（30/31/…/39）下的PNG</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        for</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> digit_dir </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">in</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> Path</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">root_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">).</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">rglob</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">digit</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">            if</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> digit_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">is_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">():</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">                # 遍历digit下的子文件夹（30、31...39）</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">                for</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> label_dir </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">in</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> digit_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">iterdir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">():</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">                    if</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> label_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">is_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">():</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">                        # 获取子文件夹编号（30/31/…/39），转换为数字标签</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">                        try</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">                            dir_num </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> int</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">label_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">name</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">                            # 仅处理30-39的文件夹（对应数字0-9），过滤其他无关文件夹</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">                            if</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 30</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676"> &lt;=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> dir_num </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">&lt;=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 39</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">                                label </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> dir_num </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">-</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 30</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 核心映射：30→0，31→1...39→9</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">                                # 读取该文件夹下所有PNG图片（大小写兼容）</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">                                for</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> img_path </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">in</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> label_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">rglob</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">*.[pP][nN][gG]</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">                                    self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">append</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965">str</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_path</span><span style="--shiki-light:#999999;--shiki-dark:#666666">))</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">                                    self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">append</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">label</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">                        except</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> ValueError</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">                            # 跳过非数字命名的文件夹，避免报错</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">                            continue</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">        # 空数据校验</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        if</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676"> ==</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">            raise</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> FileNotFoundError</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">                f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"未在 </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">root_dir</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> 下找到digit文件夹，或digit下无30-39的子文件夹/PNG图片！</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">\n</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">                f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"请检查：1.数据集是by_field 2.存在digit文件夹 3.子文件夹为30-39"</span></span>
<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666">            )</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">        print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"📌 成功匹配：digit下30-39文件夹 → 共加载 </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965">len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> 张手写数字图片"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">    def</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> __len__</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        return</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">    def</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> __getitem__</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> idx</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        img_path </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">[</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">idx</span><span style="--shiki-light:#999999;--shiki-dark:#666666">]</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">        # 读取为RGB（兼容RGBA/单通道PNG，保持和预处理一致）</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        image </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> Image</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">open</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_path</span><span style="--shiki-light:#999999;--shiki-dark:#666666">).</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">convert</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">'</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">RGB</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">'</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        label </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">[</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">idx</span><span style="--shiki-light:#999999;--shiki-dark:#666666">]</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        if</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">            image </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">image</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        return</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> image</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> label</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ✅ 子集数据集（用于9:1训练/测试拆分）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">class</span><span style="--shiki-light:#2E8F82;--shiki-dark:#5DA994"> SubsetMNISTDataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665">Dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">    def</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> __init__</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> transform</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">None</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">        self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> img_paths</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">        self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">labels </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> labels</span></span>
<span class="line"><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">        self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">transform </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> transform</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">    def</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> __len__</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        return</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">    def</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> __getitem__</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> idx</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        img_path </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">[</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">idx</span><span style="--shiki-light:#999999;--shiki-dark:#666666">]</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        image </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> Image</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">open</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_path</span><span style="--shiki-light:#999999;--shiki-dark:#666666">).</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">convert</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">'</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">RGB</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">'</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        label </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">[</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">idx</span><span style="--shiki-light:#999999;--shiki-dark:#666666">]</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        if</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">            image </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076"> self</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">image</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        return</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> image</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> label</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ✅ ResNet18 模型（添加Dropout抑制过拟合）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> models</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">resnet18</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">weights</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">None</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ✨ 核心修改：替换fc层为「Dropout + 全连接」的组合层</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">fc </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> nn</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">Sequential</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    nn</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">Dropout</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">p</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">dropout_prob</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 添加Dropout层，训练时随机丢弃50%的神经元</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    nn</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">Linear</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">fc</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">in_features</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 10</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 输出10类（0-9）</span></span>
<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ✅ 优化器与损失函数（调低学习率，提升收敛性）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">criterion </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> nn</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">CrossEntropyLoss</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># 改用AdamW，正则化效果更好，适合手写数字分类</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">optimizer </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> optim</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">AdamW</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">parameters</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(),</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> lr</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">lr</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> weight_decay</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">weight_decay</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">scheduler </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> optim</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">lr_scheduler</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">ReduceLROnPlateau</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">optimizer</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77"> '</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">max</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">'</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> patience</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">3</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> factor</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">0.5</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ✅ 训练/测试函数（带进度条，实时监控）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">best_acc </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.0</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">counter </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">def</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665"> train_one_epoch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">train</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 训练模式下，Dropout自动启用（随机丢弃神经元）</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    train_loss </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.0</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    pbar </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> tqdm</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> desc</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">训练中</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> colour</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">blue</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">    for</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">in</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> pbar</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> non_blocking</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> non_blocking</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        optimizer</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">zero_grad</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        output </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        loss </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> criterion</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">output</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        loss</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">backward</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        optimizer</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">step</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        train_loss </span><span style="--shiki-light:#999999;--shiki-dark:#666666">+=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> loss</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">item</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">        # 实时显示当前批次损失</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        pbar</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">set_postfix</span><span style="--shiki-light:#999999;--shiki-dark:#666666">({</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">当前损失</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676"> f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loss</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">item</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">:.4f</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">})</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    avg_train_loss </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> train_loss </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">/</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">\n</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">✅ 本轮训练完成 | 平均训练损失: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">avg_train_loss</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">:.4f</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">def</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665"> test_model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">    global</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> best_acc</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> counter</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">eval</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">  # 测试模式下，Dropout自动禁用（所有神经元参与计算）</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    test_loss </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0.0</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    correct </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    pbar </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> tqdm</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> desc</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">测试中</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> colour</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">green</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">    with</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> torch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">no_grad</span><span style="--shiki-light:#999999;--shiki-dark:#666666">():</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        for</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">in</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> pbar</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">            data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> non_blocking</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">),</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">to</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> non_blocking</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">            output </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">            test_loss </span><span style="--shiki-light:#999999;--shiki-dark:#666666">+=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> criterion</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">output</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> target</span><span style="--shiki-light:#999999;--shiki-dark:#666666">).</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">item</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">            pred </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> output</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">argmax</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">dim</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">1</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> keepdim</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">            correct </span><span style="--shiki-light:#999999;--shiki-dark:#666666">+=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> pred</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">eq</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">target</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">view_as</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">pred</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)).</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">sum</span><span style="--shiki-light:#999999;--shiki-dark:#666666">().</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">item</span><span style="--shiki-light:#999999;--shiki-dark:#666666">()</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    test_loss </span><span style="--shiki-light:#999999;--shiki-dark:#666666">/=</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    acc </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 100.0</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676"> *</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> correct </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">/</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">\n</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">🎯 本轮测试完成 | 测试准确率: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">acc</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">:.2f</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">% | 平均测试损失: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">test_loss</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">:.4f</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # 学习率调度+早停+保存最佳模型</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    scheduler</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">step</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">acc</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">    if</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> acc </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">&gt;</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> best_acc </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">+</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> min_delta</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        best_acc </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> acc</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        counter </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 0</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        torch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">save</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">state_dict</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(),</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">best_resnet18_byfield.pth</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">        print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"✅ 保存最佳模型 | 目前最高测试精度: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">best_acc</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">:.2f</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">%"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">    else</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        counter </span><span style="--shiki-light:#999999;--shiki-dark:#666666">+=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 1</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">        print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"⚠️  精度无提升 | </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">counter</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">/</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">patience</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> | 最高精度: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">best_acc</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">:.2f</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">%"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">    return</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> acc</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># 🚀 主程序（Windows稳定版，9:1分层拆分）</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD"># ======================</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">if</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> __name__</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676"> ==</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">__main__</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">🔍 开始加载by_field数据集...</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # 加载全量数据（仅digit文件夹下30-39的图片）</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    full_dataset </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> CustomMNISTDataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">root_dir</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">None</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"✅ 全量数据加载完成：共 </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965">len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">full_dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> 张图片"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # 9:1分层随机拆分（stratify保证训练/测试集标签分布一致）</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    train_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> test_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> train_labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> test_labels </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> train_test_split</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        full_dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">img_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        full_dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span></span>
<span class="line"><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">        test_size</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">0.1</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span></span>
<span class="line"><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">        random_state</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">42</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span></span>
<span class="line"><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">        stratify</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">full_dataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">.</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">labels</span></span>
<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666">    )</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # 构建训练/测试集，分别应用对应变换</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    train_data </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> SubsetMNISTDataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">train_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> train_labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">train_transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    test_data </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> SubsetMNISTDataset</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">test_paths</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> test_labels</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">test_transform</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # Windows安全多进程数据加载器（3080适配，不报错+提速）</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    train_loader </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> DataLoader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        train_data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> batch_size</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">batch_size</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> shuffle</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span></span>
<span class="line"><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">        num_workers</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">1</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> pin_memory</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> persistent_workers</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span></span>
<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666">    )</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">    test_loader </span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> DataLoader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        test_data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> batch_size</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">batch_size</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> shuffle</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">False</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span></span>
<span class="line"><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A">        num_workers</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">1</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> pin_memory</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#B07D48;--shiki-dark:#BD976A"> persistent_workers</span><span style="--shiki-light:#999999;--shiki-dark:#666666">=</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">True</span></span>
<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666">    )</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # 打印训练信息</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">\n</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">⚙️  训练配置 | 设备: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">device</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> | 批次大小: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">batch_size</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> | 学习率: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">lr</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> | Dropout概率: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">dropout_prob</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"📊  数据拆分 | 训练集: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965">len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">train_data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> 张 | 测试集: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965">len</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">test_data</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> 张 (9:1)"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"🚀  开始训练 | 最大轮数: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">epochs</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> | 早停耐心值: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">patience</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}\n</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # 训练主循环</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">    for</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> epoch </span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">in</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965"> range</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91">1</span><span style="--shiki-light:#999999;--shiki-dark:#666666">,</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> epochs </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">+</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91"> 1</span><span style="--shiki-light:#999999;--shiki-dark:#666666">):</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">        print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"======== Epoch </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">epoch</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">/</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">epochs</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D"> ========"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        train_one_epoch</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">train_loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">        test_model</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">test_loader</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">        # 触发早停，终止训练</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">        if</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> counter </span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">&gt;=</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE"> patience</span><span style="--shiki-light:#999999;--shiki-dark:#666666">:</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">            print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">\n</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">📌 触发早停条件，训练提前结束！</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375">            break</span></span>
<span class="line"></span>
<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD">    # 训练完成总结</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">\n</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">🏆 训练全部完成 | 最终最高测试精度: </span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">{</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE">best_acc</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">:.2f</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076">}</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">%"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span>
<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965">    print</span><span style="--shiki-light:#999999;--shiki-dark:#666666">(</span><span style="--shiki-light:#AB5959;--shiki-dark:#CB7676">f</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D">"💾 最佳模型已保存为: best_resnet18_byfield.pth"</span><span style="--shiki-light:#999999;--shiki-dark:#666666">)</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>AI时代，别让“害怕”挡住你的脚步</strong>。机器学习入门真的很简单，调参是改数字，GPU是自动调，换网络是改一行代码——勇敢地动手写第一行代码，跑通第一个项目，你会发现，原来你也能轻松玩转机器学习。</p>
<p>现在，就打开编辑器，敲下第一行代码吧！</p>
]]></content:encoded>
    </item>
    <item>
      <title>圣诞快乐</title>
      <link>https://wuguangzheng.top/blog/820rdx3d/</link>
      <guid>https://wuguangzheng.top/blog/820rdx3d/</guid>
      <source url="https://wuguangzheng.top/rss.xml">圣诞快乐</source>
      <pubDate>Wed, 24 Dec 2025 16:25:34 GMT</pubDate>
      <content:encoded><![CDATA[<!-- 在需要隐藏代码区的 md 文件中，添加以下样式 -->
]]></content:encoded>
    </item>
    <item>
      <title>《阿凡达3》观后感：3小时坐得我腰酸，后排小孩都睡成小猪了</title>
      <link>https://wuguangzheng.top/blog/iu7t71uv/</link>
      <guid>https://wuguangzheng.top/blog/iu7t71uv/</guid>
      <source url="https://wuguangzheng.top/rss.xml">《阿凡达3》观后感：3小时坐得我腰酸，后排小孩都睡成小猪了</source>
      <description>阿凡达3观后感：3小时坐得我腰酸，后排小孩都睡成小猪了</description>
      <pubDate>Mon, 22 Dec 2025 12:14:26 GMT</pubDate>
      <content:encoded><![CDATA[<p>谁懂啊！抱着“年度视觉盛宴”的期待冲了《阿凡达3》，结果全程在“等震撼”和“看时间”中反复横跳😭</p>
<p>先说最期待的视觉效果——真的没get到网传的“顶级震撼”！</p>
<p>第一部阿凡达的森林飞翔、第二部的水下沉浸感，那种“哇塞这世界真的存在”的惊艳感完全没有了。这一部的火山灰场景看着灰蒙蒙的，所谓的“火元素”也只是个背景板，连柴火堆的视觉层次都比它丰富。唯一有点新意的浮空水母商船，也就惊鸿一瞥，跟剧情半毛钱关系没有，纯粹是花钱炫技的无效奇观。</p>
<p>最绝的是后排小孩哥！全程就没安静过，不是在问就是在准备问：“妈妈，结束了吗？”“妈妈，还有多久结束啊？”🤣 平均十分钟追问一次，语气从一开始的小声询问，慢慢变成带着点委屈的嘟囔，到后面直接带着哭腔拉妈妈的手：“我不想看了，什么时候结束呀？”</p>
<p>那魔性的“结束了吗”简直是全场背景音，我旁边的人都忍不住低头憋笑。本来我还在硬撑着看剧情，被他问得我也忍不住掏手机看时间，瞬间共情：这孩子说出了全场的心声啊！这波真实reaction比电影本身还戳人，直接把《阿凡达3》3个半小时的冗长感焊死在公屏上了好吗！</p>
<p>3个半小时的时长真的太磨人了！有效剧情大概也就1小时，剩下的全是重复的家庭戏和套路化的打斗。杰克一家围着“family”反复说教，吵架能吵20分钟没结果，营救戏跟前两部几乎一模一样，天空战+水下战的拼贴组合，看开头就知道结尾。</p>
<p>中途我旁边的情侣换了三次姿势，前排大哥隔十分钟就掏手机看时间，我自己也是全程紧绷着腰杆硬撑，生怕一不小心就跟着后排小孩一起睡过去。离场的时候听到好多人吐槽“还不如二刷别的”，我狠狠共情了！</p>
<p>不是说特效不精良，而是没了技术想象力的支撑，再顶级的工业水准也只剩空洞。现在观众早就不满足于“光看个热闹”了，没了新鲜的世界观和紧凑的剧情，再长的时长、再贵的票价也留不住注意力啊。</p>
<p>总结：不推荐专门冲IMAX！想打卡的建议选最晚场，反正容易犯困，看完直接回家睡觉刚好😴</p>
]]></content:encoded>
    </item>
    <item>
      <title>香港大埔宏福苑火灾：警钟长鸣，消防安全不容忽视</title>
      <link>https://wuguangzheng.top/blog/gdwyfxss/</link>
      <guid>https://wuguangzheng.top/blog/gdwyfxss/</guid>
      <source url="https://wuguangzheng.top/rss.xml">香港大埔宏福苑火灾：警钟长鸣，消防安全不容忽视</source>
      <description>感觉世界是相互联系的</description>
      <pubDate>Fri, 28 Nov 2025 13:56:50 GMT</pubDate>
      <content:encoded><![CDATA[<h2>一、引言：灾难突袭，警钟长鸣</h2>
<p>2025年11月26日，香港新界大埔屋邨宏福苑发生了一起严重的五级火警，造成重大人员伤亡。这场火灾不仅给受害者及其家庭带来了无法估量的伤痛，也暴露了高层建筑在消防安全方面的深层隐患。作为近60年来香港最严重的火灾之一，它为我们敲响了警钟：全民消防安全需要引起每个人的重视，我们不仅要从火灾现状和起因中吸取教训，更要主动采取措施，确保安全，避免类似悲剧重演。</p>
<h2>二、火灾现状：高层灾难的残酷真相</h2>
<p>这场大火规模之大、影响之深刻令人震惊。根据香港特区政府28日下午发布的官方数据，火灾已造成<strong>128人遇难</strong>，79人受伤，仍有约200人情况未明。令人痛心的是，不排除警方进入现场调查时再发现遗体。</p>
<p>火灾救援工作动用了大量资源，共出动<strong>391架次消防车</strong>、185架次救护车、2311名消防及救护人员。在救援过程中，12名消防员受伤，沙田消防局的何伟豪同志不幸殉职。这场火灾波及范围极广，宏福苑8座楼宇中有7座被火势波及，大大增加了救援难度。</p>
<p>高层火灾的独特风险在此次灾难中表现得淋漓尽致。火灾蔓延速度极快，从26日下午2时51分发生火灾，到下午6时22分升为五级警情，仅用了3个多小时。外围易燃材料加剧了火势，玻璃爆破后火焰迅速进入室内，烟雾迅速蔓延至楼道和楼梯，使疏散变得极为困难。</p>
<h2>三、起火原因：多重隐患的叠加爆发</h2>
<p>根据官方初步调查，火灾的直接原因可以追溯到宏昌阁低层围网最先起火，引燃发泡胶板并快速蔓延波及其他楼宇，令玻璃爆破、火势急速增强并蔓延到室内。高温令竹棚燃烧，烧断的竹子飞坠令其他棚网起火，形成连锁反应。</p>
<p>但这起火灾的背后，隐藏着许多深层隐患。首先，建筑外立面的保护材料不符合阻燃要求，发泡胶等易燃材料的使用，严重扩大了火灾的蔓延范围。据调查，着火建筑物外墙有保护网、防水帆布、塑料布，疑未符合防火标准。</p>
<p>其次，维修工程中可能涉及的不当行为也是调查重点。香港廉政公署已就大埔宏福苑大维修工程可能涉及的贪污问题成立专案小组并展开全面调查，目前已拘捕8名人士，包括工程顾问、棚架工程分判商及中间人。警方此前已拘捕3名工程公司负责人，涉嫌误杀。</p>
<p>此外，专业分析指出，多栋同时施工导致原本存在的防火间距被临时“抹除”，以及冬季风干物燥的气候条件，都成为火势的天然助推器。这些因素彼此叠加，使得一次点火成为了大灾难的引爆点。</p>
<h2>四、普通人应对火灾：从预防到自救的全流程指南</h2>
<p>火灾虽无法预测，但我们可以采取一系列措施预防和应对。在火灾发生前，我们应做好充分的安全准备。<strong>居家排查</strong>至关重要，要规范用电、用气，不私拉乱接电线，不乱放电动车，不占用消防通道和楼道，定期清理阳台易燃杂物。家庭应配备必要的灭火器、烟感报警器和防烟面罩，并定期进行消防演练，熟悉疏散路线。</p>
<p>在火灾发生时，<strong>科学自救</strong>至关重要。记住核心法则：“小火快跑，浓烟关门”。在火灾发生初期，若火势较小，应快速撤离；但如果火势较大或门外浓烟弥漫，应关好门窗，用湿毛巾堵住门缝，等待救援。逃生时尽量低姿势前行，用湿毛巾或衣物保护口鼻，不要乘坐电梯。若身处较高楼层，应尽量沿楼梯下楼，不要跳楼或贪恋财物，防止因过度紧张或判断失误引发更大危险。</p>
<p>特别值得注意的是，对于老旧高层建筑的居民，应当了解所在建筑的消防设施状况，积极参与社区消防管理，发现隐患及时向物业或相关部门反映。</p>
<h2>五、事后反思与应对：强化安全意识与责任</h2>
<p>香港特区政府针对此次灾难已采取多项应对措施。政府宣布成立“大埔宏福苑援助基金”，并投入3亿港元作为启动资金，目前已收到各界捐款超5亿港元，总额达8亿港元。特区政府将向<strong>每位遇难者家属发放20万港元慰问金</strong>，向每户受灾居民发放5万港元生活津贴。</p>
<p>同时，全港所有政府建筑物及设施将于11月29日至12月1日下半旗志哀，政府总部将举行默哀仪式，民政事务总署会在全港18区设置吊唁处。这些举措体现了对逝者的尊重和对生者的关怀。</p>
<p>从更广泛的视角看，每次火灾过后，作为社会成员，我们都应该进行深刻反思。强化安全意识不仅是政府和物业管理方的责任，更是每个居民的责任。专家建议，未来的消防安全应从“满足合规性要求”转向“维持安全等价性”的思路，特别是在老旧建筑维修期间，需要提供额外的防护措施，维持原有的安全水平。</p>
<h2>六、结语：以教训为鉴，守护生命安全</h2>
<p>香港大埔宏福苑火灾是一次惨痛的教训，它向我们展示了高层建筑中消防安全的严重漏洞，特别是在维修期间的风险管理不足。这场灾难提醒我们，一座城市的消防安全，并不只是“有没有足够多的消防车”，也不只是“是否有完善的消防条例”，而是城市在日常运行中，是否能够正视那些看似零散但实际上具有系统性的风险。</p>
<p>在未来的日子里，我们必须从这场灾难中汲取教训，以预防为主、以自救为辅，切实提高全社会的安全意识。无论是个人、社区还是政府，都应形成合力，<strong>堵塞安全漏洞</strong>，切实提高消防安全标准，让悲剧不再重演。</p>
<p>我们每个人都有责任守护生命安全，警钟已经敲响，行动刻不容缓。</p>
]]></content:encoded>
    </item>
    <item>
      <title>低空经济：技术硬核与场景落地的双重震撼</title>
      <link>https://wuguangzheng.top/blog/siqpnsy1/</link>
      <guid>https://wuguangzheng.top/blog/siqpnsy1/</guid>
      <source url="https://wuguangzheng.top/rss.xml">低空经济：技术硬核与场景落地的双重震撼</source>
      <description>2025湖南（国际）通用航空及低空经济产业博览会观展</description>
      <pubDate>Tue, 25 Nov 2025 12:48:38 GMT</pubDate>
      <content:encoded><![CDATA[<h2>一、现场直击：6 万平米展区里的 “低空未来秀”</h2>
<p>上周六踩进长沙国际会展中心，6 万平米的展区直接把我看傻了 —— 原来低空经济早就不是概念，而是看得见摸得着的实景剧。作为航天迷兼科技观察者，那些会飞的 “大家伙” 和藏在背后的生意经，比任何展览都让人兴奋。</p>
<p>W2 馆的湖南本土企业区堪称 “硬核装备秀场”。山河星航的 SA160 五座机摆在 C 位，机身摸上去像高级碳纤维行李箱，现场工程师说这是国内首个过民航认证的全复材飞机，最牛的是发动机上的 “智能体检仪”—— 能实时抓 120 多项数据，相当于给飞机装了 24 小时心电图。不远处中国航发的展台更热闹，1000 千瓦级氢燃料发动机旁围满了人，配套的 “数字孪生” 系统能毫秒级算清油耗和排放，据说这技术已经达到国际顶尖水平。</p>
<p>比起装备，应用场景才是真・震撼。湖南智航飞购的屏幕上，长沙县 12 条无人机航线像发光的脉络在跳动：用户下单后，系统自动规划路线，无人机 30 分钟就能把外卖、药品送到小区楼下。现场工作人员甩了组数据：这 “空中配送圈” 靠北斗定位和物联网撑着，现在每天稳定跑几百单，每条航线还能拿 10 万元政府补贴。隔壁志翔科技的物流无人机更夸张，400 公斤的载重能爬高原，自带的避障算法连山间乱流都能躲，这不就是未来山区快递的解决方案？</p>
<h2>二、基建暗战：“国家队” 织的 “低空天网” 有多牛？</h2>
<p>外行看飞机，内行看基建。这次展会最让我意外的是，三大运营商和中国铁塔这些 “通信大佬” 才是低空经济的隐形靠山，他们正在搭一张能让所有飞行器安全飞起来的 “数字天空”。</p>
<p>中国移动的展台藏着黑科技：普通 5G 基站既能传信号，又能当雷达用，连低空那些 “低小慢” 飞行器都能精准定位，以后无人机乱飞的问题可能就靠这解决了。中国电信更实在，演示了 “5G + 卫星” 的组合拳 —— 哪怕无人机飞到深山老林，信号都不会断，这对搞林业巡检、河道监测的老板来说简直是刚需。</p>
<p>中国联通盯紧了 “安全饭”，针对警用、电力这些高要求场景，搞了 “网络切片” 技术，相当于给飞行器开了条专属高速路，别人蹭不进来，数据传输比快递还靠谱。最绝的是中国铁塔，他们要把全国近 210 万座通信塔改成 “数字塔”，既装监控又装无人机机巢，以后建低空基础设施不用从头挖坑，直接共享现成的资源，省钱又快。</p>
<h2>三、政策红包 + 商业机会：普通人能蹭上这波万亿红利吗？</h2>
<p>逛展时最戳我的不是技术，是展区屏幕循环播的政策和数据 —— 这背后全是真金白银的机会。根据多家市场研究机构预测，中国低空经济市场规模预计将在 2025 年突破万亿元，并在 2035 年达到数万亿元级别，而政策正在把 “蛋糕” 递到创业者手上。</p>
<p>先领政策红包：地方补贴比想象中大方
湖南直接给无人机物流航线发钱，每条 10 万元，还要求数据同步到统一平台，这相当于既给补贴又帮企业建运营体系。深圳更狠，载人飞行器取证直接奖 1500 万，无人机物流按飞行架次给梯度奖励，现在已经开通 434 条航线，一年配送 77.6 万架次。中央层面更有超 100 亿元专项基金，专门砸向通信、导航这些基建短板。简单说，现在进场做低空生意，等于政策帮你垫成本。</p>
<p>赚钱门路拆解：三类机会最靠谱
根据行业规律，低空经济的赚钱逻辑分三层，现在入场时机正好：</p>
<p>硬件卖水人（稳赚）：无人机、发动机、飞控系统这些刚需品不愁卖。像极飞的农业无人机、大疆的物流机型，已经占据 B 端市场半壁江山。连配套的电池、检测设备都成了香饽饽，毕竟飞行器飞得越勤，耗材换得越密。</p>
<p>运营服务（快赚）：别盯着 C 端载客，B 端刚需才是当下金矿。比如深圳美团的无人机配送已实现常态化，无人机配送、电力巡检等服务已形成按次 / 按年等收费模式；低空旅游也有明确的包机服务定价，费用因机型和服务内容差异较大，这种依托场景的收费模式现金流普遍较稳。</p>
<p>数据生意（躺赚）：长沙飞行服务站、厦门 “一网统飞” 平台都在收飞行数据，这些数据既能卖给政府做空域管理，又能帮企业优化航线。以后搞 AI 分析服务、给智慧城市提供监控数据，都是坐收利润的活儿。</p>
<p>避坑提醒：这两类生意暂时别碰</p>
<p>业内人透露，现在低空经济有两个 “坑” 要躲：一是 C 端载客（比如空中出租车），普通人接受度低，而且 eVTOL 单机造价几百万，短期根本赚不回本钱；二是盲目建机场，现在政策鼓励共享铁塔资源，自建基础设施纯属浪费钱。聪明的玩法是轻资产运营，比如租无人机搞植保，或者跟景区合作做低空旅游，风险小还能拿补贴。</p>
<h2>四、终极判断：低空经济的 “黄金 5 年” 来了吗？</h2>
<p>中国工程院院士刘大响说，低空经济要搞 “研发 + 制造 + 运营 + 服务” 全链条，现在看这个链条已经转起来了：湖南造发动机、深圳搞运营、运营商搭基建、政策给补贴，连人才培养都跟上了（省发改委和民航大学共建安全平台）。</p>
<p>更关键的是，空域正在逐步放开，2025 年多地已经试点低空开放，2030 年可能实现规模化通航。对爱好者来说，以后能玩的飞行器会越来越多；对创业者来说，现在进场抓物流、巡检这些刚需场景，正好能赶上政策红利期。毕竟万亿市场刚起步，早布局的人才能分到最大块的蛋糕。</p>
]]></content:encoded>
    </item>
    <item>
      <title>冬季防火指南：手把手教你当 “灭火逃生大神”</title>
      <link>https://wuguangzheng.top/blog/wq00r32o/</link>
      <guid>https://wuguangzheng.top/blog/wq00r32o/</guid>
      <source url="https://wuguangzheng.top/rss.xml">冬季防火指南：手把手教你当 “灭火逃生大神”</source>
      <description>不枉上了堂消防教育课</description>
      <pubDate>Tue, 25 Nov 2025 12:48:38 GMT</pubDate>
      <content:encoded><![CDATA[<p>冬天一到，暖气、电热毯、火锅轮番上阵，可火灾隐患也跟着“升温”！昨天看完消防教育课，我悟了：掌握正确技能，咱不仅能远离危险，关键时刻还能化身“消防安全侠”！</p>
<p>今天就用唠嗑的方式，把灭火器、防毒面具这些“保命神器”的用法给你讲明白，保证你一看就会、一学就安心！</p>
<h2>一、灭火器：记住“提拔握压”，火苗见你就怕</h2>
<p>别看灭火器长得“敦实”，操作起来比开饮料还简单，核心就4个字：提、拔、握、压！</p>
<p>提：双手稳稳提起灭火器，注意别磕到自己或别人；</p>
<p>拔：拔掉保险销，就像拔钥匙一样，“解锁”后才能用；</p>
<p>握：一手握住喷管前端，对准火焰的根部（别朝天喷，要打“七寸”）；</p>
<p>压：另一手压下手柄，左右扫射。</p>
<p>⚠️ 记住：只适用于小火！如果火势已大，别逞强，赶紧撤！</p>
<h2>二、防毒面具：30秒“变身”，浓烟里呼吸自由</h2>
<p>火灾中最致命的往往是浓烟！防毒面具就是你的“空气保镖”，戴起来比戴口罩还快：</p>
<p>取出面具，拉开松紧带，由上至下套头；
双手按压面罩边缘，确保严密贴合口鼻；
深呼吸检查是否漏气，顺畅即可行动。
一般能支撑30分钟，足够你冷静逃离浓烟区！</p>
<h2>三、防火服+灭火毯：一个护身，一个灭小火</h2>
<p>防火服：消防员的“黄金铠甲”，遇大火时穿戴可隔热防护。穿戴顺序牢记：裤子→上衣→头盔→手套，全身防护不留缝隙；
灭火毯：厨房油锅起火时，直接盖上锅面，火瞬间缺氧熄灭。用后洗净可重复使用，家家必备！
最后叮嘱：冬季防火别侥幸，安全意识要扎心
天干物燥，记得：电器不超载，取暖器远离窗帘沙发，出门关气断电。</p>
<p>万一遇火情，先判大小——小火用神器，大火快逃生，弯腰低姿捂口鼻，走楼梯不乘电梯！</p>
<p>技能在手，安全你有，这个冬天咱们都是自己的“消防卫士”！</p>
]]></content:encoded>
    </item>
    <item>
      <title>S2赛季来了</title>
      <link>https://wuguangzheng.top/blog/c997r3jr/</link>
      <guid>https://wuguangzheng.top/blog/c997r3jr/</guid>
      <source url="https://wuguangzheng.top/rss.xml">S2赛季来了</source>
      <pubDate>Mon, 27 Oct 2025 05:05:49 GMT</pubDate>
      <enclosure url="https://wugz1995.oss-cn-guangzhou.aliyuncs.com/%E5%9B%BE%E7%89%87/%E5%8D%9A%E5%AE%A2/2c0a8b9447f4702266a6ee2bd619cc70_compress.jpg" type="image/jpeg"/>
    </item>
    <item>
      <title>3、我要建博客之部署到服务器</title>
      <link>https://wuguangzheng.top/blog/wy3xqqg2/</link>
      <guid>https://wuguangzheng.top/blog/wy3xqqg2/</guid>
      <source url="https://wuguangzheng.top/rss.xml">3、我要建博客之部署到服务器</source>
      <description>搭建博客之手动部署到自动部署，可省心、省力、省心！</description>
      <pubDate>Fri, 24 Oct 2025 15:56:31 GMT</pubDate>
      <content:encoded><![CDATA[<p>终于拥有自己的独立博客啦！不用再受第三方平台限制，自定义程度拉满～</p>
<p>这篇把从手动部署到自动同步的全流程拆给新手，跟着做就能成！</p>
<h2>📦 先备齐这些 “装备”（两种部署通用）</h2>
<p>云服务器：选阿里云 / 腾讯云新手套餐，1 核 2G 足够，系统挑 Linux。</p>
<p>工具：FTP 软件（传文件）、VsCode（改博客配置）。</p>
<p>博客源码：我用 VuePress，本地先跑通（npm run docs:dev能预览再往下走）。</p>
<h2>🛠 手动部署：先搞懂 “底层逻辑”</h2>
<p>手动就是把本地 VuePress 生成的文件，传到服务器让别人能访问～</p>
<p>本地执行npm run docs:build，得到 dist 文件夹（这是最终要上线的内容）。</p>
<p>用 FTP 软件连服务器，把 dist 里的文件全传到 /www/wwwroot/（路径记好）。</p>
<p>服务器装 Nginx，配置网站根目录指向刚才的文件夹。</p>
<p>输服务器 IP，能看到博客页面就成！</p>
<h2>⚡ 自动部署：解放双手！3 种方案任选</h2>
<p>手动更改文章要重复传文件太麻烦，自动部署能实现 “本地改完，服务器秒更”～</p>
<ol>
<li>Gitee+Webhook（最常用）
本地 VuePress 项目推到 Gitee 仓库。</li>
</ol>
<p>服务器装 Webhook 和 git 客户端，Webhook 配好和 Gitee 的连接。</p>
<p>Gitee 仓库里设 Webhook，填服务器地址 + 密钥。</p>
<p>改完文章推 Gitee，自动触发服务器拉取最新代码。</p>
<ol start="2">
<li>Gitee+Jenkins（适合多项目）
服务器装 Jenkins，创建 “流水线项目”。</li>
</ol>
<p>配置 Gitee 仓库地址，加 “构建触发器”。</p>
<p>写个简单脚本，让 Jenkins 拉代码后自动更到网站目录。</p>
<p>优势是能管理多个项目，后续扩展方便。</p>
<ol start="3">
<li>腾讯云 EdgeOne：Pages 服务（最省心）
不用自己折腾服务器环境！直接连 Gitee 仓库。</li>
</ol>
<p>选 “静态网站”，填仓库地址和分支。</p>
<p>开启 “自动部署”，改完文章推仓库就自动更新。</p>
<p>缺点是自定义配置少，适合纯展示型博客。</p>
<h2>🆚 手动 vs 自动怎么选？</h2>
<p>刚入门：先手动！搞懂文件怎么到服务器，后续排错更顺。</p>
<p>频繁更文：选自动！Gitee+Webhook 性价比最高，配置一次管很久。</p>
<p>怕麻烦：直接上腾讯云 EdgeOne：Pages（非广告，别的网站托管工具也可以），5 分钟就能上线。</p>
<h2>✨ 后续优化小技巧</h2>
<p>绑个域名：阿里云买域名，解析到服务器 IP，不用记一串数字。</p>
<p>开 HTTPS：服务器装个 Let's Encrypt 免费证书，地址栏显小绿锁。</p>
<p>定期备份：把 Gitee 仓库设成私有，再定期导出博客内容。</p>
]]></content:encoded>
    </item>
    <item>
      <title>2、我要建博客之第一步</title>
      <link>https://wuguangzheng.top/blog/cy0v5tj5/</link>
      <guid>https://wuguangzheng.top/blog/cy0v5tj5/</guid>
      <source url="https://wuguangzheng.top/rss.xml">2、我要建博客之第一步</source>
      <description>搭建博客之具体操作步骤，包括安装开发工具、安装 Node.js、安装博客框架、运行博客项目、撰写第一篇博客文章、再次运行查看效果。</description>
      <pubDate>Wed, 15 Oct 2025 15:00:13 GMT</pubDate>
      <content:encoded><![CDATA[<p>想拥有自己的小博客但怕代码劝退？哪怕是小白，亲测这套流程超简单！跟着做，半小时就能在电脑上跑起自己的博客～重要的是行动！👇</p>
<h2>✅ 第一步：安装开发工具（VsCode）</h2>
<p>这是写代码的 “记事本”，新手友好度极高。</p>
<p>用豆包或其他 AI 工具搜索「VsCode」，点击官网链接下载，选择与自己电脑匹配的系统（Windows/Mac）。</p>
<p>安装过程中，务必勾选「添加到 PATH」选项，否则后续操作可能会遇到问题。</p>
<p>打开 VsCode 后，搜索「Chinese」插件并安装，重启软件即可切换为中文界面。</p>
<h2>✅ 第二步：安装 Node.js</h2>
<p>Node.js 是博客运行所需的 “小引擎”，按步骤操作即可完成。</p>
<p>用豆包搜索「Node.js」，选择下载 LTS 长期支持版，该版本稳定性更高，不易出错。</p>
<p>安装时无需修改默认选项，一路点击 “下一步” 即可。</p>
<p>验证安装是否成功：打开 VsCode 的「终端」（通过顶部菜单 “查看→终端” 找到），输入node -v，若能显示版本号则说明安装成功。</p>
<h2>✅ 第三步：安装博客框架（VuePress）</h2>
<p>选择 VuePress 是因为它无需编写复杂代码，用 Markdown 就能发布文章。Markdown 的核心优势是简单易上手、跨平台兼容且专注内容创作，无需复杂排版操作就能生成结构化文档，类似写论文时用到的 LaTex。</p>
<p>先在电脑中新建一个文件夹，建议命名为「blog」，并记住文件夹的保存路径。</p>
<p>在 VsCode 中通过 “文件→打开文件夹”，选择并打开刚才新建的「blog」文件夹。</p>
<p>在终端中输入命令进行安装，具体操作可参考 <a href="https://vuepress.vuejs.org/zh/guide/getting-started.html" target="_blank" rel="noopener noreferrer">VuePress</a> 官方指南,核心命令为：</p>
<div class="language- line-numbers-mode" data-highlighter="shiki" data-ext="" style="--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212"><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code class="language-"><span class="line"><span>npm init vuepress vuepress-starter</span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2>✅ 第四步：运行博客项目</h2>
<p>完成这一步，就能让博客在电脑上 “跑起来”。</p>
<p>在终端中输入命令：<code>npm vuepress dev docs</code></p>
<p>等待终端显示「success」后，复制下方出现的链接（通常为<a href="http://localhost:8080" target="_blank" rel="noopener noreferrer">http://localhost:8080</a>）。</p>
<p>将复制的链接粘贴到浏览器地址栏，即可看到博客的初步雏形。🥳</p>
<h2>✅ 第五步：撰写第一篇博客文章</h2>
<p>用 Markdown 格式写作，操作像记笔记一样简单。</p>
<p>在 VsCode 中打开「docs」文件夹，在该文件夹下新建一个「blog」文件夹。</p>
<p>在新建的「blog」文件夹中创建文件，命名为「我的第一篇博客.md」。</p>
<p>按照 Markdown 语法撰写内容，例如用# 标题表示一级标题、## 小标题表示二级标题、- 列表项表示列表，完成后保存文件。</p>
<h2>✅ 第六步：再次运行查看效果</h2>
<p>刷新博客页面，就能看到新写的文章。✨</p>
<p>注：是热更新，你每敲一个字都会看到结果。</p>
]]></content:encoded>
    </item>
    <item>
      <title>1、我要建博客之前期准备</title>
      <link>https://wuguangzheng.top/blog/jrc3m7dk/</link>
      <guid>https://wuguangzheng.top/blog/jrc3m7dk/</guid>
      <source url="https://wuguangzheng.top/rss.xml">1、我要建博客之前期准备</source>
      <description>博客搭建方法论，包括准备工作、技术选型、环境配置、项目初始化等。</description>
      <pubDate>Mon, 13 Oct 2025 14:43:48 GMT</pubDate>
      <content:encoded><![CDATA[<p>在互联网时代，个人博客早已成为展示自我、分享观点和沉淀知识的重要载体。无论是技术爱好者记录学习心得，还是创作者传播生活感悟，搭建属于自己的博客都极具意义。本文将以基于架构的软件开发方法为核心框架，拆解博客建设的完整流程，并详细说明所需的技术准备，帮助零基础或有一定基础的读者顺利开启博客搭建之旅。</p>
<h1>建设博客的整体流程：以架构思维驱动开发</h1>
<p>基于架构的软件开发方法强调 <strong>“先谋后动”</strong>，通过明确需求、设计架构、实现与验证，确保最终产品符合预期且具备可扩展性。博客建设遵循这一逻辑，可分为以下 6 个核心阶段：</p>
<h2>1. 需求采集：明确 “为什么建博客”</h2>
<p>需求采集是博客建设的起点，核心是回答 <strong>“博客的定位、目标用户和核心功能”</strong> 三大问题，避免盲目开发。</p>
<p>我自己想的是，拥有一个自己的网络天地 。如果是其它项目，这个是很需要下功夫的地方。好的开始是成功的一半。</p>
<h2>2. 需求分析：把 “石头” 点成 “金子”</h2>
<p>需求分析是对需求的再审视，挖掘需求的价值。举个例子，博客能不能对接 AI 辅助写作，从而达到每天更新的目的。如果能实现，是不是可以高效产出优质文章。如果不能，那这个想法是不是有价值，可以留到以后实现。</p>
<p>这样的分析和联想，你可以从沙子里淘到金子。</p>
<h2>3. 架构设计：搭建博客的 “技术骨架”</h2>
<p>架构设计决定博客的技术选型和整体结构，需结合需求和自身技术能力选择合适的方案，常见分为 <strong>“自主开发”</strong> 和 <strong>“基于开源框架二次开发”</strong> 两种模式。</p>
<h3>技术栈选型：</h3>
<ul>
<li>
<p><strong>前端</strong>：若需自主开发页面，可选择 “HTML+CSS+JavaScript” 基础栈，或使用 Vue、React 框架提升开发效率；若追求简便，可直接使用现成的博客主题模板（如 Hexo、Jekyll 的开源主题）。</p>
</li>
<li>
<p><strong>后端</strong>：根据语言偏好选择，例如 Java（SpringBoot 框架）、Python（Django/Flask 框架）、Node.js（Express 框架），轻量级博客推荐 Django 或 Flask（快速上手），大型博客可选择 SpringBoot（稳定性强）。</p>
</li>
<li>
<p><strong>数据库</strong>：小型博客推荐 MySQL（开源、易用）或 SQLite（轻量、内存数据库），需设计核心数据表（如 “文章表” 含标题 / 内容 / 发布时间，“分类表” 含分类名 / 分类 ID，“用户表” 含用户名 / 密码）。</p>
</li>
<li>
<p><strong>服务器与部署</strong>：可选择 ECS 云服务器（如阿里云、腾讯云），也可以选择静态网站托管（Vercel）。</p>
</li>
</ul>
<h2>4. 软件开发：搭积木建房子</h2>
<p>软件开发阶段需遵循 <strong>“分模块、迭代开发”</strong> 的原则，先实现核心功能，再逐步完善细节，避免一次性开发过多导致混乱。</p>
<h3>基础环境搭建：</h3>
<p>先配置开发环境（如安装 JDK、Python、数据库、代码编辑器），创建项目结构（如后端项目分 “控制层、服务层、数据访问层”，前端项目分 “页面、样式、脚本” ）。</p>
<h3>核心功能开发：</h3>
<ol>
<li>
<p>文章内容呈现</p>
</li>
<li>
<p>网站后台管理</p>
</li>
</ol>
<h3>代码规范与注释：</h3>
<p>编写清晰的代码注释（如接口功能、参数含义），遵循语言规范（如 Java 的驼峰命名法、Python 的 PEP8 规范），方便后续测试和维护。</p>
<h2>5. 测试：确保博客 “能用、好用、安全”</h2>
<p>测试是发现问题的关键环节，需覆盖功能、性能、安全性等维度，避免上线后出现明显 bug 影响用户体验。</p>
<h3>功能测试：</h3>
<p>逐一验证需求中的功能是否正常，例如 “发布文章能否保存、图片是否能显示、评论能否提交、分类标签是否能关联文章”，模拟用户操作场景（如输入错误格式的内容，查看是否有提示）。</p>
<h3>性能测试：</h3>
<p>使用工具（如 Chrome 浏览器的 “开发者工具”）测试页面加载速度，检查是否有冗余代码或过大图片导致加载缓慢；测试数据库查询速度，例如首页加载 10 篇文章时，响应时间是否＜1 秒。</p>
<h3>安全性测试：</h3>
<p>重点检查登录功能（如密码是否加密存储、是否防止暴力破解）、评论功能（如是否过滤恶意脚本，防止 XSS 攻击）、后端接口（如是否验证用户权限，防止未登录用户修改文章）。</p>
<h3>兼容性测试：</h3>
<p>在不同设备（手机、平板、电脑）和浏览器（Chrome、Edge、Safari）上打开博客，检查页面排版是否正常、功能是否可用。</p>
<h3>问题修复与迭代：</h3>
<p>记录测试中发现的问题（如 “图片上传失败”“评论无法回复”），优先修复高优先级问题，修复后重新测试，确保问题彻底解决。</p>
<h2>6. 部署上线：让博客 “被所有人访问”</h2>
<p>部署上线是将本地开发的博客项目部署到云服务器，使其能通过互联网访问，核心步骤包括服务器配置、项目部署和域名绑定。</p>
<h3>服务器准备：</h3>
<p>购买云服务器（推荐 Linux 系统，如 CentOS、Ubuntu），完成基础配置（如设置安全组，开放 80 端口（HTTP）、443 端口（HTTPS）、22 端口（SSH 远程连接）），通过适合的工具连接服务器（Workbench 远程连接）。</p>
<h3>环境部署：</h3>
<p>在服务器上安装所需软件（如 JDK、Python、MySQL、Nginx），例如使用 “yum” 命令（Linux）快速安装，确保服务器环境与本地开发环境一致。</p>
<h3>项目部署：</h3>
<ul>
<li>
<p><strong>后端项目</strong>：将本地打包好的项目（如 Java 的 JAR 包、Python 的项目文件夹）通过 FTP 工具（如 FileZilla）上传到服务器，使用命令启动项目（如 “java -jar blog.jar”），并配置进程守护（如使用 Supervisor，防止项目意外停止）。</p>
</li>
<li>
<p><strong>前端项目</strong>：将前端打包后的静态文件（HTML、CSS、JS）上传到服务器，配置 Nginx 作为 Web 服务器，指向前端文件目录，实现 “输入服务器 IP 即可访问博客首页”。</p>
</li>
<li>
<p><strong>自动化部署</strong>：通过工具或脚本自动完成 “代码提交→构建→测试→部署” 的全流程，减少人工操作，避免人为错误，同时让代码快速上线。</p>
</li>
</ul>
<h3>域名与 HTTPS 配置：</h3>
<p>若有域名（如<a href="https://xxx.com" target="_blank" rel="noopener noreferrer">xxx.com</a>），需在域名服务商处将域名解析到服务器 IP，完成后 “域名 + 端口” 即可访问博客；为提升安全性，可申请免费的 SSL 证书（如 Let’s Encrypt），配置 HTTPS，使访问地址变为 “<a href="https://xxx.com" target="_blank" rel="noopener noreferrer">https://xxx.com</a>”。</p>
<h3>上线验证：</h3>
<p>通过域名访问博客，测试所有功能（如浏览文章、登录管理后台），确认无问题后，博客正式上线。</p>
]]></content:encoded>
    </item>
    <item>
      <title>博客上线了</title>
      <link>https://wuguangzheng.top/blog/swc6sxhq/</link>
      <guid>https://wuguangzheng.top/blog/swc6sxhq/</guid>
      <source url="https://wuguangzheng.top/rss.xml">博客上线了</source>
      <description>我个人的博客网站已经上线了，这里记录了我在技术领域的一些思考与实践。</description>
      <pubDate>Mon, 13 Oct 2025 04:35:22 GMT</pubDate>
      <content:encoded><![CDATA[<h2>一、个人工作背景与博客初衷</h2>
<p>作为国企信息技术岗位的一员，日常工作多是围绕系统二次开发、RPA（机器人流程自动化）、项目建设的标准化流程推进，习惯了在项目文档与软件开发中保持严谨，却很少有一个“完全属于自己”的空间，去审视IT工作的成果和经验，去记录自己在技术方面的成长。</p>
<h2>二、搭建独立博客的核心意义</h2>
<p>也正因如此，在这个信息碎片化的时代，当同事问我“为啥还要花时间搭独立博客，发在技术社区不更省事吗”时，我反而更确定做这件事的意义。对我而言，建博客从来不是为了追逐流量，而是想对抗工作与学习中“碎片化信息的流失”——比如某次解决RPA项目二次开发问题的思路，在会议上匆匆记在笔记本角落，转头可能就被新的任务覆盖；又比如研究国产数仓适配时的实践心得，在社交平台分享时总受限于篇幅，没法把从需求分析到架构设计、再到CI（持续集成）/CD（持续部署）的全流程说透。这些藏在日常工作里的“技术沉淀”，需要一个更系统、更持久的载体来留存，而独立博客恰好能成为这样的“阵地”。</p>
<h2>三、延续技术圈交流感的期待</h2>
<p>更何况，我始终记得刚入行时，曾在前辈的个人博客里找到过解决老系统升级难题的关键思路——那种“有人把实践经验毫无保留分享出来”的纯粹，让我一直觉得技术圈的成长从来不是孤军奋战。如今自己搭建这个博客，也想延续这份“交流感”：既为自己的技术成长做一份“可视化档案”，也希望把 IT 工作中那些偏向实际应用的实践（比如大型系统从0到1的建设、RPA在企业场景的建设、项目管理的实践）整理出来，和同领域的朋友多些交流。毕竟，比起在算法推荐里被动接收信息，我更期待在这里，用最直接的方式，和大家一起把技术实践里的“干货”挖得更深一点。</p>
<h2>四、后续内容预告</h2>
<p>下一篇讲讲我的博客是怎么弄的。</p>
<h2>五、最后</h2>
<p>最后，感谢你能看到这里，希望你能喜欢我的博客，也希望它能给你带来一些收获。</p>
]]></content:encoded>
    </item>
  </channel>
</rss>