<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>https://blog.hyperthreading.cn/</id>
  <title type="text">Hyper Threading</title>
  <subtitle type="text">超线程的个人博客网站</subtitle>
  <updated>2026-05-22T00:00:00.000Z</updated>
  <author><name>超线程</name></author>
  <link rel="alternate" href="https://blog.hyperthreading.cn/"/>
  <link rel="self" href="https://blog.hyperthreading.cn/atom.xml"/>
  <generator uri="https://github.com/CuteLeaf/Firefly">Firefly v6.16.8</generator>
    <entry>
      <id>https://blog.hyperthreading.cn/posts/cloudflare%E5%85%8D%E8%B4%B9vpn%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B_edgetunnel/</id>
      <title type="text">Cloudflare 免费 VPN 部署教程：基于 edgetunnel 零成本搭建个人代理面板</title>
      <published>2026-05-22T00:00:00.000Z</published>
      <updated>2026-05-22T00:00:00.000Z</updated>
      <author><name>超线程</name></author>
      <link rel="alternate" href="https://blog.hyperthreading.cn/posts/cloudflare%E5%85%8D%E8%B4%B9vpn%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B_edgetunnel/"/>
      <summary type="text">参考零度博客教程，使用 Cloudflare Pages、Workers KV 和开源项目 cmliu/edgetunnel，零成本部署一个可视化管理的个人代理面板，并导入订阅到常见客户端使用。</summary>
      <content type="html"><![CDATA[<p>很多人找“免费 VPN”，第一反应是去网上搜公共节点。但这类方案通常有三个问题：不稳定、速度波动大、随时可能失效。相比之下，更适合长期使用的思路，其实是借助 Cloudflare 的免费能力，自己部署一个轻量的代理面板，再把订阅链接导入客户端使用。</p>
<p>这篇文章参考了<a href="https://www.freedidi.com/23618.html" target="_blank">零度博客</a>的教程，并重新整理成适合直接照着操作的版本。整套方案的核心是 Cloudflare Pages + Workers KV，再配合一个已经成熟的开源项目完成面板和订阅管理。</p>
<section><h2>本文使用的开源项目<a href="#本文使用的开源项目"><span>#</span></a></h2><p>参考教程里实际使用的项目是：</p><ul>
<li>GitHub 仓库：<a href="https://github.com/cmliu/edgetunnel" target="_blank">https://github.com/cmliu/edgetunnel</a></li>
<li>项目名称：<code>cmliu/edgetunnel</code></li>
<li>项目说明：一个基于 Cloudflare Workers / Pages 的多功能面板，支持 VLESS、Trojan、Shadowsocks 等协议，带后台管理、订阅生成和 KV 配置能力。</li>
</ul></section>
<section><h2>先说结论：这套方案在做什么？<a href="#先说结论这套方案在做什么"><span>#</span></a></h2><p>这套方案并不是“白嫖现成 VPN 服务”，而是把 Cloudflare 当作免费托管平台，部署一个属于你自己的轻量代理面板。你后续使用时，主要流程是：</p><ol>
<li>注册免费域名</li>
<li>把域名接入 Cloudflare</li>
<li>创建 Workers KV</li>
<li>在 Cloudflare Pages 部署 <code>edgetunnel</code></li>
<li>配置后台密码和 KV 绑定</li>
<li>绑定自定义域名</li>
<li>登录后台生成订阅</li>
<li>导入客户端使用</li>
</ol><p>整个流程不需要 VPS，也不需要购买服务器。对于轻量使用、技术学习和个人折腾来说，这确实是一个成本很低的路线。</p><blockquote><p>提醒一下：请遵守你所在地法律法规，以及 Cloudflare 和相关开源项目的服务条款。本文仅用于技术学习与个人网络加速研究。</p></blockquote></section>
<section><h2>部署前准备<a href="#部署前准备"><span>#</span></a></h2><p>开始之前，你需要准备下面几样东西：</p><ul>
<li>一个 Cloudflare 账号</li>
<li>一个邮箱</li>
<li>一个免费域名</li>
<li>一个可上传 ZIP 的 Cloudflare Pages 项目</li>
<li>一个代理客户端，比如 <code>v2rayN</code>、<code>Clash Verge</code>、<code>sing-box</code> 等</li>
</ul><p>如果你完全没有域名，参考教程里使用的是免费域名平台。注册成功后，拿到一个可管理的子域名即可继续。</p></section>
<section><h2>第一步：注册免费域名<a href="#第一步注册免费域名"><span>#</span></a></h2><p>先准备一个免费域名。登录下面网站：</p><ul>
<li><code>dnshe.com</code></li>
</ul><p>注册并登录后，可以申请免费的二级域名。可选的免费根域后缀包括：</p><ul>
<li><code>ccwu.cc</code></li>
<li><code>us.ci</code></li>
</ul><p>注册完成后，你会拿到一个类似下面这样的可管理域名，后面用于接入 Cloudflare：</p><ul>
<li><code>yourname.ccwu.cc</code></li>
<li><code>yourname.us.ci</code></li>
</ul></section>
<section><h2>第二步：把域名托管到 Cloudflare<a href="#第二步把域名托管到-cloudflare"><span>#</span></a></h2><p>登录 Cloudflare 后，把刚注册的域名接入进去。这里的目标很明确：让这个域名能在 Cloudflare 后台完成 DNS 管理，并能给 Pages 项目绑定自定义域名。</p><p>具体操作可以按下面步骤来：</p><ol>
<li>打开 <code>Cloudflare Dashboard</code>，登录你的账号。</li>
<li>在首页点击 <code>Add a domain / 添加站点</code>。</li>
<li>在输入框里填入你刚注册到的免费域名，例如 <code>yourname.ccwu.cc</code>，然后点击 <code>Continue</code>。</li>
<li>方案选择里选免费套餐，也就是 <code>Free</code>，然后继续下一步。</li>
<li>Cloudflare 会自动扫描一次现有 DNS 记录。免费二级域名刚注册时通常没有太多记录，这里直接继续即可。</li>
<li>到下一步后，Cloudflare 会给你分配两条新的 <code>Nameserver</code>，一般长这样：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>xxx.ns.cloudflare.com</span></div></div><div><div><div>2</div></div><div><span>yyy.ns.cloudflare.com</span></div></div></code></pre><div><div></div><div></div></div></figure></div><ol>
<li>先不要关闭这个页面，复制好这两条 <code>Nameserver</code>。</li>
<li>回到你注册免费域名的平台后台，比如 <code>dnshe.com</code>，找到这个域名的管理页面。</li>
<li>在域名管理里找到DNS服务器，把原来的默认DNS服务器列表，替换成 Cloudflare 给你的两条 <code>Nameserver</code>，然后保存。</li>
<li>改完以后，回到 Cloudflare 刚才那个页面，点击 <code>Continue</code> 或 <code>Done, check nameservers</code> 等待校验。</li>
</ol><p>正常情况下，Cloudflare 会在几分钟到几十分钟内识别到新的 <code>Nameserver</code>。有些免费域名平台生效会慢一点，如果暂时还是 <code>Pending</code>，先等一会再刷新。</p><p>当 Cloudflare 状态变成已激活后，说明这个域名已经成功托管进来了。接下来你就可以在 Cloudflare 控制台里继续做 <code>Pages</code>、<code>KV</code> 和自定义域名绑定。</p></section>
<section><h2>第三步：创建 Workers KV 命名空间<a href="#第三步创建-workers-kv-命名空间"><span>#</span></a></h2><p><code>edgetunnel</code> 的后台配置依赖 Cloudflare KV 存储，所以这一步不能省。</p><p>操作路径大致如下：</p><p><code>Cloudflare Dashboard -&gt; Workers &amp; Pages -&gt; Storage / Workers KV -&gt; Create</code></p><p>创建一个新的 KV 命名空间即可，名字可以自定义，比如：</p><ul>
<li><code>edgetunnel-kv</code></li>
<li><code>vpn-panel-kv</code></li>
</ul><p>创建完成后先不用往里面写数据，后面只要把它绑定到 Pages 项目即可。</p></section>
<section><h2>第四步：下载并部署 edgetunnel 到 Cloudflare Pages<a href="#第四步下载并部署-edgetunnel-到-cloudflare-pages"><span>#</span></a></h2><p>这里就是整篇教程最核心的一步。</p><p>你需要先打开 GitHub 仓库：</p><p><a href="https://github.com/cmliu/edgetunnel" target="_blank">https://github.com/cmliu/edgetunnel</a></p><p>进入仓库后，可以按照仓库 README 里提供的 Pages 上传部署方式来操作。参考教程采用的是“上传 ZIP 文件到 Pages”的方式，因为对新手最友好，不需要先折腾 GitHub Actions 或构建脚本。</p><p>操作思路如下：</p><ol>
<li>打开 <code>cmliu/edgetunnel</code> 项目主页</li>
<li>下载仓库中用于 Pages 部署的压缩包 <code>main.zip</code></li>
<li>进入 Cloudflare 的 <code>Workers &amp; Pages</code></li>
<li>创建新的 Pages 项目</li>
<li>选择上传资产或上传项目压缩包</li>
<li>把 <code>main.zip</code> 上传并部署</li>
</ol><p>部署完成后，Cloudflare 会先给你一个默认访问地址，通常是 <code>xxx.pages.dev</code> 这种形式。</p><p>这时候项目虽然已经跑起来了，但还不能直接用，因为后台密码和 KV 绑定还没有配。</p></section>
<section><h2>第五步：配置后台密码 ADMIN<a href="#第五步配置后台密码-admin"><span>#</span></a></h2><p>部署完成后，进入 Pages 项目设置，添加环境变量。</p><p>路径一般是：</p><p><code>Settings -&gt; Variables and Secrets</code></p><p>新增一个变量：</p><ul>
<li>变量名：<code>ADMIN</code></li>
<li>变量值：你自己设置的后台登录密码</li>
</ul><p>比如：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ADMIN=123456</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>保存以后，重新部署一次项目，让这个变量真正生效。</p><p>这一项很关键，因为你后面访问 <code>/admin</code> 后台时，就是靠这个密码登录。如果不设置，后台通常无法正常进入。</p></section>
<section><h2>第六步：绑定 KV 命名空间<a href="#第六步绑定-kv-命名空间"><span>#</span></a></h2><p>接着进入项目设置中的 <code>Bindings</code> 页面，把前面创建的 KV 命名空间绑定进来。</p><p>绑定时这样填：</p><ul>
<li>类型：<code>KV Namespace</code></li>
<li>变量名：<code>KV</code></li>
<li>绑定目标：你刚才创建的 KV 命名空间</li>
</ul><p>保存以后，再重新部署一次。</p><p>这里最常见的坑有两个：</p><ul>
<li>变量名写错，不是 <code>KV</code></li>
<li>绑定完成后忘记重新部署</li>
</ul><p>如果后台能打开，但保存配置失败，或者订阅链接生成异常，第一时间就先检查这一步。</p></section>
<section><h2>第七步：给 Pages 绑定自定义域名<a href="#第七步给-pages-绑定自定义域名"><span>#</span></a></h2><p>现在可以给 Pages 项目绑定你自己的域名了。</p><p>进入：</p><p><code>Pages Project -&gt; Custom domains</code></p><p>绑定刚刚申请的免费域名，例如 <code>yourname.ccwu.cc</code>。</p><p>按照 Cloudflare 后台提示配置即可。参考教程和 <code>edgetunnel</code> 项目 README 中提到，如果域名 DNS 不在 Cloudflare，需要按提示手动添加一条 CNAME 记录，指向：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>edgetunnel.pages.dev</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>实际操作时，以你当前 Pages 项目控制台显示的目标记录为准。</p><p>DNS 生效后，你就可以通过自定义域名访问你的面板了。</p></section>
<section><h2>第八步：登录后台并生成订阅<a href="#第八步登录后台并生成订阅"><span>#</span></a></h2><p>浏览器打开：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>https://你的域名/admin</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>输入刚才设置好的 <code>ADMIN</code> 密码，就可以进入后台。</p><p>进入后台后，通常可以完成这些操作：</p><ul>
<li>配置节点参数</li>
<li>生成单节点链接</li>
<li>生成订阅地址</li>
<li>导出给 Clash、sing-box、Surge 等客户端使用</li>
</ul><p><code>edgetunnel</code> 支持的协议比较丰富，常见包括：</p><ul>
<li>VLESS</li>
<li>Trojan</li>
<li>Shadowsocks</li>
</ul><p>对于大多数人来说，最省事的用法不是复制单条节点，而是直接复制订阅地址导入客户端。后续如果你在后台改了参数，客户端更新订阅就行，不需要每次手动改。</p></section>
<section><h2>第九步：导入客户端使用<a href="#第九步导入客户端使用"><span>#</span></a></h2><p>部署成功后，后台一般会给你两类内容：</p><ul>
<li>单节点链接</li>
<li>订阅地址</li>
</ul><p>推荐优先使用订阅地址。这样后面调整配置更方便。</p><p>常见客户端导入方式大致如下：</p><section><h3>v2rayN<a href="#v2rayn"><span>#</span></a></h3><ul>
<li>选择“添加订阅”或“从剪贴板导入”</li>
<li>粘贴后台生成的订阅链接</li>
<li>更新订阅后选择节点使用</li>
</ul></section><section><h3>Clash Verge / Clash Meta<a href="#clash-verge--clash-meta"><span>#</span></a></h3><ul>
<li>添加远程订阅</li>
<li>粘贴订阅 URL</li>
<li>更新配置并启用代理</li>
</ul></section><section><h3>sing-box<a href="#sing-box"><span>#</span></a></h3><ul>
<li>导入订阅</li>
<li>同步配置后选择可用节点</li>
</ul></section></section>
<section><h2>常见问题<a href="#常见问题"><span>#</span></a></h2><section><h3>1. 后台打不开怎么办？<a href="#1-后台打不开怎么办"><span>#</span></a></h3><p>优先检查下面几项：</p><ul>
<li>自定义域名是否已经生效</li>
<li><code>ADMIN</code> 环境变量是否添加成功</li>
<li>环境变量添加后是否重新部署</li>
<li>域名是否确实绑定到了当前 Pages 项目</li>
</ul></section><section><h3>2. 后台能打开，但保存配置失败怎么办？<a href="#2-后台能打开但保存配置失败怎么办"><span>#</span></a></h3><p>大多数情况下是 KV 绑定没配对。请重点检查：</p><ul>
<li>是否已经创建 KV 命名空间</li>
<li>变量名是不是严格写成 <code>KV</code></li>
<li>添加绑定后是否重新部署</li>
</ul></section><section><h3>3. 自定义域名访问失败怎么办？<a href="#3-自定义域名访问失败怎么办"><span>#</span></a></h3><p>通常是 DNS 问题。重点检查：</p><ul>
<li>CNAME 是否填写正确</li>
<li>域名是否已接入 Cloudflare</li>
<li>DNS 记录是否还在传播中</li>
</ul></section><section><h3>4. 为什么面板部署成功了，但代理还是不好用？<a href="#4-为什么面板部署成功了但代理还是不好用"><span>#</span></a></h3><p>这种情况通常不是 Pages 部署失败，而是节点参数、订阅格式或客户端配置有问题。建议先用仓库默认推荐参数跑通，再慢慢折腾高级配置，比如 ProxyIP、优选订阅或链式代理。</p></section></section>
<section><h2>这套方案的优点和限制<a href="#这套方案的优点和限制"><span>#</span></a></h2><section><h3>优点<a href="#优点"><span>#</span></a></h3><ul>
<li>不需要购买 VPS</li>
<li>部署成本极低</li>
<li>Cloudflare 平台可用性较好</li>
<li>有后台管理面板，维护方便</li>
<li>支持主流客户端订阅导入</li>
</ul></section><section><h3>限制<a href="#限制"><span>#</span></a></h3><ul>
<li>依赖第三方开源项目维护</li>
<li>免费域名稳定性一般</li>
<li>高级配置对新手不够友好</li>
<li>Cloudflare 的平台策略变化，可能影响长期使用体验</li>
</ul></section></section>
<section><h2>总结<a href="#总结"><span>#</span></a></h2><p>如果你只是想零成本搭一个自己的轻量代理面板，那么基于 Cloudflare Pages + Workers KV + <code>cmliu/edgetunnel</code> 的这套方案，确实是目前比较容易上手的一条路线。</p><p>它最大的价值，不是“白嫖一个公共 VPN”，而是让你用 Cloudflare 的免费基础设施，部署一个属于自己的可管理订阅系统。整个流程里，真正最容易出错的地方只有三个：</p><ol>
<li>域名 DNS 没配对</li>
<li><code>ADMIN</code> 环境变量漏配</li>
<li><code>KV</code> 绑定后忘记重新部署</li>
</ol><p>把这三个点处理好，基本就能把整套面板跑起来。</p></section>
<section><h2>参考链接<a href="#参考链接"><span>#</span></a></h2><ul>
<li>参考教程：<a href="https://www.freedidi.com/23618.html" target="_blank">https://www.freedidi.com/23618.html</a></li>
<li>开源项目 GitHub：<a href="https://github.com/cmliu/edgetunnel" target="_blank">https://github.com/cmliu/edgetunnel</a></li>
<li>Cloudflare Pages 文档：<a href="https://developers.cloudflare.com/pages/" target="_blank">https://developers.cloudflare.com/pages/</a></li>
<li>Cloudflare Pages 自定义域名文档：<a href="https://developers.cloudflare.com/pages/configuration/custom-domains/" target="_blank">https://developers.cloudflare.com/pages/configuration/custom-domains/</a></li>
<li>Cloudflare Pages 绑定与环境变量文档：<a href="https://developers.cloudflare.com/pages/functions/bindings/" target="_blank">https://developers.cloudflare.com/pages/functions/bindings/</a></li>
<li>Cloudflare Workers KV 文档：<a href="https://developers.cloudflare.com/kv/" target="_blank">https://developers.cloudflare.com/kv/</a></li>
</ul></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.hyperthreading.cn/posts/fns_%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97_%E8%B8%A9%E5%9D%91%E7%AC%94%E8%AE%B0/</id>
      <title type="text">FNS 部署指南与踩坑笔记</title>
      <published>2026-04-28T00:00:00.000Z</published>
      <updated>2026-04-28T00:00:00.000Z</updated>
      <author><name>超线程</name></author>
      <link rel="alternate" href="https://blog.hyperthreading.cn/posts/fns_%E9%83%A8%E7%BD%B2%E6%8C%87%E5%8D%97_%E8%B8%A9%E5%9D%91%E7%AC%94%E8%AE%B0/"/>
      <summary type="text">记录 Fast Note Sync Service 在 Ubuntu 服务器上的部署流程、Nginx Proxy Manager 反代配置，以及 Cloudflare、Obsidian 插件接入中的常见踩坑与解决方案。</summary>
      <content type="html"><![CDATA[<section><h1>Fast Note Sync Service (FNS) 部署指南 &amp; 踩坑笔记<a href="#fast-note-sync-service-fns-部署指南--踩坑笔记"><span>#</span></a></h1><blockquote><p>基于 <a href="https://github.com/haierkeys/fast-note-sync-service" target="_blank">haierkeys/fast-note-sync-service</a> 官方仓库 + 真实部署踩坑记录整理<br />
环境：百度云 VPS / Ubuntu / Nginx Proxy Manager (Docker) / Cloudflare CDN<br />
仓库当前版本：v3.0.3（2026-05）</p></blockquote><hr /><section><h2>一、部署方式选择<a href="#一部署方式选择"><span>#</span></a></h2><p>官方提供两种部署方式，按需选择：</p>

<table><thead><tr><th>方式</th><th>适用场景</th><th>维护复杂度</th></tr></thead><tbody><tr><td><strong>一键脚本（推荐）</strong></td><td>单机部署、快速上手</td><td>低</td></tr><tr><td><strong>Docker</strong></td><td>已有 Docker 环境、需要容器化隔离</td><td>低</td></tr></tbody></table><hr /><section><h3>方式 1：一键脚本安装（推荐）<a href="#方式-1一键脚本安装推荐"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 海外服务器</span></div></div><div><div><div>2</div></div><div><span>bash</span><span> </span><span>&lt;(</span><span>curl</span><span> </span><span>-fsSL</span><span> https://raw.githubusercontent.com/haierkeys/fast-note-sync-service/master/scripts/quest_install.sh)</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 国内服务器（腾讯云 CNB 镜像，速度快）</span></div></div><div><div><div>5</div></div><div><span>bash</span><span> </span><span>&lt;(</span><span>curl</span><span> </span><span>-fsSL</span><span> https://cnb.cool/haierkeys/fast-note-sync-service/-/git/raw/master/scripts/quest_install.sh)</span><span> </span><span>--cnb</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>脚本自动完成：</p><ul>
<li>下载对应系统的二进制文件到 <code>/opt/fast-note</code></li>
<li>创建全局快捷命令 <code>fns</code>（位于 <code>/usr/local/bin/fns</code>）</li>
<li>注册 Systemd/Linux 或 Launchd/macOS 服务并设置开机自启</li>
<li>进入交互式菜单，支持安装/升级/启停/切换镜像源</li>
</ul><hr /></section><section><h3>方式 2：Docker 部署<a href="#方式-2docker-部署"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span># 拉取镜像</span></div></div><div><div><div>2</div></div><div><span>docker</span><span> </span><span>pull</span><span> </span><span>haierkeys/fast-note-sync-service:latest</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span># 启动容器</span></div></div><div><div><div>5</div></div><div><span>docker</span><span> </span><span>run</span><span> </span><span>-tid</span><span> </span><span>--name</span><span> </span><span>fast-note-sync-service</span><span> </span><span>\</span></div></div><div><div><div>6</div></div><div><span>    </span><span>-p</span><span> </span><span>9000:9000</span><span> </span><span>\</span></div></div><div><div><div>7</div></div><div><span>    </span><span>-v</span><span> </span><span>/data/fast-note-sync/storage/:/fast-note-sync/storage/</span><span> </span><span>\</span></div></div><div><div><div>8</div></div><div><span>    </span><span>-v</span><span> </span><span>/data/fast-note-sync/config/:/fast-note-sync/config/</span><span> </span><span>\</span></div></div><div><div><div>9</div></div><div><span>    </span><span>haierkeys/fast-note-sync-service:latest</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>或用 docker-compose：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>version</span><span>: </span><span>'3'</span></div></div><div><div><div>2</div></div><div><span>services</span><span>:</span></div></div><div><div><div>3</div></div><div><span>  </span><span>fast-note-sync-service</span><span>:</span></div></div><div><div><div>4</div></div><div><span>    </span><span>image</span><span>: </span><span>haierkeys/fast-note-sync-service:latest</span></div></div><div><div><div>5</div></div><div><span>    </span><span>container_name</span><span>: </span><span>fast-note-sync-service</span></div></div><div><div><div>6</div></div><div><span>    </span><span>restart</span><span>: </span><span>always</span></div></div><div><div><div>7</div></div><div><span>    </span><span>ports</span><span>:</span></div></div><div><div><div>8</div></div><div><span><span>      </span></span><span>- </span><span>"9000:9000"</span></div></div><div><div><div>9</div></div><div><span>    </span><span>volumes</span><span>:</span></div></div><div><div><div>10</div></div><div><span><span>      </span></span><span>- </span><span>./storage:/fast-note-sync/storage</span></div></div><div><div><div>11</div></div><div><span><span>      </span></span><span>- </span><span>./config:/fast-note-sync/config</span></div></div></code></pre><div><div></div><div></div></div></figure></div><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>docker</span><span> </span><span>compose</span><span> </span><span>up</span><span> </span><span>-d</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section><section><h2>二、首次启动必做检查<a href="#二首次启动必做检查"><span>#</span></a></h2><section><h3>1. 放行本地防火墙（ufw）<a href="#1-放行本地防火墙ufw"><span>#</span></a></h3><p>安装脚本<strong>不会自动放行 ufw</strong>，这是最常见的”服务启动但端口不通”原因：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ufw</span><span> </span><span>allow</span><span> </span><span>9000/tcp</span></div></div><div><div><div>2</div></div><div><span>ufw</span><span> </span><span>reload</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>2. 放行云服务器安全组<a href="#2-放行云服务器安全组"><span>#</span></a></h3><p>登录云厂商控制台（阿里云/腾讯云/百度云/AWS），在<strong>安全组入方向</strong>添加：</p><ul>
<li>协议：TCP</li>
<li>端口：<code>9000</code></li>
<li>源地址：<code>0.0.0.0/0</code></li>
</ul></section><section><h3>3. 修改默认 Token 密钥<a href="#3-修改默认-token-密钥"><span>#</span></a></h3><p>启动日志会提示：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>WARN  Using default secret key - please change security.auth-token-key</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>生成安全密钥并修改配置：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>openssl</span><span> </span><span>rand</span><span> </span><span>-base64</span><span> </span><span>32</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>编辑 <code>/opt/fast-note/config/config.yaml</code>（一键脚本）或挂载的 <code>./config/config.yaml</code>（Docker）：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>security</span><span>:</span></div></div><div><div><div>2</div></div><div><span>    </span><span>auth-token-key</span><span>: </span><span>"你生成的64位密钥"</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>重启服务生效。</strong></p><hr /></section></section><section><h2>三、服务管理<a href="#三服务管理"><span>#</span></a></h2><section><h3>常用命令<a href="#常用命令"><span>#</span></a></h3><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>fns</span><span> </span><span>status</span><span>    </span><span># 查看服务状态</span></div></div><div><div><div>2</div></div><div><span>fns</span><span> </span><span>start</span><span>     </span><span># 启动</span></div></div><div><div><div>3</div></div><div><span>fns</span><span> </span><span>stop</span><span>      </span><span># 停止</span></div></div><div><div><div>4</div></div><div><span>fns</span><span> </span><span>update</span><span>    </span><span># 升级到最新版</span></div></div><div><div><div>5</div></div><div><span>fns</span><span> </span><span>menu</span><span>      </span><span># 进入交互式菜单（安装/升级/启停/切换镜像）</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>关于 systemctl<a href="#关于-systemctl"><span>#</span></a></h3><p>新版本 <code>fns</code> 脚本安装时会自动注册 Systemd 服务，因此也可以用 systemctl 管理：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>systemctl</span><span> </span><span>status</span><span> </span><span>fast-note</span></div></div><div><div><div>2</div></div><div><span>systemctl</span><span> </span><span>start</span><span> </span><span>fast-note</span></div></div><div><div><div>3</div></div><div><span>systemctl</span><span> </span><span>stop</span><span> </span><span>fast-note</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p>旧版本（v2.x 及之前）依赖交互菜单重启，当前版本已支持 systemctl 直接管理。</p></blockquote><hr /></section></section><section><h2>四、配置域名 + HTTPS（Nginx Proxy Manager）<a href="#四配置域名--httpsnginx-proxy-manager"><span>#</span></a></h2><section><h3>前置条件<a href="#前置条件"><span>#</span></a></h3><ul>
<li>已安装 <a href="https://nginxproxymanager.com/" target="_blank">Nginx Proxy Manager</a>（Docker 部署）</li>
<li>域名 DNS 已解析到服务器公网 IP</li>
<li>NPM 容器与 FNS 在同一 Docker 网络或能访问宿主机</li>
</ul></section><section><h3>NPM 配置步骤<a href="#npm-配置步骤"><span>#</span></a></h3><ol>
<li>登录 NPM 后台（默认 <code>http://服务器IP:81</code>）</li>
<li><strong>Proxy Hosts → Add Proxy Host</strong></li>
</ol>

<table><thead><tr><th>字段</th><th>值</th></tr></thead><tbody><tr><td>Domain Names</td><td><code>notesync.yourdomain.com</code></td></tr><tr><td>Scheme</td><td><code>http</code></td></tr><tr><td>Forward Hostname / IP</td><td><code>172.17.0.1</code>（Docker 网关地址）或宿主机内网 IP</td></tr><tr><td>Forward Port</td><td><code>9000</code></td></tr><tr><td>Websockets Support</td><td><strong>✅ 必须勾选</strong>（同步接口使用 WS）</td></tr><tr><td>Block Common Exploits</td><td>建议勾选</td></tr></tbody></table><ol>
<li>
<p><strong>SSL 选项卡</strong></p>
<ul>
<li>SSL Certificate: <code>Request a new SSL Certificate</code></li>
<li>Force SSL: 建议勾选（配合 Cloudflare Full 模式）</li>
<li>HTTP/2 Support: 勾选</li>
</ul>
</li>
<li>
<p><strong>Advanced 自定义配置</strong></p>
</li>
</ol><p>进入 Advanced → Custom Nginx Configuration，粘贴：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>client_max_body_size </span><span>50m</span><span>;</span></div></div><div><div><div>2</div></div><div><span>proxy_buffering </span><span>off</span><span>;</span></div></div><div><div><div>3</div></div><div><span>proxy_max_temp_file_size </span><span>0</span><span>;</span></div></div><div><div><div>4</div></div><div><span>proxy_read_timeout </span><span>86400</span><span>;</span></div></div><div><div><div>5</div></div><div><span>proxy_send_timeout </span><span>86400</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><blockquote><p><code>client_max_body_size</code> 控制附件上传大小；<code>proxy_buffering off</code> 保证 WebSocket/大文件实时传输不缓冲。</p></blockquote><ol>
<li><strong>保存并测试</strong></li>
</ol><p>浏览器访问 <code>https://notesync.yourdomain.com/webgui</code></p><hr /></section></section><section><h2>五、核心配置（ext-api-url）<a href="#五核心配置ext-api-url"><span>#</span></a></h2><p>编辑 <code>/opt/fast-note/config/config.yaml</code>（或 Docker 挂载的 <code>./config/config.yaml</code>）：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>server</span><span>:</span></div></div><div><div><div>2</div></div><div><span>    </span><span># 仅用域名访问时，填域名</span></div></div><div><div><div>3</div></div><div><span>    </span><span>ext-api-url</span><span>: </span><span>"https://notesync.yourdomain.com"</span></div></div><div><div><div>4</div></div><div><span>    </span><span>share-base-url</span><span>: </span><span>"https://notesync.yourdomain.com"</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>    </span><span># IP/域名共存时，留空让前端自适应</span></div></div><div><div><div>7</div></div><div><span>    </span><span># ext-api-url: ""</span></div></div><div><div><div>8</div></div><div><span>    </span><span># share-base-url: ""</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>修改后重启服务：<code>fns restart</code> 或 <code>systemctl restart fast-note</code>。</p><hr /></section><section><h2>六、MCP（Model Context Protocol）配置<a href="#六mcpmodel-context-protocol配置"><span>#</span></a></h2><p>FNS v3.0+ 原生支持 MCP，可作为 MCP Server 接入 Cherry Studio、Cursor、Claude Code 等 AI 客户端，让 AI 直接读写私人笔记。</p><section><h3>通用请求头<a href="#通用请求头"><span>#</span></a></h3>

<table><thead><tr><th>头字段</th><th>说明</th></tr></thead><tbody><tr><td><code>Authorization: Bearer &lt;Token&gt;</code></td><td>从 WebGUI “复制 API 配置” 获取的 Token</td></tr><tr><td><code>X-Default-Vault-Name: &lt;VaultName&gt;</code></td><td>默认 Vault 名称（可选）</td></tr></tbody></table></section><section><h3>方式 A：StreamableHTTP（推荐）<a href="#方式-astreamablehttp推荐"><span>#</span></a></h3><p>所有 MCP 客户端通用：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"mcpServers"</span><span>: {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"fns"</span><span>: {</span></div></div><div><div><div>4</div></div><div><span>      </span><span>"url"</span><span>: </span><span>"http://&lt;IP&gt;:9000/api/mcp"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>      </span><span>"type"</span><span>: </span><span>"http"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>      </span><span>"headers"</span><span>: {</span></div></div><div><div><div>7</div></div><div><span>        </span><span>"Authorization"</span><span>: </span><span>"Bearer &lt;Token&gt;"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>        </span><span>"X-Default-Vault-Name"</span><span>: </span><span>"&lt;VaultName&gt;"</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>12</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>方式 B：SSE（向后兼容，适用于 Cherry Studio 等）<a href="#方式-bsse向后兼容适用于-cherry-studio-等"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"mcpServers"</span><span>: {</span></div></div><div><div><div>3</div></div><div><span>    </span><span>"fns"</span><span>: {</span></div></div><div><div><div>4</div></div><div><span>      </span><span>"url"</span><span>: </span><span>"http://&lt;IP&gt;:9000/api/mcp/sse"</span><span>,</span></div></div><div><div><div>5</div></div><div><span>      </span><span>"type"</span><span>: </span><span>"sse"</span><span>,</span></div></div><div><div><div>6</div></div><div><span>      </span><span>"headers"</span><span>: {</span></div></div><div><div><div>7</div></div><div><span>        </span><span>"Authorization"</span><span>: </span><span>"Bearer &lt;Token&gt;"</span><span>,</span></div></div><div><div><div>8</div></div><div><span>        </span><span>"X-Default-Vault-Name"</span><span>: </span><span>"&lt;VaultName&gt;"</span></div></div><div><div><div>9</div></div><div><span><span>      </span></span><span>}</span></div></div><div><div><div>10</div></div><div><span><span>    </span></span><span>}</span></div></div><div><div><div>11</div></div><div><span><span>  </span></span><span>}</span></div></div><div><div><div>12</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section><section><h2>七、Obsidian 插件使用方法<a href="#七obsidian-插件使用方法"><span>#</span></a></h2><section><h3>1. 安装插件<a href="#1-安装插件"><span>#</span></a></h3><ul>
<li><strong>方式 A</strong>：Obsidian 社区插件市场搜索 <code>Fast Note Sync</code></li>
<li><strong>方式 B</strong>：手动下载 <a href="https://github.com/haierkeys/obsidian-fast-note-sync" target="_blank">obsidian-fast-note-sync</a> 最新 Release，解压到 <code>.obsidian/plugins/obsidian-fast-note-sync/</code></li>
</ul></section><section><h3>2. 获取 API 配置<a href="#2-获取-api-配置"><span>#</span></a></h3><ol>
<li>浏览器打开 FNS WebGUI：<code>https://notesync.yourdomain.com/webgui</code></li>
<li>首次使用需<strong>注册账号</strong>（第一个注册的账号即为管理员，UID 为 1）</li>
<li>登录后，点击页面上的 <strong>“复制 API 配置”</strong></li>
<li>配置内容会自动复制到剪贴板：</li>
</ol><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"serverUrl"</span><span>: </span><span>"https://notesync.yourdomain.com"</span><span>,</span></div></div><div><div><div>3</div></div><div><span>  </span><span>"token"</span><span>: </span><span>"Bearer xxxxxxxx"</span><span>,</span></div></div><div><div><div>4</div></div><div><span>  </span><span>"vault"</span><span>: </span><span>"defaultVault"</span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>3. 粘贴到 Obsidian 插件设置<a href="#3-粘贴到-obsidian-插件设置"><span>#</span></a></h3><ol>
<li>打开 Obsidian → 设置 → 第三方插件 → Fast Note Sync</li>
<li>将复制的 API 配置<strong>完整粘贴</strong>到输入框中</li>
<li>插件自动解析 <code>serverUrl</code>、<code>token</code>、<code>vault</code></li>
<li>保存设置</li>
</ol></section><section><h3>4. 首次同步<a href="#4-首次同步"><span>#</span></a></h3><ol>
<li>在 Obsidian 中打开命令面板（Ctrl/Cmd + P）</li>
<li>搜索 <code>Fast Note Sync: 同步全部</code> 或点击左侧栏的同步图标</li>
<li>插件自动创建 Vault 并开始双向同步</li>
</ol></section><section><h3>5. 多设备同步<a href="#5-多设备同步"><span>#</span></a></h3><p>在其他设备的 Obsidian 中重复上述步骤，使用<strong>同一套 API 配置</strong>即可。</p><hr /></section></section><section><h2>八、进阶配置<a href="#八进阶配置"><span>#</span></a></h2><section><h3>数据库<a href="#数据库"><span>#</span></a></h3><p>默认使用 SQLite，适合个人使用。如需 MySQL/PostgreSQL，修改 <code>config.yaml</code>：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>database</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>type</span><span>: </span><span>mysql</span><span>          </span><span># mysql | postgres | sqlite</span></div></div><div><div><div>3</div></div><div><span>  </span><span>host</span><span>: </span><span>127.0.0.1</span></div></div><div><div><div>4</div></div><div><span>  </span><span>port</span><span>: </span><span>3306</span></div></div><div><div><div>5</div></div><div><span>  </span><span>username</span><span>: </span><span>fns</span></div></div><div><div><div>6</div></div><div><span>  </span><span>password</span><span>: </span><span>"your-password"</span></div></div><div><div><div>7</div></div><div><span>  </span><span>name</span><span>: </span><span>fast_note_sync</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>存储后端<a href="#存储后端"><span>#</span></a></h3><p>支持本地文件系统、阿里云 OSS、AWS S3、Cloudflare R2、MinIO、WebDAV：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>storage</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>local-fs</span><span>:</span></div></div><div><div><div>3</div></div><div><span>    </span><span>is-enable</span><span>: </span><span>true</span></div></div><div><div><div>4</div></div><div><span>    </span><span>httpfs-is-enable</span><span>: </span><span>true</span></div></div><div><div><div>5</div></div><div><span>    </span><span>save-path</span><span>: </span><span>"storage/uploads"</span></div></div><div><div><div>6</div></div><div><span>  </span><span>aliyun-oss</span><span>:</span></div></div><div><div><div>7</div></div><div><span>    </span><span>is-enable</span><span>: </span><span>false</span><span>     </span><span># 设为 true 并配置 AccessKey 等</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>内网穿透<a href="#内网穿透"><span>#</span></a></h3><p>FNS 原生支持 ngrok 和 Cloudflare Tunnel：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>ngrok</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>enabled</span><span>: </span><span>true</span></div></div><div><div><div>3</div></div><div><span>  </span><span>auth-token</span><span>: </span><span>"your-token"</span></div></div><div><div><div>4</div></div><div><span>  </span><span>domain</span><span>: </span><span>"your-domain.ngrok.io"</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span>cloudflare</span><span>:</span></div></div><div><div><div>7</div></div><div><span>  </span><span>enabled</span><span>: </span><span>true</span></div></div><div><div><div>8</div></div><div><span>  </span><span>token</span><span>: </span><span>"your-tunnel-token"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>Git 自动提交<a href="#git-自动提交"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>git</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>name</span><span>: </span><span>"FNS Service"</span></div></div><div><div><div>3</div></div><div><span>  </span><span>email</span><span>: </span><span>"fns@email.com"</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>关闭注册（多用户场景）<a href="#关闭注册多用户场景"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>user</span><span>:</span></div></div><div><div><div>2</div></div><div><span>  </span><span>register-is-enable</span><span>: </span><span>false</span></div></div><div><div><div>3</div></div><div><span>  </span><span>admin-uid</span><span>: </span><span>1</span><span>    </span><span># 指定管理员 UID</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section><section><h2>九、踩坑笔记（Troubleshooting）<a href="#九踩坑笔记troubleshooting"><span>#</span></a></h2><section><h3>坑 1：服务启动但 9000 端口无法访问<a href="#坑-1服务启动但-9000-端口无法访问"><span>#</span></a></h3><p><strong>现象</strong>：<code>fns status</code> 显示运行中，但浏览器/curl 访问超时。<br />
<strong>原因</strong>：<code>ufw</code> 或云安全组未放行 9000。<br />
<strong>解决</strong>：</p><div><figure><figcaption><span></span><span>Terminal window</span></figcaption><pre><code><div><div><div>1</div></div><div><span>ufw</span><span> </span><span>allow</span><span> </span><span>9000/tcp</span></div></div><div><div><div>2</div></div><div><span># 同时检查云控制台安全组</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section><section><h3>坑 2：GitHub 支持文档下载超时<a href="#坑-2github-支持文档下载超时"><span>#</span></a></h3><p><strong>现象</strong>：日志出现 <code>Failed to fetch support records ... context deadline exceeded</code>。<br />
<strong>原因</strong>：服务器无法访问 <code>raw.githubusercontent.com</code>（国内常见）。<br />
<strong>影响</strong>：仅影响 WebGUI 帮助文档加载，<strong>不影响核心同步功能</strong>。<br />
<strong>解决</strong>：忽略或配置代理。</p><hr /></section><section><h3>坑 3：修改 ext-api-url 后 IP 访问报错<a href="#坑-3修改-ext-api-url-后-ip-访问报错"><span>#</span></a></h3><p><strong>现象</strong>：<code>ext-api-url</code> 设为域名后，<code>http://IP:9000/webgui</code> 打开报错。<br />
<strong>原因</strong>：前端强制向域名发起 API 请求，跨域或协议不匹配。<br />
<strong>解决</strong>：</p><ul>
<li><strong>推荐（生产）</strong>：统一使用域名访问</li>
<li><strong>IP/域名共存</strong>：<code>ext-api-url</code> 和 <code>share-base-url</code> 留空 <code>""</code></li>
</ul><hr /></section><section><h3>坑 4：Cloudflare + NPM 导致 ERR_TOO_MANY_REDIRECTS<a href="#坑-4cloudflare--npm-导致-err_too_many_redirects"><span>#</span></a></h3><p><strong>现象</strong>：浏览器提示”重定向次数过多”。<br />
<strong>原因</strong>：Cloudflare SSL 加密模式为 <strong>Flexible</strong>，回源 HTTP；NPM 开启 <strong>Force SSL</strong> 后检测到 HTTP 就 301 跳 HTTPS，死循环。<br />
<strong>解决</strong>（二选一）：</p>

<table><thead><tr><th>方案</th><th>操作</th></tr></thead><tbody><tr><td><strong>推荐</strong></td><td>Cloudflare → SSL/TLS → 加密模式改为 <strong>Full (strict)</strong></td></tr><tr><td>备选</td><td>NPM 中关闭 <strong>Force SSL</strong></td></tr></tbody></table><hr /></section><section><h3>坑 5：NPM 中 Forward IP 填 127.0.0.1 不通<a href="#坑-5npm-中-forward-ip-填-127001-不通"><span>#</span></a></h3><p><strong>现象</strong>：NPM 返回 502 Bad Gateway。<br />
<strong>原因</strong>：NPM 是 Docker 容器，<code>127.0.0.1</code> 指向容器自身。<br />
<strong>解决</strong>：填写 Docker 网关 <code>172.17.0.1</code>，或宿主机内网 IP。</p><hr /></section><section><h3>坑 6：SSL 证书申请失败（Cloudflare 代理开启时）<a href="#坑-6ssl-证书申请失败cloudflare-代理开启时"><span>#</span></a></h3><p><strong>原因</strong>：Cloudflare 橙色云拦截 HTTP-01 验证请求。<br />
<strong>解决</strong>：</p><ul>
<li><strong>方案 A</strong>：申请证书时临时关闭 Cloudflare 代理（灰色云），申请完再开启</li>
<li><strong>方案 B（推荐）</strong>：NPM 中用 <strong>DNS Challenge</strong>，Provider 选 Cloudflare，API Token 需 <code>Zone:Read + DNS:Edit</code> 权限</li>
</ul><hr /></section><section><h3>坑 7：大文件/附件同步失败或超时<a href="#坑-7大文件附件同步失败或超时"><span>#</span></a></h3><p><strong>原因</strong>：NPM 默认 <code>client_max_body_size</code> 太小，或 <code>proxy_buffering</code> 开启。<br />
<strong>解决</strong>：在 NPM Advanced 中加上：</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>client_max_body_size </span><span>50m</span><span>;</span></div></div><div><div><div>2</div></div><div><span>proxy_buffering </span><span>off</span><span>;</span></div></div><div><div><div>3</div></div><div><span>proxy_max_temp_file_size </span><span>0</span><span>;</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section><section><h3>坑 8：Obsidian 插件连接不上<a href="#坑-8obsidian-插件连接不上"><span>#</span></a></h3><p><strong>检查清单</strong>：</p><ol>
<li>服务器 9000 端口是否放行（ufw + 安全组）</li>
<li>如使用域名，确认 <code>ext-api-url</code> 配置正确</li>
<li>如使用 HTTPS，确认证书有效（非自签）</li>
<li>如使用 Cloudflare，确认加密模式为 Full (strict)</li>
<li>在 WebGUI 点击”复制 API 配置”，完整粘贴到插件设置</li>
<li>确认 <code>serverUrl</code> 与浏览器访问地址一致（不混用 IP 和域名）</li>
</ol><hr /></section><section><h3>坑 9：Docker 部署的数据持久化<a href="#坑-9docker-部署的数据持久化"><span>#</span></a></h3><p><strong>现象</strong>：容器重启后数据丢失。<br />
<strong>原因</strong>：未挂载 <code>storage</code> 和 <code>config</code> 卷。<br />
<strong>解决</strong>：启动时务必通过 <code>-v</code> 或 <code>volumes</code> 挂载宿主机目录。</p><hr /></section><section><h3>坑 10：国内服务器拉取 Docker 镜像慢<a href="#坑-10国内服务器拉取-docker-镜像慢"><span>#</span></a></h3><p><strong>解决</strong>：配置 Docker 镜像加速器（如阿里云加速器、中科大源）：</p><div><figure><figcaption><span>/etc/docker/daemon.json</span></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span>  </span><span>"registry-mirrors"</span><span>:</span><span> [</span><span>"https://docker.mirrors.ustc.edu.cn"</span><span>]</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section><section><h2>十、官方参考链接<a href="#十官方参考链接"><span>#</span></a></h2><ul>
<li>FNS 仓库主页：<a href="https://github.com/haierkeys/fast-note-sync-service" target="_blank">https://github.com/haierkeys/fast-note-sync-service</a></li>
<li>国内镜像：<a href="https://cnb.cool/haierkeys/fast-note-sync-service" target="_blank">https://cnb.cool/haierkeys/fast-note-sync-service</a></li>
<li>官方 Nginx 配置示例：<a href="https://github.com/haierkeys/fast-note-sync-service/blob/master/scripts/https-nginx-example.conf" target="_blank">https://github.com/haierkeys/fast-note-sync-service/blob/master/scripts/https-nginx-example.conf</a></li>
<li>完整配置示例：<a href="https://github.com/haierkeys/fast-note-sync-service/blob/master/config/config.yaml" target="_blank">https://github.com/haierkeys/fast-note-sync-service/blob/master/config/config.yaml</a></li>
<li>Obsidian 插件仓库：<a href="https://github.com/haierkeys/obsidian-fast-note-sync" target="_blank">https://github.com/haierkeys/obsidian-fast-note-sync</a></li>
</ul></section></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.hyperthreading.cn/posts/pytorch%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</id>
      <title type="text">PyTorch 学习笔记</title>
      <published>2025-12-01T00:00:00.000Z</published>
      <updated>2025-12-01T00:00:00.000Z</updated>
      <author><name>超线程</name></author>
      <link rel="alternate" href="https://blog.hyperthreading.cn/posts/pytorch%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
      <summary type="text"></summary>
      <content type="html"><![CDATA[<section><h2>PyTorch 核心知识点整理<a href="#pytorch-核心知识点整理"><span>#</span></a></h2></section>
<section><h2>一、基础概念<a href="#一基础概念"><span>#</span></a></h2><section><h3>1.1 Tensor（张量）<a href="#11-tensor张量"><span>#</span></a></h3><ul>
<li>
<p>核心数据结构：类似于 NumPy 的 ndarray，但支持 GPU 加速和自动求导。</p>
</li>
<li>
<p>创建方式：</p>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># 从 Python 列表或 NumPy 数组创建</span></div></div><div><div><div>4</div></div><div><span><span>x </span><span>=</span><span> torch.</span><span>tensor</span><span>([</span></span><span>1</span><span>, </span><span>2</span><span>, </span><span>3</span><span>])</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># 创建特定值的张量</span></div></div><div><div><div>7</div></div><div><span><span>a </span><span>=</span><span> torch.</span><span>zeros</span><span>((</span></span><span>2</span><span>, </span><span>3</span><span>))</span></div></div><div><div><div>8</div></div><div><span><span>b </span><span>=</span><span> torch.</span><span>ones</span><span>((</span></span><span>2</span><span>, </span><span>3</span><span>))</span></div></div><div><div><div>9</div></div><div><span><span>c </span><span>=</span><span> torch.</span><span>rand</span><span>((</span></span><span>2</span><span>, </span><span>3</span><span>))</span></div></div><div><div><div>10</div></div><div><span><span>d </span><span>=</span><span> torch.</span><span>randn</span><span>((</span></span><span>2</span><span>, </span><span>3</span><span>))</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span># 创建序列</span></div></div><div><div><div>13</div></div><div><span><span>r1 </span><span>=</span><span> torch.</span><span>arange</span><span>(</span></span><span>0</span><span>, </span><span>10</span><span>, </span><span>2</span><span>)</span></div></div><div><div><div>14</div></div><div><span><span>r2 </span><span>=</span><span> torch.</span><span>linspace</span><span>(</span></span><span>0</span><span>, </span><span>1</span><span>, </span><span>5</span><span>)</span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span># 创建单位矩阵</span></div></div><div><div><div>17</div></div><div><span><span>i </span><span>=</span><span> torch.</span><span>eye</span><span>(</span></span><span>3</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p>属性：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>x.dtype</span></div></div><div><div><div>2</div></div><div><span>x.shape</span></div></div><div><div><div>3</div></div><div><span><span>x.</span><span>size</span><span>()</span></span></div></div><div><div><div>4</div></div><div><span>x.device</span></div></div><div><div><div>5</div></div><div><span>x.requires_grad</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>操作：</p>
<ul>
<li>
<p>索引与切片：与 NumPy 类似。</p>
</li>
<li>
<p>视图 (View) 与 复制 (Copy)：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>y </span><span>=</span><span> x.</span><span>view</span><span>(</span><span>-</span></span><span>1</span><span>)          </span><span># 返回一个新视图，共享底层数据（要求内存连续）</span></div></div><div><div><div>2</div></div><div><span><span>z </span><span>=</span><span> x.</span><span>reshape</span><span>(</span><span>-</span></span><span>1</span><span>)       </span><span># 更灵活的形状变换，可能返回视图或副本</span></div></div><div><div><div>3</div></div><div><span><span>x_copy </span><span>=</span><span> x.</span><span>clone</span><span>()      </span></span><span># 返回数据的副本</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>数学运算：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>s </span><span>=</span><span> torch.</span><span>sum</span><span>(x)</span></span></div></div><div><div><div>2</div></div><div><span><span>m </span><span>=</span><span> torch.</span><span>mean</span><span>(x.</span><span>float</span><span>())</span></span></div></div><div><div><div>3</div></div><div><span><span>mx </span><span>=</span><span> torch.</span><span>max</span><span>(x)</span></span></div></div><div><div><div>4</div></div><div><span><span>e </span><span>=</span><span> torch.</span><span>exp</span><span>(x.</span><span>float</span><span>())</span></span></div></div><div><div><div>5</div></div><div><span><span>lg </span><span>=</span><span> torch.</span><span>log</span><span>(x.</span><span>float</span><span>())</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>广播 (Broadcasting)：自动扩展张量以进行运算。</p>
</li>
<li>
<p>类型转换：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>xf </span><span>=</span><span> x.</span><span>float</span><span>()</span></span></div></div><div><div><div>2</div></div><div><span><span>xl </span><span>=</span><span> x.</span><span>long</span><span>()</span></span></div></div><div><div><div>3</div></div><div><span><span>x2 </span><span>=</span><span> x.</span><span>to</span><span>(</span></span><span>dtype</span><span><span>=</span><span>torch.float32)</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>设备转移：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>device </span><span>=</span><span> torch.</span><span>device</span><span>(</span></span><span>"cuda:0"</span><span> </span><span>if</span><span><span> torch.cuda.</span><span>is_available</span><span>() </span></span><span>else</span><span> </span><span>"cpu"</span><span>)</span></div></div><div><div><div>2</div></div><div><span><span>x_gpu </span><span>=</span><span> x.</span><span>to</span><span>(device)</span></span></div></div><div><div><div>3</div></div><div><span><span>x_cpu </span><span>=</span><span> x_gpu.</span><span>cpu</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul>
</li>
</ul></section><section><h3>1.2 自动求导（Autograd）<a href="#12-自动求导autograd"><span>#</span></a></h3><ul>
<li>
<p>核心机制：PyTorch 能自动计算张量的梯度。</p>
</li>
<li>
<p>关键属性：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span># requires_grad: 设置张量需要计算梯度（通常对模型参数设置）</span></div></div><div><div><div>4</div></div><div><span><span>w </span><span>=</span><span> torch.</span><span>randn</span><span>(</span></span><span>10</span><span>, </span><span>requires_grad</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span># grad: 存储计算得到的梯度</span></div></div><div><div><div>7</div></div><div><span>w.grad</span></div></div><div><div><div>8</div></div><div>
</div></div><div><div><div>9</div></div><div><span># grad_fn: 指向创建该张量的 Function 对象，用于构建计算图</span></div></div><div><div><div>10</div></div><div><span><span>y </span><span>=</span><span> w </span><span>*</span><span> </span></span><span>2</span></div></div><div><div><div>11</div></div><div><span>y.grad_fn</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>基本流程：</p>
<div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>x </span><span>=</span><span> torch.</span><span>randn</span><span>(</span></span><span>10</span><span>)</span></div></div><div><div><div>4</div></div><div><span><span>w </span><span>=</span><span> torch.</span><span>randn</span><span>(</span></span><span>10</span><span>, </span><span>requires_grad</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>5</div></div><div><span><span>b </span><span>=</span><span> torch.</span><span>randn</span><span>(</span></span><span>1</span><span>, </span><span>requires_grad</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span><span>y </span><span>=</span><span> (x </span><span>*</span><span> w).</span><span>sum</span><span>() </span><span>+</span><span> b</span></span></div></div><div><div><div>8</div></div><div><span><span>loss </span><span>=</span><span> y</span></span></div></div><div><div><div>9</div></div><div>
</div></div><div><div><div>10</div></div><div><span><span>loss.</span><span>backward</span><span>()</span></span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>with</span><span><span> torch.</span><span>no_grad</span><span>():</span></span></div></div><div><div><div>13</div></div><div><span><span>    </span></span><span>w </span><span>-=</span><span> </span><span>0.01</span><span><span> </span><span>*</span><span> w.grad</span></span></div></div><div><div><div>14</div></div><div><span><span>    </span></span><span>b </span><span>-=</span><span> </span><span>0.01</span><span><span> </span><span>*</span><span> b.grad</span></span></div></div><div><div><div>15</div></div><div>
</div></div><div><div><div>16</div></div><div><span><span>w.grad.</span><span>zero_</span><span>()</span></span></div></div><div><div><div>17</div></div><div><span><span>b.grad.</span><span>zero_</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div>
</li>
<li>
<p>停止梯度：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>x </span><span>=</span><span> torch.</span><span>randn</span><span>(</span></span><span>3</span><span>, </span><span>requires_grad</span><span>=</span><span>True</span><span>)</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>with</span><span><span> torch.</span><span>no_grad</span><span>():</span></span></div></div><div><div><div>6</div></div><div><span><span>    </span></span><span>y </span><span>=</span><span> x </span><span>*</span><span> </span><span>2</span></div></div><div><div><div>7</div></div><div>
</div></div><div><div><div>8</div></div><div><span><span>z </span><span>=</span><span> x.</span><span>detach</span><span>()</span></span></div></div><div><div><div>9</div></div><div><span><span>x.</span><span>requires_grad_</span><span>(</span></span><span>False</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section></section>
<section><h2>二、神经网络模块<a href="#二神经网络模块"><span>#</span></a></h2><section><h3>2.1 定义网络<a href="#21-定义网络"><span>#</span></a></h3><ul>
<li>
<p>常见写法：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div><span>import</span><span> torch.nn </span><span>as</span><span> nn</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>class</span><span><span> </span><span>MyModel</span><span>(</span><span>nn</span><span>.</span><span>Module</span><span>)</span></span><span>:</span></div></div><div><div><div>5</div></div><div><span>    </span><span>def</span><span> </span><span>__init__</span><span>(</span><span>self</span><span>):</span></div></div><div><div><div>6</div></div><div><span>        </span><span>super</span><span>().</span><span>__init__</span><span>()</span></div></div><div><div><div>7</div></div><div><span>        </span><span>self</span><span><span>.net </span><span>=</span><span> nn.</span><span>Sequential</span><span>(</span></span></div></div><div><div><div>8</div></div><div><span><span>            </span></span><span>nn.</span><span>Linear</span><span>(</span><span>10</span><span>, </span><span>32</span><span>),</span></div></div><div><div><div>9</div></div><div><span><span>            </span></span><span>nn.</span><span>ReLU</span><span>(),</span></div></div><div><div><div>10</div></div><div><span><span>            </span></span><span>nn.</span><span>Linear</span><span>(</span><span>32</span><span>, </span><span>10</span><span>),</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>)</span></div></div><div><div><div>12</div></div><div>
</div></div><div><div><div>13</div></div><div><span>    </span><span>def</span><span> </span><span>forward</span><span>(</span><span>self</span><span>,</span><span><span> </span><span>x</span></span><span>):</span></div></div><div><div><div>14</div></div><div><span>        </span><span>return</span><span> </span><span>self</span><span><span>.</span><span>net</span><span>(x)</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>常用层：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch.nn </span><span>as</span><span> nn</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>nn.Linear</span></div></div><div><div><div>4</div></div><div><span>nn.Conv2d</span></div></div><div><div><div>5</div></div><div><span>nn.MaxPool2d</span></div></div><div><div><div>6</div></div><div><span>nn.AvgPool2d</span></div></div><div><div><div>7</div></div><div><span>nn.BatchNorm1d</span></div></div><div><div><div>8</div></div><div><span>nn.BatchNorm2d</span></div></div><div><div><div>9</div></div><div><span>nn.BatchNorm3d</span></div></div><div><div><div>10</div></div><div><span>nn.Dropout</span></div></div><div><div><div>11</div></div><div><span>nn.Embedding</span></div></div><div><div><div>12</div></div><div><span><span>nn.</span><span>LSTM</span></span></div></div><div><div><div>13</div></div><div><span><span>nn.</span><span>GRU</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>激活函数：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch.nn </span><span>as</span><span> nn</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>nn.ReLU</span></div></div><div><div><div>4</div></div><div><span>nn.Sigmoid</span></div></div><div><div><div>5</div></div><div><span>nn.Tanh</span></div></div><div><div><div>6</div></div><div><span>nn.Softmax</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>容器：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch.nn </span><span>as</span><span> nn</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>nn.Sequential</span></div></div><div><div><div>4</div></div><div><span>nn.ModuleList</span></div></div><div><div><div>5</div></div><div><span>nn.ModuleDict</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section><section><h3>2.2 损失函数（Loss Functions）<a href="#22-损失函数loss-functions"><span>#</span></a></h3><ul>
<li>
<p>常用损失：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch.nn </span><span>as</span><span> nn</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>nn.MSELoss                 </span><span># 回归</span></div></div><div><div><div>4</div></div><div><span>nn.CrossEntropyLoss        </span><span># 分类（输入 logits，内部会做 Softmax）</span></div></div><div><div><div>5</div></div><div><span>nn.BCELoss                 </span><span># 二元交叉熵（输入概率）</span></div></div><div><div><div>6</div></div><div><span>nn.BCEWithLogitsLoss       </span><span># Sigmoid + BCELoss，数值更稳定</span></div></div><div><div><div>7</div></div><div><span>nn.NLLLoss                 </span><span># 负对数似然（常与 LogSoftmax 配合）</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>使用：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>loss </span><span>=</span><span> </span><span>criterion</span><span>(predicted_output, true_target)</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section><section><h3>2.3 优化器（Optimizers）<a href="#23-优化器optimizers"><span>#</span></a></h3><ul>
<li>
<p>作用：根据计算出的梯度更新模型参数。</p>
</li>
<li>
<p>常用优化器：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>torch.optim.</span><span>SGD</span></span></div></div><div><div><div>4</div></div><div><span>torch.optim.Adam</span></div></div><div><div><div>5</div></div><div><span>torch.optim.RMSprop</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>基本使用流程：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>optimizer </span><span>=</span><span> torch.optim.</span><span>Adam</span><span>(model.</span><span>parameters</span><span>(), </span></span><span>lr</span><span>=</span><span>0.001</span><span>)</span></div></div><div><div><div>2</div></div><div><span><span>loss </span><span>=</span><span> </span><span>criterion</span><span>(outputs, labels)</span></span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span><span>optimizer.</span><span>zero_grad</span><span>()</span></span></div></div><div><div><div>5</div></div><div><span><span>loss.</span><span>backward</span><span>()</span></span></div></div><div><div><div>6</div></div><div><span><span>optimizer.</span><span>step</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section></section>
<section><h2>三、数据处理<a href="#三数据处理"><span>#</span></a></h2><section><h3>3.1 Dataset<a href="#31-dataset"><span>#</span></a></h3><ul>
<li>
<p>抽象基类：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from</span><span> torch.utils.data </span><span>import</span><span> Dataset</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>自定义数据集：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from</span><span> torch.utils.data </span><span>import</span><span> Dataset</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>class</span><span><span> </span><span>MyCustomDataset</span><span>(</span><span>Dataset</span><span>)</span></span><span>:</span></div></div><div><div><div>4</div></div><div><span>    </span><span>def</span><span> </span><span>__len__</span><span>(</span><span>self</span><span>):</span></div></div><div><div><div>5</div></div><div><span>        </span><span>return</span><span> </span><span>0</span></div></div><div><div><div>6</div></div><div>
</div></div><div><div><div>7</div></div><div><span>    </span><span>def</span><span> </span><span>__getitem__</span><span>(</span><span>self</span><span>,</span><span><span> </span><span>idx</span></span><span>):</span></div></div><div><div><div>8</div></div><div><span>        </span><span>return</span><span> </span><span>None</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>内置数据集：torchvision.datasets.MNIST/CIFAR10/ImageFolder 等。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torchvision</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>torchvision.datasets.</span><span>MNIST</span></span></div></div><div><div><div>4</div></div><div><span><span>torchvision.datasets.</span><span>CIFAR10</span></span></div></div><div><div><div>5</div></div><div><span>torchvision.datasets.ImageFolder</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section><section><h3>3.2 DataLoader<a href="#32-dataloader"><span>#</span></a></h3><ul>
<li>
<p>作用：将数据集封装成可迭代对象，支持批量加载、打乱、多进程加载。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from</span><span> torch.utils.data </span><span>import</span><span> DataLoader</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>DataLoader</span><span>(dataset, </span></span><span>batch_size</span><span>=</span><span>32</span><span>, </span><span>shuffle</span><span>=</span><span>True</span><span>, </span><span>num_workers</span><span>=</span><span>4</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>使用：</p>
</li>
</ul><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>dataset </span><span>=</span><span> </span><span>MyCustomDataset</span><span>(</span><span>...</span><span>)</span></span></div></div><div><div><div>2</div></div><div><span><span>dataloader </span><span>=</span><span> </span><span>DataLoader</span><span>(dataset, </span></span><span>batch_size</span><span>=</span><span>32</span><span>, </span><span>shuffle</span><span>=</span><span>True</span><span>, </span><span>num_workers</span><span>=</span><span>4</span><span>)</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>for</span><span> batch_data, batch_labels </span><span>in</span><span> dataloader:</span></div></div><div><div><div>5</div></div><div><span>    </span><span># 训练/验证逻辑</span></div></div><div><div><div>6</div></div><div><span>    </span><span>pass</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>四、训练与验证流程<a href="#四训练与验证流程"><span>#</span></a></h2><section><h3>4.1 基本训练循环<a href="#41-基本训练循环"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>model.</span><span>train</span><span>()  </span></span><span># 设置为训练模式（影响 Dropout, BatchNorm 等层）</span></div></div><div><div><div>2</div></div><div><span>for</span><span> epoch </span><span>in</span><span> </span><span>range</span><span>(num_epochs):</span></div></div><div><div><div>3</div></div><div><span>    </span><span>for</span><span> inputs, labels </span><span>in</span><span> train_loader:</span></div></div><div><div><div>4</div></div><div><span><span>        </span></span><span>inputs, labels </span><span>=</span><span> inputs.</span><span>to</span><span>(device), labels.</span><span>to</span><span>(device)</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>optimizer.</span><span>zero_grad</span><span>()  </span><span># 1. 清空梯度</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>outputs </span><span>=</span><span> </span><span>model</span><span>(inputs)  </span><span># 2. 前向传播</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>loss </span><span>=</span><span> </span><span>criterion</span><span>(outputs, labels)  </span><span># 3. 计算损失</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>loss.</span><span>backward</span><span>()  </span><span># 4. 反向传播</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>optimizer.</span><span>step</span><span>()  </span><span># 5. 更新参数</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span>        </span><span># 可选：记录损失、准确率等</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>4.2 验证/测试循环<a href="#42-验证测试循环"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>model.</span><span>eval</span><span>()  </span></span><span># 设置为评估模式（关闭 Dropout, 固定 BatchNorm 统计量）</span></div></div><div><div><div>2</div></div><div><span>with</span><span><span> torch.</span><span>no_grad</span><span>():  </span></span><span># 关闭梯度计算，节省内存和计算</span></div></div><div><div><div>3</div></div><div><span>    </span><span>for</span><span> inputs, labels </span><span>in</span><span> val_loader:</span></div></div><div><div><div>4</div></div><div><span><span>        </span></span><span>inputs, labels </span><span>=</span><span> inputs.</span><span>to</span><span>(device), labels.</span><span>to</span><span>(device)</span></div></div><div><div><div>5</div></div><div><span><span>        </span></span><span>outputs </span><span>=</span><span> </span><span>model</span><span>(inputs)</span></div></div><div><div><div>6</div></div><div><span><span>        </span></span><span>loss </span><span>=</span><span> </span><span>criterion</span><span>(outputs, labels)</span></div></div><div><div><div>7</div></div><div><span>        </span><span># 计算准确率或其他指标</span></div></div><div><div><div>8</div></div><div><span>        </span><span># 记录验证损失和指标</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section></section>
<section><h2>五、模型保存与加载<a href="#五模型保存与加载"><span>#</span></a></h2><ul>
<li>保存模型参数：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>torch.</span><span>save</span><span>(model.</span><span>state_dict</span><span>(), </span></span><span>"model_weights.pth"</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>加载模型参数：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>model </span><span>=</span><span> </span><span>MyModel</span><span>()  </span></span><span># 先实例化模型结构</span></div></div><div><div><div>2</div></div><div><span><span>model.</span><span>load_state_dict</span><span>(torch.</span><span>load</span><span>(</span></span><span>"model_weights.pth"</span><span>))</span></div></div><div><div><div>3</div></div><div><span><span>model.</span><span>eval</span><span>()  </span></span><span># 通常加载后用于推理，设为评估模式</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>保存整个模型（不推荐，依赖具体类定义）：
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>torch.</span><span>save</span><span>(model, </span></span><span>"entire_model.pth"</span><span>)</span></div></div><div><div><div>2</div></div><div><span><span>model </span><span>=</span><span> torch.</span><span>load</span><span>(</span></span><span>"entire_model.pth"</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section>
<section><h2>六、GPU 加速<a href="#六gpu-加速"><span>#</span></a></h2><ul>
<li>
<p>检查 GPU 可用性：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>torch.cuda.</span><span>is_available</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>指定设备：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>device </span><span>=</span><span> torch.</span><span>device</span><span>(</span></span><span>"cuda:0"</span><span> </span><span>if</span><span><span> torch.cuda.</span><span>is_available</span><span>() </span></span><span>else</span><span> </span><span>"cpu"</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>转移张量和模型：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>tensor </span><span>=</span><span> tensor.</span><span>to</span><span>(device)</span></span></div></div><div><div><div>2</div></div><div><span><span>model </span><span>=</span><span> model.</span><span>to</span><span>(device)</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section>
<section><h2>七、其他重要特性<a href="#七其他重要特性"><span>#</span></a></h2><section><h3>7.1 TorchScript（模型部署）<a href="#71-torchscript模型部署"><span>#</span></a></h3><ul>
<li>
<p>将 PyTorch 模型转换为可序列化的、独立于 Python 的中间表示，便于在 C++ 环境或生产环境中部署。</p>
</li>
<li>
<p>常用方式：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>torch.jit.</span><span>trace</span><span>(model, example_input)</span></span></div></div><div><div><div>4</div></div><div><span><span>torch.jit.</span><span>script</span><span>(model)</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section><section><h3>7.2 分布式训练<a href="#72-分布式训练"><span>#</span></a></h3><ul>
<li>
<p>常用方式：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>torch.nn.DataParallel</span></div></div><div><div><div>4</div></div><div><span>torch.nn.parallel.DistributedDataParallel</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section><section><h3>7.3 混合精度训练（AMP）<a href="#73-混合精度训练amp"><span>#</span></a></h3><ul>
<li>
<p>常用工具：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span>torch.cuda.amp.autocast</span></div></div><div><div><div>4</div></div><div><span>torch.cuda.amp.GradScaler</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section><section><h3>7.4 可视化与调试<a href="#74-可视化与调试"><span>#</span></a></h3><ul>
<li>
<p>TensorBoard：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from</span><span> torch.utils.tensorboard </span><span>import</span><span> SummaryWriter</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>打印模型结构：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>print</span><span>(model)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>结构摘要（需安装第三方包）：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>summary</span><span>(model, input_size)</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section></section>
<section><h2>八、常用工具库<a href="#八常用工具库"><span>#</span></a></h2><ul>
<li>
<p>TorchVision：提供图像数据集、模型架构、图像变换工具。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torchvision</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>TorchText：提供文本数据集和预处理工具（NLP）。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torchtext</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>TorchAudio：提供音频数据集和处理工具。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torchaudio</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ul></section>
<section><h2>九、最佳实践<a href="#九最佳实践"><span>#</span></a></h2><ol>
<li>
<p>总是清空梯度：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>optimizer.</span><span>zero_grad</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>区分训练和评估模式：</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>model.</span><span>train</span><span>()</span></span></div></div><div><div><div>2</div></div><div><span><span>model.</span><span>eval</span><span>()</span></span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span>with</span><span><span> torch.</span><span>no_grad</span><span>():</span></span></div></div><div><div><div>5</div></div><div><span>    </span><span>pass</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>使用数据加载器：进行批量、打乱和并行数据加载。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from</span><span> torch.utils.data </span><span>import</span><span> DataLoader</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>dataloader </span><span>=</span><span> </span><span>DataLoader</span><span>(dataset, </span></span><span>batch_size</span><span>=</span><span>32</span><span>, </span><span>shuffle</span><span>=</span><span>True</span><span>, </span><span>num_workers</span><span>=</span><span>4</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>设备管理：显式地将模型和数据移动到目标设备。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>inputs </span><span>=</span><span> inputs.</span><span>to</span><span>(device)</span></span></div></div><div><div><div>2</div></div><div><span><span>labels </span><span>=</span><span> labels.</span><span>to</span><span>(device)</span></span></div></div><div><div><div>3</div></div><div><span><span>model </span><span>=</span><span> model.</span><span>to</span><span>(device)</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>保存和加载模型参数：优先保存/加载参数字典，而不是整个模型对象。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>torch.</span><span>save</span><span>(model.</span><span>state_dict</span><span>(), </span></span><span>"model_weights.pth"</span><span>)</span></div></div><div><div><div>2</div></div><div><span><span>model.</span><span>load_state_dict</span><span>(torch.</span><span>load</span><span>(</span></span><span>"model_weights.pth"</span><span>))</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>设置随机种子：保证实验的可复现性。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div><span>import</span><span> numpy </span><span>as</span><span> np</span></div></div><div><div><div>3</div></div><div>
</div></div><div><div><div>4</div></div><div><span><span>torch.</span><span>manual_seed</span><span>(</span></span><span>42</span><span>)</span></div></div><div><div><div>5</div></div><div><span><span>np.random.</span><span>seed</span><span>(</span></span><span>42</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>利用自动混合精度：在支持的 GPU 上加速训练。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from</span><span> torch.cuda.amp </span><span>import</span><span> autocast, GradScaler</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>scaler </span><span>=</span><span> </span><span>GradScaler</span><span>()</span></span></div></div><div><div><div>4</div></div><div><span>with</span><span><span> </span><span>autocast</span><span>():</span></span></div></div><div><div><div>5</div></div><div><span><span>    </span></span><span>loss </span><span>=</span><span> </span><span>criterion</span><span>(outputs, labels)</span></div></div><div><div><div>6</div></div><div><span><span>scaler.</span><span>scale</span><span>(loss).</span><span>backward</span><span>()</span></span></div></div><div><div><div>7</div></div><div><span><span>scaler.</span><span>step</span><span>(optimizer)</span></span></div></div><div><div><div>8</div></div><div><span><span>scaler.</span><span>update</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
<li>
<p>监控训练过程：记录损失、准确率、学习率等。</p>
<div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>from</span><span> torch.utils.tensorboard </span><span>import</span><span> SummaryWriter</span></div></div><div><div><div>2</div></div><div>
</div></div><div><div><div>3</div></div><div><span><span>writer </span><span>=</span><span> </span><span>SummaryWriter</span><span>()</span></span></div></div><div><div><div>4</div></div><div><span><span>writer.</span><span>add_scalar</span><span>(</span></span><span>"loss/train"</span><span><span>, loss.</span><span>item</span><span>(), global_step)</span></span></div></div><div><div><div>5</div></div><div><span><span>writer.</span><span>flush</span><span>()</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div>
</li>
</ol><hr /></section>]]></content>
    </entry>
    <entry>
      <id>https://blog.hyperthreading.cn/posts/%E5%8D%B7%E7%A7%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9Ccnn/</id>
      <title type="text">卷积神经网络（CNN）</title>
      <published>2025-12-01T00:00:00.000Z</published>
      <updated>2025-12-01T00:00:00.000Z</updated>
      <author><name>超线程</name></author>
      <link rel="alternate" href="https://blog.hyperthreading.cn/posts/%E5%8D%B7%E7%A7%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9Ccnn/"/>
      <summary type="text"></summary>
      <content type="html"><![CDATA[<section><h2>🌟 卷积神经网络（CNN）终极详解<a href="#-卷积神经网络cnn终极详解"><span>#</span></a></h2></section>
<section><h2>一、CNN 的生物学灵感与哲学思想<a href="#一cnn-的生物学灵感与哲学思想"><span>#</span></a></h2><section><h3>1.1 生物视觉皮层启发<a href="#11-生物视觉皮层启发"><span>#</span></a></h3><p>CNN 的设计灵感来源于 1960 年代神经科学家 Hubel 和 Wiesel 对猫视觉皮层的研究：</p><ul>
<li>简单细胞（Simple Cells）：只对特定位置、方向的边缘/条状刺激有反应 → 对应 CNN 的“卷积核”</li>
<li>复杂细胞（Complex Cells）：对某方向边缘有反应，但位置不敏感 → 对应“池化层”的平移不变性</li>
<li>层级结构：低级特征（边缘）→ 中级特征（形状）→ 高级特征（物体）→ 对应 CNN 的“层叠结构”</li>
</ul><p>🧬 CNN 是对生物视觉系统的“工程化模拟”，不是完全复制，而是提取其核心思想：局部感受、层次抽象、权值共享 。</p></section><section><h3>1.2 哲学思想：让机器“学会看”<a href="#12-哲学思想让机器学会看"><span>#</span></a></h3><ul>
<li>传统方法：人工设计特征（如SIFT、HOG）→ 费时费力，泛化差</li>
<li>CNN 方法：端到端学习 ，从原始像素自动学习最优特征表示</li>
<li>核心哲学：Representation Learning（表示学习）</li>
</ul><hr /></section></section>
<section><h2>二、卷积操作的数学本质（超详细）<a href="#二卷积操作的数学本质超详细"><span>#</span></a></h2><section><h3>2.1 离散卷积公式（2D）<a href="#21-离散卷积公式2d"><span>#</span></a></h3><p>对输入图像 <span><span>I∈RH×WI \in \mathbb{R}^{H \times W}</span><span><span><span></span><span>I</span><span></span><span>∈</span><span></span></span><span><span></span><span><span>R</span><span><span><span><span><span><span></span><span><span><span>H</span><span>×</span><span>W</span></span></span></span></span></span></span></span></span></span></span></span> 和卷积核 <span><span>K∈Rk×kK \in \mathbb{R}^{k \times k} </span><span><span><span></span><span>K</span><span></span><span>∈</span><span></span></span><span><span></span><span><span>R</span><span><span><span><span><span><span></span><span><span><span>k</span><span>×</span><span>k</span></span></span></span></span></span></span></span></span></span></span></span> ，输出特征图 <span><span>OO</span><span><span><span></span><span>O</span></span></span></span> 在位置 <span><span>(i,j)(i,j)</span><span><span><span></span><span>(</span><span>i</span><span>,</span><span></span><span>j</span><span>)</span></span></span></span> 的值为：</p><p><span><span>O(i,j)=(I\*K)(i,j)=∑_m=0k−1∑_n=0k−1I(i+m,j+n)⋅K(m,n)O(i,j) = (I \* K)(i,j) = \sum\_{m=0}^{k-1} \sum\_{n=0}^{k-1} I(i+m, j+n) \cdot K(m,n)</span><span><span><span></span><span>O</span><span>(</span><span>i</span><span>,</span><span></span><span>j</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>(</span><span>I</span><span><span>\*</span></span><span>K</span><span>)</span><span>(</span><span>i</span><span>,</span><span></span><span>j</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>∑</span><span></span><span>_</span><span><span><span>m</span><span></span><span>=</span><span></span><span>0</span></span><span><span><span><span><span><span></span><span><span><span>k</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span><span></span><span>∑</span><span></span><span>_</span><span><span><span>n</span><span></span><span>=</span><span></span><span>0</span></span><span><span><span><span><span><span></span><span><span><span>k</span><span>−</span><span>1</span></span></span></span></span></span></span></span></span><span>I</span><span>(</span><span>i</span><span></span><span>+</span><span></span></span><span><span></span><span>m</span><span>,</span><span></span><span>j</span><span></span><span>+</span><span></span></span><span><span></span><span>n</span><span>)</span><span></span><span>⋅</span><span></span></span><span><span></span><span>K</span><span>(</span><span>m</span><span>,</span><span></span><span>n</span><span>)</span></span></span></span></p><p>注意：实际深度学习框架中多为“互相关（cross-correlation）”，即不翻转核，但习惯仍称“卷积”。</p></section><section><h3>2.2 多通道输入/输出<a href="#22-多通道输入输出"><span>#</span></a></h3><ul>
<li>
<p>输入通道数：<span><span>C_inC\_{in} </span><span><span><span></span><span>C</span><span>_</span><span><span>in</span></span></span></span></span>（如RGB=3）</p>
</li>
<li>
<p>输出通道数：<span><span>C_out C\_{out}</span><span><span><span></span><span>C</span><span>_</span><span><span>o</span><span>u</span><span>t</span></span></span></span></span>（即卷积核个数）</p>
</li>
<li>
<p>每个卷积核尺寸：<span><span>k×k×C_ink \times k \times C\_{in}</span><span><span><span></span><span>k</span><span></span><span>×</span><span></span></span><span><span></span><span>k</span><span></span><span>×</span><span></span></span><span><span></span><span>C</span><span>_</span><span><span>in</span></span></span></span></span></p>
</li>
<li>
<p>总参数量：<span><span>C_out×(k×k×C_in+1)C\_{out} \times (k \times k \times C\_{in} + 1)</span><span><span><span></span><span>C</span><span>_</span><span><span>o</span><span>u</span><span>t</span></span><span></span><span>×</span><span></span></span><span><span></span><span>(</span><span>k</span><span></span><span>×</span><span></span></span><span><span></span><span>k</span><span></span><span>×</span><span></span></span><span><span></span><span>C</span><span>_</span><span><span>in</span></span><span></span><span>+</span><span></span></span><span><span></span><span>1</span><span>)</span></span></span></span>（+1 是偏置项）</p>
</li>
<li>
<p>✅ 举例：</p>
</li>
<li>
<p>输入：224×224×3</p>
</li>
<li>
<p>卷积层：64个 3×3 卷积核</p>
</li>
<li>
<p>参数量 = <span><span>64×(3×3×3+1)=64×28=1,79264 \times (3 \times 3 \times 3 + 1) = 64 \times 28 = 1,792</span><span><span><span></span><span>64</span><span></span><span>×</span><span></span></span><span><span></span><span>(</span><span>3</span><span></span><span>×</span><span></span></span><span><span></span><span>3</span><span></span><span>×</span><span></span></span><span><span></span><span>3</span><span></span><span>+</span><span></span></span><span><span></span><span>1</span><span>)</span><span></span><span>=</span><span></span></span><span><span></span><span>64</span><span></span><span>×</span><span></span></span><span><span></span><span>28</span><span></span><span>=</span><span></span></span><span><span></span><span>1</span><span>,</span><span></span><span>792</span></span></span></span></p>
</li>
<li>
<p>对比全连接：<span><span>224×224×3×1000=150M224 \times 224 \times 3 \times 1000 = 150M</span><span><span><span></span><span>224</span><span></span><span>×</span><span></span></span><span><span></span><span>224</span><span></span><span>×</span><span></span></span><span><span></span><span>3</span><span></span><span>×</span><span></span></span><span><span></span><span>1000</span><span></span><span>=</span><span></span></span><span><span></span><span>150</span><span>M</span></span></span></span>→ CNN 参数效率极高！</p>
</li>
</ul></section><section><h3>2.3 输出尺寸计算公式<a href="#23-输出尺寸计算公式"><span>#</span></a></h3><p>给定：</p><ul>
<li>输入尺寸：<span><span>W_in×H_inW\_{in} \times H\_{in}</span><span><span><span></span><span>W</span><span>_</span><span><span>in</span></span><span></span><span>×</span><span></span></span><span><span></span><span>H</span><span>_</span><span><span>in</span></span></span></span></span></li>
<li>卷积核尺寸：<span><span>KK</span><span><span><span></span><span>K</span></span></span></span></li>
<li>步长：<span><span>SS</span><span><span><span></span><span>S</span></span></span></span></li>
<li>填充：<span><span>PP</span><span><span><span></span><span>P</span></span></span></span></li>
</ul><p>输出尺寸：</p><p><span><span>W_out=⌊W_in+2P−KS⌋+1W\_{out} = \left\lfloor \frac{W\_{in} + 2P - K}{S} \right\rfloor + 1</span><span><span><span></span><span>W</span><span>_</span><span><span>o</span><span>u</span><span>t</span></span><span></span><span>=</span><span></span></span><span><span></span><span><span><span>⌊</span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>S</span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>W</span><span>_</span><span><span>in</span></span><span>+</span><span>2</span><span>P</span><span>−</span><span>K</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span><span>⌋</span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>1</span></span></span></span></p><p>📌 常用设置：K=3, S=1, P=1 → 尺寸不变；K=3, S=2, P=1 → 尺寸减半</p><hr /></section></section>
<section><h2>三、CNN 各层组件深度剖析<a href="#三cnn-各层组件深度剖析"><span>#</span></a></h2><section><h3>3.1 卷积层（Conv Layer）——不止是“滑动窗口”<a href="#31-卷积层conv-layer不止是滑动窗口"><span>#</span></a></h3><section><h4>类型扩展<a href="#类型扩展"><span>#</span></a></h4><ul>
<li>标准卷积（Standard Conv）：上述基本形式</li>
<li>空洞卷积（Dilated Conv）：在核元素间插入“空洞”，扩大感受野而不增加参数。用于语义分割（如DeepLab）</li>
<li>转置卷积（Transposed Conv）：又称“反卷积”，用于上采样（如图像生成、分割）</li>
<li>深度可分离卷积（Depthwise Separable Conv）：
<ul>
<li>Step1: Depthwise Conv —— 每个输入通道单独卷积</li>
<li>Step2: Pointwise Conv —— 1×1卷积融合通道</li>
<li>参数量大幅减少 → 用于MobileNet等轻量模型</li>
</ul>
</li>
</ul></section><section><h4>感受野（Receptive Field）<a href="#感受野receptive-field"><span>#</span></a></h4><ul>
<li>定义：输出特征图上某一点，对应输入图像的区域大小</li>
<li>随着网络加深，感受野增大 → 高层神经元“看到”更大范围</li>
<li>计算公式（简化）：若每层 stride=1，则第L层感受野 ≈ <span><span>1+(K−1)×L1 + (K-1) \times L</span><span><span><span></span><span>1</span><span></span><span>+</span><span></span></span><span><span></span><span>(</span><span>K</span><span></span><span>−</span><span></span></span><span><span></span><span>1</span><span>)</span><span></span><span>×</span><span></span></span><span><span></span><span>L</span></span></span></span></li>
</ul><p>🎯 目标检测中，大感受野对检测大物体至关重要。</p><hr /></section></section><section><h3>3.2 激活函数 —— 为什么ReLU是王者？<a href="#32-激活函数--为什么relu是王者"><span>#</span></a></h3><section><h4>常见激活函数对比<a href="#常见激活函数对比"><span>#</span></a></h4>

<table><thead><tr><th>函数</th><th>公式</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>Sigmoid</td><td><span><span>11+e−x\frac{1}{1+e^{-x}}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>1</span><span>+</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span>x</span></span></span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>1</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></td><td>输出0~1，可解释概率</td><td>梯度消失、非零中心</td></tr><tr><td>Tanh</td><td><span><span>ex−e−xex+e−x\frac{e^x - e^{-x}}{e^x + e^{-x}}</span><span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span>e</span><span><span><span><span><span><span></span><span><span>x</span></span></span></span></span></span></span></span><span>+</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span>x</span></span></span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>e</span><span><span><span><span><span><span></span><span><span>x</span></span></span></span></span></span></span></span><span>−</span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>−</span><span>x</span></span></span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></td><td>零中心</td><td>梯度消失</td></tr><tr><td>ReLU</td><td><span><span>max⁡(0,x)\max(0,x)</span><span><span><span></span><span>max</span><span>(</span><span>0</span><span>,</span><span></span><span>x</span><span>)</span></span></span></span></td><td>计算快、缓解梯度消失</td><td>“死神经元”问题</td></tr><tr><td>Leaky ReLU</td><td><span><span>max⁡(0.01x,x)\max(0.01x, x)</span><span><span><span></span><span>max</span><span>(</span><span>0.01</span><span>x</span><span>,</span><span></span><span>x</span><span>)</span></span></span></span></td><td>解决死神经元</td><td>需调参</td></tr><tr><td>ELU</td><td><span><span>x&gt;0:x;x≤0:α(ex−1)x&gt;0: x; x≤0: \alpha(e^x-1)</span><span><span><span></span><span>x</span><span></span><span>&gt;</span><span></span></span><span><span></span><span>0</span><span></span><span>:</span><span></span></span><span><span></span><span>x</span><span>;</span><span></span><span>x</span><span></span><span>≤</span><span></span></span><span><span></span><span>0</span><span></span><span>:</span><span></span></span><span><span></span><span>α</span><span>(</span><span><span>e</span><span><span><span><span><span><span></span><span><span>x</span></span></span></span></span></span></span></span><span></span><span>−</span><span></span></span><span><span></span><span>1</span><span>)</span></span></span></span></td><td>负值有梯度，均值≈0</td><td>计算稍慢</td></tr></tbody></table><p>✅ 实践建议：默认用ReLU，如遇神经元“死亡”，换Leaky ReLU或ELU。</p><hr /></section></section><section><h3>3.3 池化层 —— 为什么Max Pooling最常用？<a href="#33-池化层--为什么max-pooling最常用"><span>#</span></a></h3><section><h4>Max Pooling vs Average Pooling<a href="#max-pooling-vs-average-pooling"><span>#</span></a></h4><ul>
<li>Max Pooling：保留最显著特征，增强纹理/边缘响应 → 更适合分类</li>
<li>Average Pooling：平滑特征，保留背景信息 → 有时用于最后全局池化</li>
</ul></section><section><h4>全局平均池化（Global Average Pooling, GAP）<a href="#全局平均池化global-average-pooling-gap"><span>#</span></a></h4><ul>
<li>对每个特征图求平均，得到一个值 → 替代全连接层</li>
<li>优点：无参数、防过拟合、可解释性强（CAM可视化）</li>
<li>应用：GoogLeNet、ResNet等现代架构</li>
</ul><hr /></section></section><section><h3>3.4 批归一化（Batch Normalization, BN）——训练加速神器<a href="#34-批归一化batch-normalization-bn训练加速神器"><span>#</span></a></h3><section><h4>为什么需要 BN？<a href="#为什么需要-bn"><span>#</span></a></h4><p>深度网络中，层间输入分布会不断变化（Internal Covariate Shift）→ 训练不稳定、需小学习率。</p></section><section><h4>BN公式（训练时）<a href="#bn公式训练时"><span>#</span></a></h4><p>对一个batch的某通道数据 <span><span>xx</span><span><span><span></span><span>x</span></span></span></span>：</p><p><span><span>x^=x−μ_Bσ_B2+ϵ,y=γx^+β\hat{x} = \frac{x - \mu\_B}{\sqrt{\sigma\_B^2 + \epsilon}}, \quad y = \gamma \hat{x} + \beta</span><span><span><span></span><span><span><span><span><span><span></span><span>x</span></span><span><span></span><span><span>^</span></span></span></span></span></span></span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span><span><span><span><span><span></span><span><span>σ</span><span>_</span><span><span>B</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span>+</span><span>ϵ</span></span></span><span><span></span><span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span>x</span><span>−</span><span>μ</span><span>_</span><span>B</span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span><span>,</span><span></span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>γ</span><span><span><span><span><span><span></span><span>x</span></span><span><span></span><span><span>^</span></span></span></span></span></span></span><span></span><span>+</span><span></span></span><span><span></span><span>β</span></span></span></span></p><p>其中 <span><span>μ_B,σ_B2\mu\_B, \sigma\_B^2</span><span><span><span></span><span>μ</span><span>_</span><span>B</span><span>,</span><span></span><span>σ</span><span>_</span><span><span>B</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span> 是batch均值和方差，<span><span>γ,β\gamma, \beta</span><span><span><span></span><span>γ</span><span>,</span><span></span><span>β</span></span></span></span> 是可学习参数。</p></section><section><h4>作用<a href="#作用"><span>#</span></a></h4><ul>
<li>加速收敛（可用大学习率）</li>
<li>一定程度替代Dropout（正则化效果）</li>
<li>提高模型鲁棒性</li>
</ul><p>📌 实践：通常在卷积后、激活前 插入BN层（Conv → BN → ReLU）</p><hr /></section></section><section><h3>3.5 全连接层与Softmax —— 最后的决策者<a href="#35-全连接层与softmax--最后的决策者"><span>#</span></a></h3><section><h4>Softmax函数<a href="#softmax函数"><span>#</span></a></h4><p>将网络输出 <span><span>z=\[z_1,z_2,...,z_K]z = \[z\_1, z\_2, ..., z\_K]</span><span><span><span></span><span>z</span><span></span><span>=</span><span></span></span><span><span></span><span><span>\[</span></span><span>z</span><span>_1</span><span>,</span><span></span><span>z</span><span>_2</span><span>,</span><span></span><span>...</span><span>,</span><span></span><span>z</span><span>_</span><span>K</span><span>]</span></span></span></span> 转为概率分布：</p><p><span><span>p_i=ez_i∑_j=1Kez_jp\_i = \frac{e^{z\_i}}{\sum\_{j=1}^K e^{z\_j}}</span><span><span><span></span><span>p</span><span>_</span><span>i</span><span></span><span>=</span><span></span></span><span><span></span><span><span></span><span><span><span><span><span><span></span><span><span><span>∑</span><span></span><span>_</span><span><span><span>j</span><span>=</span><span>1</span></span><span><span><span><span><span><span></span><span><span>K</span></span></span></span></span></span></span></span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>z</span><span>_</span><span>j</span></span></span></span></span></span></span></span></span></span></span></span><span><span></span><span></span></span><span><span></span><span><span><span><span>e</span><span><span><span><span><span><span></span><span><span><span>z</span><span>_</span><span>i</span></span></span></span></span></span></span></span></span></span></span></span></span><span>​</span></span><span><span><span></span></span></span></span></span><span></span></span></span></span></span></p></section><section><h4>损失函数：交叉熵（Cross-Entropy）<a href="#损失函数交叉熵cross-entropy"><span>#</span></a></h4><p><span><span>L=−∑_i=1Ky_ilog⁡(p_i)\mathcal{L} = -\sum\_{i=1}^K y\_i \log(p\_i)</span><span><span><span></span><span>L</span><span></span><span>=</span><span></span></span><span><span></span><span>−</span><span></span><span>∑</span><span></span><span>_</span><span><span><span>i</span><span></span><span>=</span><span></span><span>1</span></span><span><span><span><span><span><span></span><span><span>K</span></span></span></span></span></span></span></span><span>y</span><span>_</span><span>i</span><span></span><span>lo<span>g</span></span><span>(</span><span>p</span><span>_</span><span>i</span><span>)</span></span></span></span></p><p>其中 <span><span>y_iy\_i</span><span><span><span></span><span>y</span><span>_</span><span>i</span></span></span></span> 是真实标签的one-hot编码。</p><p>✅ 交叉熵 + Softmax 是分类任务的黄金搭档。</p><hr /></section></section></section>
<section><h2>四、CNN 训练全流程详解<a href="#四cnn-训练全流程详解"><span>#</span></a></h2><section><h3>4.1 数据预处理<a href="#41-数据预处理"><span>#</span></a></h3><ul>
<li>归一化：像素值 /255.0 → [0,1] 或 标准化 <span><span>(x−mean)/std(x - mean)/std</span><span><span><span></span><span>(</span><span>x</span><span></span><span>−</span><span></span></span><span><span></span><span>m</span><span>e</span><span>an</span><span>)</span><span>/</span><span>s</span><span>t</span><span>d</span></span></span></span></li>
<li>数据增强（Data Augmentation）：
<ul>
<li>随机裁剪、旋转、翻转、色彩抖动、CutMix、MixUp</li>
<li>本质：增加数据多样性，提升泛化，防过拟合</li>
</ul>
</li>
</ul></section><section><h3>4.2 优化器选择<a href="#42-优化器选择"><span>#</span></a></h3>

<table><thead><tr><th>优化器</th><th>特点</th><th>适用场景</th></tr></thead><tbody><tr><td>SGD</td><td>基础，需手动调学习率</td><td>理论研究、简单任务</td></tr><tr><td>SGD + Momentum</td><td>加速收敛，减少震荡</td><td>通用</td></tr><tr><td>Adam</td><td>自适应学习率，收敛快</td><td>默认首选，尤其小数据</td></tr><tr><td>RMSProp</td><td>适合非平稳目标</td><td>RNN/CNN均可</td></tr></tbody></table><p>🚀 实践建议：新手用 Adam (lr=0.001) ，高手可尝试 SGD + Momentum + 学习率衰减</p></section><section><h3>4.3 正则化技术<a href="#43-正则化技术"><span>#</span></a></h3><ul>
<li>L2权重衰减（Weight Decay）：损失函数加 <span><span>λ∥θ∥2\lambda \|\theta\|^2</span><span><span><span></span><span>λ</span><span>∥</span><span>θ</span><span><span>∥</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span></span></span></span></li>
<li>Dropout：训练时随机丢弃神经元（通常FC层用，rate=0.5）</li>
<li>Early Stopping：验证集loss不再下降时停止</li>
<li>Label Smoothing：软化one-hot标签，防过自信</li>
</ul><hr /></section></section>
<section><h2>五、经典CNN架构深度解析<a href="#五经典cnn架构深度解析"><span>#</span></a></h2><section><h3>5.1 LeNet-5 (1998) —— 开山鼻祖<a href="#51-lenet-5-1998--开山鼻祖"><span>#</span></a></h3><p>INPUT → Conv1 → Pool1 → Conv2 → Pool2 → FC1 → FC2 → OUTPUT</p><ul>
<li>用于手写数字识别（MNIST）</li>
<li>首次证明CNN可行性</li>
</ul></section><section><h3>5.2 AlexNet (2012) —— 深度学习革命<a href="#52-alexnet-2012--深度学习革命"><span>#</span></a></h3><ul>
<li>8层（5Conv + 3FC）</li>
<li>首次使用ReLU、Dropout</li>
<li>数据增强 + GPU训练</li>
<li>ImageNet Top-5错误率从26%→15.3%</li>
</ul></section><section><h3>5.3 VGGNet (2014) —— 简洁之美<a href="#53-vggnet-2014--简洁之美"><span>#</span></a></h3><ul>
<li>核心：统一使用3×3小卷积核堆叠</li>
<li>感受野等价于一个大核，但参数更少</li>
<li>VGG16：13Conv + 3FC = 16层</li>
<li>至今仍被用作特征提取器（如风格迁移）</li>
</ul></section><section><h3>5.4 GoogLeNet / Inception (2014) —— 多尺度融合<a href="#54-googlenet--inception-2014--多尺度融合"><span>#</span></a></h3><ul>
<li>Inception模块：并行使用1×1, 3×3, 5×5卷积 + Pooling → 捕捉多尺度特征</li>
<li>1×1卷积：降维/升维，减少计算量（“瓶颈层”）</li>
<li>22层，参数比AlexNet少12倍</li>
</ul></section><section><h3>5.5 ResNet (2015) —— 突破深度极限<a href="#55-resnet-2015--突破深度极限"><span>#</span></a></h3><ul>
<li>残差块（Residual Block）：
<span><span>y=F(x)+xy = F(x) + x</span><span><span><span></span><span>y</span><span></span><span>=</span><span></span></span><span><span></span><span>F</span><span>(</span><span>x</span><span>)</span><span></span><span>+</span><span></span></span><span><span></span><span>x</span></span></span></span></li>
<li>解决“网络退化”问题（深层网络训练误差反而上升）</li>
<li>可训练超1000层网络（ResNet-152常用）</li>
<li>核心思想：让网络学习残差（变化量），而非直接映射</li>
</ul><p>🏆 ResNet是现代CNN的基石，几乎所有新模型都受其影响。</p></section><section><h3>5.6 EfficientNet (2019) —— 平衡的艺术<a href="#56-efficientnet-2019--平衡的艺术"><span>#</span></a></h3><ul>
<li>提出复合缩放（Compound Scaling） ：同时缩放网络深度（d）、宽度（w）、分辨率（r）</li>
<li>公式：<span><span>d=αϕ,w=βϕ,r=γϕd = \alpha^\phi, w = \beta^\phi, r = \gamma^\phi</span><span><span><span></span><span>d</span><span></span><span>=</span><span></span></span><span><span></span><span><span>α</span><span><span><span><span><span><span></span><span><span>ϕ</span></span></span></span></span></span></span></span><span>,</span><span></span><span>w</span><span></span><span>=</span><span></span></span><span><span></span><span><span>β</span><span><span><span><span><span><span></span><span><span>ϕ</span></span></span></span></span></span></span></span><span>,</span><span></span><span>r</span><span></span><span>=</span><span></span></span><span><span></span><span><span>γ</span><span><span><span><span><span><span></span><span><span>ϕ</span></span></span></span></span></span></span></span></span></span></span>，约束 <span><span>α⋅β2⋅γ2≈2\alpha \cdot \beta^2 \cdot \gamma^2 \approx 2</span><span><span><span></span><span>α</span><span></span><span>⋅</span><span></span></span><span><span></span><span><span>β</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>⋅</span><span></span></span><span><span></span><span><span>γ</span><span><span><span><span><span><span></span><span><span>2</span></span></span></span></span></span></span></span><span></span><span>≈</span><span></span></span><span><span></span><span>2</span></span></span></span></li>
<li>在相同计算量下达到SOTA精度</li>
</ul><hr /></section></section>
<section><h2>六、CNN 在各领域的应用详解（附模型）<a href="#六cnn-在各领域的应用详解附模型"><span>#</span></a></h2><section><h3>6.1 图像分类 → ResNet, EfficientNet, Vision Transformer<a href="#61-图像分类--resnet-efficientnet-vision-transformer"><span>#</span></a></h3></section><section><h3>6.2 目标检测<a href="#62-目标检测"><span>#</span></a></h3><section><h4>两阶段检测器（精度高）<a href="#两阶段检测器精度高"><span>#</span></a></h4><ul>
<li>Faster R-CNN：RPN生成候选框 + CNN分类</li>
<li>Mask R-CNN：Faster R-CNN + 分割分支</li>
</ul></section><section><h4>单阶段检测器（速度快）<a href="#单阶段检测器速度快"><span>#</span></a></h4><ul>
<li>YOLO系列（You Only Look Once）：将检测视为回归问题</li>
<li>SSD（Single Shot MultiBox Detector）：多尺度特征图预测</li>
</ul></section></section><section><h3>6.3 语义分割<a href="#63-语义分割"><span>#</span></a></h3><ul>
<li>FCN（全卷积网络）：将FC层替换为卷积，输出像素级预测</li>
<li>U-Net：编码器-解码器结构 + 跳跃连接（医学图像标配）</li>
<li>DeepLab系列：空洞卷积 + ASPP（多尺度上下文）</li>
</ul></section><section><h3>6.4 姿态估计<a href="#64-姿态估计"><span>#</span></a></h3><ul>
<li>OpenPose：多阶段CNN，同时预测关键点和连接</li>
<li>HRNet：保持高分辨率特征，精度更高</li>
</ul></section><section><h3>6.5 医学影像<a href="#65-医学影像"><span>#</span></a></h3><ul>
<li>nnU-Net：自动适配任何医学分割任务的框架</li>
<li>CheXNet：121层DenseNet，用于胸部X光肺炎检测</li>
</ul></section><section><h3>6.6 视频理解<a href="#66-视频理解"><span>#</span></a></h3><ul>
<li>3D CNN（如C3D）：卷积核扩展到时间维</li>
<li>Two-Stream Network：RGB流 + 光流流</li>
<li>I3D（Inflated 3D ConvNet）：将2D卷积核“膨胀”为3D</li>
</ul><hr /></section></section>
<section><h2>七、CNN 的前沿发展与未来<a href="#七cnn-的前沿发展与未来"><span>#</span></a></h2><section><h3>7.1 CNN vs Transformer<a href="#71-cnn-vs-transformer"><span>#</span></a></h3><ul>
<li>Vision Transformer (ViT)：将图像分块，用Transformer编码 → 在大数据下超越CNN</li>
<li>混合模型：CNN提取局部特征 + Transformer建模长程依赖（如Swin Transformer）</li>
<li>趋势：CNN不会消失，但与Attention机制深度融合</li>
</ul></section><section><h3>7.2 轻量化CNN<a href="#72-轻量化cnn"><span>#</span></a></h3><ul>
<li>MobileNet系列：深度可分离卷积</li>
<li>ShuffleNet：通道混洗减少计算</li>
<li>GhostNet：用廉价操作生成“幻影”特征图</li>
</ul></section><section><h3>7.3 自监督学习<a href="#73-自监督学习"><span>#</span></a></h3><ul>
<li>MoCo, SimCLR：无标签数据预训练CNN，再微调</li>
<li>减少对标注数据的依赖</li>
</ul></section><section><h3>7.4 可解释性与可视化<a href="#74-可解释性与可视化"><span>#</span></a></h3><ul>
<li>CAM / Grad-CAM：可视化CNN关注区域</li>
<li>特征反演：从特征图重建输入图像</li>
</ul><hr /></section></section>
<section><h2>八、学习路径与资源推荐<a href="#八学习路径与资源推荐"><span>#</span></a></h2><section><h3>8.1 学习路线图<a href="#81-学习路线图"><span>#</span></a></h3><p>数学基础 → Python/PyTorch → CNN理论 → 经典论文 → 复现项目 → 参加比赛（Kaggle）→ 研究前沿</p></section><section><h3>8.2 书籍推荐<a href="#82-书籍推荐"><span>#</span></a></h3><ul>
<li>《深度学习》（花书）Ian Goodfellow — 理论基石</li>
<li>《动手学深度学习》（李沐）— 代码实践神器（有PyTorch版）</li>
<li>《神经网络与深度学习》（邱锡鹏）— 中文精品</li>
</ul></section><section><h3>8.3 视频课程<a href="#83-视频课程"><span>#</span></a></h3><ul>
<li>吴恩达《Deep Learning Specialization》（Coursera）</li>
<li>李沐《动手学深度学习》B站课程</li>
<li>斯坦福CS231n（YouTube）— CNN圣经级课程</li>
</ul></section><section><h3>8.4 实战平台<a href="#84-实战平台"><span>#</span></a></h3><ul>
<li>Kaggle：大量图像比赛（入门推荐：Digit Recognizer, Dogs vs Cats）</li>
<li>Google Colab：免费GPU，开箱即用</li>
<li>Hugging Face：预训练模型库（含CNN）</li>
</ul><hr /></section></section>
<section><h2>九、一个完整CNN项目实战框架（PyTorch）<a href="#九一个完整cnn项目实战框架pytorch"><span>#</span></a></h2><section><h3>9.1 数据加载与增强<a href="#91-数据加载与增强"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>import</span><span> torch</span></div></div><div><div><div>2</div></div><div><span>import</span><span> torch.nn </span><span>as</span><span> nn</span></div></div><div><div><div>3</div></div><div><span>import</span><span> torch.optim </span><span>as</span><span> optim</span></div></div><div><div><div>4</div></div><div><span>from</span><span> torchvision </span><span>import</span><span> datasets, transforms</span></div></div><div><div><div>5</div></div><div>
</div></div><div><div><div>6</div></div><div><span><span>transform </span><span>=</span><span> transforms.</span><span>Compose</span><span>([</span></span></div></div><div><div><div>7</div></div><div><span><span>    </span></span><span>transforms.</span><span>Resize</span><span>((</span><span>32</span><span>, </span><span>32</span><span>)),</span></div></div><div><div><div>8</div></div><div><span><span>    </span></span><span>transforms.</span><span>ToTensor</span><span>(),</span></div></div><div><div><div>9</div></div><div><span><span>    </span></span><span>transforms.</span><span>Normalize</span><span>((</span><span>0.5</span><span>,), (</span><span>0.5</span><span>,))</span></div></div><div><div><div>10</div></div><div><span>])</span></div></div><div><div><div>11</div></div><div>
</div></div><div><div><div>12</div></div><div><span><span>trainset </span><span>=</span><span> datasets.</span><span>CIFAR10</span><span>(</span></span><span>root</span><span>=</span><span>"./data"</span><span>, </span><span>train</span><span>=</span><span>True</span><span>, </span><span>download</span><span>=</span><span>True</span><span>, </span><span>transform</span><span><span>=</span><span>transform)</span></span></div></div><div><div><div>13</div></div><div><span><span>trainloader </span><span>=</span><span> torch.utils.data.</span><span>DataLoader</span><span>(trainset, </span></span><span>batch_size</span><span>=</span><span>64</span><span>, </span><span>shuffle</span><span>=</span><span>True</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div></section><section><h3>9.2 定义带BN和Dropout的CNN<a href="#92-定义带bn和dropout的cnn"><span>#</span></a></h3><div><div><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>class</span><span><span> </span><span>CNN</span><span>(</span><span>nn</span><span>.</span><span>Module</span><span>)</span></span><span>:</span></div></div><div><div><div>2</div></div><div><span>    </span><span>def</span><span> </span><span>__init__</span><span>(</span><span>self</span><span>):</span></div></div><div><div><div>3</div></div><div><span>        </span><span>super</span><span>().</span><span>__init__</span><span>()</span></div></div><div><div><div>4</div></div><div><span>        </span><span>self</span><span><span>.features </span><span>=</span><span> nn.</span><span>Sequential</span><span>(</span></span></div></div><div><div><div>5</div></div><div><span><span>            </span></span><span>nn.</span><span>Conv2d</span><span>(</span><span>3</span><span>, </span><span>32</span><span>, </span><span>3</span><span>, </span><span>padding</span><span>=</span><span>1</span><span>),</span></div></div><div><div><div>6</div></div><div><span><span>            </span></span><span>nn.</span><span>BatchNorm2d</span><span>(</span><span>32</span><span>),</span></div></div><div><div><div>7</div></div><div><span><span>            </span></span><span>nn.</span><span>ReLU</span><span>(),</span></div></div><div><div><div>8</div></div><div><span><span>            </span></span><span>nn.</span><span>MaxPool2d</span><span>(</span><span>2</span><span>),</span></div></div><div><div><div>9</div></div><div><span><span>            </span></span><span>nn.</span><span>Conv2d</span><span>(</span><span>32</span><span>, </span><span>64</span><span>, </span><span>3</span><span>, </span><span>padding</span><span>=</span><span>1</span><span>),</span></div></div><div><div><div>10</div></div><div><span><span>            </span></span><span>nn.</span><span>BatchNorm2d</span><span>(</span><span>64</span><span>),</span></div></div><div><div><div>11</div></div><div><span><span>            </span></span><span>nn.</span><span>ReLU</span><span>(),</span></div></div><div><div><div>12</div></div><div><span><span>            </span></span><span>nn.</span><span>MaxPool2d</span><span>(</span><span>2</span><span>),</span></div></div><div><div><div>13</div></div><div><span><span>            </span></span><span>nn.</span><span>Conv2d</span><span>(</span><span>64</span><span>, </span><span>128</span><span>, </span><span>3</span><span>, </span><span>padding</span><span>=</span><span>1</span><span>),</span></div></div><div><div><div>14</div></div><div><span><span>            </span></span><span>nn.</span><span>BatchNorm2d</span><span>(</span><span>128</span><span>),</span></div></div><div><div><div>15</div></div><div><span><span>            </span></span><span>nn.</span><span>ReLU</span><span>(),</span></div></div><div><div><div>16</div></div><div><span><span>            </span></span><span>nn.</span><span>AdaptiveAvgPool2d</span><span>((</span><span>1</span><span>, </span><span>1</span><span>)),</span></div></div><div><div><div>17</div></div><div><span><span>        </span></span><span>)</span></div></div><div><div><div>18</div></div><div><span>        </span><span>self</span><span><span>.classifier </span><span>=</span><span> nn.</span><span>Sequential</span><span>(</span></span></div></div><div><div><div>19</div></div><div><span><span>            </span></span><span>nn.</span><span>Dropout</span><span>(</span><span>0.5</span><span>),</span></div></div><div><div><div>20</div></div><div><span><span>            </span></span><span>nn.</span><span>Linear</span><span>(</span><span>128</span><span>, </span><span>10</span><span>),</span></div></div><div><div><div>21</div></div><div><span><span>        </span></span><span>)</span></div></div><div><div><div>22</div></div><div>
</div></div><div><div><div>23</div></div><div><span>    </span><span>def</span><span> </span><span>forward</span><span>(</span><span>self</span><span>,</span><span><span> </span><span>x</span></span><span>):</span></div></div><div><div><div>24</div></div><div><span><span>        </span></span><span>x </span><span>=</span><span> </span><span>self</span><span><span>.</span><span>features</span><span>(x)</span></span></div></div><div><div><div>25</div></div><div><span><span>        </span></span><span>x </span><span>=</span><span> torch.</span><span>flatten</span><span>(x, </span><span>1</span><span>)</span></div></div><div><div><div>26</div></div><div><span><span>        </span></span><span>x </span><span>=</span><span> </span><span>self</span><span><span>.</span><span>classifier</span><span>(x)</span></span></div></div><div><div><div>27</div></div><div><span>        </span><span>return</span><span> x</span></div></div></code></pre><div><div></div><div></div></div></figure><div></div></div><span>展开</span><span>收起</span></div></div></section><section><h3>9.3 训练循环<a href="#93-训练循环"><span>#</span></a></h3><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span><span>model </span><span>=</span><span> </span><span>CNN</span><span>().</span><span>cuda</span><span>()</span></span></div></div><div><div><div>2</div></div><div><span><span>criterion </span><span>=</span><span> nn.</span><span>CrossEntropyLoss</span><span>()</span></span></div></div><div><div><div>3</div></div><div><span><span>optimizer </span><span>=</span><span> optim.</span><span>Adam</span><span>(model.</span><span>parameters</span><span>(), </span></span><span>lr</span><span>=</span><span>0.001</span><span>)</span></div></div><div><div><div>4</div></div><div>
</div></div><div><div><div>5</div></div><div><span>for</span><span> epoch </span><span>in</span><span> </span><span>range</span><span>(</span><span>10</span><span>):</span></div></div><div><div><div>6</div></div><div><span>    </span><span>for</span><span> inputs, labels </span><span>in</span><span> trainloader:</span></div></div><div><div><div>7</div></div><div><span><span>        </span></span><span>inputs, labels </span><span>=</span><span> inputs.</span><span>cuda</span><span>(), labels.</span><span>cuda</span><span>()</span></div></div><div><div><div>8</div></div><div><span><span>        </span></span><span>optimizer.</span><span>zero_grad</span><span>()</span></div></div><div><div><div>9</div></div><div><span><span>        </span></span><span>outputs </span><span>=</span><span> </span><span>model</span><span>(inputs)</span></div></div><div><div><div>10</div></div><div><span><span>        </span></span><span>loss </span><span>=</span><span> </span><span>criterion</span><span>(outputs, labels)</span></div></div><div><div><div>11</div></div><div><span><span>        </span></span><span>loss.</span><span>backward</span><span>()</span></div></div><div><div><div>12</div></div><div><span><span>        </span></span><span>optimizer.</span><span>step</span><span>()</span></div></div><div><div><div>13</div></div><div><span>    </span><span>print</span><span>(</span><span>f</span><span>"Epoch </span><span>{</span><span><span>epoch </span><span>+</span><span> </span></span><span>1}</span><span>, Loss: </span><span>{</span><span><span>loss.</span><span>item</span><span>()</span></span><span>:.4f</span><span>}</span><span>"</span><span>)</span></div></div></code></pre><div><div></div><div></div></div></figure></div><hr /></section></section>
<section><h2>十、总结：CNN 的核心价值<a href="#十总结cnn-的核心价值"><span>#</span></a></h2><p>🧠 CNN 的本质是“空间特征的层次化自动提取器” 。</p><p>它通过：</p><ul>
<li>局部连接 → 捕捉空间相关性</li>
<li>权值共享 → 极大减少参数</li>
<li>池化操作 → 提供不变性与降维</li>
<li>深度堆叠 → 实现从像素到语义的抽象</li>
</ul><p>彻底改变了计算机视觉，并辐射到NLP、语音、生物、物理等众多领域。</p></section>]]></content>
    </entry>
</feed>
