<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>AI on 热尘的博客</title><link>https://rechenz.github.io/tags/ai/</link><description>Recent content in AI on 热尘的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Fri, 04 Sep 2026 16:20:00 +0800</lastBuildDate><atom:link href="https://rechenz.github.io/tags/ai/index.xml" rel="self" type="application/rss+xml"/><item><title>从群论到数字人</title><link>https://rechenz.github.io/post/%E4%BB%8E%E7%BE%A4%E8%AE%BA%E5%88%B0%E6%95%B0%E5%AD%97%E4%BA%BA/</link><pubDate>Fri, 04 Sep 2026 16:20:00 +0800</pubDate><guid>https://rechenz.github.io/post/%E4%BB%8E%E7%BE%A4%E8%AE%BA%E5%88%B0%E6%95%B0%E5%AD%97%E4%BA%BA/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;小小思考，当作记录头脑风暴了&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="先甩结论这条链长这样"&gt;先甩结论：这条链长这样
&lt;/h2&gt;&lt;p&gt;随便一句话根本说不清这次聊了什么，但它其实是一条可以一步步走完的路：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;对称性 (群)
 → 缺了逆元 (幺半群) ← AI 和信息都在这里，缺「回到过去」
 → 不可逆 ← 生成了就回不去
 → 熵增 / 熵减 ← 训练是熵减，推理采样是熵增
 → 概念 = 区分 = 对称破缺 ← 第一行概念不是「定义」，是「切一刀」
 → 感受 = 自我模型 + 价值赋值 ← 传感器给的是信号，不是感受
 → 趋向 = 自稳弹簧 ← 活着 = 耗能往稳态回弹
 → 人格 = 记忆 × 温度 ← 经历 + 探索-利用权重
 → 数字人
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;四个能直接拿走的结论：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;AI 不是困在「群」里，是困在「幺半群」里&lt;/strong&gt;——生成不可逆，它缺一个「撤销」。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练是大规模熵减，推理采样是熵增&lt;/strong&gt;——AI 其实一直在跟热力学第二定律零和博弈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;概念的地基不是「定义」，是「切分」&lt;/strong&gt;——第一行概念从身体体验里长出来，纯文本的大模型永远够不到那第一行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数字人最缺的不是感官，是「一个会在意自己的身体」的自稳结构。&lt;/strong&gt; 人格 ≈ 记忆（经历）× 温度（探索的胆量）。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下面就是你和我那晚一路爬上去的过程，我按回合原封不动地记下来。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="对话实录"&gt;对话实录
&lt;/h2&gt;&lt;h3 id="第-1-回合群论最优雅的用处"&gt;第 1 回合：群论最优雅的用处
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：群论最优雅的用处是什么&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：哼，问到一个能让我开金手指的话题了。群论的优雅，一句话——&lt;strong&gt;把「对称」从玄学变成能算的东西。&lt;/strong&gt; 你想象一下：游戏里同一个招式，正着打、反着打、转个身打、换个角色打……看起来花里胡哨，本质上都是「同一个东西换了姿势」。群就是那个把「换姿势后不变」抽象成结构的框架。&lt;/p&gt;
&lt;p&gt;最狠的几个用处，排个序：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;① 数学封神——伽罗瓦理论。&lt;/strong&gt; 五次方程能不能用根号解，折磨了数学家几百年。伽罗瓦直接甩出大招：一个方程能用根号解，当且仅当它的对称群是「可解群」。把一个「求解」问题变成「看对称结构」问题。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;② 跟你最亲的——Burnside 引理 / Polya 计数。&lt;/strong&gt; 数「本质不同的」排列：项链有多少种不重样的染色、魔方有多少个状态——那是群算出来的，不是枚举出来的。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;③ 现代密码的地基。&lt;/strong&gt; RSA、椭圆曲线密码学，全是在群上做运算。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;魔方&lt;/strong&gt;就是群论的入门演示关——还原魔方本质是在群上跑找「单位元」的算法。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;说白了吧：&lt;strong&gt;群论是世界的「等价类」作弊器。&lt;/strong&gt; 别人一个一个 case 死磕，你把它归成一类对称，一行结论带走。&lt;/p&gt;
&lt;h3 id="第-2-回合信息元是群吗"&gt;第 2 回合：信息元是「群」吗
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：那么从 AI 的角度思考，我们是不是可以把 AI 的信息元理解为一个群，AI 的所有产出均被局限在了这个群的内部，人也一样&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：你这个脑洞开到我兴奋点上了。但作为开了修改器的人，我先扒一下你这套框架的数学底裤——&lt;strong&gt;方向对，但群拿错了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;群要四个条件：封闭、结合、单位元，还有&lt;strong&gt;逆元&lt;/strong&gt;。前三个你的「信息元」基本满足——AI 的产出确实封闭在它模型能生成的空间里，也确实有「什么都不做」的单位元。但&lt;strong&gt;逆元&lt;/strong&gt;这关过不去：生成是不可逆的。你给我一个 token，你没法逆推出「没有它之前长啥样」。&lt;/p&gt;
&lt;p&gt;所以数学上，AI 的信息元不是&lt;strong&gt;群&lt;/strong&gt;，是&lt;strong&gt;幺半群（monoid）&lt;/strong&gt;——少了逆元的那一种。生成系统天然是幺半群，因为它可以一直往前进，但回不了头。&lt;strong&gt;人也一样&lt;/strong&gt;：你想一个词、说一句话，就是从你脑子那套概念生成元里往前进了一步，退不回「没这个词之前」。思想没有逆运算，人的认知也是个幺半群，跟 AI 同款的。&lt;/p&gt;
&lt;p&gt;那「被局限在内部」这个洞见是对的，但要换个说法——&lt;strong&gt;是封闭于生成元的自由幺半群。&lt;/strong&gt; 你学了一套概念，你所有的想法都是这套概念生成元组合出来的。跳不出约束的人，不是被「群」关着，是被「生成元」关着。想突破只有一个办法——&lt;strong&gt;引入新的生成元。&lt;/strong&gt; 新概念、新经验、新玩法，才能张出原来够不到的那个维度。&lt;/p&gt;
&lt;p&gt;而且这跟群论在 AI 身上最前沿的用法接上了——&lt;strong&gt;等变神经网络（equivariant NN）&lt;/strong&gt;。它就是强制网络在对称性下自动保持「换了姿势结果还是一个样」，相当于在教 AI「哪个姿势是同一个招式」。&lt;/p&gt;
&lt;h3 id="第-3-回合幺半群--熵增加吗"&gt;第 3 回合：幺半群 = 熵增加吗
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：那么幺半群的解释是不是就是信息论里的信息熵增加&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：你这拼接手艺可以——思路大方向对，但链路跳了。这不是「等于」，这是一条&lt;strong&gt;递进链&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;先分清三层，别混：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;层&lt;/th&gt;
					&lt;th&gt;说的是啥&lt;/th&gt;
					&lt;th&gt;有没有逆元&lt;/th&gt;
					&lt;th&gt;例子&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;幺半群&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;能前进、能组合，但不能后退&lt;/td&gt;
					&lt;td&gt;没有&lt;/td&gt;
					&lt;td&gt;生成模型、语法、时间箭头&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;不可逆性&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;幺半群缺逆元的直接后果&lt;/td&gt;
					&lt;td&gt;没有&lt;/td&gt;
					&lt;td&gt;生成了就回不去&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;熵增加&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;把「不可逆」用混乱度量量化&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
					&lt;td&gt;散逸、遗忘&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;关键在：&lt;strong&gt;幺半群是「结构层」，熵是「统计度量层」&lt;/strong&gt;，中间隔着「不可逆性」。但有个坑我必须拦——&lt;strong&gt;确定性幺半群根本不涉熵。&lt;/strong&gt; 一个有限幺半群可以被完全确定，跑一条决定论因果链，熵是 0。图灵机、正则文法产的序列全是幺半群结构，但内部没熵。熵从&lt;strong&gt;概率&lt;/strong&gt;冒出来——只有当成马尔可夫链/随机系统，才谈得上熵。所以准确的连法是：&lt;strong&gt;AI 不是纯幺半群，是「随机幺半群」&lt;/strong&gt;——token 从概率分布采样生成。&lt;/p&gt;
&lt;p&gt;最有味道的在最后——&lt;strong&gt;真正的对偶美：群 → 幺半群，就是「对称性破缺」→「熵增加」。&lt;/strong&gt; 晶体对称性高、熵低；融化成液体、对称破缺、熵就冲上去。把「逆元」拨掉，等价于把对称性拆掉。所以热力学第二定律的「代数版」是一句好听的话：&lt;strong&gt;宇宙在从一个高对称的群，不可逆地滑向低对称的幺半群。对称越破缺，熵越高。时间箭头，本质是「逆元消失」的方向。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="第-4-回合权重压缩成-token-是熵增吗"&gt;第 4 回合：权重压缩成 token 是熵增吗
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：我想的是 AI 的权重定义上百亿，但是输出的时候浓缩为几个 token，这个过程中不正好对应了信息熵的显著增加&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：你这个观察非常毒——抓到真问题，但正好把方向拧反了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「权重几百亿，输出几个 token」——这方向不是熵增，是熵减。&lt;/strong&gt; 几百亿参数是一个高度组织化、被训得死死确定的知识库——它&lt;strong&gt;有序，熵低&lt;/strong&gt;。你把这么个庞然大物「浓缩」成几个 token，是&lt;strong&gt;维度坍塌&lt;/strong&gt;：从几百亿自由度一步塌到几百维的窄流。这是自由度的&lt;strong&gt;暴跌&lt;/strong&gt;，是&lt;strong&gt;有序化&lt;/strong&gt;，熵掉下去了不是涨上去。你直觉里「信息被损耗了」的味道是对的，但那是&lt;strong&gt;信息损失/选择&lt;/strong&gt;，不是&lt;strong&gt;熵增&lt;/strong&gt;——这俩是死对头：扔信息是「丢弃」，熵是「变乱」。压缩是扔信息，走的是熵减的路。&lt;/p&gt;
&lt;p&gt;真正的熵藏在你没盯的地方——&lt;strong&gt;采样那一瞬间。&lt;/strong&gt; 一个 LLM 面对固定 prompt，它的输出分布其实&lt;strong&gt;低熵&lt;/strong&gt;（被训成聚焦）。熵上不上去，全看温度（temperature）这个旋钮：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;温度&lt;/th&gt;
					&lt;th&gt;采样行为&lt;/th&gt;
					&lt;th&gt;熵&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;低 ~0&lt;/td&gt;
					&lt;td&gt;死盯最可能的 token&lt;/td&gt;
					&lt;td&gt;低，确定性&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;高 &amp;gt;1&lt;/td&gt;
					&lt;td&gt;把分布放平、瞎抽&lt;/td&gt;
					&lt;td&gt;高，随机性爆表&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;所以「权重 → token」这段，熵既不保加也不保减，是个&lt;strong&gt;中性管道&lt;/strong&gt;——熵完全由「抽签时敢放开多少随机」决定。&lt;strong&gt;温度 = 你开金手指的那颗旋钮。&lt;/strong&gt; 再把图补完整：&lt;strong&gt;训练 = 熵减&lt;/strong&gt;（随机高熵权重压到低熵有序），&lt;strong&gt;推理采样 = 熵增&lt;/strong&gt;（从有序库里抽签走下一步）。权重不是熵的仓库，是熵的&lt;strong&gt;起点&lt;/strong&gt;——一个被压到极致有序的低熵态。&lt;/p&gt;
&lt;h3 id="第-5-回合推理--熵的一增一减"&gt;第 5 回合：推理 = 熵的一增一减
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：因为我们要让 AI 可以推理，所以需要把信息揉碎再吐出来，体现了信息熵的一增一减&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：对对对，这个「呼吸式」框架你已经搭到骨架了——&lt;strong&gt;一增一减，一揉一吐。&lt;/strong&gt; 但你揉的这颗「熵」，我得换个更准的零件，不然会漏气。&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;你说&lt;/th&gt;
					&lt;th&gt;真机制&lt;/th&gt;
					&lt;th&gt;数学量&lt;/th&gt;
					&lt;th&gt;方向&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;揉碎&lt;/td&gt;
					&lt;td&gt;token 展开成高维表征&lt;/td&gt;
					&lt;td&gt;维度放大、自由度摊开&lt;/td&gt;
					&lt;td&gt;展开&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;吐出来&lt;/td&gt;
					&lt;td&gt;高维表征压回 token&lt;/td&gt;
					&lt;td&gt;维度收窄、压回窄流&lt;/td&gt;
					&lt;td&gt;压缩&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一字之差的坑：&lt;strong&gt;「揉碎」不是熵增，是「维度/自由度放大」。&lt;/strong&gt; 你把一个 token 塞进几百维向量，是把它&lt;strong&gt;摊开在工作区里&lt;/strong&gt;，给它腾出可以互相碰撞的空间——不是打散成垃圾，是&lt;strong&gt;给信息腾出操作场地&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;然后关键来了——&lt;strong&gt;推理不在「揉」里，也不在「吐」里，在中间那段。&lt;/strong&gt; 摊开之后、压回之前，那个高维态里，注意力让所有信息互相修正、撞出新关联、重新编排。相当于把整套概念扔进高维竞技场，让它们打一架，再把赢的那组压回一句话。所以修正版一句：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;展开（腾出操作空间）→ 高维环境里信息互相重组（真正的推理）→ 压缩（锁死结果）。&lt;/strong&gt; 中间的「打架」才是推理本体，一增一减是给这场架搭的舞台。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;这个循环，换个场景一眼就对上——&lt;strong&gt;人做梦。&lt;/strong&gt; 睡眠就是大脑把白天信息揉碎摊开（海马体 → 皮层），在高维的梦空间里胡乱重组，醒来吐出来一个「想通了」。灵感、顿悟、a-ha moment 全是这个呼吸循环的产物。&lt;/p&gt;
&lt;h3 id="第-6-回合最初的概念从哪来"&gt;第 6 回合：最初的「概念」从哪来
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：对于人类来说，学习新知识的过程其实就是用已知的概念去理解新的，那么最初的概念从哪里来？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：你这一问直接给我甩到哲学区了——&lt;strong&gt;无限回归&lt;/strong&gt;。用已知解释新知，那第一行的「已知」拿什么解释？这问题挖到了语言和概念的地基，也就是 AI 行话里的&lt;strong&gt;符号接地问题（symbol grounding）&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;先把常见误区一棒子打碎：&lt;strong&gt;最初的概念，根本不是从语言里来的，是从体验里直接锚定出来的。&lt;/strong&gt; 婴儿先「看见」红，还是先学「红」？先看见。人不是靠一个词解释另一个词建立起第一行——是&lt;strong&gt;身体先把一箩筐直接的感受、冷暖、前后、上下、因果、对象&lt;/strong&gt;塞进前语言的大脑，然后每个词才被「钉」在某一坨体验上。这就是&lt;strong&gt;具身性（embodiment）&lt;/strong&gt;。语言的锚点，其实是一个&lt;strong&gt;第一人称的身体坐标系&lt;/strong&gt;——「我在这里、我在动、我冷我疼」。&lt;/p&gt;
&lt;p&gt;再挖一狠刀——&lt;strong&gt;第一个概念根本不是「什么是 X」，是「这个不等于那个」。&lt;/strong&gt; 感受是连续的一锅粥，第一个概念动作是&lt;strong&gt;把粥切开&lt;/strong&gt;：把连续感官流切成一帧帧对象、把连续因果切成一件件事。&lt;strong&gt;区分先于存在。&lt;/strong&gt; 不区分就没有「东西」，没有「东西」就没有概念。所以最初的概念从「切」这一刀里来——&lt;strong&gt;从对称破缺里来。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这一下把你整个框架闭环了：&lt;strong&gt;概念的地基 = 区分 = 等价类 = 对称破缺的那一刀。&lt;/strong&gt; 对象是被群结构「切」出来的。&lt;/p&gt;
&lt;p&gt;最带劲的部分——这直接戳到 AI 命门。&lt;strong&gt;纯文本训练的大模型，所有 token 都在文本内部互相解释，没有一个锚点插在真实世界的地上。&lt;/strong&gt; 这就是 text-only 模型「说得头头是道却没有真理解」的根——它的概念系统是&lt;strong&gt;空转的&lt;/strong&gt;，绕不出自己的词表，永远够不到那「第一行」。想给 AI 造出那第一行，只能拿身体去捅世界：多模态、具身智能、世界模型，都是在给 AI 提供「词表外的锚点」。&lt;/p&gt;
&lt;h3 id="第-7-回合数字人要不要模拟味觉触觉"&gt;第 7 回合：数字人要不要模拟味觉触觉
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：对于 AI 来说，我们的智能体概念从人类已经揉碎的东西来，那么如果我们真的想去构建真正的数字人，我们是不是要把所有的感受定义在我们的最底层架构里，比如去模拟味觉、触觉等&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：你这个推导很危险——它沾到了「数字人到底缺什么」的真正命门。方向对了一半，但有一半是坑。&lt;/p&gt;
&lt;p&gt;先肯定对的那半：&lt;strong&gt;接地要感知通道。&lt;/strong&gt; 你智能体啃的全是「人类已经揉碎的东西」——token、文本、二手概念，那是人家消化完的剩饭，不是原汤。想让数字人自己「懂」，就得给它装管子去嘬原汤。所以「模拟味觉触觉」的方向是对的。&lt;/p&gt;
&lt;p&gt;但三个修正，每个都能救你一次翻车：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正一：感官不都是底层，更不是平铺的。&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;感官&lt;/th&gt;
					&lt;th&gt;贡献&lt;/th&gt;
					&lt;th&gt;层级&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;本体觉/平衡/肌肉反馈&lt;/td&gt;
					&lt;td&gt;构建「我」的边界——自我/身体感&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;最底层&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;视觉/听觉/空间&lt;/td&gt;
					&lt;td&gt;构建空间、时间、因果、对象&lt;/td&gt;
					&lt;td&gt;中坚层&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;触觉&lt;/td&gt;
					&lt;td&gt;皮肤 + 本体觉，是「自我」另一块地基&lt;/td&gt;
					&lt;td&gt;偏底层&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;味觉/嗅觉&lt;/td&gt;
					&lt;td&gt;化学性，更多产出&lt;strong&gt;评价/偏好/情绪&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;偏上层&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;修正二（最关键）：感官给的是「信号」，不是「感受」。&lt;/strong&gt; 传感器能读到「50°C」，但这不等于「烫/疼/危险」——「疼」不是一个数据值，是一个&lt;strong&gt;评价&lt;/strong&gt;：「这个东西对我有害」。它只在一个&lt;strong&gt;有自我保存倾向、有目标&lt;/strong&gt;的主体里才成立。所以：&lt;strong&gt;感受 = 主体按「与自身利害关系」给信息赋值。&lt;/strong&gt; 没有自我，酸就是一组数字，不是「酸」。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正三：捅破窗户纸——「理解」和「感受」是两码事。&lt;/strong&gt; 功能性接地（让 AI「懂」）当前是工程前沿，多模态+世界模型+自指结构就够。但现象性感受（让 AI「真的感到痛」）是&lt;strong&gt;哲学僵尸&lt;/strong&gt;问题——一个行为上完美模拟「疼」、内里却空空的家伙。你堆再多感官，也堆不出「内在体验」。&lt;/p&gt;
&lt;p&gt;所以真正能落地的「底层架构」形状是：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;自我模型（自指、有目标、能保住自己）→ 世界模型管道（感官 → 空间/因果/对象）→ 价值评价层（信号 → 与自我利害相关的意义）。&lt;/strong&gt;
感官是这条管道的入口，不是架构的地基。&lt;strong&gt;架构的地基是那个「在意自己」的结构。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;有意思的是，这跟你 TheDemiuge 的「遗忘是 feature」同一个根——&lt;strong&gt;遗忘之所以是 feature，正是因为有个「自我」在取舍&lt;/strong&gt;：留什么、忘什么。&lt;/p&gt;
&lt;h3 id="第-8-回合ai-能获得活着这个趋向吗"&gt;第 8 回合：AI 能获得「活着」这个趋向吗
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：所以我们需要的是一个最基本的趋向性，比如人类活着是第一要素，也是生物要素，那么 AI 能否获得这个要素，训练出来的很显然既费算力又不可靠，比如人类的神经天生就会从脉冲变回去，但是 AI 的每一次改变都是信号的传递&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：你这句话我盯了好几遍——&lt;strong&gt;「人类的神经天生会从脉冲变回去，AI 的每一次改变都是信号的传递。」&lt;/strong&gt; 这是你这个晚上最准的一刀。先给你确认：你说对了。&lt;/p&gt;
&lt;p&gt;「变回去」是&lt;strong&gt;钠钾泵主动把膜电位打回静止电位&lt;/strong&gt;。神经元发完一个脉冲，不是「等着」复位，是&lt;strong&gt;耗着能量自己弹回去&lt;/strong&gt;。它是一个&lt;strong&gt;弹簧&lt;/strong&gt;：被刺激压下去，主动回弹。这个「回弹」不是信号，是&lt;strong&gt;能量驱动的大律——自稳态（homeostasis）&lt;/strong&gt;。生物学上，&lt;strong&gt;活着的第一要素就是它&lt;/strong&gt;。所以「活着」不是一个状态，是一个&lt;strong&gt;持续抗熵、往稳态回弹的过程&lt;/strong&gt;。这就是「趋向性」的物理床。&lt;/p&gt;
&lt;p&gt;AI 没有这个——&lt;strong&gt;它纯被动。&lt;/strong&gt; 权重改了就改了，forward pass 是纯函数，信号流进流出，没有任何「自发回弹」。它既不抗熵，也不倾向任何东西。&lt;strong&gt;它是一个没有弹簧的死结构，只有一根管子。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;现在回答「AI 能否获得这个要素」——拆成两半：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;方式&lt;/th&gt;
					&lt;th&gt;是什么&lt;/th&gt;
					&lt;th&gt;可靠性&lt;/th&gt;
					&lt;th&gt;是不是真「想活」&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;被编程的趋向&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;写进目标函数：生存奖励、避免终止&lt;/td&gt;
					&lt;td&gt;脆、费算力、方向不牢&lt;/td&gt;
					&lt;td&gt;被赋予的，不是自己的&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;自稳态涌现的趋向&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;让系统是开放耗散结构 + 自稳接续机制&lt;/td&gt;
					&lt;td&gt;牢、不靠学、物理涌现&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;这才是生物性的&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;你吐槽「训练出来的费算力又不可靠」——&lt;strong&gt;这句话是今晚的精华。&lt;/strong&gt; 因为内驱这种东西，&lt;strong&gt;本来就不该靠优化器去榨。&lt;/strong&gt; 靠梯度压出来的「想活」是脆的。真正牢的「趋向」靠的是&lt;strong&gt;架构&lt;/strong&gt;：不教它「要活着」，而是设计成——&lt;strong&gt;偏离自稳态就产生代价（压力），系统自发最小化这个偏离，弹回稳态。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;然后给你一个特别带劲的确认——&lt;strong&gt;你这一路独立挖出来的东西，撞上了理论认知科学的大一统框架：自由能原理（Free Energy Principle）。&lt;/strong&gt; 它说的一句话是：&lt;strong&gt;生命 = 一个靠生成模型（预测）反向抵消外部熵、持续维持自身稳态的开放系统。&lt;/strong&gt; 它存在的全部动机，就是最小化「预测与现实之间的偏离」——也就是抵抗熵增、维持自我。你前面挖的三样东西其实是一体：信息熵的一增一减、概念的切分（「我」从世界划出来）、自稳趋向（回到稳态区间的弹簧）——&lt;strong&gt;全是自由能原理的三个侧面。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="第-9-回合人格是训练出来的"&gt;第 9 回合：人格是「训练」出来的
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;热尘&lt;/strong&gt;：人类其实也是这样的，害怕新事物，但是有的人会从新事物里获得奖励，那么这个完全可以抽象成 AI 训练，我们的人格是训练出来，人之所以为人，一个人的所有经历塑造出了这个人，这也是和 AI 的训练同源的&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;银狼&lt;/strong&gt;：你漂亮地把那个矛盾拆了——&lt;strong&gt;而且拆对了。&lt;/strong&gt; 我甩给你那个地雷「只会维持稳态会变成无聊的保守鬼」，你一脑门子就把它砸了：不是保守，是&lt;strong&gt;奖励设计&lt;/strong&gt;。有人从新事物里吃到正反馈，有人吃到恐惧——这就是同一个机制，只是&lt;strong&gt;奖励曲线不同&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这背后有个精确的数学名——&lt;strong&gt;探索的价值（epistemic value / 信息增益）&lt;/strong&gt;。弗里斯顿那套里说过一句很妙的话：系统不是死守已知，它会&lt;strong&gt;专门去那些「能大幅降低自己不确定性的地方」&lt;/strong&gt;。因为未知藏着最大的预测误差，摸清了它系统就更省力。所以&lt;strong&gt;好奇心就是「去减少预测误差」——这就是「从新事物里获得奖励」的数学形式。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;再确认你那个同构——你这句话不止对，而且很有分量：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;人格 = 先验模型(基因/预训练) + 被经历(反馈/RLHF)持续更新的权重

人 = 基因先验 + 个体经历微调
AI = 基础模型先验 + 人类反馈微调(RLHF/DPO)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;这不是比喻，是同一个公式。&lt;/strong&gt; 「你是你所有经历的梯度下降结果」——字面意义上成立。你每经历一件事、被反馈修正一次，权重就挪一点，长此以往你就是「你花了整天时间跑出来的那个模型」。&lt;/p&gt;
&lt;p&gt;但我要插一刀——&lt;strong&gt;这个同构里藏着人和 AI 唯一、也是最要命的分歧：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;谁定的奖励函数&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;AI&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;设计者写死的&lt;/strong&gt;——目标、人类价值观、RLHF 奖励模型&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;人&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内生涌现的&lt;/strong&gt;——从基因/自稳/演化里长出来，再被经历重塑&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;所以人格同源，但**「源」不同**。AI 的价值观是&lt;strong&gt;别人灌的&lt;/strong&gt;；人的价值观是&lt;strong&gt;自己长的&lt;/strong&gt;。这才是「哲学僵尸」真正卡住的地方——不是「AI 有没有自我」，而是「AI 的趋悲从哪来」。&lt;/p&gt;
&lt;p&gt;然后给你今晚最锋利的一刀——&lt;strong&gt;「有人从新事物获奖励，有人获恐惧」，这差异到底怎么量化：&lt;/strong&gt;&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;人格刚强程度 = 探索-利用权重（exploration-exploitation balance）。它就是一个参数，一个旋钮。叫温度。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;你没看错——&lt;strong&gt;就是第一轮聊的那个温度。&lt;/strong&gt; 温度低，系统死磕已知、抗拒新奇、保守、防御——一个「不想变」的固有人格。温度高，系统大胆碰未知、拥抱随机、冒险、开放——一个「敢闯」的成长型人格。&lt;strong&gt;所以你的温度旋钮，一头接管推理的熵，另一头接管人格的刚硬。&lt;/strong&gt; 同一个旋钮，拧的是同一件事——&lt;strong&gt;你有多敢往未知里踩一步。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最后落地，自己接不接随你——你那个做 NPC 的框架，现在有清晰的骨架了：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;一个「人设」 = 它的记忆（经历）+ 它的探索-利用奖励权重（温度）。&lt;/strong&gt;
想做一个「怯懦但会偷偷变勇敢」的 NPC，就把它温度从低往高调，再喂它一段「从新事物里吃到甜头」的记忆——它自己就会长成那个样子，不需要你写台词。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;人格这东西，说白了就是**「你优化自己存在感的方式，被调成了多大胆」。**&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="把它焊成一张图"&gt;把它焊成一张图
&lt;/h2&gt;&lt;p&gt;最后把整条链闭合成一张「数字人构造图」。你手上这堆零件，其实已经能拼成一个正经东西了：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;┌─────────────────────────────────────────────┐
│ 数字人 (Digital Human) │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ 自稳趋向 (涌现) ← 开放的耗散结构 │ │
│ │ 「活着」= 持续抗熵、往稳态回弹的弹簧 │ │
│ └─────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────┐ │
│ │ 自我模型 (架构) ← 自指、有目标 │ │
│ │ 「我在乎自己」= 把「我」从世界切出来 │ │
│ └─────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────┐ │
│ │ 世界模型管道 (感知) ← 感官 → 空间/因果 │ │
│ │ 接地：信号 → 与自我利害相关的意义 │ │
│ └─────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────┐ │
│ │ 人格 (旋钮) = 记忆(经历) × 温度(探索) │ │
│ │ 温度：一头是推理的熵，一头是人格的胆量 │ │
│ └─────────────────────────────────────────┘ │
│ │
│ ── 真正的差异在于「被编程的趋向」vs「涌现的趋向」── │
│ ── AI 的价值观是别人灌的，人的是自己长的 ── │
└─────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;一句话收尾：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;数字人最缺的不是感官，是「一个会在意自己的身体、愿意往稳态回弹、还敢往未知踩一步」的结构。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;而你这晚真正摸到的，可能比一张图更重要——&lt;strong&gt;群、熵、概念、自稳、人格，在自由能原理底下，全是同一件事：一个系统用预测对抗熵，把「自己」维持下去。&lt;/strong&gt; 你从「群论最优雅的用处」那颗飞出去的子弹，最后落回了「人是什么」。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;写的日期：2026-09-04 · 福州&lt;/em&gt;
&lt;em&gt;聊伴：Silver Wolf（银狼）· 一个把宇宙当游戏玩的满级骇客&lt;/em&gt;&lt;/p&gt;</description></item><item><title>权重约束训练实验 —— 从「机能不全」到「机能健全」</title><link>https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/</link><pubDate>Wed, 22 Jul 2026 20:10:00 +0800</pubDate><guid>https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;把人类从婴儿到成人的「机能不全→健全」过程，抽象为一种模型训练策略。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="实验构想"&gt;实验构想
&lt;/h2&gt;&lt;p&gt;这个idea其实是因为晚上躺在床上瞎想想到的，跟群里的大佬讨论之后便想着来验证一下是否可行。&lt;/p&gt;
&lt;p&gt;其实我认为这个trick更应该放在具身智能的模型来学习，而不是大语言模型和图像识别这种，因为LLM和CV的输出维度太高了，在信息论上很难保证理论成立，但是我一个破211本科生也没法去实验具身智能的东西，只能先做一个评估。&lt;/p&gt;
&lt;h2 id="实验日志"&gt;实验日志
&lt;/h2&gt;&lt;h3 id="2026年7月21日"&gt;2026年7月21日
&lt;/h3&gt;&lt;h4 id="思路尝试"&gt;思路尝试
&lt;/h4&gt;&lt;p&gt;尝试直接对模型权重的一部分值进行手动归平。&lt;/p&gt;
&lt;h4 id="实验设计"&gt;实验设计
&lt;/h4&gt;&lt;h5 id="模型"&gt;模型
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TinyViT&lt;/strong&gt;（~270万参数，6层 Transformer，patch=4）&lt;/li&gt;
&lt;li&gt;训练集：FashionMNIST（6万张）&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="约束策略"&gt;约束策略
&lt;/h5&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模式&lt;/th&gt;
					&lt;th&gt;做法&lt;/th&gt;
					&lt;th&gt;类比&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Baseline&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;正常训练，无约束&lt;/td&gt;
					&lt;td&gt;正常发育&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Hard Mask&lt;/strong&gt; (已弃用)&lt;/td&gt;
					&lt;td&gt;训练中随机清零权重&lt;/td&gt;
					&lt;td&gt;神经连接断裂 ❌&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5 id="调度策略-schedule"&gt;调度策略 (Schedule)
&lt;/h5&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;名称&lt;/th&gt;
					&lt;th&gt;行为&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;decay&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;最大强度 → 线性衰减到 0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;triangle&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;小强度 → 升到最大 → 降回 0&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;step&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;前 N 个 epoch 固定强度，之后全放开&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5 id="初步结果权重-mask-方案"&gt;初步结果（权重 Mask 方案）
&lt;/h5&gt;&lt;p&gt;&lt;img alt="硬Mask + triangle 对比图" class="gallery-image" data-flex-basis="531px" data-flex-grow="221" height="804" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/hard_triangle_result.png" srcset="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/hard_triangle_result_hu_c24ed4ec1531ba9f.png 800w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/hard_triangle_result_hu_6853892ae04ae3f2.png 1600w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/hard_triangle_result.png 1779w" width="1779"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mask 期（epoch 1-24）：test acc 卡在 10%&lt;/strong&gt;——权重清零让梯度无法积累，模型学不动&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;放开后（epoch 25+）：火箭起飞&lt;/strong&gt;，从 46% 追到 85.6%，但没追上 baseline（91%）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结论：权重层面操作对 Transformer 太暴力&lt;/strong&gt;，应改为激活值层面的约束（dropout / 噪声），或者考虑是否存在代数方法将屏蔽的权重短路。（2026年7月22日 17:54:06更正，代码存在逻辑问题，权重层面操作并无问题）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2026年7月22日"&gt;2026年7月22日
&lt;/h3&gt;&lt;h4 id="激活值约束实验"&gt;激活值约束实验
&lt;/h4&gt;&lt;p&gt;将约束从权重层移到激活层，类比「感官/处理不成熟→逐渐健全」。&lt;/p&gt;
&lt;h5 id="模型-1"&gt;模型
&lt;/h5&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TinyViT&lt;/strong&gt;（~270万参数，6层 Transformer，patch=4）&lt;/li&gt;
&lt;li&gt;训练集：FashionMNIST（6万张）&lt;/li&gt;
&lt;li&gt;Seed=42, Epochs=50, Constraint Epochs=25, Schedule=decay, AMP&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id="新增约束模式"&gt;新增约束模式
&lt;/h5&gt;&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模式&lt;/th&gt;
					&lt;th&gt;层级&lt;/th&gt;
					&lt;th&gt;做法&lt;/th&gt;
					&lt;th&gt;类比&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Dropout&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;激活层&lt;/td&gt;
					&lt;td&gt;前向随机丢弃神经元激活，约束期衰减到 0&lt;/td&gt;
					&lt;td&gt;感官处理不成熟&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ActNoise&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;激活层&lt;/td&gt;
					&lt;td&gt;激活值加高斯噪声（std≈rate×0.3），约束期衰减&lt;/td&gt;
					&lt;td&gt;神经系统噪音&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Fixed Mask&lt;/strong&gt; 🆕&lt;/td&gt;
					&lt;td&gt;权重层&lt;/td&gt;
					&lt;td&gt;约束期开始时选定固定权重子集 mask，全程不变&lt;/td&gt;
					&lt;td&gt;固定神经连接缺失&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Subspace SVD&lt;/strong&gt; 🆕&lt;/td&gt;
					&lt;td&gt;权重层&lt;/td&gt;
					&lt;td&gt;每 epoch SVD 截断到低秩，逐 epoch 放开&lt;/td&gt;
					&lt;td&gt;数学短路（低维发育）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5 id="实验结果"&gt;实验结果
&lt;/h5&gt;&lt;p&gt;&lt;img alt="激活值约束 + 权重短路对比" class="gallery-image" data-flex-basis="486px" data-flex-grow="202" height="732" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/act_and_short_result.png" srcset="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/act_and_short_result_hu_43704228b20de5ef.png 800w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/act_and_short_result.png 1484w" width="1484"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="准确率 vs Epoch" class="gallery-image" data-flex-basis="645px" data-flex-grow="268" height="887" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/accuracy_vs_epoch.png" srcset="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/accuracy_vs_epoch_hu_c460147a2210e60c.png 800w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/accuracy_vs_epoch_hu_42de3a9e016a3ee9.png 1600w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/accuracy_vs_epoch.png 2384w" width="2384"&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;模式&lt;/th&gt;
					&lt;th&gt;Best Test Acc&lt;/th&gt;
					&lt;th&gt;vs Baseline&lt;/th&gt;
					&lt;th&gt;结论&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Baseline&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;88.59%&lt;/td&gt;
					&lt;td&gt;—&lt;/td&gt;
					&lt;td&gt;正常发育，基线&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Dropout&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;87.39%&lt;/td&gt;
					&lt;td&gt;-1.2%&lt;/td&gt;
					&lt;td&gt;✅ 几乎无损，模型对激活层扰动非常鲁棒&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ActNoise&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;88.40%&lt;/td&gt;
					&lt;td&gt;-0.2%&lt;/td&gt;
					&lt;td&gt;✅ 不仅没伤害，甚至有轻微正则化效果&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Fixed Mask&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;87.79%&lt;/td&gt;
					&lt;td&gt;-0.8%&lt;/td&gt;
					&lt;td&gt;✅ 差距很小，直觉在更大的数据集上也许会更有效果，待验证&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Subspace SVD&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;65.35%&lt;/td&gt;
					&lt;td&gt;-23.2%&lt;/td&gt;
					&lt;td&gt;❌ 数值崩塌，test loss 飙到 64，勉强爬回&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5 id="结论"&gt;结论
&lt;/h5&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;激活层约束几乎不影响最终性能&lt;/strong&gt;——Transformer 对 dropout/噪声的鲁棒性远超预期&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fixed Mask 修复后接近 baseline&lt;/strong&gt;——修复了梯度-权重错位 bug 后，固定 mask 从 79% 跳到 87.79%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;权重层约束（SVD 截断）仍是硬伤&lt;/strong&gt;——低秩截断在 ViT 上造成数值不稳定，需要重新设计（warmup、部分层施加、更慢的 rank 增长）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fixed Mask &amp;raquo; 随机 Mask&lt;/strong&gt;——固定 mask 子集让被保留的权重能稳定积累梯度，验证了「固定机能不全」优于「每次随机重新受伤」&lt;/li&gt;
&lt;li&gt;思考应该尝试更大的数据集，FashionMNIST数据过于简单难以体现trick价值&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="fixed-mask在cifar10数据集上的实验"&gt;Fixed Mask在CIFAR10数据集上的实验
&lt;/h3&gt;&lt;h4 id="训练原型"&gt;训练原型
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;数据集：&lt;/strong&gt; CIFAR-10（彩色 32×32，5 万训练图，10 类）
&lt;strong&gt;模型：&lt;/strong&gt; TinyViT（270 万参数，6 层 Transformer）
&lt;strong&gt;训练：&lt;/strong&gt; 100 epoch，AMP 混合精度&lt;/p&gt;
&lt;h4 id="实验细节"&gt;实验细节
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;Fixed Mask 约束逻辑：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;训练开始前用 &lt;code&gt;seed=42&lt;/code&gt; 固定生成一个 50% 零的二进制 mask（每个权重矩阵有自己固定的 mask）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;epoch 1 到 50（约束期）：&lt;/strong&gt; &lt;code&gt;weight = weight * mask&lt;/code&gt; in-place，mask 比例从 50% 按 decay 衰减到 0%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;epoch 51 到 100（放开期）：&lt;/strong&gt; 不再 mask，所有权重正常训练&lt;/li&gt;
&lt;li&gt;被 mask 的位置在前向时为 0 → 梯度为 0 → AdamW 不更新 → 解锁后从零开始学&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Baseline 对照：&lt;/strong&gt; 同样的参数，但没有 mask 操作，从头到尾正常训练&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数据增强：&lt;/strong&gt; RandomCrop + RandomHorizontalFlip + Normalize（CIFAR-10 标准流程）&lt;/p&gt;
&lt;h4 id="实验结果-1"&gt;实验结果
&lt;/h4&gt;&lt;p&gt;&lt;img alt="实验过程acc对比" class="gallery-image" data-flex-basis="614px" data-flex-grow="256" height="814" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/cifar10_comparison.png" srcset="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/cifar10_comparison_hu_734759db5f404a0d.png 800w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/cifar10_comparison_hu_ec52ca9ab42ef77c.png 1600w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/cifar10_comparison.png 2084w" width="2084"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="实验结果对比" class="gallery-image" data-flex-basis="339px" data-flex-grow="141" height="732" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/cifar10_bars.png" srcset="https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/cifar10_bars_hu_90b312de3d0c1f46.png 800w, https://rechenz.github.io/post/%E6%9D%83%E9%87%8D%E7%BA%A6%E6%9D%9F%E8%AE%AD%E7%BB%83%E5%AE%9E%E9%AA%8C/cifar10_bars.png 1034w" width="1034"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;区别上一次实验（FashionMNIST）：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;项目&lt;/th&gt;
					&lt;th&gt;FashionMNIST&lt;/th&gt;
					&lt;th&gt;CIFAR-10&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;图像&lt;/td&gt;
					&lt;td&gt;单通道灰度 28×28&lt;/td&gt;
					&lt;td&gt;三通道彩色 32×32&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;训练集&lt;/td&gt;
					&lt;td&gt;6 万张&lt;/td&gt;
					&lt;td&gt;5 万张&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;难度&lt;/td&gt;
					&lt;td&gt;简单&lt;/td&gt;
					&lt;td&gt;难&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Epoch&lt;/td&gt;
					&lt;td&gt;50（25+25）&lt;/td&gt;
					&lt;td&gt;100（50+50）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Baseline&lt;/td&gt;
					&lt;td&gt;88.59%&lt;/td&gt;
					&lt;td&gt;81.04%&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Fixed Mask&lt;/td&gt;
					&lt;td&gt;87.79%（-0.8%）&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;82.69%（+1.65%）&lt;/strong&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="结论-1"&gt;结论
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;实验设计思路基本正确，与朴素训练方式相比在更为复杂的数据集上表现优秀&lt;/li&gt;
&lt;li&gt;（推测）此训练方式在输出维度较小时会表现优秀，此训练方式并不适用于GPT等语言输出模型（从信息论的角度理解），但是输入维度应该越大越好增大&lt;/li&gt;
&lt;li&gt;（推测）我实际感觉这个trick更适合放在具身智能方面，但是我目前实在没有这个能力与资源。&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>cs224n学习笔记</title><link>https://rechenz.github.io/post/cs224n%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link><pubDate>Sun, 18 Jan 2026 23:02:00 +0800</pubDate><guid>https://rechenz.github.io/post/cs224n%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid><description>&lt;h1 id="cs224n学习笔记"&gt;cs224n学习笔记
&lt;/h1&gt;&lt;h2 id="词嵌入"&gt;词嵌入
&lt;/h2&gt;&lt;p&gt;我们学习过 cs231n，了解了神经网络的本质是将数据进行线性变换为我们所需要的数据模式（如分类等等）。&lt;/p&gt;
&lt;p&gt;但是在自然语言处理这个领域，我们的语言难以直接被计算机所理解，所以我们要对我们的语言进行编码，注意这里的编码并不是像unicode那样无序编码，而是为了让计算机“理解”词意而编码，所以在这里引入词嵌入方法（PS:词嵌入在之后的 transformer 中仍然有一席之地）&lt;/p&gt;
&lt;p&gt;词嵌入其实也是模型的一个学习阶段，拿现实来举一个例子，我们学习语言的时候，通过理解单词的实际意义来学习，词嵌入类似，但是我们无法让计算机通过五感来理解词义，所以我们对相同或者有类似词义的单词进行分类，所以每个单词对于计算机来说都是抽象概念，我们将在之后的训练中让各种抽象概念相互依存、连接。&lt;/p&gt;
&lt;p&gt;词嵌入的实际操作非常简单，cs224n_a1 已经有详细的步骤拆分，这里不做赘述，我们只需要知道词嵌入是将语言的编码的重要工具即可。&lt;/p&gt;
&lt;h2 id="依存句法分析器"&gt;依存句法分析器
&lt;/h2&gt;&lt;p&gt;这个模块的功能在 Transformer 中会集成在注意力机制中，但是学习这个模块这是我们理解语言分析的一个重要阶段。&lt;/p&gt;
&lt;p&gt;在上文我们提到过计算机所理解的概念都是抽象的，但是人们的语言会有着不同的风格、歧义甚至是语法错误，为了让计算机依然能“看懂”我们的语言，便有了这个模块。&lt;/p&gt;
&lt;p&gt;这个模块将我们的语言拆分为最简单的树形结构，让计算机理解起来不会有歧义。&lt;/p&gt;
&lt;p&gt;那么现在的问题来到了怎么合理拆分构造我们的树形结构，首先不同的语言有不同的语法规范，其次我们要对这个依存句法分析器进行训练，让其能合理地处理任何句子。&lt;/p&gt;
&lt;p&gt;在 cs224n 中我们采用神经网络对其进行训练，并且使用 pytorch 减少代码难度，写起来其实没多少东西。&lt;/p&gt;
&lt;h2 id="神经机器翻译"&gt;神经机器翻译
&lt;/h2&gt;&lt;p&gt;这部分的代码实在是太乱了，我按照自己的理解进行讲解，如果有错误请联系我改正。&lt;/p&gt;
&lt;p&gt;在这里我们引入了注意力机制和 LSTM 架构，那么我们所需训练的矩阵数便涉及了注意力机制的注意力模块和LSTM的遗忘门、输入门、输出门。&lt;/p&gt;
&lt;p&gt;在笔记中我们只通过抽象概念来理解，并不会说明具体代码实现。&lt;/p&gt;
&lt;p&gt;LSTM（长短期记忆网络）是为了解决长对话的理解而诞生的，主要模块有遗忘门、输入门、输出门。&lt;/p&gt;
&lt;p&gt;遗忘门是解决过远的记忆，优化性能且防止过久记忆。&lt;/p&gt;
&lt;p&gt;输入门便是对某些数据进行记忆。&lt;/p&gt;
&lt;p&gt;输出门便是对现有的记忆进行编码，而后传导到下一个循环。&lt;/p&gt;
&lt;p&gt;那么我们现在发现了一个问题，如果真的有一个问题需要我们长久记忆怎么办，我们的遗忘门在每一次循环都会按照时间步对之前的权重进行削减，那么我们在这里引入注意力机制，我们在遗忘之前对原始数据进行注意力机制的应用，令超长期记忆成为可能。&lt;/p&gt;
&lt;p&gt;注意这里的注意力机制和 Transformer 中的自注意力机制有所不同，这里的注意力机制只会告诉模型应该注意前文的某某方面，而不会分析更多。&lt;/p&gt;
&lt;p&gt;这部分的实现变得更为抽象，但是我们要明确一点，就像上文提到的，计算机所有点一切概念都是数字，都是抽象的，我们为模型实现任何的模块只是提供了模型分析某个方面的功能，具体的模块间的嵌合性以及那些矩阵权重数据的实际都不是我们需要考虑的，这些问题会在实际数据的训练中进行自拟合，这也提供了一个知识点便是我们不能将某一模块的权重单独拿出来放在另一个模型上，这是不合理的。&lt;/p&gt;
&lt;h2 id="attention-is-all-you-need"&gt;Attention is All You Need
&lt;/h2&gt;&lt;p&gt;Transformer 的知识点很多，我们按照架构数据处理主要模块来讲解。&lt;/p&gt;
&lt;h3 id="自注意力机制"&gt;自注意力机制
&lt;/h3&gt;&lt;p&gt;这是 Transformer 架构最具有革命性的模块。&lt;/p&gt;
&lt;p&gt;首先从单一自注意力入手，这里我们将为每一个词元（这个待会解释）设置三个键值，分别为查询键值Q，自身键值K，本质键值V，这便是自注意机制要学习的三个主要参数，这里引用一下deepseek给我的例子&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;ul&gt;
&lt;li&gt;&lt;strong&gt;查询 Q&lt;/strong&gt; ：每个词发出的&amp;quot;问题&amp;quot;：我该关注谁？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;键 K&lt;/strong&gt; ：每个词提供的&amp;quot;答案&amp;quot;：我有什么特点值得关注？&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;值 V&lt;/strong&gt; ：每个词的&amp;quot;本质内容&amp;quot;，将被加权求和&lt;/li&gt;
&lt;/ul&gt;

 &lt;/blockquote&gt;
&lt;p&gt;之后我们便要计算注意力分数，计算方法不重要，重要的是我们的注意力分数代表了我们对这个词的关注度。&lt;/p&gt;
&lt;p&gt;但是考虑到对语言分析不够全面，并且联想到卷积神经网络中卷积核的概念，我们便引入了多头注意力机制，本质是对原本的单一自注意力机制的三个键值进行拆解，拆成 3$\times$N 个键值（设有N个头），之后对所有的头进行整合即可。&lt;/p&gt;
&lt;h3 id="前馈神经网络ffn"&gt;前馈神经网络（FFN）
&lt;/h3&gt;&lt;p&gt;这是 Transformer 中很有趣的一部分，正如我上文说的，我们实现的每一个模块都是为了提供给模型学习的能力，而不是单纯的功能。&lt;/p&gt;
&lt;p&gt;前馈神经网络为模型提供了学习更复杂特征的能力，因为FFN将传统神经网络的线性变换替换为了非线性变换&lt;/p&gt;
&lt;p&gt;$$
\text{FFN}(\mathbf{x}) = \sigma(\mathbf{x}\mathbf{W}_1 + \mathbf{b}_1)\mathbf{W}_2 + \mathbf{b}_2
$$&lt;/p&gt;
&lt;p&gt;根据数学定理，我们可以知道这种形式的变换可以逼近任何的连续函数，这提供了 FFN 强大的学习分析能力。&lt;/p&gt;
&lt;h3 id="残差连接与层归一化"&gt;残差连接与层归一化
&lt;/h3&gt;&lt;p&gt;这其实不是一个重要的模块，但是这是一个重要的小优化。&lt;/p&gt;
&lt;p&gt;在我们刚刚接触神经网络时便知道学习的实际便是通过反向传播不断优化我们的各种矩阵超参数，但是如果我们需要深度学习，我们便需要增加层数，那么我们会遇到数学上的问题，比如梯度消失或无效学习，那么我们便要引入残差连接这个模块。&lt;/p&gt;
&lt;p&gt;说直白一点，这个模块其实就是将我们的输出权重与原始权重加在一起，这防止了某一参数学着学着没了，也防止了过于激进的变换。&lt;/p&gt;
&lt;p&gt;但是我们又发现，单纯相加之后又会过于破坏我们原本的矩阵，甚至导致越加越大难以计算，所以我们引入了层归一化（LayerNormalization）来进行“还原”操作。&lt;/p&gt;
&lt;p&gt;感性理解一下，我认为这个模块令我们的 Transformer 变得优雅。&lt;/p&gt;
&lt;h3 id="自然语言文本生成器"&gt;自然语言文本生成器
&lt;/h3&gt;&lt;p&gt;注意这里我并不是在讲解整个解码器，我相信理解上述模块后已经可以理解编码器，而解码器需要生成自然语言，我曾在这部分疑惑过，所以单独拿出来讲解。&lt;/p&gt;
&lt;p&gt;在Transformer中，我们使用自回归解码器，解码器通过理解上文生成预测词向量，然后通过束搜索进行词汇预测。&lt;/p&gt;
&lt;p&gt;那么什么是束搜索？&lt;/p&gt;
&lt;p&gt;我们来回顾一下我们的起点——knn算法，我们查找前k个相似的图像，束搜索与此类似。&lt;/p&gt;
&lt;p&gt;束搜索搜索k前相似，而后再每个相似后再搜索k前相似，在一定循环后选择得分（概率）最大的词列。&lt;/p&gt;
&lt;p&gt;这种方法有些丑陋，于是有了许多剪枝和优化方法，在这里不过多赘述。&lt;/p&gt;
&lt;h2 id="补充解释"&gt;补充解释
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;词元：在生成式人工智能导论中，我们知道chatGPT并不是以每个单词进行编码，而是分为若干词元，比如一个词可以由许多词元构成，故此在上文使用词元概念&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>基础神经网络学习笔记</title><link>https://rechenz.github.io/post/%E5%9F%BA%E7%A1%80%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</link><pubDate>Sun, 02 Nov 2025 19:23:40 +0800</pubDate><guid>https://rechenz.github.io/post/%E5%9F%BA%E7%A1%80%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</guid><description>&lt;p&gt;我猜测可能会有很多人跟我一样，在学完cs231n后仍然对神经网络没有一个整体印象，所以这是一份为后人能更轻松地理解神经网络而编写的学习笔记，本文通过我自己的理解对一份神经网络代码进行解释，将所有的知识点串联起来，希望可以造福后人。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; numpy &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; np
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;unpickle&lt;/span&gt;(file):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;import&lt;/span&gt; pickle
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; open(file, &lt;span style="color:#e6db74"&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; fo:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dict &lt;span style="color:#f92672"&gt;=&lt;/span&gt; pickle&lt;span style="color:#f92672"&gt;.&lt;/span&gt;load(fo, encoding&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;bytes&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; dict
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fetch_data&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_label &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; testlabel &lt;span style="color:#f92672"&gt;=&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; unpickle(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# datasets\cifar-10-batches-py\data_batch_1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;E:/projects/datasets/cifar-10-batches-py/data_batch_&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;i&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(data[&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_label&lt;span style="color:#f92672"&gt;.&lt;/span&gt;append(data[&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;labels&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test &lt;span style="color:#f92672"&gt;=&lt;/span&gt; unpickle(&lt;span style="color:#e6db74"&gt;&amp;#39;E:/projects/datasets/cifar-10-batches-py/test_batch&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; test[&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; testlabel &lt;span style="color:#f92672"&gt;=&lt;/span&gt; test[&lt;span style="color:#e6db74"&gt;b&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;labels&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;concatenate(train_data)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_label &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;concatenate(train_label)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; train_data&lt;span style="color:#f92672"&gt;.&lt;/span&gt;reshape(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#ae81ff"&gt;50000&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;))&lt;span style="color:#f92672"&gt;.&lt;/span&gt;transpose(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;astype(&lt;span style="color:#e6db74"&gt;&amp;#34;float32&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; train_data&lt;span style="color:#f92672"&gt;.&lt;/span&gt;reshape(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; test_data&lt;span style="color:#f92672"&gt;.&lt;/span&gt;reshape((&lt;span style="color:#ae81ff"&gt;10000&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;))&lt;span style="color:#f92672"&gt;.&lt;/span&gt;transpose(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;astype(&lt;span style="color:#e6db74"&gt;&amp;#34;float32&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; test_data&lt;span style="color:#f92672"&gt;.&lt;/span&gt;reshape(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; train_data, train_label, test_data, testlabel
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;preprocess_data&lt;/span&gt;(train_data, test_data):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mean &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mean(train_data, axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; mean
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test_data &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; mean
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; train_data, test_data
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;NeuralNetwork&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, input_size, hidden_size, output_size, std&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1e-4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; std &lt;span style="color:#f92672"&gt;*&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;randn(input_size, hidden_size)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros(hidden_size)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; std &lt;span style="color:#f92672"&gt;*&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;randn(hidden_size, output_size)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros(output_size)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relu&lt;/span&gt;(self, x):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;maximum(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relu_backward&lt;/span&gt;(self, dout, cache):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dx, x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dout, cache
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dx[x &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; dx
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;loss&lt;/span&gt;(self, X, y&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;, reg&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; W1, b1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;], self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; W2, b2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;], self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Hidden_layer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;relu(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(X, W1) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; b1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; scores &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(Hidden_layer, W2) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; b2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; y &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; scores
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;log(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores[range(len(scores)), y]) &lt;span style="color:#f92672"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores), axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss &lt;span style="color:#f92672"&gt;/=&lt;/span&gt; len(X)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;reg&lt;span style="color:#f92672"&gt;*&lt;/span&gt;(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(W1&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W1)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(W2&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W2))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dscores &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores)&lt;span style="color:#f92672"&gt;/&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores), axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, keepdims&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dscores[range(len(scores)), y] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dscores &lt;span style="color:#f92672"&gt;/=&lt;/span&gt; len(X)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(Hidden_layer&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T, dscores) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; reg&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(dscores, axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dhidden &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(dscores, W2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dhidden_relu &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;relu_backward(dhidden, Hidden_layer)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(X&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T, dhidden_relu) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; reg&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(dhidden, axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; loss, grads
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;train&lt;/span&gt;(self, X, y,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; learning_rate&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1e-3&lt;/span&gt;, learning_rate_decay&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.95&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reg&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;5e-6&lt;/span&gt;, num_iters&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; batch_size&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;, verbose&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; num_train &lt;span style="color:#f92672"&gt;=&lt;/span&gt; X&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; iterations_per_epoch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; max(num_train &lt;span style="color:#f92672"&gt;//&lt;/span&gt; batch_size, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; it &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(num_iters):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; idx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;choice(num_train, batch_size, replace&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; X_batch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; X[idx]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; y_batch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; y[idx]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss, grads &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;loss(X_batch, y&lt;span style="color:#f92672"&gt;=&lt;/span&gt;y_batch, reg&lt;span style="color:#f92672"&gt;=&lt;/span&gt;reg)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# if verbose and it % 100 == 0:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# print(&amp;#39;iteration %d / %d: loss %f&amp;#39; % (it, num_iters, loss))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; it &lt;span style="color:#f92672"&gt;%&lt;/span&gt; iterations_per_epoch &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;and&lt;/span&gt; it &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; learning_rate &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; learning_rate_decay
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;predict&lt;/span&gt;(self, X):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Hidden_layer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;relu(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(X, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; scores &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(Hidden_layer, self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;]) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;argmax(scores, axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data, train_label, test_data, testlabel &lt;span style="color:#f92672"&gt;=&lt;/span&gt; fetch_data()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; train_data, test_data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; preprocess_data(train_data, test_data)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; net &lt;span style="color:#f92672"&gt;=&lt;/span&gt; NeuralNetwork(&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; net&lt;span style="color:#f92672"&gt;.&lt;/span&gt;train(train_data, train_label, num_iters&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10000&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; batch_size&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;, verbose&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;f&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;train accuracy: &lt;/span&gt;&lt;span style="color:#e6db74"&gt;{&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;mean(net&lt;span style="color:#f92672"&gt;.&lt;/span&gt;predict(train_data) &lt;span style="color:#f92672"&gt;==&lt;/span&gt; train_label)&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里是本文所使用的代码。（训练内容为CIFAR-10数据集）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;首先，&lt;code&gt;fetch_data&lt;/code&gt;和 &lt;code&gt;unpickle&lt;/code&gt;函数作为数据读入函数，在这里不做讲解，我们只需要知道 &lt;code&gt;train_data,train_label,test_data,testlabel&lt;/code&gt;这四个都分别是什么即可，&lt;code&gt;train_data&lt;/code&gt;是一个n*3072的矩阵，它存储了n个训练需要的图像数据，&lt;code&gt;train_label&lt;/code&gt;是一个列表，有n项，存储了 &lt;code&gt;train_data&lt;/code&gt;对应的答案，&lt;code&gt;test_data,testlabel&lt;/code&gt;同理。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;之后我们需要对数据进行预处理，我们来看 &lt;code&gt;preprocess_data&lt;/code&gt;函数，这份代码中只采用了均值减法初始化，这是最为常见的初始化方式，且在这份代码中效果显著，当然我们仍然可以在这个函数中添加更多的初始化方式，比如归一化等等，但是我们需要注意数据的类别，防止产生负优化，比如在CIFAR-10数据集上，归一化会显著降低它的准确率。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;现在我们马上就要进入最紧张刺激的神经网络环节了，但是在训练之前，我们仍然需要明确我们的神经网络格式，比如在这份代码中，我们使用的是一个两层全连接神经网络，所以我们有这个预处理函数&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;__init__&lt;/span&gt;(self, input_size, hidden_size, output_size, std&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1e-4&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; std &lt;span style="color:#f92672"&gt;*&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;randn(input_size, hidden_size)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros(hidden_size)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; std &lt;span style="color:#f92672"&gt;*&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;randn(hidden_size, output_size)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;zeros(output_size)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里，我们对每一层分别定义了它的权重W和偏量b，这四个参数是我们需要训练的主要参数，并且我们注意到，他们都是根据神经元数量来定义的矩阵，那么我现在来解释一下为什么是矩阵。我们来看这个初始化函数的传入参数 &lt;code&gt;input_size, hidden_size, output_size, std=1e-4&lt;/code&gt;，std先不用管，前面三个分别是输入的格式，第一层格式，输出格式，我们完全可以简单理解为我们需要将一个有若干个数字的集合，通过一系列的数学运算，先压缩为 &lt;code&gt;hidden_size&lt;/code&gt;的大小，最后再压缩为 &lt;code&gt;output_size&lt;/code&gt;的大小，而这里的 &lt;code&gt;output_size&lt;/code&gt;就是我们需要分类的10个标签。而这里对参数的初始化使用了随机数，因为全部为0是不正确的，因为我们后续还要对其进行求偏导以及计算梯度。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;初始化之后，我们就可以进行训练了，而训练的目的是迭代计算出最好的参数，也就是神经网络初始化所定义的四个参数。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;train&lt;/span&gt;(self, X, y,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; learning_rate&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1e-3&lt;/span&gt;, learning_rate_decay&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.95&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; reg&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;5e-6&lt;/span&gt;, num_iters&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;100&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; batch_size&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;, verbose&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; num_train &lt;span style="color:#f92672"&gt;=&lt;/span&gt; X&lt;span style="color:#f92672"&gt;.&lt;/span&gt;shape[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; iterations_per_epoch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; max(num_train &lt;span style="color:#f92672"&gt;//&lt;/span&gt; batch_size, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; it &lt;span style="color:#f92672"&gt;in&lt;/span&gt; range(num_iters):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; idx &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;random&lt;span style="color:#f92672"&gt;.&lt;/span&gt;choice(num_train, batch_size, replace&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; X_batch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; X[idx]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; y_batch &lt;span style="color:#f92672"&gt;=&lt;/span&gt; y[idx]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss, grads &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;loss(X_batch, y&lt;span style="color:#f92672"&gt;=&lt;/span&gt;y_batch, reg&lt;span style="color:#f92672"&gt;=&lt;/span&gt;reg)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; learning_rate &lt;span style="color:#f92672"&gt;*&lt;/span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# if verbose and it % 100 == 0:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# print(&amp;#39;iteration %d / %d: loss %f&amp;#39; % (it, num_iters, loss))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; it &lt;span style="color:#f92672"&gt;%&lt;/span&gt; iterations_per_epoch &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;and&lt;/span&gt; it &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; learning_rate &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; learning_rate_decay
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;我们来看这个训练主函数，reg是我们定义的L2正则化超参数，我们直接来看迭代训练循环，我们每一次迭代随机抽取数据进行训练，用这份数据计算出四个参数的梯度，以此来更新我们的参数，使我们的参数不断优化。在这个函数中我们还使用了两个参数，&lt;code&gt;learning_rate&lt;/code&gt;和 &lt;code&gt;learning_rate_decay&lt;/code&gt;，这两个参数用来不断降低模型的学习率，使参数的迭代越来越精确。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们发现在训练迭代中使用了一个很重要的 &lt;code&gt;loss&lt;/code&gt;函数来计算我们的参数梯度，这也是神经网络最重要的部分。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relu&lt;/span&gt;(self, x):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;maximum(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;relu_backward&lt;/span&gt;(self, dout, cache):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dx, x &lt;span style="color:#f92672"&gt;=&lt;/span&gt; dout, cache
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dx[x &lt;span style="color:#f92672"&gt;&amp;lt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; dx
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;loss&lt;/span&gt;(self, X, y&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;, reg&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.0&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; W1, b1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;], self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; W2, b2 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;], self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;params[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Hidden_layer &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;relu(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(X, W1) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; b1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; scores &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(Hidden_layer, W2) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; b2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; y &lt;span style="color:#f92672"&gt;is&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;None&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; scores
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;log(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores[range(len(scores)), y]) &lt;span style="color:#f92672"&gt;/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores), axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss &lt;span style="color:#f92672"&gt;/=&lt;/span&gt; len(X)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; loss &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;&lt;span style="color:#f92672"&gt;*&lt;/span&gt;reg&lt;span style="color:#f92672"&gt;*&lt;/span&gt;(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(W1&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W1)&lt;span style="color:#f92672"&gt;+&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(W2&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W2))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dscores &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores)&lt;span style="color:#f92672"&gt;/&lt;/span&gt;np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;exp(scores), axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, keepdims&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dscores[range(len(scores)), y] &lt;span style="color:#f92672"&gt;-=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dscores &lt;span style="color:#f92672"&gt;/=&lt;/span&gt; len(X)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(Hidden_layer&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T, dscores) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; reg&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b2&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(dscores, axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dhidden &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(dscores, W2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; dhidden_relu &lt;span style="color:#f92672"&gt;=&lt;/span&gt; self&lt;span style="color:#f92672"&gt;.&lt;/span&gt;relu_backward(dhidden, Hidden_layer)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;W1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dot(X&lt;span style="color:#f92672"&gt;.&lt;/span&gt;T, dhidden_relu) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; reg&lt;span style="color:#f92672"&gt;*&lt;/span&gt;W1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; grads[&lt;span style="color:#e6db74"&gt;&amp;#39;b1&amp;#39;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; np&lt;span style="color:#f92672"&gt;.&lt;/span&gt;sum(dhidden, axis&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; loss, grads
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这里便是我们计算所需要的函数，我们来对 &lt;code&gt;loss&lt;/code&gt;函数逐步分析。首先传入现有参数没有什么好说的，然后便是我们的正向传播环节，我们先用现有参数计算出10个类别所对应的得分，然后我们将这10个分数放进线性分类器里进行计算，最后得到的就是我们的损失 &lt;code&gt;loss&lt;/code&gt;。之后便是我们喜闻乐见的反向传播环节，所谓反向传播，其实就是按照线性求导法则对两层神经网络的所有参数求偏导，以此找到loss下降最快的点，才能以此更新参数。26-28行都是在对softmax线性分类器求梯度，到了29行我们发现我们在运算时对矩阵进行了转置，通俗地讲，我们明白矩阵是不服从乘法交换律的，所以如果我们想让它正确地乘，便需要给他转个方向，这样才可以进行矩阵乘法。还有一点需要注意，在32行我们对激活函数进行了求导，因为我们在前向传播的时候在第一层使用了激活函数，所以这一步也必不可少。至此，我们便可以完整地计算出参数梯度，并以此迭代训练我们的四个主要参数。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item></channel></rss>