<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Transformer on 边个濑椰的博客</title><link>https://blog.kawausococo.top/tags/transformer/</link><description>Recent content in Transformer on 边个濑椰的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Wed, 28 Jan 2026 14:31:08 +0800</lastBuildDate><atom:link href="https://blog.kawausococo.top/tags/transformer/index.xml" rel="self" type="application/rss+xml"/><item><title>CS224N</title><link>https://blog.kawausococo.top/p/cs224n/</link><pubDate>Wed, 28 Jan 2026 14:31:08 +0800</pubDate><guid>https://blog.kawausococo.top/p/cs224n/</guid><description>&lt;h2 id="intro"&gt;Intro
&lt;/h2&gt;&lt;p&gt;本篇是对&lt;a class="link" href="https://web.stanford.edu/class/archive/cs/cs224n/cs224n.1246/" target="_blank" rel="noopener"
 &gt;Stanford CS 224N | Natural Language Processing with Deep Learning (Spring 2024)&lt;/a&gt; 这门课程的学习笔记。关于这门课的知识点，总结如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;词向量、RNN、LSTM、Seq2Seq 模型、机器翻译、注意力机制、Transformer 等等&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="what-is-this-course-about"&gt;What is this course about?
&lt;/h3&gt;&lt;p&gt;Natural language processing (NLP) or computational linguistics is one of the most important technologies of the information age. Applications of NLP are everywhere because people communicate almost everything in language: web search, advertising, emails, customer service, language translation, virtual agents, medical reports, politics, etc. In the 2010s, deep learning (or neural network) approaches obtained very high performance across many different NLP tasks, using single end-to-end neural models that did not require traditional, task-specific feature engineering. In the 2020s amazing further progress was made through the scaling of Large Language Models, such as ChatGPT. In this course, students will gain a thorough introduction to both the basics of Deep Learning for NLP and the latest cutting-edge research on Large Language Models (LLMs). Through lectures, assignments and a final project, students will learn the necessary skills to design, implement, and understand their own neural network models, using the Pytorch framework.&lt;/p&gt;
&lt;h2 id="word-vectors"&gt;Word Vectors
&lt;/h2&gt;&lt;p&gt;$ vector(”King”)- vector(”Man”) + vector(”Woman”) $&lt;/p&gt;
&lt;p&gt;&lt;em&gt;results in a vector that is closest to the vector representation of the word Queen&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="how-do-we-have-usable-meaning-in-a-computer"&gt;How do we have usable meaning in a computer?
&lt;/h3&gt;&lt;p&gt;Slides里介绍了几种方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WordNet&lt;/li&gt;
&lt;li&gt;one-hot vectors&lt;/li&gt;
&lt;li&gt;word vectors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么前两种都有其现实意义，但也有明显的弊端。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;WordNet，完全靠&lt;code&gt;synonum sets&lt;/code&gt;和&lt;code&gt;hypernyms sets&lt;/code&gt;来确定词汇间的关系、构造复杂、无法及时吸收新词汇&amp;hellip;&amp;hellip;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;one-hot vectors给每个词都设置了&lt;code&gt;symbol&lt;/code&gt;，尽管是用数字表达，但是&lt;strong&gt;相近的词之间在数学上没有联系&lt;/strong&gt;（向量的点积为0）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么下面就引出了一句名言：&lt;em&gt;&amp;ldquo;You shall know a word by the company it keeps&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;以及word vectors的思想，将&lt;strong&gt;词汇归一化到一个向量&lt;/strong&gt;中，虽然每个词汇有多个词义，但其分布却近似是其多个词义的平均，并用点积来确定词向量间的相关性。&lt;/p&gt;
&lt;h3 id="word2vec"&gt;Word2vec
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://arxiv.org/pdf/1301.3781" target="_blank" rel="noopener"
 &gt;original word2vec paper&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Word2vec&lt;/code&gt;很好地反映了word vectors的思想，计算中心词和相邻词的相似度，确定其概率分布：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We have a large corpus (“body”) of text: a long list of words&lt;/li&gt;
&lt;li&gt;Every word in a fixed vocabulary is represented by a &lt;strong&gt;vector&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Go through each position t in the text, which has a center word c and context (“outside”) words o&lt;/li&gt;
&lt;li&gt;Use the &lt;strong&gt;similarity of the word vectors for c and o to calculate the probability&lt;/strong&gt; of o given c (or vice versa)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep adjusting the word vectors&lt;/strong&gt; to maximize this probability&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/Word2Vec-1.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;h4 id="objective-function"&gt;Objective Function
&lt;/h4&gt;&lt;p&gt;那么如何计算其似然程度(Likelihood)呢，For each position = $t=1,......,T$, predict context words within a window of fixed size $m$, given center word $w_t$. Data likelihood :
&lt;/p&gt;
$$
L(\theta) = \prod_{t=1}^{T} \prod_{\substack{-m \le j \le m \\ j \neq 0}} P(w_{t+j} \mid w_t; \theta)
$$&lt;p&gt;
为减小数据复杂程度，及方便计算机处理，优化上公式，对其进行平均负对数似然操作，The objective function $J(\theta)$ is the (average) negative log likelihood:
&lt;/p&gt;
$$
J(\theta) = -\frac{1}{T} \log L(\theta) = -\frac{1}{T} \sum_{t=1}^{T} \sum_{substack{-m \le j \le m \\ j \neq 0}} \log P(w_{t+j} \mid w_t; \theta)
$$&lt;p&gt;
&lt;strong&gt;最小化 $J(\theta)$&lt;/strong&gt; 等价于 &lt;strong&gt;最大化预测准确率&lt;/strong&gt;。&lt;/p&gt;
&lt;h4 id="prediction-function"&gt;Prediction Function
&lt;/h4&gt;$$
P(o \mid c) = \frac{\exp(u_o^T v_c)}{\sum_{w \in V} \exp(u_w^T v_c)}
$$&lt;ol&gt;
&lt;li&gt;$u_o^T v_c$ : 点积越大，代表这两个词在向量空间中的位置越接近，即语义相关性越高。
Dot product compares similarity of o and c. $u^T v = u \cdot v = \sum_{i=1}^{n} u_i v_i$ Larger dot product = larger probability.&lt;/li&gt;
&lt;li&gt;$\exp()$ : 将任何实数映射为&lt;strong&gt;正数&lt;/strong&gt;。由于指数函数的增长特性，它会放大较大点积的影响，使相关性高的词获得更高的权重。&lt;/li&gt;
&lt;li&gt;${\sum_{w \in V} \exp(u_w^T v_c)}$ : 分母是对词汇表$V$中所有可能的词进行求和。这一步确保了所有可能输出的概率之和等于 &lt;strong&gt;1&lt;/strong&gt;，从而构成一个标准的概率分布。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这也是对Softmax Function的应用
&lt;/p&gt;
$$
\text{softmax}(x_i) = \frac{\exp(x_i)}{\sum_{j=1}^{n} \exp(x_j)} = p_i
$$&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Softmax 函数将任意值 $x_i$ 映射为一个概率分布 $p_i$。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;“max”：因为它会&lt;strong&gt;放大&lt;/strong&gt;最大值 $x_i$ 对应的概率，使大的更大。&lt;/li&gt;
&lt;li&gt;“soft”：因为它仍然会给较小的 $x_i$ &lt;strong&gt;分配一些概率&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="to-train-the-model"&gt;To Train the Model
&lt;/h4&gt;&lt;p&gt;To train a model, we gradually adjust parameters to minimize a loss.
&lt;/p&gt;
$$
\theta = \begin{bmatrix} 
v_{aardvark} \\ v_a \\ \vdots \\ v_{zebra} \\ u_{aardvark} \\ u_a \\ \vdots \\ u_{zebra}
\end{bmatrix} \in \mathbb{R}^{2dV}
$$&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果词向量维度为 $d$，词汇量为 $V$，则&lt;strong&gt;总参数量&lt;/strong&gt;为 $2dV$。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;每个单词有两个向量，$\theta$ 包含了词汇表中所有单词的两种向量表示（中心词向量 $v$ 和背景词向量 $u$）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;计算所有参数的梯度，以优化模型&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;梯度公式就是对Softmax Function的求偏导，数学过程如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;初始损失函数 (单词对的负对数似然)&lt;/strong&gt;
这是针对一个中心词 $c$ 和一个背景词 $o$ 的基本损失定义：
&lt;/p&gt;
$$
 \text{Loss} = -\log P(o \mid c)
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;代入Softmax定义展开&lt;/strong&gt;
将 $P(o|c)$ 的公式代入，利用对数性质将除法化为减法：
&lt;/p&gt;
$$
 \text{Loss} = -\log \left( \frac{\exp(u_o^T v_c)}{\sum_{w \in V} \exp(u_w^T v_c)} \right) = -u_o^T v_c + \log \sum_{w \in V} \exp(u_w^T v_c)
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第一部分求导&lt;/strong&gt;
对点积项关于中心词向量 $v_c$ 求偏导：
&lt;/p&gt;
$$
 \frac{\partial}{\partial v_c} (u_o^T v_c) = u_o
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;第二部分求导&lt;/strong&gt;
利用链式法则对 $\log \sum \exp(\dots)$ 形式进行求导：
&lt;/p&gt;
$$
 \frac{\partial}{\partial v_c} \log \sum_{w \in V} \exp(u_w^T v_c) = \frac{1}{\sum_{w \in V} \exp(u_w^T v_c)} \cdot \sum_{x \in V} \left[ \exp(u_x^T v_c) \cdot u_x \right]
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;转化为概率期望形式&lt;/strong&gt;
将上一步的结果重新组合，提取出原始的概率项 $P(x|c)$：
&lt;/p&gt;
$$
 \sum_{x \in V} \left[ \frac{\exp(u_x^T v_c)}{\sum_{w \in V} \exp(u_w^T v_c)} \right] u_x = \sum_{x \in V} P(x \mid c) u_x
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;最终梯度公式&lt;/strong&gt;
将两部分合并，得到最终用于更新 $v_c$ 的梯度：
&lt;/p&gt;
$$
 \frac{\partial \text{Loss}}{\partial v_c} = -u_o + \sum_{x \in V} P(x \mid c) u_x
 $$&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="gradient-descent"&gt;Gradient Descent
&lt;/h4&gt;&lt;p&gt;梯度下降更新方程 (矩阵形式)
&lt;/p&gt;
$$
\theta^{new} = \theta^{old} - \alpha \nabla_{\theta} J(\theta)
$$&lt;p&gt;
梯度下降更新方程 (单个参数形式)
&lt;/p&gt;
$$
\theta_j^{new} = \theta_j^{old} - \alpha \frac{\partial}{\partial \theta_j^{old}} J(\theta)
$$&lt;ul&gt;
&lt;li&gt;$\alpha$ (alpha): 步长或学习率（step size / learning rate）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是实际应用并非上面的方法，而是用&lt;strong&gt;随机梯度下降&lt;/strong&gt;，(Stochastic Gradient Descent, SGD)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;目标函数&lt;/strong&gt; $J(\theta)$ 是语料库中&lt;strong&gt;所有&lt;/strong&gt;窗口的函数。如果每次更新都要计算整个语料库的梯度 $\nabla_{\theta} J(\theta)$，计算成本极其昂贵，在进行单次更新前需要等待极长时间。&lt;/li&gt;
&lt;li&gt;SGD不再计算整个语料库，而是通过&lt;strong&gt;重复采样窗口&lt;/strong&gt;，&lt;strong&gt;每处理一个（或一小批）窗口就更新一次参数。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="skip-gram-model-with-negative-sampling"&gt;Skip-gram Model with Negative Sampling
&lt;/h4&gt;&lt;p&gt;&lt;a class="link" href="https://proceedings.neurips.cc/paper_files/paper/2013/file/9aa42b31882ec039965f3c4923ce901b-Paper.pdf" target="_blank" rel="noopener"
 &gt;negative sampling paper&lt;/a&gt;
&lt;/p&gt;
$$
P(o\mid c)=\frac{\exp(u_x^T v_c)}{\sum_{w \in V} \exp(u_w^T v_c)}
$$&lt;p&gt;
采用最传统的方法计算概率时，即softmax，它的&lt;strong&gt;分母&lt;/strong&gt;是全部词的叠加，计算量太大&lt;/p&gt;
&lt;p&gt;而Skip-gram Model with Negative Sampling不需计算所有可能的词，而是训练一些逻辑回归，更偏好实际的上下文而非随机的上下文，实际上会选K个负样本，计算量就变为了$O(K)$
&lt;/p&gt;
$$
J_{neg-sample}(u_o, v_c, U) = -\log \sigma(u_o^T v_c) - \sum_{k \in \{K \text{ sampled indices}\}} \log \sigma(-u_k^T v_c)
$$&lt;p&gt;
其中，$\sigma(x)=\frac{1}{1+e^{-x}}$即sigmoid函数，使符合的结果概率接近于1，而不符合的则接近于0&lt;/p&gt;
&lt;p&gt;但这又会导致低频词，如&amp;quot;zebra&amp;quot;的概率过低，而像&amp;quot;the&amp;quot;这样的词则概率较高，所以给公式加上$3/4$次方：
&lt;/p&gt;
$$
P(W)=U(W)^{3/4}/Z
$$&lt;p&gt;
来提高低频词的概率。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="glove"&gt;GloVe
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://nlp.stanford.edu/pubs/glove.pdf" target="_blank" rel="noopener"
 &gt;original GloVe papar&lt;/a&gt; (Global Vectors for Word Representation)&lt;/p&gt;
&lt;h4 id="co-occurrence-martix"&gt;Co-occurrence Martix
&lt;/h4&gt;&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/co-occurrence.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;构建共现矩阵的方法非常简单，首先设定窗口长度，然后对在窗口长度内出现的共现词频率进行计数，一个简单的例子如上图（窗口为1，仅算相邻词）。但是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&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;/li&gt;
&lt;li&gt;功能词出现频次极高，但没有提供相应的信息；&lt;/li&gt;
&lt;li&gt;没有反映出词距与词相关性之间的联系。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么如何进行降维来优化？经典的方法是进行SVD矩阵分解（虽然问了AI也没明白原理，而且Assignment1中用一个&lt;code&gt;sklearn&lt;/code&gt;的函数就解决了）&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/SVD.png" alt="" loading="lazy" /&gt;
&lt;/p&gt;
$$
X = U \Sigma V^T
$$&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;$X$ (共现矩阵)&lt;/strong&gt;：大小为 $|V| \times |V|$（词表大小）。每个元素 $X_{ij}$ 代表词 $i$ 和词 $j$ 在语料库中共同出现的次数。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$U$ 和 $V$ (正交矩阵)&lt;/strong&gt;：它们的列向量是相互正交的单位向量（Orthonormal）。在 NLP 中，$U$ 的每一行通常被视为该词的原始“嵌入”。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;$\Sigma$ (对角矩阵)&lt;/strong&gt;：对角线上的值 $\sigma_1, \sigma_2, \dots$ 称为&lt;strong&gt;奇异值&lt;/strong&gt;。它们按从大到小排列，代表了数据在对应维度上的&lt;strong&gt;重要程度（方差/信息量）&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么降维便是将从共现矩阵得到的的，长度为$V$的词向量降维成长度为$K$的向量&lt;/p&gt;
&lt;p&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 style="text-align: left"&gt;&lt;/th&gt;
					&lt;th style="text-align: left"&gt;$x = \text{solid}$&lt;/th&gt;
					&lt;th style="text-align: left"&gt;$x = \text{gas}$&lt;/th&gt;
					&lt;th style="text-align: left"&gt;$x = \text{water}$&lt;/th&gt;
					&lt;th style="text-align: left"&gt;$x = \text{fashion}$&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;$P(x\mid\text{ice})$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$1.9 \times 10^{-4}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$6.6 \times 10^{-5}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$3.0 \times 10^{-3}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$1.7 \times 10^{-5}$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;$P(x\mid\text{steam})$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$2.2 \times 10^{-5}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$7.8 \times 10^{-4}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$2.2 \times 10^{-3}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$1.8 \times 10^{-5}$&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td style="text-align: left"&gt;$\dfrac{P(x\mid\text{ice})}{P(x\mid\text{steam})}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$8.9$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$8.5 \times 10^{-2}$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$1.36$&lt;/td&gt;
					&lt;td style="text-align: left"&gt;$0.96$&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="analogies"&gt;Analogies
&lt;/h4&gt;&lt;p&gt;词向量虽然数学原理上很强大，但是其实际的类比(Analogy)场景却是有不少问题：&lt;/p&gt;
&lt;p&gt;下例可见，是一个$woman+grandfather-man=?$的问题，那么显而易见且最有可能的结果就是&lt;code&gt;grandmother&lt;/code&gt;，那么为何程序给出的另外几个，如&lt;code&gt;granddaughter&lt;/code&gt;, &lt;code&gt;mother&lt;/code&gt;之类，score也几乎一样很高呢？&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Run this cell to answer the analogy -- man : grandfather :: woman : x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pprint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wv_from_bin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;most_similar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;positive&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;woman&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;grandfather&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;negative&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;man&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;grandmother&amp;#39;&lt;/span&gt;, 0.7608445286750793&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;granddaughter&amp;#39;&lt;/span&gt;, 0.7200808525085449&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;daughter&amp;#39;&lt;/span&gt;, 0.7168302536010742&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;mother&amp;#39;&lt;/span&gt;, 0.7151536345481873&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;niece&amp;#39;&lt;/span&gt;, 0.7005682587623596&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;father&amp;#39;&lt;/span&gt;, 0.6659888029098511&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;aunt&amp;#39;&lt;/span&gt;, 0.6623409390449524&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;grandson&amp;#39;&lt;/span&gt;, 0.6618767976760864&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;grandparents&amp;#39;&lt;/span&gt;, 0.644661009311676&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;wife&amp;#39;&lt;/span&gt;, 0.6445354223251343&lt;span class="o"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;虽说Assignment里没有标准答案，但是通过AI可以得知：这涉及到“语义聚类”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;语义的“近邻效应”&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;在向量空间中，逻辑相似的词通常会聚在一起形成一个“簇”。当你计算出 $\vec{w} + \vec{g} - \vec{m}$ 时，你实际上是在空间中定位了一个&lt;strong&gt;坐标点&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;granddaughter&lt;/code&gt; 等同样具有“女性”和“亲属”属性，且在语料库中经常与 &lt;code&gt;grandfather&lt;/code&gt; 或 &lt;code&gt;grandmother&lt;/code&gt; 出现在相似的上下文。在向量维度上，它们在“亲属关系”这个维度上非常接近。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;维度的“重叠性”&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;词向量通常有几百个维度。虽然我们减去了 &lt;code&gt;man&lt;/code&gt; 并加上了 &lt;code&gt;grandfather&lt;/code&gt;，但这并不能完全抹除其他维度的相似性。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;daughter&lt;/code&gt;、&lt;code&gt;mother&lt;/code&gt;、&lt;code&gt;grandmother&lt;/code&gt; 共享了绝大部分维度：[+女性]、[+人类]、[+亲属]。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面的例子，属于&amp;quot;Incorrect Analogy&amp;quot;，我们来看易得答案为&lt;code&gt;socks&lt;/code&gt;，但为何模型忽略了&lt;code&gt;glove&lt;/code&gt;和&lt;code&gt;hand&lt;/code&gt;，而输出了各种&lt;code&gt;square&lt;/code&gt;的名词？显然和&lt;code&gt;foot&lt;/code&gt;“脚”的释义无关，而是“英尺”的释义。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pprint&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wv_from_bin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;most_similar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;positive&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;foot&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;glove&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;negative&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hand&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;[(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;45,000-square&amp;#39;&lt;/span&gt;, 0.4922032654285431&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;15,000-square&amp;#39;&lt;/span&gt;, 0.4649604558944702&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;10,000-square&amp;#39;&lt;/span&gt;, 0.4544755816459656&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;6,000-square&amp;#39;&lt;/span&gt;, 0.44975775480270386&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3,500-square&amp;#39;&lt;/span&gt;, 0.444133460521698&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;700-square&amp;#39;&lt;/span&gt;, 0.44257497787475586&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;50,000-square&amp;#39;&lt;/span&gt;, 0.4356396794319153&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3,000-square&amp;#39;&lt;/span&gt;, 0.43486514687538147&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;30,000-square&amp;#39;&lt;/span&gt;, 0.4330596923828125&lt;span class="o"&gt;)&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;footed&amp;#39;&lt;/span&gt;, 0.43236875534057617&lt;span class="o"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;语义多义性&lt;/strong&gt;的干扰
&lt;ul&gt;
&lt;li&gt;上面也提到，&lt;code&gt;foot&lt;/code&gt;也是计量单位”英尺“的英文，和&lt;code&gt;square&lt;/code&gt;组合是合理的&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;训练语料的偏见&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;既然&lt;code&gt;foot&lt;/code&gt;有多个释义，但输出却全是其“英尺”的意思，那么这可能体现了用来训练的语料中多是&lt;code&gt;...square&lt;/code&gt;和&lt;code&gt;foot&lt;/code&gt;相关联&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;词的选择
&lt;ul&gt;
&lt;li&gt;即使输出全是&lt;code&gt;...square&lt;/code&gt;，其score值也不过0.5，这不仅说明模型找不到强相关的词，而且说明了模型很可能没能理解&lt;code&gt;glove&lt;/code&gt;与&lt;code&gt;hand, foot&lt;/code&gt;的联系&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="neural-network"&gt;Neural Network
&lt;/h2&gt;&lt;p&gt;&lt;em&gt;A neural network = running several logistic regressions at the same time.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://cs231n.github.io/neural-networks-1/" target="_blank" rel="noopener"
 &gt;CS231n Deep Learning on Network Architectures&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="link" href="https://cs231n.github.io/optimization-2/" target="_blank" rel="noopener"
 &gt;CS231n Deep Learning for Computer Vision on Backprop&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="structure"&gt;Structure
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/neural-network-1.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/neural-network-2.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="non-linearities"&gt;Non-linearities
&lt;/h3&gt;&lt;p&gt;为什么神经网络需要非线性(Non-linearities)？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;核心观点：神经网络执行函数逼近，例如回归或分类。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;没有非线性&lt;/strong&gt;：深度神经网络只能执行&lt;strong&gt;线性变换&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;多层失效&lt;/strong&gt;：额外的层会被压缩成单个线性变换：$W_1 W_2 x = Wx$（即多层线性层等同于一层）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有了非线性&lt;/strong&gt;：通过包含非线性的多层结构，网络可以逼近更复杂的函数！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/neural-network-3.png" alt="" loading="lazy" /&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;右侧三张波形图&lt;/strong&gt;：展示了随着函数复杂度的增加，只有非线性模型才能拟合这些起伏的蓝点（观测数据）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于常用的非线性函数，在《智能计算系统》课上均有学习，不多赘述&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/neural-network-4.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="gradients"&gt;Gradients
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://cs231n.stanford.edu/handouts/derivatives.pdf" target="_blank" rel="noopener"
 &gt;derivatives.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;梯度，简单地讲就是对变量的微积分，比如我们有：
&lt;/p&gt;
$$
f(x)=x^3
$$&lt;p&gt;
那么它的梯度就是：
&lt;/p&gt;
$$
\frac{df}{dx}=3x^2
$$&lt;p&gt;
当然，这只是个非常简单的例子，实际上是大规模的&lt;strong&gt;链式法则&lt;/strong&gt;计算，对矩阵(Jacabian Matrix)进行梯度计算。&lt;/p&gt;
&lt;h4 id="chain-rule"&gt;Chain Rule
&lt;/h4&gt;&lt;p&gt;在单变量微积分中，如果 $y = f(u)$ 且 $u = g(x)$，那么：
&lt;/p&gt;
$$
\frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx}
$$&lt;p&gt;
但在神经网络中，每一层都是一个向量 $\mathbf{h,z} \in \mathbb{R}^n$。当我们将这个逻辑扩展到向量时，乘法就变成了&lt;strong&gt;矩阵乘法&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;对于多个变量，应与&lt;strong&gt;Jacobians矩阵相乘&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;假设有 $\mathbf h= f(z)$ 和 $\mathbf z=Wx+b$ ，下面的这些偏导数就是雅可比矩阵
&lt;/p&gt;
$$
\frac{\partial \mathbf{h}}{\partial \mathbf{x}} = \frac{\partial \mathbf{h}}{\partial \mathbf{z}} \frac{\partial \mathbf{z}}{\partial \mathbf{x}}
$$&lt;h4 id="matrix-calculus"&gt;Matrix Calculus
&lt;/h4&gt;&lt;p&gt;由下式得，矩阵只有对角元素，其余部分均为0：
&lt;/p&gt;
$$
\begin{aligned} \left( \frac{\partial \mathbf{h}}{\partial \mathbf{z}} \right)_{ij} &amp;= \frac{\partial h_i}{\partial z_j} = \frac{\partial}{\partial z_j} f(z_i) \quad &amp;&amp; \text{definition of Jacobian} \\ &amp;= \begin{cases} f'(z_i) &amp; \text{if } i = j \\ 0 &amp; \text{if otherwise} \end{cases} \quad &amp;&amp; \text{regular 1-variable derivative} \end{aligned}
$$$$
\frac{\partial \mathbf h}{\partial \mathbf z} = 
\begin{pmatrix}
f'(z_1) &amp; 0 &amp; \cdots &amp; 0 \\
0 &amp; f'(z_2) &amp; \cdots &amp; 0 \\
\vdots &amp; \vdots &amp; \ddots &amp; \vdots \\
0 &amp; 0 &amp; \cdots &amp; f'(z_n)
\end{pmatrix}
= \operatorname{diag}(f'(\mathbf z))
$$&lt;p&gt;此外，还有一常有的Jacobian：
&lt;/p&gt;
$$
\frac{\partial}{\partial \mathbf{u}}(\mathbf{u}^T \mathbf{h})=\mathbf h^T
$$&lt;p&gt;
假设 $\mathbf{u}$ 和 $\mathbf{h}$ 都是 $n$ 维列向量：
&lt;/p&gt;
$$
\mathbf{u} = \begin{bmatrix} u_1 \\ u_2 \\ \vdots \\ u_n \end{bmatrix}, \quad \mathbf{h} = \begin{bmatrix} h_1 \\ h_2 \\ \vdots \\ h_n \end{bmatrix}
$$&lt;p&gt;
那么它们的内积（也就是括号里的部分）是一个&lt;strong&gt;标量&lt;/strong&gt;：
&lt;/p&gt;
$$
f = \mathbf{u}^T \mathbf{h} = u_1 h_1 + u_2 h_2 + \dots + u_n h_n = \sum_{i=1}^n u_i h_i
$$&lt;p&gt;
我们要对向量 $\mathbf{u}$ 求导。根据 Jacobian Matrix 的定义，我们需要对 $\mathbf{u}$ 中的每一个元素 $u_k$ 分别求导：
&lt;/p&gt;
$$
\frac{\partial f}{\partial u_k} = \frac{\partial}{\partial u_k} (u_1 h_1 + \dots + u_k h_k + \dots + u_n h_n)
$$&lt;p&gt;
由于除了 $u_k h_k$ 这一项外，其他项都不包含 $u_k$，所以它们对 $u_k$ 的导数都是 $0$：
&lt;/p&gt;
$$
\frac{\partial f}{\partial u_k} = h_k
$$&lt;p&gt;
按照 &lt;strong&gt;Jacobian 矩阵的惯例&lt;/strong&gt;，一个标量对一个&lt;strong&gt;列向量&lt;/strong&gt;求导，结果是一个&lt;strong&gt;行向量&lt;/strong&gt;：
&lt;/p&gt;
$$
\frac{\partial f}{\partial \mathbf{u}} = \begin{bmatrix} \frac{\partial f}{\partial u_1} &amp; \frac{\partial f}{\partial u_2} &amp; \dots &amp; \frac{\partial f}{\partial u_n} \end{bmatrix} = \begin{bmatrix} h_1 &amp; h_2 &amp; \dots &amp; h_n \end{bmatrix} = \mathbf{h}^T
$$&lt;h5 id="write-out-the-jacobians"&gt;Write out the Jacobians
&lt;/h5&gt;$$
\begin{aligned} \frac{\partial s}{\partial \mathbf{b}} &amp;= \frac{\partial s}{\partial \mathbf{h}} \frac{\partial \mathbf{h}}{\partial \mathbf{z}} \frac{\partial \mathbf{z}}{\partial \mathbf{b}} \\ &amp;= \mathbf{u}^T \text{diag}(f'(\mathbf{z})) \mathbf{I} \\ &amp;= \mathbf{u}^T \odot f'(\mathbf{z}) \end{aligned}
$$&lt;p&gt;$\odot$ = Hadamard product = element-wise multiplication of 2 vectors to give vector&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;变量&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;神经网络中的含义&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;说明&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;$s$&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;损失函数值 (Loss/Score)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;最终的标量输出（例如交叉熵损失）。我们要看它随参数如何变化。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;$\mathbf{b}$&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;偏置向量 (Bias)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;当前层的偏置项，神经网络需要学习的参数之一。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;$\mathbf{z}$&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;净输入 (Logits/Pre-activation)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;线性组合后的结果，即 $\mathbf{z} = \mathbf{W}\mathbf{x} + \mathbf{b}$。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;$\mathbf{h}$&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;激活值 (Activation/Hidden state)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;$\mathbf{z}$ 经过非线性激活函数后的输出，即 $\mathbf{h} = f(\mathbf{z})$。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;$\mathbf{u}^T$&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;上游传回的梯度 ($\frac{\partial s}{\partial \mathbf{h}}$)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;损失函数对当前层输出的导数，它是从更高层“反向传播”回来的信号。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;$f'(\mathbf{z})$&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;激活函数的导数&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;比如 ReLU 或 Sigmoid 的导数。它决定了哪些神经元处于活跃状态。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;$\mathbf{I}$&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;单位矩阵 (Identity Matrix)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;因为 $\mathbf{z} = \dots + \mathbf{b}$，$\mathbf{z}$ 对 $\mathbf{b}$ 求导的结果是 1（矩阵形式即为单位阵）。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5 id="re-using-computation"&gt;Re-using Computation
&lt;/h5&gt;&lt;p&gt;误差信号（Upstream Gradient）$\boldsymbol{\delta}$：
&lt;/p&gt;
$$
\boldsymbol{\delta} = \frac{\partial s}{\partial \mathbf{h}} \frac{\partial \mathbf{h}}{\partial \mathbf{z}} = \mathbf{u}^T \circ f'(\mathbf{z})
$$&lt;p&gt;
我们先算出这个值$\boldsymbol{\delta}$ ，可以简化计算：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;对权重矩阵 $W$ 的梯度展开：
&lt;/p&gt;
$$
 \frac{\partial s}{\partial \mathbf{W}} = \boldsymbol{\delta} \frac{\partial \mathbf{z}}{\partial \mathbf{W}}
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对偏置向量 $\mathbf{b}$ 的梯度简化：
&lt;/p&gt;
$$
 \frac{\partial s}{\partial \mathbf{b}} = \boldsymbol{\delta} \frac{\partial \mathbf{z}}{\partial \mathbf{b}} = \boldsymbol{\delta}
 $$&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id="shape-convention"&gt;Shape Convention
&lt;/h4&gt;&lt;p&gt;假设权重 $\mathbf{W} \in \mathbb{R}^{n \times m}$，输出是一个标量 $s$（损失）。按纯数学定义，$\frac{\partial s}{\partial \mathbf{W}}$ 应该是一个 $1 \times nm$ 的行向量（Jacobian）。但如果使用这种形式，梯度更新公式 $\theta^{new} = \theta^{old} - \alpha \nabla_{\theta} J(\theta)$ 就会因维度不匹配而无法直接相减。&lt;/p&gt;
&lt;p&gt;为了计算方便，我们约定&lt;strong&gt;梯度的形状必须等于参数的形状&lt;/strong&gt;。因此 $\frac{\partial s}{\partial \mathbf{W}}$ 也是一个 $n \times m$ 的矩阵：
&lt;/p&gt;
$$
\frac{\partial s}{\partial \mathbf{W}} = \begin{bmatrix} \frac{\partial s}{\partial W_{11}} &amp; \dots &amp; \frac{\partial s}{\partial W_{1m}} \\ \vdots &amp; \ddots &amp; \vdots \\ \frac{\partial s}{\partial W_{n1}} &amp; \dots &amp; \frac{\partial s}{\partial W_{nm}} \end{bmatrix}
$$$$
\frac{\partial s}{\partial \mathbf{W}} = \boldsymbol{\delta}^T \mathbf{x}^T
$$&lt;p&gt;那么我们究竟应该以什么样的“形状”来呈现导数结果？&lt;/p&gt;
&lt;p&gt;采取始终遵循**形状约定 (Shape Convention)**的方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;做法&lt;/strong&gt;：不拘泥于严格的 Jacobian 定义，而是时刻盯着变量的维度（Dimensions）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;核心技巧&lt;/strong&gt;：通过观察维度来决定何时需要对某个项进行转置，或者调整矩阵相乘的顺序，以确保每一层算出来的梯度形状和该层的参数形状完全一致。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关于 $\boldsymbol{\delta}$ 的重要结论&lt;/strong&gt;：传导至隐层（Hidden layer）的误差信号 $\boldsymbol{\delta}$，其维度应该与该隐层的神经元数量（即激活值向量的维度）完全相同。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="backpropagation"&gt;Backpropagation
&lt;/h3&gt;&lt;p&gt;按流程逐步计算各函数，从输入得到输出，即是&lt;strong&gt;正向传播(Forward Propagation)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/backpropagation-1.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;对于反向传播中的单个节点，有$downstream\ gradient=upstream\ gradient\times local\ gradient$&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/backpropagation-2.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;对于单节点的多输入，upstream gradient不变，各输入的local gradient不同，但计算公式是不变的&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/backpropagation-3.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;下面举个多输入的实际例子&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/backpropagation-4.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;我们可以在这个基础上，假设输入y的值变为了2.1，那么$a=x+y=3.1$，$b=max(y+z)=y=2.1$，$a\times b=6.51$&lt;/p&gt;
&lt;p&gt;所以，y值变化的0.1导致了结果0.51的变化，那么梯度就是$\frac{\Delta f}{\Delta y}=5.1$&lt;/p&gt;
&lt;h4 id="implementations"&gt;Implementations
&lt;/h4&gt;&lt;p&gt;那么理论上，在已知正向传播的符号和计算的情况下，计算机可以自动得出反向传播的结果。但是在现代框架中，用户需手动设计局部导数的结算，这也比全自动方式提升了系统的运行效率和稳定性。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MultiplyGate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="c1"&gt;# must keep these around!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dz&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dz&lt;/span&gt; &lt;span class="c1"&gt;# [dz/dx * dL/dz]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dz&lt;/span&gt; &lt;span class="c1"&gt;# [dz/dy * dL/dz]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h5 id="numeric-gradient-checking"&gt;Numeric Gradient Checking
&lt;/h5&gt;&lt;p&gt;在手动推导和实现反向传播（Backprop）时，这是确保你数学公式没推错、代码没写错的标准验证方法：
&lt;/p&gt;
$$
f'(x) \approx \frac{f(x + h) - f(x - h)}{2h}
$$&lt;ul&gt;
&lt;li&gt;只需要前向传播函数 $f(x)$ 即可计算，不需要任何复杂的数学推导，不容易写错。&lt;/li&gt;
&lt;li&gt;必须对模型的&lt;strong&gt;每一个参数&lt;/strong&gt;分别进行两次前向传播（加 $h$ 和减 $h$），效率很低。&lt;/li&gt;
&lt;li&gt;适合局部测试，不要对整个大型网络做验证，只针对某个特定层或小规模参数（如一个 $3 \times 3$ 的矩阵）进行。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="dependency-parsing"&gt;Dependency Parsing
&lt;/h2&gt;&lt;h3 id="syntactic-structure"&gt;Syntactic Structure
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phrase structure&lt;/strong&gt; organizes words into nested constituents.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们可以自己定义phrase构成的语法，比如名词短语可以是“&lt;em&gt;限定词 + 形容词 + 名词&lt;/em&gt;”，“&lt;em&gt;限定词 + 名词 + 介词短语&lt;/em&gt;”……介词短语可以是“&lt;em&gt;介词 + 名词&lt;/em&gt;……”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dependency structure&lt;/strong&gt; shows which words depend on (modify, attach to, or are arguments of) which other words&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;语言中很容易出现歧义(ambiguity)，在英语里有了介词短语，歧义就更多了，举个例子：&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Scientists count whales from space&amp;quot;可以理解为&amp;quot;Scientists [count] [whales from space]&amp;rdquo; 或者 &amp;ldquo;Scientists [count whales] [from space]&amp;rdquo; ……&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/dependency-1.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;h3 id="dependency-grammar-and-treebanks"&gt;Dependency Grammar and Treebanks
&lt;/h3&gt;&lt;p&gt;Dependency syntax postulates that syntactic structure consists of relations between
lexical items, normally binary asymmetric relations (“arrows”) called dependencies&lt;/p&gt;
&lt;p&gt;下图是个比较古老的&amp;quot;dependency structure&amp;quot;&lt;/p&gt;
&lt;p&gt;An arrow connects a head (governor, superior, regent) with a dependent (modifier, inferior, subordinate)&lt;/p&gt;
&lt;p&gt;Usually, dependencies form a tree (a connected, acyclic, single-root graph)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/dependency-2.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;h4 id="annotated-data"&gt;Annotated Data
&lt;/h4&gt;&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/dependency-3.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;起初，构建语言库（Treebank）似乎比手动编写语法规则要慢得多，且看起来没那么有用。手动标注数据确实是件麻烦的工作，但现在看来，却有很大的优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;复用性(Reusability)：一套标注好的数据可以用来训练多种解析器（Parsers）、词性标注器（POS Taggers）&lt;/li&gt;
&lt;li&gt;覆盖面广(Board coverage)：手动编写规则往往只能覆盖几个直觉上的例子，而标注真实语料可以涵盖语言在现实中的各种复杂用法。&lt;/li&gt;
&lt;li&gt;频率与分布信息(Frequencies and distributional information)：它能告诉机器哪些结构更常见，帮助概率模型做出更准确的判断。&lt;/li&gt;
&lt;li&gt;评估NLP(A way to evaluate NLP systems)：没有这套“标准”，我们就无法衡量一个 AI 模型的准确率（如 LAS/UAS 得分）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么关于示例图中的各依存关系的意思，如下：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;缩写&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;意思&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;简单理解&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;nsubj&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;名词主语&lt;/td&gt;
					&lt;td&gt;动作的发出者（如 &lt;strong&gt;I&lt;/strong&gt; think）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;nsubjpass&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;被动主语&lt;/td&gt;
					&lt;td&gt;被动语态里的主语（如 &lt;strong&gt;city&lt;/strong&gt; called）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ccomp&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;从句&lt;/td&gt;
					&lt;td&gt;动词后面的整个小句子（如 think &lt;strong&gt;&amp;hellip;&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;advmod&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;状语修饰&lt;/td&gt;
					&lt;td&gt;修饰动词的程度、疑问等（如 &lt;strong&gt;Why&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;amod&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;形容词修饰&lt;/td&gt;
					&lt;td&gt;修饰名词的形容词（如 &lt;strong&gt;famous&lt;/strong&gt; goat）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;compound&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;复合修饰&lt;/td&gt;
					&lt;td&gt;名词修饰名词（如 &lt;strong&gt;goat&lt;/strong&gt; trainer）&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;det&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;限定关系&lt;/td&gt;
					&lt;td&gt;指向 a, the, any 等词&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;case&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;介词关系&lt;/td&gt;
					&lt;td&gt;指向 in, at 等介词&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;conj&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;并列关系&lt;/td&gt;
					&lt;td&gt;用 or, and 连接的词（如 trainer or &lt;strong&gt;something&lt;/strong&gt;）&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id="dependency-conditioning-preferences"&gt;Dependency Conditioning Preferences
&lt;/h4&gt;&lt;p&gt;在进行句法分析时，计算机会根据“依存条件偏好（Dependency Conditioning Preferences）”来判断两个词之间是否存在依存关系：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;双词亲和力 (Bilexical affinities)：依存关系（例如 [discussion → issues]）是合理的。&lt;/li&gt;
&lt;li&gt;依存距离 (Dependency distance)：大多数（但并非所有）依存关系发生在邻近的单词之间。&lt;/li&gt;
&lt;li&gt;介入材料 (Intervening material)：依存关系很少跨越中间的动词或标点符号。&lt;/li&gt;
&lt;li&gt;中心词的价态 (Valency of heads)：对于一个中心词（Head）来说，通常在它的哪一侧会有多少个依存词？&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="projectivity"&gt;Projectivity
&lt;/h4&gt;&lt;p&gt;如果一个句子的单词按线性顺序排列，且所有的依存弧（dependency arcs）都画在单词上方时，&lt;strong&gt;没有任何两条弧线发生交叉&lt;/strong&gt;，那么这个解析就是“投影的”。那么互出现了交叉，就是非投影的(non-projectivity)，说明发生了“长距离位移”或结构重叠。&lt;/p&gt;
&lt;p&gt;但是现实中非投影的例子很常见，比如&amp;quot;&lt;em&gt;Who did Bill buy the coffee from yesterday&lt;/em&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/dependency-4.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;h3 id="transition-based-dependency-parser"&gt;Transition-Based Dependency Parser
&lt;/h3&gt;&lt;p&gt;首先，这Transition-Based Dependency Parser分有一个Stack和一个Buffer，和三种操作：&lt;/p&gt;
&lt;p&gt;Start: $\sigma = [ROOT], \beta = w_1, ..., w_n, A = \emptyset$&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Shift: $\sigma, w_i | \beta, A \Rightarrow \sigma | w_i, \beta, A $&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Left-$Arc_r$: $\sigma | w_i | w_j, \beta, A \Rightarrow \sigma | w_j, \beta, A \cup \{r(w_j, w_i)\} $&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Right-$Arc_r$: $\sigma | w_i | w_j, \beta, A \Rightarrow \sigma | w_j, \beta, A \cup \{r(w_i, w_j)\}$&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finish: $\sigma = [w], \beta = \emptyset$&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;σ&lt;/strong&gt;（sigma）表示 &lt;strong&gt;堆栈（stack）&lt;/strong&gt;，存储当前正在处理或等待建立关系的词。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;β&lt;/strong&gt;（beta）表示 &lt;strong&gt;缓冲区（buffer）&lt;/strong&gt;，存储尚未处理的输入词序列。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;A&lt;/strong&gt; 表示 &lt;strong&gt;依存弧集合（set of dependency arcs）&lt;/strong&gt;，存储已建立的依存关系。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Left-$Arc_r$ 和 Right-$Arc_r$ 是两种规约模型，用来表明一个词是另一个的依存词，以左或右方向。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么下面先来举个例子：Analysis of &amp;ldquo;&lt;em&gt;I ate fish&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/dependency-5.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Left Arc&lt;/strong&gt;操作 生成了一个由栈顶指向第二个元素的弧，建立了&amp;quot;&lt;code&gt;ate&lt;/code&gt;&amp;ldquo;是中心词，&amp;ldquo;I&amp;quot;依存于&amp;rdquo;&lt;code&gt;ate&lt;/code&gt;&amp;ldquo;的关系。然后将&amp;rdquo;&lt;code&gt;I&lt;/code&gt;&amp;ldquo;移出栈。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shift&lt;/strong&gt;操作 将&amp;rdquo;&lt;code&gt;fish&lt;/code&gt;&amp;ldquo;从缓冲区移入栈中&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Right Arc&lt;/strong&gt;操作 生成了一个由第二个元素指向栈顶元素的弧，建立了&amp;rdquo;&lt;code&gt;ate&lt;/code&gt;&amp;ldquo;是中心词,&amp;quot;&lt;code&gt;fish&lt;/code&gt;&amp;ldquo;依存于&amp;rdquo;&lt;code&gt;ate&lt;/code&gt;&amp;ldquo;的关系。然后将&amp;rdquo;&lt;code&gt;fish&lt;/code&gt;&amp;ldquo;移出栈。&lt;/li&gt;
&lt;li&gt;最后的&lt;strong&gt;Right Arc&lt;/strong&gt;操作 使&amp;rdquo;&lt;code&gt;[root]&lt;/code&gt;&amp;ldquo;指向&amp;rdquo;&lt;code&gt;ate&lt;/code&gt;&amp;quot;，并在&amp;rdquo;&lt;code&gt;ate&lt;/code&gt;&amp;ldquo;出栈后，只剩下根节点，操作完成。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="evaluation-of-dependency-parsing"&gt;Evaluation of Dependency Parsing
&lt;/h4&gt;&lt;p&gt;评价依存分析的指标分为&lt;strong&gt;UAS&lt;/strong&gt;（无标签附件分数）和 &lt;strong&gt;LAS&lt;/strong&gt;（有标签附件分数），下面是一个具体的例子: &amp;ldquo;&lt;em&gt;[ROOT] She saw the video lecture.&lt;/em&gt;&amp;quot;，表中&amp;quot;Gold&amp;quot;是标准答案，&amp;ldquo;Parsed&amp;quot;是分析出的答案：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/dependency-6.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可见，UAS计算的是&lt;code&gt;Head&lt;/code&gt;寻找得是否正确，本例中第三个&amp;quot;the&amp;quot;的依存词和标准不符。&lt;/li&gt;
&lt;li&gt;LAS计算的它们之间的关系类型是否标注正确，即&lt;code&gt;Head&lt;/code&gt;和关系标签(&lt;code&gt;label&lt;/code&gt;)都要一致，本例中只有&amp;quot;She&amp;quot;和&amp;quot;saw&amp;quot;是与标准相符的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="neural-dependency-parsing"&gt;Neural dependency parsing
&lt;/h3&gt;&lt;p&gt;More than 95% of parsing time is consumed by feature computation&lt;/p&gt;
&lt;p&gt;所以，我们可以用神经网络来加速特征提取，当然其方法还是基于上面的基于转移（Transition-based）的神经依存句法分析器。具体使用了了向量化、非线性等深度学习知识搭建出了第一个基于神经网络的依存分析器(2014年)。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/dependency-7.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;h2 id="recurrent-neural-networks"&gt;Recurrent Neural Networks
&lt;/h2&gt;&lt;h3 id="language-modeling"&gt;Language Modeling
&lt;/h3&gt;&lt;p&gt;语言模型(Language Modeling) 简单地讲就是输入文本（词），输出概率。
&lt;/p&gt;
$$
\begin{aligned}
P(\boldsymbol{x}^{(1)}, \dots, \boldsymbol{x}^{(T)}) &amp;= P(\boldsymbol{x}^{(1)}) \times P(\boldsymbol{x}^{(2)} | \boldsymbol{x}^{(1)}) \times \dots \times P(\boldsymbol{x}^{(T)} | \boldsymbol{x}^{(T-1)}, \dots, \boldsymbol{x}^{(1)}) \\
&amp;= \prod_{t=1}^{T} \underbrace{P(\boldsymbol{x}^{(t)} | \boldsymbol{x}^{(t-1)}, \dots, \boldsymbol{x}^{(1)})}_{\text{This is what our LM provides}}
\end{aligned}
$$&lt;p&gt;
$P(\boldsymbol{x}^{(1)}, \dots, \boldsymbol{x}^{(T)})$ 表示一整个序列（如一句话）出现的概率，通过将联合概率&lt;strong&gt;分解为一系列条件概率的乘积&lt;/strong&gt;（链式法则），我们可以计算序列的概率。语言模型的核心任务就是根据之前的上下文 $\boldsymbol{x}^{(t-1)}, \dots, \boldsymbol{x}^{(1)}$ 来&lt;strong&gt;预测&lt;/strong&gt;下一个 token $\boldsymbol{x}^{(t)}$ 出现的概率。&lt;/p&gt;
&lt;h3 id="n-gram-language-models"&gt;n-gram Language Models
&lt;/h3&gt;&lt;p&gt;An n-gram is a chunk of n consecutive words. n表示由几个词构成一个单位，即n-gram。为实现n-gram Language Models，步骤如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;首先，做一个&lt;strong&gt;马尔可夫假设&lt;/strong&gt;：第 $t+1$ 个词 $x^{(t+1)}$ 仅取决于其前面的 $n-1$ 个词。
&lt;/p&gt;
$$
 P(x^{(t+1)} | x^{(t)}, \dots, x^{(1)}) = P(x^{(t+1)} | \underbrace{x^{(t)}, \dots, x^{(t-n+2)}}_{n-1 \text{ words}}) \quad \text{(assumption)}
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;利用条件概率的定义，上述公式可以写为 $n$-gram 与 $(n-1)$-gram 概率的比值：
&lt;/p&gt;
$$
 = \frac{P(x^{(t+1)}, x^{(t)}, \dots, x^{(t-n+2)}) \leftarrow \text{prob of a n-gram}}{P(x^{(t)}, \dots, x^{(t-n+2)}) \leftarrow \text{prob of a (n-1)-gram}} \quad \text{(definition of conditional prob)}
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通过在大型文本语料库中&lt;strong&gt;计数 (Counting)&lt;/strong&gt; 它们来统计词组出现的频率，来近似概率：
&lt;/p&gt;
$$
 \approx \frac{\text{count}(x^{(t+1)}, x^{(t)}, \dots, x^{(t-n+2)})}{\text{count}(x^{(t)}, \dots, x^{(t-n+2)})} \quad \text{(statistical approximation)}
 $$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;举个例子，假设我们有一个4-gram Language Model，要预测最后一个空可能出现的单词：&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;as the proctor started the clock, the students opened their &amp;hellip;&amp;hellip;&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;我们只取最后的三个词组成的短语&amp;rdquo;&lt;em&gt;students opened their&lt;/em&gt;&amp;rdquo;
&lt;/p&gt;
$$
P(w\mid students\ opened\ their)=\frac{count(students\ opened\ their\ w)}{count(students\ opened\ their)}
$$&lt;p&gt;
根据语料库，&amp;quot;&lt;em&gt;students opened their books&lt;/em&gt;&amp;ldquo;可能是出现频率最高的，而更符合语境的&amp;rdquo;&lt;em&gt;&amp;hellip;&amp;hellip;exams&lt;/em&gt;&amp;ldquo;出现频率更低&lt;/p&gt;
&lt;h4 id="problems-with-n-gram-language-models"&gt;Problems with n-gram Language Models
&lt;/h4&gt;&lt;p&gt;当使用计数法计算概率，会面临&lt;strong&gt;稀疏性问题&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;如果词组 &amp;ldquo;students opened their $w$&amp;rdquo; 在训练数据中从未出现过，那么对于任何该词 $w$，其概率都将变为 &lt;strong&gt;0&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;通过为词表中的每个词 $w \in V$ 的计数增加一个极小的数值 $\delta$ (平滑化 Smoothing)解决&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;如果前缀 &amp;ldquo;students opened their&amp;rdquo; 在训练数据中从未出现过，我们将无法计算任何 $w$ 的概率，因为分母为 0。&lt;/p&gt;
&lt;p&gt;不再考虑完整的前缀，而是退而求其次，仅根据更短的上下文（例如 &amp;ldquo;opened their&amp;rdquo;）进行条件概率计算。(回退 Backoff)&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;同时也会面临&lt;strong&gt;存储&lt;/strong&gt;的问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;需要存放语料库中所有n-gram的计数&lt;/li&gt;
&lt;li&gt;若是n需要增加，语料库的size也要大幅增加&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="a-fixed-window-neural-language-model"&gt;A fixed-window neural Language Model
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/RNN-1.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;输入层 (Words / One-hot vectors)&lt;/strong&gt;: 输入为单词的 one-hot 向量 $\boldsymbol{x}^{(1)}, \boldsymbol{x}^{(2)}, \boldsymbol{x}^{(3)}, \boldsymbol{x}^{(4)}$。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;嵌入层 (Concatenated word embeddings)&lt;/strong&gt;: 将单词转换为稠密的向量表示（embeddings），并进行拼接：
&lt;/p&gt;
$$
 \boldsymbol{e} = [\boldsymbol{e}^{(1)}; \boldsymbol{e}^{(2)}; \boldsymbol{e}^{(3)}; \boldsymbol{e}^{(4)}]
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;隐藏层 (Hidden layer)&lt;/strong&gt;: 通过权重矩阵 $W$ 和偏置 $b_1$ 进行线性变换，并经过激活函数 $f$（通常为 tanh 或 ReLU）：
&lt;/p&gt;
$$
 \boldsymbol{h} = f(W\boldsymbol{e} + \boldsymbol{b}_1)
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;输出层 (Output distribution)&lt;/strong&gt;: 经过权重矩阵 $U$ 和偏置 $b_2$，最后通过 &lt;strong&gt;softmax&lt;/strong&gt; 函数生成词典 $V$ 上的概率分布 $\hat{\boldsymbol{y}}$：
&lt;/p&gt;
$$
 \hat{\boldsymbol{y}} = \text{softmax}(U\boldsymbol{h} + \boldsymbol{b}_2) \in \mathbb{R}^{|V|}
 $$&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;那么相对于n-gram方法，改进了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解决稀疏性问题&lt;/strong&gt;：不再依赖精确的计数，通过向量空间的相似性来泛化未见过的词组。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;存储优化&lt;/strong&gt;：不需要存储所有观察到的 $n$-gram 频率，只需存储模型参数。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是仍有问题没能解决：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;固定窗口限制&lt;/strong&gt;：
&lt;ul&gt;
&lt;li&gt;固定的上下文窗口通常太小。&lt;/li&gt;
&lt;li&gt;扩大窗口会线性导致权重矩阵 $W$ 的参数量激增。&lt;/li&gt;
&lt;li&gt;无论窗口多大，它永远无法捕捉超出该范围的长程依赖。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;缺乏对称性&lt;/strong&gt;：输入 $\boldsymbol{x}^{(1)}$ 和 $\boldsymbol{x}^{(2)}$ 与矩阵 $W$ 中完全不同的权重相乘，模型处理每个位置输入的方式没有一致性。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rnn-language-model"&gt;RNN Language Model
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://karpathy.github.io/2015/05/21/rnn-effectiveness/" target="_blank" rel="noopener"
 &gt;The Unreasonable Effectiveness of Recurrent Neural Networks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/RNN-2.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;RNN 的优点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以处理&lt;strong&gt;任意长度&lt;/strong&gt;的输入。&lt;/li&gt;
&lt;li&gt;理论上，第 $t$ 步的计算可以使用&lt;strong&gt;很多步之前&lt;/strong&gt;的信息。&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;/ul&gt;
&lt;p&gt;&lt;strong&gt;RNN 的缺点&lt;/strong&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;实践难题&lt;/strong&gt;：在实际应用中，很难获取到&lt;strong&gt;很多步之前&lt;/strong&gt;的信息（梯度消失/爆炸问题）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="train-an-rnn-language-modle"&gt;Train an RNN Language Modle
&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;获取一个大型文本语料库，它是由单词序列组成的：$\boldsymbol{x}^{(1)}, \dots, \boldsymbol{x}^{(T)}$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将序列输入 RNN-LM，并为&lt;strong&gt;每一个时间步 $t$&lt;/strong&gt; 计算输出分布 $\hat{\boldsymbol{y}}^{(t)}$。这意味着模型在给定目前为止已见单词的情况下，预测&lt;strong&gt;每一个位置&lt;/strong&gt;上可能出现的单词概率分布。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;模型在每一个步长 $t$ 都会产生一个损失，第 $t$ 步的损失函数是预测概率分布 $\hat{\boldsymbol{y}}^{(t)}$ 与&lt;strong&gt;真实的下一个单词&lt;/strong&gt; $\boldsymbol{y}^{(t)}$（即 $\boldsymbol{x}^{(t+1)}$ 的 one-hot 向量）之间的&lt;strong&gt;交叉熵&lt;/strong&gt;
&lt;/p&gt;
$$
 J^{(t)}(\theta) = CE(\boldsymbol{y}^{(t)}, \hat{\boldsymbol{y}}^{(t)}) = - \sum_{w \in V} \boldsymbol{y}^{(t)}_w \log \hat{\boldsymbol{y}}^{(t)}_w = - \log \hat{\boldsymbol{y}}^{(t)}_{\boldsymbol{x}_{t+1}}
 $$&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;为了获得整个训练集的损失，需要将所有步骤的损失取平均值：
&lt;/p&gt;
$$
 J(\theta) = \frac{1}{T} \sum_{t=1}^{T} J^{(t)}(\theta) = \frac{1}{T} \sum_{t=1}^{T} - \log \hat{\boldsymbol{y}}^{(t)}_{\boldsymbol{x}_{t+1}}
 $$&lt;p&gt;
计算损失应用了&lt;strong&gt;Teacher Forcing&lt;/strong&gt;的概念，即并不使用模型在上一步&lt;strong&gt;实际预测&lt;/strong&gt;出的单词作为下一步的输入，而是直接将语料库中的&lt;strong&gt;真实正确答案&lt;/strong&gt;喂给模型。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一次性计算整个语料库 $\boldsymbol{x}^{(1)}, \dots, \boldsymbol{x}^{(T)}$ 的损失（Loss）和梯度（Gradients）在内存方面是&lt;strong&gt;极其昂贵的&lt;/strong&gt;，所以在实际操作中，我们将序列 $\boldsymbol{x}^{(1)}, \dots, \boldsymbol{x}^{(T)}$ 看作是一个个&lt;strong&gt;句子&lt;/strong&gt;或&lt;strong&gt;文档&lt;/strong&gt;，使用随机梯度下降来对一**小块数据 **计算损失和梯度，并立即进行参数更新&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="backpropagation-for-rnn"&gt;Backpropagation for RNN
&lt;/h4&gt;&lt;p&gt;RNN参数的训练，采用&lt;strong&gt;随时间&lt;/strong&gt;的反向传播，沿着时间步 $i = t, \dots, 0$ 反向传播，并在过程中累加梯度。&lt;/p&gt;
&lt;p&gt;由于 $\boldsymbol{W}_h$ 在每一个时间步都是共享的（相同的权重），因此总梯度是每一个时间步产生的梯度之和。
&lt;/p&gt;
$$
\frac{\partial J^{(t)}}{\partial \boldsymbol{W}_h} = \sum_{i=1}^{t} \left. \frac{\partial J^{(t)}}{\partial \boldsymbol{W}_h} \right|_{(i)} \frac{\partial \boldsymbol{W}_h|_{(i)}}{\partial \boldsymbol{W}_h} = \sum_{i=1}^{t} \left. \frac{\partial J^{(t)}}{\partial \boldsymbol{W}_h} \right|_{(i)}
$$&lt;p&gt;
随着序列增长，完整的反向传播计算量极大，且容易出现梯度消失或爆炸问题。在实际应用中，为了提高训练效率，通常会在约 &lt;strong&gt;20 个时间步&lt;/strong&gt;后进行“截断”。&lt;/p&gt;
&lt;h4 id="exploding-gradient"&gt;Exploding Gradient
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;梯度爆炸&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果 $W_h$ 的特征值（大致可以理解为权重的大小）大于 1。&lt;/li&gt;
&lt;li&gt;随着时间步 $T$ 的增加，梯度会呈&lt;strong&gt;指数级增长&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;模型权重会更新得过大，导致网络变得极不稳定，参数值可能会溢出（变成 NaN），训练崩溃。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果在更新模型参数前，梯度的&lt;strong&gt;范数 (norm)&lt;/strong&gt; 超过了预设的某个&lt;strong&gt;阈值&lt;/strong&gt;，则按比例将其缩小，如果 $\|\hat{\boldsymbol{g}}\| \ge threshold$ ，则进行&lt;strong&gt;梯度裁剪&lt;/strong&gt;，梯度裁剪&lt;strong&gt;让模型更新时保持在&lt;/strong&gt;相同的方向&lt;strong&gt;上，但只迈出&lt;/strong&gt;更小的一步：
&lt;/p&gt;
$$
\hat{\boldsymbol{g}} \leftarrow \frac{threshold}{\|\hat{\boldsymbol{g}}\|} \hat{\boldsymbol{g}}
$$&lt;h4 id="vanishing-gradient"&gt;Vanishing Gradient
&lt;/h4&gt;&lt;p&gt;&lt;strong&gt;梯度消失&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果 $W_h$ 的特征值小于 1，或者激活函数（如图中提到的 $f$ 或 tanh）的导数小于 1。&lt;/li&gt;
&lt;li&gt;梯度会随着反向传播的步数增加而&lt;strong&gt;指数级减小&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;这对应了提到的 RNN 缺点：&lt;strong&gt;“在实践中，很难获取到很多步之前的信息”&lt;/strong&gt;。当梯度变得极其微小时，远距离的权重更新几乎停滞，模型“忘记”了长期的上下文。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于 vanilla RNN（基础 RNN）来说，学习如何跨越多个时间步长来&lt;strong&gt;保留信息&lt;/strong&gt;实在是太困难了，因为隐藏状态 $\boldsymbol{h}^{(t)}$ 会被不断地&lt;strong&gt;重写&lt;/strong&gt;：
&lt;/p&gt;
$$
\boldsymbol{h}^{(t)} = \sigma(\boldsymbol{W}_h \boldsymbol{h}^{(t-1)} + \boldsymbol{W}_x \boldsymbol{x}^{(t)} + \boldsymbol{b})
$$&lt;p&gt;
所以，我们引入独立记忆 ，如LSTM。或者建立直接连接，如Attention机制。&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="long-short-term-memory"&gt;&lt;strong&gt;Long&lt;/strong&gt; &lt;strong&gt;Short-Term&lt;/strong&gt; Memory
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://colah.github.io/posts/2015-08-Understanding-LSTMs/" target="_blank" rel="noopener"
 &gt;Understanding LSTM Networks &amp;ndash; colah&amp;rsquo;s blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;遗忘门 (Forget gate)&lt;/strong&gt;：控制从上一个细胞状态中保留什么以及忘记什么。
&lt;/p&gt;
$$
\boldsymbol{f}^{(t)} = \sigma (\boldsymbol{W}_f \boldsymbol{h}^{(t-1)} + \boldsymbol{U}_f \boldsymbol{x}^{(t)} + \boldsymbol{b}_f)
$$&lt;p&gt;
&lt;strong&gt;输入门 (Input gate)&lt;/strong&gt;：控制新细胞内容的哪些部分被写入到细胞中。
&lt;/p&gt;
$$
\boldsymbol{i}^{(t)} = \sigma (\boldsymbol{W}_i \boldsymbol{h}^{(t-1)} + \boldsymbol{U}_i \boldsymbol{x}^{(t)} + \boldsymbol{b}_i)
$$&lt;p&gt;
&lt;strong&gt;输出门 (Output gate)&lt;/strong&gt;：控制细胞的哪些部分被输出到隐藏状态中。
&lt;/p&gt;
$$
\boldsymbol{o}^{(t)} = \sigma (\boldsymbol{W}_o \boldsymbol{h}^{(t-1)} + \boldsymbol{U}_o \boldsymbol{x}^{(t)} + \boldsymbol{b}_o)
$$&lt;p&gt;
&lt;strong&gt;New cell content&lt;/strong&gt;：这是要被写入细胞的新内容（即我们在之前讨论中提到的“候选内容”）。
&lt;/p&gt;
$$
\tilde{\boldsymbol{c}}^{(t)} = \tanh (\boldsymbol{W}_c \boldsymbol{h}^{(t-1)} + \boldsymbol{U}_c \boldsymbol{x}^{(t)} + \boldsymbol{b}_c)
$$&lt;p&gt;
&lt;strong&gt;Cell state&lt;/strong&gt;：擦除（“忘记”）上一个细胞状态中的某些内容，并写入（“输入”）一些新的细胞内容。
&lt;/p&gt;
$$
\boldsymbol{c}^{(t)} = \boldsymbol{f}^{(t)} \odot \boldsymbol{c}^{(t-1)} + \boldsymbol{i}^{(t)} \odot \tilde{\boldsymbol{c}}^{(t)}
$$&lt;p&gt;
&lt;strong&gt;隐藏状态 (Hidden state)&lt;/strong&gt;：从细胞中读取（“输出”）某些内容。
&lt;/p&gt;
$$
\boldsymbol{h}^{(t)} = \boldsymbol{o}^{(t)} \odot \tanh \boldsymbol{c}^{(t)}
$$&lt;h4 id="step-by-step-lstm-walk-through"&gt;Step-by-Step LSTM Walk Through
&lt;/h4&gt;&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/LSTM3-chain.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在上图中，每条线都承载着一个完整的向量，从一个节点的输出指向其他节点的输入。粉色圆圈代表逐点运算，例如向量加法，而黄色方框代表已学习的神经网络层。合并的线条表示连接，而分叉的线条表示其内容被复制，并将副本发送到不同的位置。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/LSTM3-C-line.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;LSTM 的关键在于单元状态，也就是图中贯穿顶部的水平线。&lt;/p&gt;
&lt;p&gt;单元状态就像一条传送带，它沿着整个链条直线传递，只有一些微小的线性交互。信息很容易原封不动地沿着传送带流动。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;LSTM 能够对单元状态进行信息添加或移除，这种操作由称为“门”的结构进行精细调控。&lt;/p&gt;
&lt;p&gt;门是一种选择性地允许信息通过的方式。它们由一个 sigmoid 神经网络层和一个逐点乘法运算组成。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/LSTM3-focus-f.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LSTM 的第一步是决定我们要从细胞状态中丢弃什么信息 。这个决定由一个称为“遗忘门层”的 sigmoid 层来做出 。它接收 $h_{t-1}$ 和 $x_t$，并为细胞状态 $C_{t-1}$ 中的每个数字输出一个介于 0 和 1 之间的数值；1 代表“完全保留”，而 0 代表“彻底丢弃” 。&lt;/li&gt;
&lt;li&gt;让我们回到之前那个尝试根据前面所有单词预测下一个单词的语言模型例子 。在这样一个问题中，细胞状态可能包含了当前主语的性别信息，以便模型能使用正确的代词 。当我们看到一个新的主语时，我们会希望忘记旧主语的性别 。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/LSTM3-focus-i.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下一步是决定我们要将什么新信息存储在细胞状态中 。这包含两个部分。首先，一个称为“输入门层”的 sigmoid 层决定了我们将更新哪些值；接着，一个 $\tanh$ 层创建了一个包含新候选值的向量 $\tilde{C}_t$，这些值可以被添加到状态中。在下一步里，我们将结合这两个部分来对状态进行更新 。&lt;/li&gt;
&lt;li&gt;在我们的语言模型例子中，我们会希望将新主语的性别添加到细胞状态中，以替换我们正在遗忘的旧性别信息 。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/LSTM3-focus-C.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;现在是时候将旧的细胞状态 $C_{t-1}$ 更新为新的细胞状态 $C_t$ 了。前面的步骤已经决定了要做什么，我们只需要去实际执行它 。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们将旧状态乘以 $f_t$，以此来忘掉我们之前决定要忘记的信息 。然后我们加上 $i_t * \tilde{C}_t$。这就是新的候选值，根据我们决定更新每个状态值的程度进行了缩放 。&lt;/p&gt;
&lt;p&gt;在语言模型的例子中，正是在这里，我们实际丢弃了关于旧主语性别的信息，并添加了新信息，就像我们在前面步骤中决定的那样 。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/cs224n/LSTM3-focus-o.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;最后，我们需要决定我们要输出什么 。这个输出将基于我们的细胞状态，但会是一个经过过滤的版本 。&lt;/p&gt;
&lt;p&gt;首先，我们运行一个 sigmoid 层，它决定了我们要输出细胞状态的哪些部分 。然后，我们将细胞状态通过 $\tanh$（将值推到 -1 和 1 之间）并将其乘以 sigmoid 门的输出，这样我们就只输出了我们决定输出的部分 。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以语言模型为例，由于它刚刚处理了一个主语，接下来可能会倾向于输出与谓语动词相关的信息，以预判后续内容。例如，模型可能会输出该主语是单数还是复数，这样如果接下来出现动词，我们就能知道该以何种形式进行词形变化。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="how-does-lstm-solve-vanishing-gradients"&gt;How does LSTM solve vanishing gradients
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;LSTM 架构使得 RNN 更容易在多个时间步长内保留信息。例如，如果某个单元维度的遗忘门设置为 1，输入门设置为 0，那么该单元的信息将被无限期地保留。&lt;/p&gt;
&lt;p&gt;相比之下，普通的 RNN 更难学习一个循环权重矩阵 $W_h$，以保留隐藏状态中的信息。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;尽管梯度消失/爆炸现象无法避免，但对于长距离依赖关系，模型还可以创建更直接、更线性的直通连接。比如ResNet, DenseNet&amp;hellip;&amp;hellip;都在模块之间、层之间不同程度地创建了直接连接。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="bidirectional-rnns"&gt;Bidirectional RNNs
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;传统的单向 RNN 或 LSTM 存在一个明显的局限：在处理序列时，它只能“向左看”（即只利用过去的历史上下文）。然而，在许多 NLP 任务（如情感分类、命名实体识别或句子整体理解）中，当前词的准确含义往往也依赖于“右侧”（未来）的上下文。&lt;/li&gt;
&lt;li&gt;为了解决这个问题，研究者引入了双向架构（通常使用 LSTM 实现，即 BiLSTM）：
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;前向 (Forward) RNN&lt;/strong&gt;：按照从左到右的顺序处理输入序列，计算出一系列隐藏状态 $\overrightarrow{h}_t$。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;后向 (Backward) RNN&lt;/strong&gt;：按照从右到左的逆序处理同一个输入序列，计算出一系列隐藏状态 $\overleftarrow{h}_t$。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;拼接状态 (Concatenated State)&lt;/strong&gt;：在每一个时间步 $t$，将前向和后向的隐藏状态拼接在一起，形成该位置的最终表示 $h_t = [\overrightarrow{h}_t; \overleftarrow{h}_t]$。这样，每个词的特征表示就同时包含了整个句子的左侧和右侧完整信息。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;双向 LSTM 的特征提取能力非常强大，但它&lt;strong&gt;仅适用于能够一次性获取完整输入序列的任务&lt;/strong&gt;（例如对整段文本进行分类，或翻译时的源句子编码）。它&lt;strong&gt;不能&lt;/strong&gt;用于传统的语言模型（Language Modeling），因为语言模型的本质任务是“预测下一个词”，如果允许模型看到右侧的“未来”信息，就违背了自回归预测的初衷。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="neural-machine-translation"&gt;Neural Machine Translation
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;神经机器翻译是 NLP 深度学习领域的第一个巨大成功。NMT 主要是基于 &lt;strong&gt;Sequence-to-Sequence (Seq2Seq)&lt;/strong&gt; 架构，该架构的核心正是由两个 RNN（通常是 LSTM）组成的：&lt;strong&gt;编码器 (Encoder)&lt;/strong&gt; 和 &lt;strong&gt;解码器 (Decoder)&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;Encoder负责读取源语言句子，但在读取过程中它不产生实际的翻译输出，而是不断更新其隐藏状态。当 Encoder 处理完源句子的最后一个词后，其&lt;strong&gt;最终的隐藏状态&lt;/strong&gt;（Final Hidden State）被视作整个句子的语义浓缩。它充当了一个“信息瓶颈”，因为整个源句子的所有复杂含义都必须被压缩进这一个固定维度的向量中。&lt;/li&gt;
&lt;li&gt;Decodere端的 LSTM 本质上是一个&lt;strong&gt;条件语言模型 (Conditional Language Model)&lt;/strong&gt;，初始隐藏状态不再是随机的或全零的，而是被严格赋值为 Encoder 输出的那个“瓶颈”向量。这意味着 Decoder 的所有生成动作都是&lt;strong&gt;以源句子的语义向量为条件&lt;/strong&gt;展开的。
在每一个时间步，它根据当前的隐藏状态输出概率最高的词，并将该词（Feeding in last word）作为下一步的输入继续循环，直到生成句子结束标记 &lt;code&gt;&amp;lt;EOS&amp;gt;&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Pytorch基础</title><link>https://blog.kawausococo.top/p/pytorch%E5%9F%BA%E7%A1%80/</link><pubDate>Thu, 22 Jan 2026 10:49:28 +0800</pubDate><guid>https://blog.kawausococo.top/p/pytorch%E5%9F%BA%E7%A1%80/</guid><description>&lt;p&gt;本篇是对Pytorch基础使用的学习，主要基于B站小土堆的https://www.bilibili.com/video/BV1hE411t7RN/以及Gemini的帮助，除实践外也包含了一些深度学习模型的原理&lt;/p&gt;
&lt;h2 id="dataset"&gt;Dataset
&lt;/h2&gt;&lt;p&gt;An abstract class representing a &lt;code&gt;Dataset&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;All datasets that represent a map from keys to data samples should subclass it. All subclasses should overwrite &lt;code&gt;__getitem__&lt;/code&gt;, supporting fetching a data sample for a given key. Subclasses could also optionally overwrite &lt;code&gt;__len__&lt;/code&gt;, which is expected to return the size of the dataset by many &lt;code&gt;~torch.utils.data.Sampler&lt;/code&gt; implementations and the default options of &lt;code&gt;~torch.utils.data.DataLoader&lt;/code&gt;. Subclasses could also optionally implement &lt;code&gt;__getitems__&lt;/code&gt;, for speedup batched samples loading. This method accepts list of indices of samples of batch and returns list of samples.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;note&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;~torch.utils.data.DataLoader&lt;/code&gt; by default constructs an index sampler that yields integral indices. To make it work with a map-style dataset with non-integral indices/keys, a custom sampler must be provided.&lt;/li&gt;
&lt;/ul&gt;

 &lt;blockquote&gt;
 &lt;p&gt;一个表示数据集的抽象类。&lt;/p&gt;
&lt;p&gt;所有实现从键（keys）到数据样本（data samples）映射的数据集都应该继承这个类。所有子类都必须重写 &lt;code&gt;__getitem__&lt;/code&gt; 方法，以支持根据给定的键获取数据样本。子类也可以选择性地重写 &lt;code&gt;__len__&lt;/code&gt; 方法，许多 &lt;code&gt;~torch.utils.data.Sampler&lt;/code&gt; 实现和 &lt;code&gt;~torch.utils.data.DataLoader&lt;/code&gt; 的默认选项都需要通过这个方法返回数据集的大小。子类还可以选择性地实现 &lt;code&gt;__getitems__&lt;/code&gt; 方法，以加速批量样本的加载。此方法接受批处理样本的索引列表，并返回样本列表。&lt;/p&gt;
&lt;p&gt;注意&lt;/p&gt;
&lt;p&gt;默认情况下，&lt;code&gt;~torch.utils.data.DataLoader&lt;/code&gt; 会构造一个生成整数索引的采样器。要让其与非整数索引/键的映射式数据集一起工作，必须提供自定义的采样器。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="自定义dataset"&gt;自定义Dataset
&lt;/h3&gt;&lt;p&gt;那么在实际的使用中，比如有一个数据集（我们拿之前用过的fer2013来举例）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;先定义一个数据类继承&lt;code&gt;Dataset&lt;/code&gt;，定义&lt;code&gt;__init__()&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;torch.utils.data&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Dataset&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Dataset&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;root_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label_dir&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root_dir&lt;/span&gt; &lt;span class="c1"&gt;# 如 fer2013/test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;label_dir&lt;/span&gt; &lt;span class="c1"&gt;# 如 angry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 路径合并函数 解决跨系统的文件路径问题&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;img_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 如angry文件夹下，所有图片名的string list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重写&lt;code&gt;__getitem()&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__getitem__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;img_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;img_path&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;img_item_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;img_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 拼接出具体的某一个图片的路径&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_item_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label_dir&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="c1"&gt;# 返回数据集中的一个对象（图片）及其类型&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重写&lt;code&gt;__len()__&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__len__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;img_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;定义示例&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;root_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fer2013/train&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;angry_label_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;angry&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;angry_dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;angry_label_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dataset合并&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;disguest_label_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;disguest&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;disgust_dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;disguest_label_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;train_dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;angry_dataset&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;disgust_dataset&lt;/span&gt; &lt;span class="c1"&gt;# &amp;#39;+&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id="tensorboard"&gt;TensorBoard
&lt;/h2&gt;&lt;h3 id="summarywriter"&gt;SummaryWriter
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;创建日志目录&lt;/li&gt;
&lt;li&gt;初始化&lt;code&gt;Writer&lt;/code&gt;对象&lt;/li&gt;
&lt;li&gt;生成事件文件
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;这个文件才是真正的数据库&lt;/strong&gt;(events.out&amp;hellip;&amp;hellip;)当后续调用 &lt;code&gt;writer.add_scalar&lt;/code&gt; 时，数据并不是直接画在屏幕上，而是被追加写进这个文件里。&lt;/li&gt;
&lt;li&gt;当你执行完相应代码，运行 &lt;code&gt;tensorboard --logdir=logs&lt;/code&gt; 时，TensorBoard 的后端服务器就会去读取这个文件里的内容，并在浏览器里渲染成图表。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;torch.utils.tensorboard&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;SummaryWriter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SummaryWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;logs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 这行代码会在你的项目根目录下创建一个名为&amp;#34;logs&amp;#34;的文件夹&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;需注意，每次实验可以用&lt;strong&gt;不同的文件夹来记录数据&lt;/strong&gt;，比如&lt;code&gt;writer = SummaryWriter(&amp;quot;logs/lr0.01_batch32&amp;quot;)&lt;/code&gt;修改了学习率后&lt;code&gt;writer = SummaryWriter(&amp;quot;logs/lr0.001_batch32&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;h4 id="add_scalar"&gt;add_scalar()
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;绘图函数&lt;code&gt;add_scalar()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_scalar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;scalar_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 对应图像的y轴&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;global_step&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# 对应图像的x轴&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;walltime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;new_style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;double_precision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;​```&lt;/span&gt; &lt;span class="n"&gt;例&lt;/span&gt; &lt;span class="err"&gt;```&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_scalar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;y=2x&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="add_image"&gt;add_image()
&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;查看图片函数&lt;code&gt;add_image()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;img_tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;global_step&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;walltime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dataformats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;CHW&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;要注意参数的类型要求：&lt;code&gt;img_tensor (torch.Tensor, numpy.ndarray, or string/blobname): Image data&lt;/code&gt;，所以要将PIL类型的图片进行转换，比如用&lt;code&gt;numpy&lt;/code&gt;来转换。以及数据的shape要求： Tensor with :math:&lt;code&gt;(1, H, W)&lt;/code&gt;, :math:&lt;code&gt;(H, W)&lt;/code&gt;, :math:&lt;code&gt;(H, W, 3)&lt;/code&gt; is also suitable as long as corresponding &lt;code&gt;dataformats&lt;/code&gt; argument is passed, e.g. &lt;code&gt;CHW&lt;/code&gt;, &lt;code&gt;HWC&lt;/code&gt;, &lt;code&gt;HW&lt;/code&gt;. 即三种图片数据的格式，其&lt;strong&gt;通道数、高度、宽度&lt;/strong&gt;的顺序不同。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-py" data-lang="py"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img_array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;图像形状: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;img_array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;test&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;img_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;dataformats&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;HW&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 由.shape可得&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h4 id="add_graph"&gt;add_graph()
&lt;/h4&gt;&lt;hr&gt;
&lt;h2 id="常见的transforms"&gt;常见的Transforms
&lt;/h2&gt;&lt;p&gt;下面基本都是对图像的处理方法&lt;/p&gt;
&lt;h3 id="totensor"&gt;ToTensor
&lt;/h3&gt;&lt;p&gt;Convert a PIL Image or ndarray to tensor and scale the values accordingly.&lt;/p&gt;
&lt;p&gt;This transform does not support torchscript.&lt;/p&gt;
&lt;p&gt;Converts a PIL Image or numpy.ndarray (H x W x C) in the range [0, 255] to a torch.FloatTensor of shape (C x H x W) in the range [0.0, 1.0] if the PIL Image belongs to one of the modes (L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1) or if the numpy.ndarray has dtype = np.uint8&lt;/p&gt;
&lt;p&gt;In the other cases, tensors are returned without scaling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;note&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Because the input image is scaled to [0.0, 1.0], this transformation should not be used when transforming target image masks. See the [references](vscode-file://vscode-app/d:/Microsoft VS Code/resources/app/out/vs/code/electron-browser/workbench/workbench.html) for implementing the transforms for image masks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;将PIL图片转为torch类型&lt;/strong&gt;，如&lt;code&gt;torch.Size([1, 48, 48])&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;trans_totensor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToTensor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img_tensor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;trans_totensor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_tensor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ToTensor&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;img_tensor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="normalize"&gt;Normalize
&lt;/h3&gt;&lt;p&gt;Normalize a tensor image with mean and standard deviation.&lt;/p&gt;
&lt;p&gt;​ This transform does not support PIL Image.&lt;/p&gt;
&lt;p&gt;​ Given mean: &lt;code&gt;(mean[1],...,mean[n])&lt;/code&gt; and std: &lt;code&gt;(std[1],..,std[n])&lt;/code&gt; for &lt;code&gt;n&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;​ channels, this transform will normalize each channel of the input&lt;/p&gt;
&lt;p&gt;​ &lt;code&gt;torch.*Tensor&lt;/code&gt; i.e.,&lt;/p&gt;
&lt;p&gt;​ &lt;code&gt;output[channel] = (input[channel] - mean[channel]) / std[channel]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;note:&lt;/p&gt;
&lt;p&gt;​ This transform acts out of place, i.e., it does not mutate the input tensor.&lt;/p&gt;
&lt;p&gt;Args:&lt;/p&gt;
&lt;p&gt;​ mean (sequence): Sequence of means for each channel.&lt;/p&gt;
&lt;p&gt;​ std (sequence): Sequence of standard deviations for each channel.&lt;/p&gt;
&lt;p&gt;​ inplace(bool,optional): Bool to make this operation in-place.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Normailize&lt;/code&gt; 的数学原理是：&lt;/li&gt;
&lt;/ul&gt;
$$
output = \frac{input-mean}{std}
$$&lt;ul&gt;
&lt;li&gt;参数&lt;code&gt;mean&lt;/code&gt;影响的是“中心位置”，在&lt;code&gt;ToTensor&lt;/code&gt;之后，像素值在 $[0, 1]$ 之间，中心大约在 $0.5$，如&lt;code&gt;mean = 0.5&lt;/code&gt;，那么减去 $0.5$ 后，数据的中心变成了 $0$。原本 $[0, 1]$ 的范围变成了 $[-0.5, 0.5]$&lt;/li&gt;
&lt;li&gt;参数&lt;code&gt;std&lt;/code&gt;影响的是“缩放幅度”，如&lt;code&gt;std = 0.5&lt;/code&gt;，那么就是将数据范围再除以$0.5$，最终范围从 $[-0.5, 0.5]$ 变成了 $[-1, 1]$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="resize"&gt;Resize
&lt;/h3&gt;&lt;p&gt;Resize the input image to the given size.&lt;/p&gt;
&lt;p&gt;​ If the image is torch Tensor, it is expected&lt;/p&gt;
&lt;p&gt;​ to have [&amp;hellip;, H, W] shape, where &amp;hellip; means a maximum of two leading dimensions&lt;/p&gt;
&lt;p&gt;Args:&lt;/p&gt;
&lt;p&gt;​ size (sequence or int): Desired output size. If size is a sequence like&lt;/p&gt;
&lt;p&gt;​ (h, w), output size will be matched to this. If size is an int,&lt;/p&gt;
&lt;p&gt;​ smaller edge of the image will be matched to this number.&lt;/p&gt;
&lt;p&gt;​ i.e, if height &amp;gt; width, then image will be rescaled to&lt;/p&gt;
&lt;p&gt;​ (size * height / width, size).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;resize()&lt;/code&gt;支持PIL和Tensor两种图片格式，如果是 Tensor，期望形状为 &lt;code&gt;[..., H, W]&lt;/code&gt;。这里的 &lt;code&gt;...&lt;/code&gt; 表示它可以处理 &lt;code&gt;[C, H, W]&lt;/code&gt;（单张图）或 &lt;code&gt;[B, C, H, W]&lt;/code&gt;（一个 Batch 的图）&lt;/li&gt;
&lt;li&gt;参数&lt;code&gt;size&lt;/code&gt;需注意写成序列形式，如&lt;code&gt;resize((512, 512))&lt;/code&gt;，而如果只输入一个参数，如&lt;code&gt;resize(512)&lt;/code&gt;，那么图片短边会变为512，而长边会按比例改变&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;trans_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resize&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;224&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;224&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img_resize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;trans_resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_resize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="compse"&gt;Compse
&lt;/h3&gt;&lt;p&gt;Composes several transforms together. This transform does not support torchscript.&lt;/p&gt;
&lt;p&gt;​ Please, see the note below.&lt;/p&gt;
&lt;p&gt;Args:&lt;/p&gt;
&lt;p&gt;​ transforms (list of &lt;code&gt;Transform&lt;/code&gt; objects): list of transforms to compose.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;compse()&lt;/code&gt;操作是对各种&lt;code&gt;transforms&lt;/code&gt;操作的流水线&lt;strong&gt;类&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;在深度学习中，图片通常需要经过一系列的固定步骤（比如：缩放 -&amp;gt; 转为 Tensor -&amp;gt; 归一化）。如果不用 &lt;code&gt;Compose&lt;/code&gt;，你每一张图都要手动调用多个函数，代码会非常冗余&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compse()&lt;/code&gt;的参数类型是一个列表，操作是按顺序执行的，所以前一个操作输出的数据类型必须能作为下一个操作的输入。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;torchvision&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 定义训练集的预处理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;train_transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Compose&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resize&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;224&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;224&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="c1"&gt;# VGG16标准输入是224x224&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RandomHorizontalFlip&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# 数据增强：随机水平翻转&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToTensor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# 归一化到 [0.0, 1.0]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# 标准化到 [-1.0, 1.0]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img_tensor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;train_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="pytorch数据集使用"&gt;Pytorch数据集使用
&lt;/h2&gt;&lt;p&gt;例如，我们要导入视觉学习的数据集，可以直接在程序中进行数据集的下载&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;torchvision&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;train_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CIFAR10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./dataset...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;test_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CIFAR10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./dataset...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;root&lt;/code&gt;参数表示数据集存放的位置，&lt;code&gt;train&lt;/code&gt;参数表示数据集是否用来训练，&lt;code&gt;download&lt;/code&gt;参数表示是否下载到本地（会生成一个下载链接）&lt;/li&gt;
&lt;li&gt;具体的参数设置，每个数据集都可能有所区别&amp;hellip;&amp;hellip;&lt;/li&gt;
&lt;li&gt;如果是下载完成到本地的数据集，可以将其复制到项目目录的dataset文件夹下，再运行程序即可节省下载的时间&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 可以看到测试数据集的所有类别&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;test_set&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_set&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# 输出测试集第一个元素对应的类别&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="dataloader"&gt;DataLoader
&lt;/h2&gt;&lt;p&gt;Data loader combines a dataset and a sampler, and provides an iterable over the given dataset.&lt;/p&gt;
&lt;p&gt;​ The :class:&lt;code&gt;~torch.utils.data.DataLoader&lt;/code&gt; supports both map-style and&lt;/p&gt;
&lt;p&gt;​ iterable-style datasets with single- or multi-process loading, customizing&lt;/p&gt;
&lt;p&gt;​ loading order and optional automatic batching (collation) and memory pinning.&lt;/p&gt;
&lt;p&gt;在训练模型时，不能一次性把数据集中的大量数据塞进内存。&lt;code&gt;DataLoader&lt;/code&gt;实现了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Batching（批处理）：&lt;/strong&gt; 把图片打包成一组组（Batch）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Shuffling（打乱）：&lt;/strong&gt; 每一轮训练（Epoch）开始时随机洗牌，防止模型死记硬背数据顺序。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Parallel Computing（并行加载）：&lt;/strong&gt; 利用多核 CPU 提前准备下一批数据，不让 GPU 等待。&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;参数名&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;常用取值&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用描述&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;dataset&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;自定义 Dataset&lt;/td&gt;
					&lt;td&gt;必填。告诉 DataLoader 从哪个“仓库”取数据。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;batch_size&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;16, 32, 64&amp;hellip;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;每批装载的数量。&lt;/strong&gt; 越大训练越快，但越占显存。在 FER 表情识别中，32 或 64 是常用数值。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;shuffle&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt; / &lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;是否打乱顺序。&lt;/strong&gt; 训练集通常设为 &lt;code&gt;True&lt;/code&gt;（增加随机性）；测试集通常设为 &lt;code&gt;False&lt;/code&gt;。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;num_workers&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;0, 2, 4, 8&amp;hellip;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;多进程加载。&lt;/strong&gt; &lt;code&gt;0&lt;/code&gt; 表示只用主进程（慢）。增加数值可以加快读取速度。&lt;strong&gt;建议：&lt;/strong&gt; 设为 CPU 核心数的一半。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;drop_last&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt; / &lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;丢弃最后多余的数据。&lt;/strong&gt; 比如有 100 张图，&lt;code&gt;batch_size=32&lt;/code&gt;。最后剩 4 张不够一包，设为 &lt;code&gt;True&lt;/code&gt; 就会把这 4 张扔掉，确保每个 Batch 大小一致。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;pin_memory&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;内存锁页。&lt;/strong&gt; 如果你用 GPU 训练，设为 &lt;code&gt;True&lt;/code&gt; 可以加快数据从内存传输到显存的速度。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;例如，我们用&lt;code&gt;DataLoader&lt;/code&gt;处理CIFAR10中的数据&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;test_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CIFAR10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./dataset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToTensor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;test_loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;test_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num_workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;drop_last&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;结合循环和&lt;code&gt;tensorboard&lt;/code&gt;，输出每一个&lt;code&gt;epoch&lt;/code&gt;中每一&lt;code&gt;step&lt;/code&gt;用到的图片&lt;/li&gt;
&lt;li&gt;下面代码中&lt;code&gt;step + epoch * len(test_loader)&lt;/code&gt;是使用了全局步长，也可以不这样写，而是把每个&lt;code&gt;epoch&lt;/code&gt;来当作一组&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SummaryWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;dataloader&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;test_loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_images&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;test_data_batch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_loader&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="nnmodule"&gt;nn.Module
&lt;/h2&gt;&lt;p&gt;Base class for all neural network modules.&lt;/p&gt;
&lt;p&gt;​ Your models should also subclass this class.&lt;/p&gt;
&lt;p&gt;​ Modules can also contain other Modules, allowing to nest them in a tree structure.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 PyTorch 中，无论是简单的线性层，还是复杂的 VGG16 或 Transformer，本质上都是一个 &lt;code&gt;nn.Module&lt;/code&gt;。它是所有神经网络模块的&lt;strong&gt;基类&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nn.Module&lt;/code&gt; 支持嵌套，当你对大模型调用 &lt;code&gt;model.to(&amp;quot;cuda&amp;quot;)&lt;/code&gt; 时，PyTorch 会顺着这棵“树”，自动把里面所有的子层都搬到 GPU 上。&lt;/li&gt;
&lt;li&gt;只要在 &lt;code&gt;__init__&lt;/code&gt; 中把一个层赋值给 &lt;code&gt;self.xxx&lt;/code&gt;，PyTorch 就会自动识别出其中的&lt;strong&gt;权重 (Weights)&lt;/strong&gt; 和 &lt;strong&gt;偏置 (Bias)&lt;/strong&gt;，并将它们加入到待优化的参数列表中。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;编写一个&lt;code&gt;nn.Module&lt;/code&gt;子类时，必须重写&lt;code&gt;__init()__&lt;/code&gt;和&lt;code&gt;forward()&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;__init(self)__&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;在这里定义网络层（卷积、池化、全连接等）。&lt;/li&gt;
&lt;li&gt;必须调用 &lt;code&gt;super().__init__()&lt;/code&gt;。这行代码的作用是初始化父类的属性，如果没有它，PyTorch 就没法自动追踪定义的层，模型也就无法训练。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;forward(self, x)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;定义数据的流向。图片进去后，先过哪一层，再过哪一层。&lt;/li&gt;
&lt;li&gt;不需要手动调用 &lt;code&gt;forward&lt;/code&gt;，只需要运行 &lt;code&gt;model(input)&lt;/code&gt;，PyTorch 会自动触发 &lt;code&gt;forward&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;torch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;torch&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;myModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# 简单地将输出 +1 再输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="卷积-conv"&gt;卷积 Conv
&lt;/h2&gt;$$
\text{out}(N_i, C_{\text{out}_j}) = \text{bias}(C_{\text{out}_j}) +
 \sum_{k = 0}^{C_{\text{in}} - 1} \text{weight}(C_{\text{out}_j}, k) \star \text{input}(N_i, k)
$$&lt;ul&gt;
&lt;li&gt;卷积动画页面：&lt;a class="link" href="https://github.com/vdumoulin/conv_arithmetic/blob/master/README.md" target="_blank" rel="noopener"
 &gt;conv_arithmetic/README.md at master · vdumoulin/conv_arithmetic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;含义&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;作用&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;in_channels&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;输入通道数&lt;/td&gt;
					&lt;td&gt;彩色图通常为 3 (RGB)，灰度图为 1。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;out_channels&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;kernel_size&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;卷积核大小&lt;/td&gt;
					&lt;td&gt;提取特征的“窗口”大小。常用 3 或 5（VGG 常用 3）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;stride&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;步长&lt;/td&gt;
					&lt;td&gt;窗口滑动的跨度。默认为 1。步长越大，输出图片越小。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;padding&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;填充&lt;/td&gt;
					&lt;td&gt;在图片四周补 0。&lt;code&gt;'same'&lt;/code&gt; 保持大小不变，&lt;code&gt;'valid'&lt;/code&gt; 则不补。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;dilation&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;bias&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;ul&gt;
&lt;li&gt;卷积的Padding（边界扩充）参数很重要，如果周围不补零，那么卷积会导致图像尺寸越来越小&lt;/li&gt;
&lt;li&gt;形状计算公式：&lt;/li&gt;
&lt;/ul&gt;
$$
H_{out} = \left\lfloor\frac{H_{in} + 2 \times \text{padding}[0] - \text{dilation}[0]
 \times (\text{kernel_size}[0] - 1) - 1}{\text{stride}[0]} + 1\right\rfloor
$$&lt;p&gt;$W_{out}$计算同理&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CIFAR10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./dataset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToTensor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dataloader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;myModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conv1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Conv2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;out_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;kernel_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;stride&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conv1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mymodule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myModule&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 模型实例化 &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dataloader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mymodule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# torch.Size([64, 3, 32, 32])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# torch.Size([64, 6, 30, 30]) channel == 6 卷积后，channel数变化，不能直接输出图像&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="最大池化-maxpool"&gt;（最大）池化 MaxPool
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;最大池化的逻辑非常简单：在一个窗口（Kernel）范围内，&lt;strong&gt;只保留最大的那个值&lt;/strong&gt;，剩下的全部扔掉&lt;/li&gt;
&lt;li&gt;既保留输入特征，又减小了数据量，加快训练速度&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;strong&gt;参数&lt;/strong&gt;&lt;/th&gt;
					&lt;th&gt;&lt;strong&gt;独特之处&lt;/strong&gt;&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;kernel_size&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;窗口大小。常见是 &lt;code&gt;2&lt;/code&gt;（即将 $2 \times 2$ 的区域合并）。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;stride&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;默认值等于 kernel_size&lt;/strong&gt;！这和卷积不同。如果 &lt;code&gt;kernel_size=2&lt;/code&gt;，步长默认就是 &lt;code&gt;2&lt;/code&gt;，这样窗口之间就不会重叠。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;ceil_mode&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;&lt;strong&gt;非常重要。&lt;/strong&gt; 默认是 &lt;code&gt;False&lt;/code&gt;（向下取整）。如果设为 &lt;code&gt;True&lt;/code&gt;（向上取整），当窗口超出边界时，只要窗口内有数据，就会保留结果，而不是舍弃。&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;padding&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;填充。注意池化填充的是&lt;strong&gt;负无穷（$-\infty$）&lt;/strong&gt;，这样是为了保证填充位不会被选为最大值。&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tensor&lt;/span&gt;&lt;span class="p"&gt;([[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]],&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reshape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;myMoudle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myMoudle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;maxpool1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MaxPool2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kernel_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ceil_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; ceil_mode = False 就表示只有当池化核遇到的尺寸是最大尺寸（如3x3）时
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; 才会取其池化的结果，否则相反
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;maxpool1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;mymoudle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myMoudle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mymoudle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;tensor&lt;/span&gt;&lt;span class="p"&gt;([[[[&lt;/span&gt;&lt;span class="mf"&gt;2.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;5.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="p"&gt;]]]],&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;hr&gt;
&lt;h2 id="损失函数与反向传播"&gt;损失函数与反向传播
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;损失函数用于计算实际输出与目标之间的差距，为反向传播、更新参数提供一定的依据。在分类任务中，常用交叉熵函数来计算误差，&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loss_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CrossEntropyLoss&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="优化器"&gt;优化器
&lt;/h3&gt;&lt;p&gt;&lt;a class="link" href="https://docs.pytorch.org/docs/stable/optim.html" target="_blank" rel="noopener"
 &gt;torch.optim — PyTorch 2.10 documentation&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;示例代码：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero_grad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 梯度清零&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loss_fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 调用损失函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 反向传播&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="pytorch实战cifar10"&gt;Pytorch实战：CIFAR10
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;针对CIFAR10图像数据集的简单分类模型实战&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://blog.kawausococo.top/uploads/posts/pytorch/Screenshot_2026-01-26_140919.png" alt="" loading="lazy" /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首先了解Sequential，&lt;code&gt;nn.Sequential&lt;/code&gt; 是 &lt;code&gt;nn.Module&lt;/code&gt; 的一个特殊子类，它的作用是&lt;strong&gt;自动完成 &lt;code&gt;forward&lt;/code&gt; 逻辑&lt;/strong&gt;。注意：其中每一个参数都是某层的类，所以要写逗号。Sequential既简化了模型定义，也简化了&lt;code&gt;forward()&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CIFAR10_Simple&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CIFAR10_Simple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conv1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Conv2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kernel_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; 参数padding的数值可以从想象图像得到：5x5的卷积核，当中心在图像的(0,0)，那么卷积核是扩展出去2格的。上面是简单判断的方法，实际应该用尺寸计算公式来代入计算（参考“Conv卷积”节内容）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model_s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Conv2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kernel_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReLU&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;MaxPool2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kernel_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Conv2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_channels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kernel_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReLU&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;MaxPool2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Conv2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReLU&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;MaxPool2d&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Flatten&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Linear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReLU&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Linear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.conv1(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.maxpool1(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.conv2(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.maxpool2(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.conv3(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.maxpool3(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.flatten(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.linear1(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; x = self.linear2(x)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;在搭建模型前，先设置&lt;code&gt;DataLoader&lt;/code&gt;处理数据集&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;分别设置好&lt;code&gt;train_data&lt;/code&gt;和&lt;code&gt;test_data&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;dataset_transfrom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Compose&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToTensor&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Normalize&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;),(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;))])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;train_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CIFAR10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./dataset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dataset_transfrom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;test_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torchvision&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CIFAR10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./dataset&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;dataset_transfrom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# --------&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;train_loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;train_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;drop_last&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;test_loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DataLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;test_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;drop_last&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;搭建好模型后，简单测试输出尺寸是否符合要求&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;cifar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CIFAR10_Simple&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cifar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ones&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# 同数据集图片尺寸的测试&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cifar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;训练前的基本设置
&lt;ul&gt;
&lt;li&gt;定义&lt;code&gt;TensorBoard&lt;/code&gt;的&lt;code&gt;writer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;设置&lt;code&gt;device&lt;/code&gt;调用显卡加速训练&lt;/li&gt;
&lt;li&gt;实例化训练模型&lt;/li&gt;
&lt;li&gt;定义损失函数&lt;/li&gt;
&lt;li&gt;设置优化器&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SummaryWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./logs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_graph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cifar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cuda&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cuda&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_available&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;cpu&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CIFAR10_Simple&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;loss_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CrossEntropyLoss&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# 交叉熵损失函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;optim&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SGD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cifar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;lr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 学习率&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;训练部分
&lt;ul&gt;
&lt;li&gt;优化器的定式代码&lt;/li&gt;
&lt;li&gt;记录训练损失&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;total_step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# --- 训练部分 ---&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;train_loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loss_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero_grad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 记录训练损失&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_scalar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Train_Loss&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;total_step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;total_step&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;评估部分
&lt;ul&gt;
&lt;li&gt;每个epoch执行一次&lt;/li&gt;
&lt;li&gt;&lt;code&gt;with torch.no_grad()&lt;/code&gt;：关闭梯度记录&lt;/li&gt;
&lt;li&gt;统计性能指标&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;total_test_loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;total_accuracy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;no_grad&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="c1"&gt;# 测试时不需要计算梯度，节省性能&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;test_loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imgs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 计算总损失&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;loss_func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;total_test_loss&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 计算准确率：argmax(1) 找到概率最大的类别索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;accuracy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;total_accuracy&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;accuracy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;可视化&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 输出到 TensorBoard&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_scalar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Test_Loss&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_test_loss&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_loader&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_scalar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Test_Accuracy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total_accuracy&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Epoch &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;epoch&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 结束，准确率: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total_accuracy&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</description></item></channel></rss>