<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>第 3 章 深度学习基础 on 《从零学AI指南手册》</title>
		<link>https://mlwithme.github.io/dl/chapter03/</link>
		<description>Recent content in 第 3 章 深度学习基础 on 《从零学AI指南手册》</description>
		<generator>Hugo</generator>
		<language>zh_CN</language>
		
		
		
		
			<atom:link href="https://mlwithme.github.io/dl/chapter03/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>3.1 线性回归</title>
				<link>https://mlwithme.github.io/dl/chapter03/75c5fa7839174c16/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/75c5fa7839174c16/</guid>
				<description>&lt;h1 id=&#34;第-3-章-深度学习基础&#34;&gt;第 3 章 深度学习基础&lt;a class=&#34;anchor&#34; href=&#34;#%e7%ac%ac-3-%e7%ab%a0-%e6%b7%b1%e5%ba%a6%e5%ad%a6%e4%b9%a0%e5%9f%ba%e7%a1%80&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在前面两个章节我们详细介绍了深度学习的发展历史以及深度学习环境的安装与配置。在本章内容中我们将正式开始深度学习基础内容的学习。在本章内容中，我们将详尽介绍深度学习入门的基础知识，涵盖了从线性回归和逻辑回归的的由来与建模、什么是深度学习以及为什么需要深度学习等相关理念，到梯度下降和反向传播的原理及实现方法。我们将全面介绍如何从零开始构建回归和分类模型，包括逻辑回归到Softmax回归的转换，以及常用的评估指标和应对过拟合的方法。此外，本章内容还将深入探讨了超参数选择的重要性、交叉验证的实践意义、激活函数的作用，以及在多标签分类场景下的损失函数与模型评估方法。&lt;/p&gt;&#xA;&lt;h1 id=&#34;31-线性回归&#34;&gt;3.1 线性回归&lt;a class=&#34;anchor&#34; href=&#34;#31-%e7%ba%bf%e6%80%a7%e5%9b%9e%e5%bd%92&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;经过前面预备知识的介绍，现在终于正式进入到了深度学习的内容介绍中。那什么又是深度学习呢？以及我们为什么需要深度学习呢？要想弄清楚这两个问题，我们还得先从机器学习中的线性回归说起。&lt;/p&gt;&#xA;&lt;h2 id=&#34;311-理解线性回归模型&#34;&gt;3.1.1 理解线性回归模型&lt;a class=&#34;anchor&#34; href=&#34;#311-%e7%90%86%e8%a7%a3%e7%ba%bf%e6%80%a7%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;通常来讲，我们所学的每个算法都是为了解决某一类问题而诞生的。换句话说，也就是在实际情况中的确存在一些问题能够通过线性回归来解决，例如对房价的预测，但是有人可能会问，为什么对于房价的预测就应该用线性回归，而不是其他算法模型呢？其原因就在于常识告诉我们房价是随着面积的增长而增长的，且总体上呈线性增长的趋势。那有没有当面积大到一定程度后价格反而降低，因此不符合线性增长的呢？这当然也可能存在，但在实际处理中肯定会优先选择线性回归模型，当效果不佳时我们才会尝试其他算法，因此，当学习过多个算法模型后，在得到某个具体的问题时，可能就需要考虑哪种模型更适合来解决这个问题了。&lt;/p&gt;&#xA;&lt;p&gt;例如某市的房价走势如图3-1所示，其中横坐标为面积，纵坐标为价格，并且房价整体上呈线性增长的趋势。假如现在随意告诉你一个房屋的面积，要怎样才能预测（或者叫计算）出其对应的价格呢？&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-1.jpg&#34;/&gt;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-1 某市的房价走势图&#xA;&lt;/center&gt;&#xA;&lt;h2 id=&#34;312-建立线性回归模型&#34;&gt;3.1.2 建立线性回归模型&lt;a class=&#34;anchor&#34; href=&#34;#312-%e5%bb%ba%e7%ab%8b%e7%ba%bf%e6%80%a7%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;一般来讲，当我们得到一个实际问题时，首先会根据问题的背景结合常识选择一个合适的模型。同时，现在常识告诉我们房价的增长更优先符合线性回归这类模型，因此可以考虑建立一个如下所示的线性回归模型（Linear Regression）。&lt;/p&gt;&#xA;$$&#xA;\hat{y}=h(x)=wx+b\tag{3-1}&#xA;$$&lt;p&gt;&#xA;其中$w$叫权重（Weight），$b$叫偏置（Bias）或者截距（Intercept），两者都称为模型参数（Parameter）。当通过某种方法求解得到未知参数$w$和$b$之后，也就意味着我们得到了这个预测模型，即给定一个房屋面积$x$，就能够预测出其对应的房价$\hat{y}$。&lt;/p&gt;&#xA;&lt;p&gt;注意： 在机器学习中所谓的模型，可以简单理解为一个复合函数。&lt;/p&gt;&#xA;&lt;p&gt;当然，尽管影响房价的主要因素是面积，但是其它因素同样也可能影响房屋的价格。例如房屋到学校的距离、到医院的距离和到大型商场的距离等，只是各个维度对应的权重大小不同而已。虽然现实生活中一般不这么量化，但是开发商也总是会拿学区房做卖点，所以这时便有了影响房价的4个因素，而在机器学习中我们将其称为特征（Feature）或者属性（Attribute），因此，包含多个特征的线性回归就叫作多变量线性回归（Multiple Linear Regression）。&lt;/p&gt;&#xA;&lt;p&gt;此时，便可以得到如下所示的线性回归模型。&#xA;&lt;/p&gt;&#xA;$$&#xA;\hat{y}=h(x)={{w}_{1}}{{x}_{1}}+\cdots +{{w}_{4}}{{x}_{4}}+b=w^Tx+b\tag{3-2}&#xA;$$&lt;p&gt;&#xA;其中$x_1,x_2,x_3,x_4$表示输入的4项房屋信息特征，$w_1,w_2,w_3,w_4$表示每个特征对应的权重参数，$b$ 为偏置。&lt;/p&gt;&#xA;&lt;p&gt;并且我们还可以通过如下示意图来对式(3-2)中的模型进行表示：&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/000102.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;    图 3-2. 房价预测线性回归结构图（偏置未画出）&#xA;&lt;/center&gt;&#xA;&lt;h2 id=&#34;313-求解线性回归模型&#34;&gt;3.1.3 求解线性回归模型&lt;a class=&#34;anchor&#34; href=&#34;#313-%e6%b1%82%e8%a7%a3%e7%ba%bf%e6%80%a7%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;当建立好一个模型后，自然而然想到的就是如何通过给定的数据，也叫训练集（Training Data），来对模型 $h(x)$进行求解。在中学时期我们学过如何通过两个坐标点来求解过这两点的直线，可在上述的场景中这种做法显然是行不通的（因为求解线性回归模型所有的点并不在一条直线上），那有没有什么好的解决的办法呢？&lt;/p&gt;&#xA;&lt;p&gt;此时就需要我们转换一下思路了，既然不能直接进行求解，那就换一种间接的方式。现在来想象一下，当 $h(x)$ 满足一个什么样的条件时，它才能称得上是一个好的$h(x)$？ 回想一下求解$h(x)$的目的是什么，不就是希望输入面积$x$后能够输出“准确”的房价$\hat{y}$吗？既然直接求解$h(x)$不好入手，那么我们就从“准确”来入手。&lt;/p&gt;&#xA;&lt;p&gt;可又怎样来定义准确呢？在这里，我们可以通过计算每个样本的真实房价与预测房价之间的均方误差来对“准确”进行刻画。&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{cases}&#xA; J(w,b)=\frac{1}{2m}\sum\limits_{i=1}^{m}{{{({{y}^{(i)}}-{{{\hat{y}}}^{(i)}})}^{2}}}\\ &#xA;  {{{\hat{y}}}^{(i)}}=h({{x}^{(i)}})=w^T{{x}^{(i)}}+b  &#xA;\end{cases}&#xA;\tag{3-3}&#xA;$$&lt;p&gt;&#xA;其中，$m$表示样本数量； $x^{(i)}$表示第$i$个样本为一个列向量；$w$表示模型对应的参数也为一个列向量； $y^{(i)}$表示第$i$个房屋的真实价格； $\hat{y}^{(i)}$表示第$i$ 个房屋的预测价格。&lt;/p&gt;&#xA;&lt;p&gt;由式(3-3)可知，当函数$J(w,b)$取最小值时的参数$\hat{w}$和$\hat{b}$，就是要求的目标参数。为什么？因为当$J(w,b)$取最小值时就意味着此时所有样本的预测值与真实值之间的误差（Error）最小。如果极端一点，就是所有预测值都等同于真实值，那么此时的$J(w,b)$就是0了。因此，对于如何求解模型 $h(x)$ 的问题就转换成了如何最小化函数$J(w,b)$的问题，而$J(w,b)$也有一个专门的术语叫作目标函数（Objective Function）或者代价函数（Cost Function）抑或损失函数（Loss Function）。关于目标函数的求解问题将在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/ca16f8cb6df444a6&#34;&gt;3.2节&lt;/a&gt;内容中进行介绍。&lt;/p&gt;&#xA;&lt;h2 id=&#34;314-多项式回归建模&#34;&gt;3.1.4 多项式回归建模&lt;a class=&#34;anchor&#34; href=&#34;#314-%e5%a4%9a%e9%a1%b9%e5%bc%8f%e5%9b%9e%e5%bd%92%e5%bb%ba%e6%a8%a1&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在3.1.2节的内容中，我们分别介绍了单变量线性回归和多变量线性回归，接下来我们开始介绍多项式回归。那什么是多项式回归呢？现在假定已知矩形的面积公式，而不知道求解梯形的面积公式，并且同时手上有若干个类似图3-3所示的梯形。已知梯形的上底和下底，并且上底均等于高。现在需要建立一个模型，当任意给定一个类似图3-3中的梯形时能近似地算出其面积。面对这样的问题该如何进行建模呢？&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.2 线性回归简洁实现</title>
				<link>https://mlwithme.github.io/dl/chapter03/ca16f8cb6df444a6/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/ca16f8cb6df444a6/</guid>
				<description>&lt;h1 id=&#34;32-线性回归简洁实现&#34;&gt;3.2 线性回归简洁实现&lt;a class=&#34;anchor&#34; href=&#34;#32-%e7%ba%bf%e6%80%a7%e5%9b%9e%e5%bd%92%e7%ae%80%e6%b4%81%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;经过&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/75c5fa7839174c16&#34;&gt;3.1节&lt;/a&gt;内容的介绍我们对于深度学习的基本概念已经有了一定的了解，接下来我们将开始介绍如何借助PyTorch框架来快速实现上面介绍的房价预测和梯形面积预测这两个实际示例。&lt;/p&gt;&#xA;&lt;h2 id=&#34;321-pytorch使用介绍&#34;&gt;3.2.1 PyTorch使用介绍&lt;a class=&#34;anchor&#34; href=&#34;#321-pytorch%e4%bd%bf%e7%94%a8%e4%bb%8b%e7%bb%8d&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在正式介绍模型实现之前，我们先来看看即将需要使用到的PyTorch中相关模型接口的使用方法。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. &lt;code&gt;nn.Linear()&lt;/code&gt;使用&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;根据图3-7可知，对于每个网络层来说均是一个全连接层，且都可以看成由多个线性组合构成。例如对于第1个全连接层来说，其输入维度为原始样本的特征维度数4，输出维度为5，即由5个线性组合构成了该全连接层。此时，我们可以通过如下方式来定义该全连接层，示例代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;torch.nn&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;nn&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt; layer &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;) &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第1行表示导入&lt;code&gt;torch&lt;/code&gt;中的&lt;code&gt;nn&lt;/code&gt;模块。第2行表示定义一个全连接层，且该全连接层的输入特征（神经元）数量为4，输出特征数量为5，且&lt;code&gt;nn.Linear()&lt;/code&gt;内部已经自动随机初始化了网络层对应的权重参数。同理，对于第2个全连接层来说，其定义方式为&lt;code&gt;nn.Linear(5, 3) &lt;/code&gt;。因此对于式(3-1)中的单变量线性回归来说，其定义方式为&lt;code&gt;nn.Linear(1, 1) &lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;接着，我们便可以通过如下方式来完成一次全连接层的计算，示例代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;test_linear&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     x &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tensor([[&lt;span style=&#34;color:#40a070&#34;&gt;1.&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;], [&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;7&lt;/span&gt;]], dtype&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;float32)  &lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# [2,4]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;     layer &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;)  &lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;#&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;     y &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; layer(x)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第2行表示定义输入样本，形状为&lt;code&gt;[2,4]&lt;/code&gt;列，即样本数量为2，特征数量为4。第4行则是计算该全连接层对应的结果，输出形状为&lt;code&gt;[2,5]&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;2. &lt;code&gt;nn.Sequential()&lt;/code&gt;使用&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;此时我们已经知道了如何定义一个全连接层并完成对应的计算过程，但现在出现的一个问题是图3-7中有多个全连接网络层，该如何定义并完成整个计算过程呢？一种最直接的办法就是逐层单独定义并完成相应的计算过程，示例代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;multi_layers&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     x &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tensor([[&lt;span style=&#34;color:#40a070&#34;&gt;1.&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;], [&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;7&lt;/span&gt;]], dtype&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;float32)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;     layer1 &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;     layer2 &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;     layer3 &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;     y1 &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; layer1(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;7&lt;/span&gt;     y2 &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; layer2(y1)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;8&lt;/span&gt;     y3 &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; layer3(y2)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;9&lt;/span&gt;     &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(y3)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;但这样的写法会略显冗余，因为对于整个计算过程来说，我们几乎很少会用到中间结果，因此可以采用省略的写法。在PyTorch中，可以通过将所有的网络层放入到一个有序的容器中，然后一次完成整个计算过程，示例代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;multi_layers_sequential&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     x &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tensor([[&lt;span style=&#34;color:#40a070&#34;&gt;1.&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;], [&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;7&lt;/span&gt;]], dtype&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;float32)  &lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# [2,4]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;     net &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Sequential(nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;), nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;), nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;     y &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; net(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;     &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(y)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第3行中&lt;code&gt;nn.Sequential()&lt;/code&gt;便是这个有序容器，通过它便可以完成整个3层网络的计算过程。&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.3 梯度下降与反向传播</title>
				<link>https://mlwithme.github.io/dl/chapter03/97e1da1143cd4554/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/97e1da1143cd4554/</guid>
				<description>&lt;h1 id=&#34;33-梯度下降与反向传播&#34;&gt;3.3 梯度下降与反向传播&lt;a class=&#34;anchor&#34; href=&#34;#33-%e6%a2%af%e5%ba%a6%e4%b8%8b%e9%99%8d%e4%b8%8e%e5%8f%8d%e5%90%91%e4%bc%a0%e6%92%ad&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;根据&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/75c5fa7839174c16&#34;&gt;3.1.3节&lt;/a&gt;内容可知，求解网络模型参数的过程便是等价于最小化目标函数$J(w,b)$的过程。同时，经过&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/ca16f8cb6df444a6&#34;&gt;3.2节&lt;/a&gt;内容的介绍我们已经知道了如何借助PyTorch中的优化器来求解得到网络模型对应的权重参数，不过对于整个求解过程的具体原理并没有介绍。在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/ca16f8cb6df444a6&#34;&gt;3.2节&lt;/a&gt;内容中，当我们定义好损失函数后直接通过两行代码便完成了模型权重参数的优化求解过程，一句是&lt;code&gt; l.backward()&lt;/code&gt;，而另一句则是&lt;code&gt; optimizer.step()&lt;/code&gt;。那这两句代码又是什么意思呢？&lt;/p&gt;&#xA;&lt;p&gt;在接下来的这节内容中，我们将会详细介绍如何通过梯度下降算法来最小化目标函数$J(w,b)$，以及深度学习中求解网络参数梯度的利器反向传播（Back Propagation）算法。&lt;/p&gt;&#xA;&lt;h2 id=&#34;331-梯度下降引例&#34;&gt;3.3.1 梯度下降引例&lt;a class=&#34;anchor&#34; href=&#34;#331-%e6%a2%af%e5%ba%a6%e4%b8%8b%e9%99%8d%e5%bc%95%e4%be%8b&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;根据上面的介绍可以知道，梯度下降算法的目的是用来最小化目标函数，也就是说梯度下降算法是一个求解的工具。当目标函数取到（或接近）全局最小值时，我们也就求解得到了模型所对应的参数。不过那什么又是梯度下降（Gradient Descent）呢？如图3-10所示，假设有一个山谷，并且你此时处于位置A处，那么请问以什么样的方向（角度）往前跳，你才能最快地到达谷底B处呢?&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-10.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-10 跳跃方向&#xA;&lt;/center&gt;&#xA;&lt;p&gt;现在大致有3个方向可以选择，沿着$Y$轴的$\boldsymbol{V_1}$方向，沿着$X$轴的$\boldsymbol{V_2}$方向及沿着两者间的$\boldsymbol{l}$方向。其实不用问，各位读者一定都会选择$\boldsymbol{l}$所在的方向往前跳第一步，然后接着选类似的方向往前跳第二步直到谷底。可为什么都应该这样选呢？答： 这还用问一看就知，不信请读者自己试一试。&lt;/p&gt;&#xA;&lt;h2 id=&#34;332-方向导数与梯度&#34;&gt;3.3.2 方向导数与梯度&lt;a class=&#34;anchor&#34; href=&#34;#332-%e6%96%b9%e5%90%91%e5%af%bc%e6%95%b0%e4%b8%8e%e6%a2%af%e5%ba%a6&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;由一元函数导数的相关知识可知，函数$f(x)$在$x_0$处的导数反映的是$f(x)$在$x=x_0$处时的变化率；$|f^{\prime}(x_0)|$越大，也就意味着$f(x)$在该处的变化率越大，即移动$\Delta x$后产生的函数增量$\Delta y$越大。同理，在二元函数$z=f(x,y)$中，为了寻找$z$在A处的最大变化率，就应该计算函数$z$在该点的方向导数&#xA;&lt;/p&gt;&#xA;$$&#xA;\frac{\partial f}{\partial \boldsymbol{l}}=\{\frac{\partial f}{\partial x},\frac{\partial f}{\partial y}\}\cdot \{cos\alpha ,cos\beta \}=|gradf|\cdot |\boldsymbol{l}|\cdot \cos \theta\tag{3-9}&#xA;$$&lt;p&gt;&#xA;其中，$\boldsymbol{l}$为单位向量； $\alpha$和$\beta$分别为$\boldsymbol{l}$与$x$轴和$y$轴的夹角； $\theta$为梯度方向与$\boldsymbol{l}$的夹角。&lt;/p&gt;&#xA;&lt;p&gt;根据式(3-9)可知，要想方向导数取得最大值，那么$\theta$必须为0。由此可知，只有当某点处方向导数的方向与梯度的方向一致时，方向导数在该点才会取得最大的变化率。&lt;/p&gt;&#xA;&lt;p&gt;在图3-10中，已知$z=x^2+y^2+5$，A的坐标为$(-3,3,23)$，则，则$\partial z/\partial x=2x,\partial z/\partial y=2y$。由此可知，此时在点A处梯度的方向为$(-6,6)$，所以当你站在A点并沿各个方向往前跳跃同样大小的距离时，只有沿着$(\sqrt{2}/2,-\sqrt{2}/2)$这个方向（进行了单位化，并且同时取了相反方向，因为这里需要的是负增量）才会产生最大的函数增量$\Delta z$。&lt;/p&gt;&#xA;&lt;p&gt;如图3-11所示，要想每次都能以最快的速度下降，则每次都必须向着梯度的反方向向前跳跃。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-11.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-11 负梯度方向&#xA;&lt;/center&gt;&#xA;&lt;h2 id=&#34;333-梯度下降原理&#34;&gt;3.3.3 梯度下降原理&lt;a class=&#34;anchor&#34; href=&#34;#333-%e6%a2%af%e5%ba%a6%e4%b8%8b%e9%99%8d%e5%8e%9f%e7%90%86&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;介绍这么多总算是把梯度的概念讲清楚了，那么如何用具体的数学表达式进行描述呢？总不能一个劲儿地喊它“跳”不是吗？为了方便后面的表述及将读者带入一个真实求解的过程中，这里先将图3-10中的字母替换成模型中的参数进行表述。现在有一个模型的目标函数$J(w_1,w_2)=w_1^2+w_2^2+2w_2+5$（为了方便可视化，此处省略了参数$b$，原理都一样），其中$w_1$和$w_2$为待求解的权重参数，并且随机初始化点A为初始权重值。下面就一步步地通过梯度下降算法进行求解。&lt;/p&gt;&#xA;&lt;p&gt;如图3-12所示，设初始点$A=(w_1,w_2)=(-2,3)$，则此时$J(-2,3)=24$，并且点$A$第一次往前跳的方向为 $-grad\;J=-(2{{w}_{1}},2{{w}_{2}}+2)=(1,-2)$ ，即$(1,-2)$这个方向。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-12.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-12 梯度下降&#xA;&lt;/center&gt;&#xA;&lt;p&gt;如图3-13所示，$OQ$为平面上梯度的反方向，$AP$为其平移后的方向，但是长度为之前的$\alpha$倍，因此，根据梯度下降的原则，此时曲面上的$A$点就该沿着其梯度的反方向跳跃，而投影到平面则为$A$应该沿着$AP$的方向移动。假定曲面上从$A$点跳跃到了$P$点，那么对应在投影平面上就是图3-13中的$AP$部分，同时权重参数也从$A$的位置更新到了$P$点的位置。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-13.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-13 梯度计算&#xA;&lt;/center&gt;&#xA;&lt;p&gt;从图3-13可以看出，向量$\mathbf{AP}$、$\mathbf{OA}$和$\mathbf{OP}$三者的关系为&#xA;&lt;/p&gt;&#xA;$$&#xA;\mathbf{OP}=\mathbf{OA}-\mathbf{PA}\tag{3-10}&#xA;$$&lt;p&gt;&#xA;进一步，可以将式(3-10)改写成&#xA;&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.4 从零实现回归模型</title>
				<link>https://mlwithme.github.io/dl/chapter03/7b865de988ea422c/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/7b865de988ea422c/</guid>
				<description>&lt;h1 id=&#34;34-从零实现回归模型&#34;&gt;3.4 从零实现回归模型&lt;a class=&#34;anchor&#34; href=&#34;#34-%e4%bb%8e%e9%9b%b6%e5%ae%9e%e7%8e%b0%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;经过&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/97e1da1143cd4554&#34;&gt;3.3节&lt;/a&gt;内容的介绍，我们已经清楚了神经网络训练的基本流程，即先进行正向传播计算预测值，然后进行反向传播计算梯度，接着根据梯度下降算法对网络中的权重参数进行更新，最后循环迭代这3个步骤，直到损失函数收敛为止。在接下来的这节内容中，我们将会详细介绍如何从零实现&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/ca16f8cb6df444a6&#34;&gt;3.2.3节&lt;/a&gt;中的梯形面积预测实例，即一个简单的两层神经网络。&lt;/p&gt;&#xA;&lt;h2 id=&#34;341-网络结构&#34;&gt;3.4.1 网络结构&lt;a class=&#34;anchor&#34; href=&#34;#341-%e7%bd%91%e7%bb%9c%e7%bb%93%e6%9e%84&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在正式介绍实现部分之前，我们先来看一下整个模型的网络结构以及整理出前向传播和反向传播各自的计算过程。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;450&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-17.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-17. 梯形面积预测网络结果图（偏置未画出）&#xA;&lt;/center&gt;&#xA;&lt;p&gt;如图3-17所示，整个网络一共包含2层，其中输入层有2个神经元，即梯形的上底（等同于高）和下底；隐藏层有80个神经元；输出层有1个神经元。由此可以得出，在第1层中$a^1$的形状为&lt;code&gt;[m,2]&lt;/code&gt;（&lt;code&gt;m&lt;/code&gt;为样本个数），权重$w^1$的形状为&lt;code&gt;[2,80]&lt;/code&gt;，$b^1$的形状为&lt;code&gt;[80]&lt;/code&gt;；在第2层中$a^2$的形状为&lt;code&gt;[m,80]&lt;/code&gt;，权重$w^2$的形状为&lt;code&gt;[80,1]&lt;/code&gt;，$b^2$的形状为&lt;code&gt;[1]&lt;/code&gt;；最终预测输出$a^3$的形状为&lt;code&gt;[m,1]&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;进一步，可以得到模型的前向传播计算过程为&lt;/p&gt;&#xA;$$&#xA;z^2=a^1w^1+b^1 \Rightarrow a^2=f(z^2)\tag{3-38}&#xA;$$$$&#xA;z^3=a^2w^2+b^2 \Rightarrow a^3=z^3\tag{3-39}&#xA;$$&lt;p&gt;这里需要注意的是，式(3-39)中最后一层的输出并没有经过非线性变换处理。&lt;/p&gt;&#xA;&lt;p&gt;同时，模型的损失函数为&#xA;&lt;/p&gt;&#xA;$$&#xA;J(w,b)=\frac{1}{2m}\sum_{i=1}^m(y_i-\hat{y}_i)^2\tag{3-40}&#xA;$$&lt;p&gt;&#xA;最后，根据式(3-28)可得&#xA;&lt;/p&gt;&#xA;$$&#xA;\delta^{3}=[a^3-y]\odot 1\tag{3-41}&#xA;$$&lt;p&gt;&#xA;进一步根据式(3-34)、式(3-35)和式(3-41)可得&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;&amp;\frac{\partial J}{\partial w^2}=(a^2)^T\otimes\delta^3\\[1ex]&#xA;&amp;\frac{\partial J}{\partial b^2}=\delta^3&#xA;\end{aligned}&#xA;\tag{3-42}&#xA;$$&lt;p&gt;&#xA;根据式(3-36)可得&#xA;&lt;/p&gt;&#xA;$$&#xA;\delta^2=\delta^3\otimes(w^2)^T\odot f^{\prime}(z^2)\tag{3-43}&#xA;$$&lt;p&gt;进一步根据式(3-34)、式(3-35)和式(3-43)可得&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;&amp;\frac{\partial J}{\partial w^1}=(a^1)^T\otimes\delta^2\\[1ex]&#xA;&amp;\frac{\partial J}{\partial b^1}=\delta^2&#xA;\end{aligned}&#xA;\tag{3-44}&#xA;$$&lt;h2 id=&#34;342-模型实现&#34;&gt;3.4.2 模型实现&lt;a class=&#34;anchor&#34; href=&#34;#342-%e6%a8%a1%e5%9e%8b%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在完成相关迭代公式的梳理后，下面开始介绍如何从零实现这个2层神经网络模型。首先我们需要完成相关辅助函数的实现，以下完整示例代码可参见&lt;code&gt;Code/Chapter03/C05_MultiLayerReg/main.py&lt;/code&gt;文件。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. Sigmoid实现&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;对于Sigmoid函数的具体介绍可参见&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/66dd7425cdd04565&#34;&gt;3.12&lt;/a&gt;节内容，这里我们先直接进行使用，实现代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;sigmoid&lt;/span&gt;(z):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt; (&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;exp(&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;z))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;同时，后续需要用到其对应的导数，因此也要进行实现，代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;sigmoid_grad&lt;/span&gt;(z):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; sigmoid(z) &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt; sigmoid(z))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2. 损失函数实现&lt;/strong&gt;&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.5 从逻辑回归到Softmax回归</title>
				<link>https://mlwithme.github.io/dl/chapter03/18fdd1deff424a16/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/18fdd1deff424a16/</guid>
				<description>&lt;h1 id=&#34;35-从逻辑回归到softmax回归&#34;&gt;3.5 从逻辑回归到Softmax回归&lt;a class=&#34;anchor&#34; href=&#34;#35-%e4%bb%8e%e9%80%bb%e8%be%91%e5%9b%9e%e5%bd%92%e5%88%b0softmax%e5%9b%9e%e5%bd%92&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在前面几节内容中我们详细地介绍了线性回归模型的原理及其实现，在本节内容中将继续介绍下一个经典的机器学习算法——逻辑回归（Logistic Regression）及其变种Softmax回归，同时也将再次介绍深度学习中抽象特征的意义。&lt;/p&gt;&#xA;&lt;h2 id=&#34;351-理解逻辑回归模型&#34;&gt;3.5.1 理解逻辑回归模型&lt;a class=&#34;anchor&#34; href=&#34;#351-%e7%90%86%e8%a7%a3%e9%80%bb%e8%be%91%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;通常来讲，一个新算法的诞生要么用来改善已有的算法模型，要么就是首次提出用来解决一类新的问题，而逻辑回归模型恰恰属于后者，它是用来解决一类新的问题——分类（Classification）。什么是分类问题呢？&lt;/p&gt;&#xA;&lt;p&gt;现在有两堆样本点，需要建立一个模型来对新输入的样本进行预测，判断其应该属于哪个类别，即二分类问题（Binary Classification），如图3-19所示。对于这个问题的描述用线性回归来解决肯定是不行的，因为两者本就属于不同类型的问题。退一步讲，即使用线性回归来建模得到的估计也就是一条向右倾斜的直线，而我们这里需要的却是一条向左倾斜的且位于两堆样本点之间的直线。同时，回归模型的预测值都位于预测曲线附近，而无法做到区分直线两边的东西。既然用已有的线性回归解决不了，那么我们可不可以在此基础上做一点改进以实现分类的目的呢？答案是当然可以。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;340&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-19.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-19 分类任务&#xA;&lt;/center&gt;&#xA;&lt;h2 id=&#34;352-建立逻辑回归模型&#34;&gt;3.5.2 建立逻辑回归模型&lt;a class=&#34;anchor&#34; href=&#34;#352-%e5%bb%ba%e7%ab%8b%e9%80%bb%e8%be%91%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;既然是解决分类问题，那么完全可以通过建立一个模型用来预测每个样本点$(x_1,y_2)$属于其中一个类别的概率$p$，如果$p＞0.5$，我们就可以认为该样本点属于这个类别，这样就能解决上述的二分类问题了。该怎样建立这个模型呢？&lt;/p&gt;&#xA;&lt;p&gt;在前面的线性回归中，通过建模$h(x)=wx+b$来对新样本进行预测，其输出值为可能的任意实数，但此处既然要得到一个样本所属类别的概率，那最直接的办法就是通过一个函数$g(z$)，将$x_1$和$x_2$这两个特征的线性组合映射至［0,1］的范围即可。由此，便得到了逻辑回归中的预测模型&#xA;&lt;/p&gt;&#xA;$$&#xA;\hat{y}=h(x)=g(w_1x_1+w_2x_2+b)\tag{3-45}&#xA;$$&lt;p&gt;&#xA;其中，$g(\cdot)$同样为Sigmoid函数；$w_1$、$w_2$和$b$为未知参数； $h(x)$称为假设函数（Hypothesis），当$h(x)$大于某个值（通常设为0.5）时，便可以认为样本$x$属于正类，反之则认为属于负类。同时，也将$w_1x_1+w_2x_2+b=0$称为两个类别间的决策边界（Decision Boundary）。当求解得到$w_1$、$w_2$和$b$后，也就意味着得到了这个分类模型。&lt;/p&gt;&#xA;&lt;p&gt;当然，如果该数据集有$n$个特征维度，那么同样只需要将所有特征的线性组合映射至区间 [0,1] 即可&#xA;&lt;/p&gt;&#xA;$$&#xA;\hat{y}=h(x)=g({{w}_{1}}{{x}_{1}}+{{w}_{2}}{{x}_{2}}+\cdots +{{w}_{n}}{{x}_{n}}+b)\tag{3-46}&#xA;$$&lt;p&gt;可以看出，逻辑回归本质上也是一个单层的神经网络。&lt;/p&gt;&#xA;&lt;p&gt;同时，有了前面几节关于神经网络内容的介绍，我们还可以通过如下示意图来对式(3-46)中的模型进行表示&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;330&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-20.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-20 逻辑回归模型结构图（偏置未画出）&#xA;&lt;/center&gt;&#xA;&lt;p&gt;其中，输出层的曲线就表示这个映射函数 $g(z)$。&lt;/p&gt;&#xA;&lt;h2 id=&#34;353-求解逻辑回归模型&#34;&gt;3.5.3 求解逻辑回归模型&lt;a class=&#34;anchor&#34; href=&#34;#353-%e6%b1%82%e8%a7%a3%e9%80%bb%e8%be%91%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;当建立好模型之后就需要找到一种方法来求解模型中的未知参数。同线性回归一样，此时也需要通过一种间接的方式，即通过目标函数来刻画预测标签（Label）与真实标签之间的差距。当最小化目标函数后，便可以得到需要求解的参数$w$和$b$。&lt;/p&gt;&#xA;&lt;p&gt;对于逻辑回归来说，我们可以通过最小化式(3-47)中的目标函数来求解模型参数&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;  &amp; J(w,b)=-\frac{1}{m}\left[ \sum\limits_{i=1}^{m}{{{y}^{(i)}}}\log h({{x}^{(i)}})+(1-{{y}^{(i)}})\log (1-h({{x}^{(i)}})) \right] \\[1ex] &#xA; &amp; h({{x}^{(i)}})=g(w{{x}^{(i)}}+b)  &#xA;\end{aligned}\tag{3-47}&#xA;$$&lt;p&gt;&#xA;其中，$m$表示样本总数，$x^{(i)}$表示第$i$个样本，$y^{(i)}$表示第$i$个样本的真实标签，取值为0或1，$h(x^{(i)})$表示第$i$个样本为正类的预测概率。&lt;/p&gt;&#xA;&lt;p&gt;由式(3-47)可知，当函数$J(w,b)$取得最小值的参数$\hat{w}$和$\hat{b}$，也就是我们要求的目标参数。原因在于，当$J(w,b)$取得最小值时就意味着此时所有样本的预测标签与真实标签之间的差距最小，这同时也是最小化目标函数的意义，因此，对于如何求解模型$h(x)$的问题就转化为如何最小化目标函数$J(w,b)$的问题。&lt;/p&gt;&#xA;&lt;h2 id=&#34;354-从二分类到多分类&#34;&gt;3.5.4 从二分类到多分类&lt;a class=&#34;anchor&#34; href=&#34;#354-%e4%bb%8e%e4%ba%8c%e5%88%86%e7%b1%bb%e5%88%b0%e5%a4%9a%e5%88%86%e7%b1%bb&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在说完逻辑回归这个二分类模型后自然而然我们就会想到如何进行多分类的任务，因为在实际情况中，绝大多数任务场景都不会是一个简单的二分类任务。通常情况下在用逻辑回归处理多分类任务时，都会采取一种称为One-vs-all（也叫作 One-vs-rest）的方法。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/240402205552.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;    图 3-21. 三分类示例数据集&#xA;&lt;/center&gt;&#xA;&lt;p&gt;如图3-21所示为一个3分类的数据集，One-vs-all策略的核心思想是每次将其中一个类别的样本和剩余其它类的所有样本两者看作一个二分类任务进行模型训练，如图3-22所示，最后在预测过程中选择输出概率值最大那个模型对应的类别作为该样本点的所属类别。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;660&#34; src=&#34;https://mlwithme.github.io/images/dl/p3-22.jpg&#34;/&gt; &#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;    图 3-22. One-vs-all示意图&#xA;&lt;/center&gt;&#xA;&lt;p&gt;因此，对于图3-21中所示的数据集来说，便可以建立3个二分类模型$h_1(x)$、$h_2(x)$和$h_3(x)$来完成整个3分类任务。&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.6 Softmax回归简洁实现</title>
				<link>https://mlwithme.github.io/dl/chapter03/55967b0f642b4509/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/55967b0f642b4509/</guid>
				<description>&lt;h1 id=&#34;36-softmax回归简洁实现&#34;&gt;3.6 Softmax回归简洁实现&lt;a class=&#34;anchor&#34; href=&#34;#36-softmax%e5%9b%9e%e5%bd%92%e7%ae%80%e6%b4%81%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;经过&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/18fdd1deff424a16&#34;&gt;3.5节&lt;/a&gt;内容的介绍对于分类模型我们已经有了一定的了解，接下来我们将开始介绍如何借助PyTorch框架来快速实现基于Softmax回归的手写体分类任务。&lt;/p&gt;&#xA;&lt;h2 id=&#34;361-pytorch使用介绍&#34;&gt;3.6.1 PyTorch使用介绍&lt;a class=&#34;anchor&#34; href=&#34;#361-pytorch%e4%bd%bf%e7%94%a8%e4%bb%8b%e7%bb%8d&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/ca16f8cb6df444a6&#34;&gt;3.2.1节&lt;/a&gt;内容中，我们已经介绍过了PyTorch中 &lt;code&gt;nn.Linear()&lt;/code&gt;和&lt;code&gt;nn.Sequential()&lt;/code&gt;的用法，接下来我们再介绍数据集迭代器&lt;code&gt;DataLoader&lt;/code&gt;和分类任务中需要用到的&lt;code&gt;nn.CrossEntropyLoss()&lt;/code&gt;模块的使用方式。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. &lt;code&gt;DataLoader&lt;/code&gt;使用&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;根据&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/97e1da1143cd4554&#34;&gt;3.3节&lt;/a&gt;介绍的内容可知，在构造完成模型的目标函数之后便可以通过梯度下降算法来求解得到模型对应的权重参数。同时，由于在深度学习中训练集的数量巨大，很难一次同时计算所有权重参数在所有样本上的梯度，因此可以采用随机梯度下降（Stochastic Gradient Descent）或者是小批量梯度下降（Mini-batch Gradient Descent）来解决这个问题[1]。&lt;/p&gt;&#xA;&lt;p&gt;相比于梯度下降算法在所有样本上计算得到目标函数关于参数的梯度然后再进行平均，随机梯度下降算法的做法是每次迭代时只取一个样本来计算权重参数对应的梯度[2]。由于随机梯度下降是基于每个样本进行梯度计算，所以在迭代过程中每次计算得到的梯度值抖动很大，因此在实际情况中我们会每次选择一小批量的样本来计算权重参数的梯度，而这个批量的大小在深度学习中就被称为批大小（Batch Size）。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;500&#34; src=&#34;https://mlwithme.github.io/images/dl/240416201051.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;    图 3-29 随机梯度下降与梯度下降模拟结果图&lt;/center&gt;&#xA;&lt;p&gt;如图3-29所示，环形曲线表示目标函数对应的等高线，左右两边分别为随机梯度下降算法和梯度下降算法求解参数$w_1$和$w_2$的模拟过程，其中箭头方向表示负梯度方向，中间的原点表示目标函数对应的最优解。从左侧的优化过程可以看出，尽管随机梯度下降算法最终也能近似求解得到最优解，但是在整个迭代优化过程中梯度却不稳定，极有可能导致陷入局部最优解当中。但是对于梯度下降算法来说，由于其梯度是取在多个样本上的均值，因此在每次迭代过程中计算得到的梯度会相对更稳定，从而有更大的几率求解得到全局最优解。上述可视化代码可参见&lt;code&gt;Code/Chapter03/C07_DigitClassification/main.py&lt;/code&gt;文件。&lt;/p&gt;&#xA;&lt;p&gt;在PyTorch中，我们可以借助&lt;code&gt;DataLoader&lt;/code&gt;模块来快速完成小批量数据样本的迭代生成，示例代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;torchvision.transforms&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;transforms&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;torch.utils.data&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;import&lt;/span&gt; DataLoader&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;torchvision.datasets&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;import&lt;/span&gt; MNIST&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;DataLoader1&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;     data_loader &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; MNIST(root&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;~/Datasets/MNIST&amp;#39;&lt;/span&gt;, download&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;True&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;                                transform&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;transforms&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;ToTensor())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;7&lt;/span&gt;     data_iter &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; DataLoader(data_loader, batch_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;8&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;for&lt;/span&gt; (x, y) &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;in&lt;/span&gt; data_iter:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;9&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(x&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;shape,y&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;shape)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;10&lt;/span&gt; &lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# 输出结果&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;11&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;28&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;28&lt;/span&gt;]) torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;12&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;28&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;28&lt;/span&gt;]) torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;13&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;......&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第5~6行表示载入PyTorch中内置的MNIST手写体图片（见图3-25）数据集，&lt;code&gt;root&lt;/code&gt;参数为指定数据集所在的目录，&lt;code&gt;download&lt;/code&gt;为&lt;code&gt;True&lt;/code&gt;表示指定目录不存在时通过网络下载，&lt;code&gt;transform&lt;/code&gt;用于指定对原始数据进行的变化（这里仅仅是将原始的浮点数转换成PyTorch中的张量）。第7行便是通过&lt;code&gt;DataLoader&lt;/code&gt;来根据上面载入的原始数据构造一个批大小为32的迭代器。第8~9行则是用于遍历这个迭代器。第11~12行便是遍历迭代器所输出的结果，其中&lt;code&gt;[32,1,28,28]&lt;/code&gt;的含义便是该张量中有32个样本（即32张图片），每张图片的通道数为1（黑白），长和宽均为28个像素点。&lt;/p&gt;&#xA;&lt;p&gt;当然，此时可能有读者会问，如果我们载入本地的数据样本又该怎么来构造这个迭代器呢？对于这种非PyTorch内置数据集的情况，我们同样可以通过&lt;code&gt;DataLoader&lt;/code&gt;来完成迭代器的构建，只是前面多了一个步骤，示例代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;from&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;torch.utils.data&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;import&lt;/span&gt; TensorDataset&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;torch&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;import&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;numpy&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;as&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;np&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;DataLoader2&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;     x &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tensor(np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;random&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;random([&lt;span style=&#34;color:#40a070&#34;&gt;100&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;16&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;16&lt;/span&gt;]))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;     y &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tensor(np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;random&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;randint(&lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;10&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;100&lt;/span&gt;))&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;7&lt;/span&gt;     dataset &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; TensorDataset(x, y)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;8&lt;/span&gt;     data_iter &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; DataLoader(dataset, batch_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;9&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;for&lt;/span&gt; (x, y) &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;in&lt;/span&gt; data_iter:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;10&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(x&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;shape, y&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;shape)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;11&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;12&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;16&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;16&lt;/span&gt;]) torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;13&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;16&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;16&lt;/span&gt;]) torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Size([&lt;span style=&#34;color:#40a070&#34;&gt;32&lt;/span&gt;])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;14&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;......&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第5~6行用于生成原始的样本数据，并转换成张量。第7行则是根据原始数据得到实例化的&lt;code&gt;TensorDataset&lt;/code&gt;（继承自&lt;code&gt;Dataset&lt;/code&gt;），因为&lt;code&gt;FashionMNIST&lt;/code&gt;本质上也是继承自类&lt;code&gt;Dataset&lt;/code&gt;。第8行则同样是生成对应的迭代器，并指定批大小为32。第12~13行便是最终遍历迭代器所输出的结果，含义同上不再赘述。上述示例代码可参见&lt;code&gt;Code/Chapter03/C09_DataLoader/main.py&lt;/code&gt;文件。&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.7 从零实现分类模型</title>
				<link>https://mlwithme.github.io/dl/chapter03/381bbd56509e4a6f/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/381bbd56509e4a6f/</guid>
				<description>&lt;h1 id=&#34;37-从零实现分类模型&#34;&gt;3.7 从零实现分类模型&lt;a class=&#34;anchor&#34; href=&#34;#37-%e4%bb%8e%e9%9b%b6%e5%ae%9e%e7%8e%b0%e5%88%86%e7%b1%bb%e6%a8%a1%e5%9e%8b&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;经过&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/18fdd1deff424a16&#34;&gt;3.5节&lt;/a&gt;内容的介绍，我们已经清楚了深度学习中分类模型的基本原理，同时也掌握了如何快速通过PyTorch来实现Softmax回归模型。在接下来的这节内容中，我们将会详细介绍如何从零实现基于多层神经网络的手写体分类模型。&lt;/p&gt;&#xA;&lt;h2 id=&#34;371-网络结构&#34;&gt;3.7.1 网络结构&lt;a class=&#34;anchor&#34; href=&#34;#371-%e7%bd%91%e7%bb%9c%e7%bb%93%e6%9e%84&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在正式介绍实现部分之前，我们先来看一下整个模型的网络结构以及整理出前向传播和反向传播各自的计算过程。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;500&#34; src=&#34;https://mlwithme.github.io/images/dl/202507092008.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-31. 手写体识别网络结构图（偏置未画出）&#xA;&lt;/center&gt;&#xA;&lt;p&gt;如图3-31所示，整个网络一共包含3层（含有权重参数的层），其中输入层有784个神经元，即长宽均为28的图片展开后的向量维度；两个隐藏层均有1024个神经元；输出层有10个神经元，即分类类别数量。由此可以得出，在第1层中$a^1$的形状为&lt;code&gt;[m,784]&lt;/code&gt;（&lt;code&gt;m&lt;/code&gt;为样本个数），权重$w^1$的形状为&lt;code&gt;[784,1024]&lt;/code&gt;，$b^1$的形状为&lt;code&gt;[1024]&lt;/code&gt;；在第2层中$a^2$的形状为&lt;code&gt;[m,1024]&lt;/code&gt;，权重$w^2$的形状为&lt;code&gt;[1024,1024]&lt;/code&gt;，$b^2$的形状为&lt;code&gt;[1024]&lt;/code&gt;；在第3层中$a^3$的形状为&lt;code&gt;[m,1024]&lt;/code&gt;，权重$w^3$的形状为&lt;code&gt;[1024,10]&lt;/code&gt;，$b^3$的形状为&lt;code&gt;[10]&lt;/code&gt;；最终预测输出$a^4$的形状为&lt;code&gt;[m,10]&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;进一步，可以得到模型的前向传播计算过程为&#xA;&lt;/p&gt;&#xA;$$&#xA;z^2=a^1w^1+b^1\Rightarrow a^2=f(z^2)\tag{3-54}&#xA;$$$$&#xA;z^3=a^2w^2+b^2\Rightarrow a^3=f(z^3)\tag{3-55}&#xA;$$$$&#xA;z^4=a^3w^3+b^3\Rightarrow a^4=\text{Softmax}(z^4)\tag{3-56}&#xA;$$&lt;p&gt;其中，$f(\cdot)$表示非线性变换，$\text{Softmax}$的计算公式为&#xA;&lt;/p&gt;&#xA;$$&#xA;a^L_k=\frac{e^{z^L_k}}{\sum_{i=1}^{S_L}e^{z^L_i}}\tag{3-57}&#xA;$$&lt;p&gt;&#xA;同时，模型的损失函数为式(3-53)中所示的交叉熵损失函数。并且如果假设此时我们仅考虑一个样本，那么对应的目标函数则为&#xA;&lt;/p&gt;&#xA;$$&#xA;J(w,b)=-\sum_{k=1}^{S_L}y_k\cdot\log{a^L_k}\tag{3-58}&#xA;$$&lt;p&gt;其中$S_L=10$表示输出层对应神经元的个数，$L=4$表示输出层。&lt;/p&gt;&#xA;&lt;p&gt;进一步，根据式(3-58)可得目标函数$J$关于$z^L_i$的梯度，即&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;\delta^{L}_i&amp;=\frac{\partial J}{\partial z^L_i}=\frac{\partial J}{\partial a^L_1}\frac{\partial a^L_1}{\partial z^L_i}+\frac{\partial J}{\partial a^L_2}\frac{\partial a^L_2}{\partial z^L_i}+\cdots+\frac{\partial J}{\partial a^L_{S_L}}\frac{\partial a^L_{S_L}}{\partial z^L_i}\\[2ex]&#xA;&amp;=\sum_{k=1}^{S_L}\frac{\partial J}{\partial a^L_k}\frac{\partial a^L_k}{\partial z^L_i}&#xA;\end{aligned}&#xA;\tag{3-59}&#xA;$$&lt;p&gt;&#xA;由图3-31可知，$J$关于任何一个输出值$a^L_i$的梯度均只有一条路径上的依赖关系，其计算过程也就相对简单，即&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;\frac{\partial J}{\partial a^L_i}&amp;=\frac{\partial }{\partial a^L_i}\left[-\sum_{k=1}^{S_L}y_k\cdot\log{a^L_k}\right]\\[2ex]&#xA;&amp;=-y_i\frac{1}{a^L_i}&#xA;\end{aligned}\tag{3-60}&#xA;$$&lt;p&gt;&#xA;接下来，需要求解的便是$a^L_i$关于$z^L_j$的梯度（此处不要被各种下标所迷惑，一定要结合式(3-57)进行理解）。例如在求解$a^4_1$关于$z^4_2$的梯度时，根据式(3-57)可知，此时的分子与$e^{z^4_1}$是没关系的（即分子$e^{z^4_1}$看作是常数）；但是在求解$a^4_1$关于$z^4_1$的梯度时，此时的分子就不能看作是常数了。具体有&lt;/p&gt;&#xA;&lt;p&gt;当$i\neq j$时：&#xA;&lt;/p&gt;&#xA;$$&#xA;\frac{\partial a^L_i}{\partial z^L_j}=\frac{\partial}{\partial z^L_j}\frac{e^{z^L_i}}{\sum_{k=1}^{S_L}e^{z^L_k}}=\frac{0-e^{z^L_i}e^{z^L_j}}{\left(\sum_{k=1}^{S_L}e^{z^L_k}\right)^2}=-a^L_ia^L_j\tag{3-61}&#xA;$$&lt;p&gt;&#xA;当$i=j$时：&#xA;&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.8 回归模型评估指标</title>
				<link>https://mlwithme.github.io/dl/chapter03/2c061df4435d4928/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/2c061df4435d4928/</guid>
				<description>&lt;h1 id=&#34;38-回归模型评估指标&#34;&gt;3.8 回归模型评估指标&lt;a class=&#34;anchor&#34; href=&#34;#38-%e5%9b%9e%e5%bd%92%e6%a8%a1%e5%9e%8b%e8%af%84%e4%bc%b0%e6%8c%87%e6%a0%87&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/75c5fa7839174c16&#34;&gt;3.1节&lt;/a&gt;到&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/7b865de988ea422c&#34;&gt;3.4节&lt;/a&gt;内容中，我们介绍了如何建模线性回归（包括多变量与多项式回归）及如何通过PyTorch来快速搭建模型并求解，但是对于一个创建出来的模型应该怎样来对其进行评估呢？换句话说，这个模型到底怎么样呢？&lt;/p&gt;&#xA;&lt;p&gt;以最开始的房价预测为例，现在假设求解得到了图3-33所示的两个模型$h_1(x)$与$h_2(x)$，那么应该选哪一个呢？抑或在不能可视化的情况下，应该如何评估模型的好与坏呢？&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/p2-8.png&#34;/&gt;&lt;/div&gt;&lt;center&gt;  图 3-33. 不同模型对房价的预测结果&lt;/center&gt;&#xA;&lt;p&gt;在回归任务中，常见的评估指标（Metric）有平均绝对误差（Mean Absolute Error, MAE）、均方误差（Mean Square Error, MSE）、均方根误差（Root Mean Square Error, RMSE）、平均绝对百分比误差（Mean Absolute Percentage Error, MAPE）和决定系数（Coefficient of Determination）等，其中用得最为广泛的是MAE和MSE。下面我们依次来对这些指标进行介绍，同时在所有的计算公式中，$m$均表示样本数量、$y^{(i)}$均表示第$i$个样本的真实值、$\hat{y}^{(i)}$均表示第$i$个样本的预测值。&lt;/p&gt;&#xA;&lt;h2 id=&#34;381-常见回归评估指标&#34;&gt;3.8.1 常见回归评估指标&lt;a class=&#34;anchor&#34; href=&#34;#381-%e5%b8%b8%e8%a7%81%e5%9b%9e%e5%bd%92%e8%af%84%e4%bc%b0%e6%8c%87%e6%a0%87&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;1.平均绝对误差（MAE）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;MAE用来衡量预测值与真实值之间的平均绝对误差，定义如下：&lt;/p&gt;&#xA;$$&#xA;\text{MAE}=\frac{1}{m}\sum\limits_{i=1}^{m}{|}{{y}^{(i)}}-{{\hat{y}}^{(i)}}|\tag{3-69}&#xA;$$&lt;p&gt;&#xA;其中$\text{MAE}\in [0,+\infty )$，其值越小表示模型越好，实现代码如下：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;MAE&lt;/span&gt;(y, y_pre):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;mean(np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;abs(y &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt; y_pre))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2. 均方误差（MSE）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;MSE用来衡量预测值与真实值之间的误差平方，定义如下：&#xA;&lt;/p&gt;&#xA;$$&#xA;\text{MSE}=\frac{1}{m}\sum\limits_{i=1}^{m}{{{({{y}^{(i)}}-{{{\hat{y}}}^{(i)}})}^{2}}}\tag{3-70}&#xA;$$&lt;p&gt;&#xA;其中$\text{MSE}\in [0,+\infty )$，其值越小表示模型越好，实现代码如下：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;MSE&lt;/span&gt;(y, y_pre):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;mean((y &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt; y_pre) &lt;span style=&#34;color:#666&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3. 均方根误差（RMSE）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;RMSE是在MSE的基础之上取算术平方根而来，其定义如下：&#xA;&lt;/p&gt;&#xA;$$&#xA;\text{RMSE}=\sqrt{\frac{1}{m}\sum\limits_{i=1}^{m}{{{({{y}^{(i)}}-{{{\hat{y}}}^{(i)}})}^{2}}}}\tag{3-71}&#xA;$$&lt;p&gt;&#xA;其中$\text{RMSE}\in [0,+\infty )$，其值越小表示模型越好，实现代码如下：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;RMSE&lt;/span&gt;(y, y_pre): &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;sqrt(MSE(y, y_pre))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;4. 平均绝对百分比误差（MAPE）&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;MAPE和MAE类似，只是在MAE的基础上做了标准化处理，其定义如下：&#xA;&lt;/p&gt;&#xA;$$&#xA;\text{MAPE}=\frac{100\%}{m}\sum\limits_{i=1}^{m}{\left| \frac{{{y}^{(i)}}-{{{\hat{y}}}^{(i)}}}{{{y}^{(i)}}} \right|}\tag{3-72}&#xA;$$&lt;p&gt;&#xA;其中$\text{MAPE}\in [0,+\infty )$，其值越小表示模型越好，实现代码如下：&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.9 分类模型评估指标</title>
				<link>https://mlwithme.github.io/dl/chapter03/e3442eff254e473c/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/e3442eff254e473c/</guid>
				<description>&lt;h1 id=&#34;39-分类模型评估指标&#34;&gt;3.9 分类模型评估指标&lt;a class=&#34;anchor&#34; href=&#34;#39-%e5%88%86%e7%b1%bb%e6%a8%a1%e5%9e%8b%e8%af%84%e4%bc%b0%e6%8c%87%e6%a0%87&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;如同回归模型一样，分类模型在训练结束之后同样需要一种测度来对模型的结果进行评判，以便于我们进行下一步流程。相较于回归模型的评估指标，分类模型的评估指标则相对更多且考虑情况也更为繁杂。在接下来的这节内容中，我们将从零开始一步一步地详细介绍分类任务中几种常见的评估指标及其实现方法。&lt;/p&gt;&#xA;&lt;h2 id=&#34;391-准确率&#34;&gt;3.9.1 准确率&lt;a class=&#34;anchor&#34; href=&#34;#391-%e5%87%86%e7%a1%ae%e7%8e%87&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;首先介绍分类任务中最常用也是最简单评估指标准确率（Accuracy）。假定现在有一个猫狗识别程序，并且假定狗为正类别（Positives）猫为负类别（Negatives）。程序在对12张狗和10张猫的混合图片进行识别后，判定其中8张图片为狗，14张图片为猫。待程序识别完毕后，经人工核对在这8张程序判定为狗的图片中仅仅只有5张图片的确为狗，14张被判定为猫的图片中仅有7张为真实的猫。&lt;/p&gt;&#xA;&lt;p&gt;因此，准确率的定义为预测正确的样本数在总样本数中的占比，即上述例子中程序的准确率为&#xA;&lt;/p&gt;&#xA;$$&#xA;\text{Accuracy}=\frac{\text{预测正确的样本数}}{\text{总样本数}}=\frac{5+7}{12+10}\approx0.545\tag{3-74}&#xA;$$&lt;p&gt;&#xA;以上就是准确率的定义及计算过程。&lt;/p&gt;&#xA;&lt;p&gt;虽然准确率计算过程简单也十分容易理解，但是准确率却存在着一个不容忽视的弊端。例如，现在需要训练一个癌细胞诊断模型来识别癌细胞，且在训练数据中其中负样本（非癌细胞）有10万个，而正样本（癌细胞）只有200个。假如某个模型将其中的105个预测为正样本，100095个预测为负样本。最终经过核对后发现，正样本中有5个预测正确，负样本中有99900个样本预测正确。那么此时该模型在训练集上的准确率为&#xA;&lt;/p&gt;&#xA;$$&#xA;\text{Accuracy}=\frac{99900+5}{100000+200}\approx0.997\tag{3-75}&#xA;$$&lt;p&gt;&#xA;但显然，这样的一个模型对于辅助医生决策来说并没有任何作用。如果模型极端一点将所有的样本都预测为负样本，那模型的准确率更是高达$0.998$。因此，在面对类似这种样本不均衡的任务中，并不能够将准确率作为评估模型的唯一指标。此时就需要引入精确率和召回率来作为新的评价指标。&lt;/p&gt;&#xA;&lt;h2 id=&#34;392-精确率与召回率计算&#34;&gt;3.9.2 精确率与召回率计算&lt;a class=&#34;anchor&#34; href=&#34;#392-%e7%b2%be%e7%a1%ae%e7%8e%87%e4%b8%8e%e5%8f%ac%e5%9b%9e%e7%8e%87%e8%ae%a1%e7%ae%97&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;我们仍旧以上面的猫狗识别任务为例。在这8张程序判定为狗的图片中仅仅只有5张图片的确为狗，因此这5张图片就被称为预测正确的正样本（True Positives, TP）；而余下的3张被称为预测错误的正样本（False Positives, FP）。同时，在这14张程序判定为猫的图片中，仅有7张为真实的猫，即预测正确的负样本（True Negatives, TN)；而余下的7张被称为预测错误的负样本（False Negatives, FN）。&lt;/p&gt;&#xA;&lt;p&gt;此时，根据这一识别结果，我们便可以得到如图3-34所示的混淆矩阵（Confuse Matrix）。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;450&#34; src=&#34;https://mlwithme.github.io/images/dl/23020451148.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-34. 混淆矩阵图&#xA;&lt;/center&gt;&#xA;&lt;p&gt;如何来读这个混淆矩阵呢？读的时候首先横向看，然后纵向看。例如读TP的时候，首先横向表示真实的正样本，其次是纵向表示预测的正样本，因此TP表示的就是将正样本预测为正样本的个数，即预测正确，因此，同理共有以下4种情况。&lt;/p&gt;&#xA;&lt;p&gt;(1) TP： 表示将正样本预测为正样本，即预测正确。&lt;/p&gt;&#xA;&lt;p&gt;(2) FN： 表示将正样本预测为负样本，即预测错误。&lt;/p&gt;&#xA;&lt;p&gt;(3) FP： 表示将负样本预测为正样本，即预测错误。&lt;/p&gt;&#xA;&lt;p&gt;(4) TN： 表示将负样本预测为负样本，即预测正确。&lt;/p&gt;&#xA;&lt;p&gt;如果此时突然问FP表示什么含义，又该怎样迅速地反应出来呢？我们知道FP从字面意思来看表示的是错误的正类，也就是说实际上它并不是正类，而是错误的正类，即实际上为负类，因此，FP表示的就是将负样本预测为正样本的含义。再看一个FN，其字面意思为错误的负类，也就是说实际上它表示的是正类，因此FN的含义就是将正样本预测为负样本。&lt;/p&gt;&#xA;&lt;p&gt;在定义完上述4种分类情况后就能得出各种场景下的计算指标公式，如式(3-76)~式(3-78)所示。&#xA;&lt;/p&gt;&#xA;$$&#xA;\text{Accuracy}=\frac{\text{TP}+\text{TN}}{\text{TP}+\text{FP}+\text{FN}+\text{TN}}\tag{3-76}&#xA;$$$$&#xA;\text{Precision}=\frac{\text{TP}}{\text{TP}+\text{FP}}\tag{3-77}&#xA;$$$$&#xA;\text{Recall}=\frac{\text{TP}}{\text{TP}+\text{FN}}\tag{3-78}&#xA;$$$$&#xA;{\text{F}_{\text{score}}}=(1+{{\beta }^{2}})\frac{\text{Precision}\cdot \text{Recall}}{{{\beta }^{2}}\cdot \text{Precision}+\text{Recall}}\tag{3-79}&#xA;$$&lt;p&gt;注意： 当$\text{F}_{\text{score}}$中$\beta=1$时称为$\text{F}_1$值，同时$\text{F}_1$也是用得最多的$\text{F}_{\text{score}}$评价指标。&lt;/p&gt;&#xA;&lt;p&gt;在这里，我们又一次根据不同的定义形式得到了准确率的计算方式，但其本质依旧等同于式(3-74)。同时还可以看到，精确率计算的是预测对的正样本在整个预测为正样本中的比重，而召回率计算的是预测对的正样本在整个真实正样本中的比重，因此一般来讲，召回率越高也就意味着这个模型寻找正样本的能力越强（例如在判断是否为癌细胞的时候，寻找正样本癌细胞的能力就十分重要），而$\text{F}_{\text{score}}$则是精确率与召回率的调和平均。&lt;/p&gt;&#xA;&lt;p&gt;因此，根据精确率和召回率的定义，我们还可以通过更直观的图示来进行说明，如图3-35所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;250&#34; src=&#34;https://mlwithme.github.io/images/dl/23020449782.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-35. 分类情况分布图&#xA;&lt;/center&gt;&#xA;如图3-35所示，左侧的所有实心样本点为正样本（相关元素），右侧的所有空心点为负样本，中间的圆形区域为模型预测的正样本（检索元素），即圆形左侧为模型将正样本预测为正样本的情况，右侧为模型将负样本预测为正样本的情况。例如现在可以想象这么一个场景，某一次我们在使用搜索引擎搜索相关内容（正样本）时，搜索引擎一共检索返回了30个搜索页面（搜索引擎认为的正样本），而搜索引擎返回的结果就相当于是图3-35中对应的圆形区域，所以精确率和召回率还可以通过图3-36来形象地进行表示。&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/23020430313.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-36. 精确率召回率图示&#xA;&lt;/center&gt;&#xA;&lt;p&gt;从图3-36中更能直观地看出，精确率计算的是预测正确的正样本在整个被预测为正样本中的占比；而召回率计算的是预测正确的正样本在所有真实正样本中的占比。&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.10 过拟合与正则化</title>
				<link>https://mlwithme.github.io/dl/chapter03/307f927c8a1245c5/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/307f927c8a1245c5/</guid>
				<description>&lt;h1 id=&#34;310-过拟合与正则化&#34;&gt;3.10 过拟合与正则化&lt;a class=&#34;anchor&#34; href=&#34;#310-%e8%bf%87%e6%8b%9f%e5%90%88%e4%b8%8e%e6%ad%a3%e5%88%99%e5%8c%96&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;经过前面几节内容的介绍， 我们对于深度学习的理念以及最基本的回归和分类模型已经有了清晰的认识。在接下来的这节内容中，我们将逐步开始介绍深度学习中关于模型优化的一些基本内容，包括模型的过拟合、正则化和丢弃法等。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3101-模型拟合&#34;&gt;3.10.1 模型拟合&lt;a class=&#34;anchor&#34; href=&#34;#3101-%e6%a8%a1%e5%9e%8b%e6%8b%9f%e5%90%88&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/97e1da1143cd4554&#34;&gt;3.3节&lt;/a&gt;内容中，我们首次引入了梯度下降这一优化算法，以此来最小化线性回归中的目标函数，并且在经过多次迭代后便可以得到模型中对应的参数。此时可以发现，模型的参数是一步一步根据梯度下降算法更新而来，直至目标函数收敛，也就是说这是一个循序渐进的过程，因此，这一过程也被称作拟合（Fitting）模型参数的过程，当这个过程执行结束后就会产生多种拟合后的状态，例如过拟合（Overfitting）和欠拟合（Underfitting）等。&lt;/p&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/2c061df4435d4928&#34;&gt;3.8节&lt;/a&gt;内容中，我们介绍了几种评估回归模型常用的指标，但现在有一个问题： 当MAE或者RMSE越小时就代表模型越好吗？还是说在某种条件下其越小就越好呢？细心的读者可能一眼便明了，肯定是有条件下的越小所对应的模型才越好。那这其中到底是怎么回事呢？&lt;/p&gt;&#xA;&lt;p&gt;假设现在有一批样本点，它本是由函数$sin(x)$生成（现实中并不知道），但由于其他因素的缘故，使我们得到的样本点并没有准确地落在曲线$sin(x)$上，而是分布在其附近，如图3-38所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/23020633449.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-38 正弦样本点图形&#xA;&lt;/center&gt;&#xA;&lt;p&gt;如图3-38所示，黑色圆点为训练集，黑色曲线为样本真实的分布曲线。现在需要根据训练集来建立并训练模型，然后得到相应的预测函数。现在我们分别用3个不同的模型A、B和C（复杂度依次增加，例如更多的网络层数和神经元个数等）来分别根据这12个样本点进行建模，那么最终便可以得到如图3-39所示的结果。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/23020643127.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图3-39 正弦样本点拟合图形&#xA;&lt;/center&gt;&#xA;&lt;p&gt;从图3-39中可以看出，随着模型复杂度的增加，$R^2$指标的值也越来越大（$R^2\in(-\infty,1]$），并且在模型C中$R^2$还达到了1.0，但是最后就应该选择模型C吗？&lt;/p&gt;&#xA;&lt;p&gt;不知到又过了多久，突然一名客户要买你的这个模型进行商业使用，同时客户为了评估这个模型的效果自己又带来了一批新的含有标签的数据（虽然模型C已经用$R^2$测试过，但客户并不会完全相信，万一你对这个模型作弊呢）。于是你拿着客户的新数据（也是由$sin(x)$所生成），然后分别用上面的3个模型进行预测，并得到了如图3-40所示的可视化结果。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/23020658968.jpg&#34;/&gt;&lt;/div&gt;&lt;center&gt;图 3-40 正弦样本点过拟合图形&lt;/center&gt;&#xA;&lt;p&gt;如图3-40所示，各个曲线表示根据新样本预测值绘制得到的结果。此时令你感到奇怪的是，为什么模型B的结果居然会好于模型C的结果，问题出在哪里？其原因在于，当第1次通过这12个样本点进行建模时，为了尽可能地使“模型好（表现形式为$R^2$尽可能大）”而使用了非常复杂的模型，尽管最后每个训练样本点都“准确无误”地落在了预测曲线上，但是这却导致最后模型在新数据上的预测结果严重地偏离了其真实值。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3102-过拟合与欠拟合概念&#34;&gt;3.10.2 过拟合与欠拟合概念&lt;a class=&#34;anchor&#34; href=&#34;#3102-%e8%bf%87%e6%8b%9f%e5%90%88%e4%b8%8e%e6%ac%a0%e6%8b%9f%e5%90%88%e6%a6%82%e5%bf%b5&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在机器学习领域中，通常将建模时所使用的数据叫作训练集（Training Dataset），例如图3-38中的12个样本点。将测试时所使用的数据集叫作测试集（Testing Dataset）。同时把模型在训练集上产生的误差叫作训练误差（Training Error），把模型在测试集上产生的误差叫作泛化误差（Generalization Error），最后也将整个拟合模型的过程称作训练（Training）[1]。&lt;/p&gt;&#xA;&lt;p&gt;进一步讲，我们将第3.10.1节中模型C所产生的现象叫作过拟合（Overfitting），即模型在训练集上的误差很小，但在测试集上的误差却很大，也就是泛化能力弱； 相反，将其对立面模型A所产生的现象叫作欠拟合（Underfitting），即模型训练集和测试集上的误差都很大； 同时，将模型B对应的现象叫作恰拟合（Goodfitting），即模型在训练集和测试集上都有着不错的效果。&lt;/p&gt;&#xA;&lt;p&gt;同时，需要说明的是，在第3.10.1节中我们仅仅以回归任务为例来向读者直观地介绍了什么是过拟合与欠拟合，但并不代表这种现象只出现在回归模型中，事实上所有的深度学习模型都会存在着这样的问题。因此一般来讲，所谓过拟合现象指的是模型在训练集上表现很好，但在测试集上表现糟糕；欠拟合现象是指模型在两者上的表现都十分糟糕；而恰拟合现象是指模型在训练集上表现良好（尽管可能不如过拟合时好），但同时在测试集上也有着不错的表现。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3103-解决欠拟合与过拟合&#34;&gt;3.10.3 解决欠拟合与过拟合&lt;a class=&#34;anchor&#34; href=&#34;#3103-%e8%a7%a3%e5%86%b3%e6%ac%a0%e6%8b%9f%e5%90%88%e4%b8%8e%e8%bf%87%e6%8b%9f%e5%90%88&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. 如何解决欠拟合问题&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;经过上面的描述我们已经对欠拟合有了一个直观的认识，所谓欠拟合就是训练出来的模型根本不能较好地拟合现有的训练数据。在深度学习中，要解决欠拟合问题相对来讲较为简单，主要分为以下两种方法：&lt;/p&gt;&#xA;&lt;p&gt;(1) 重新设计更为复杂的模型，例如增加网络的深度、神经元的个数或者采用更为复杂的网络架构（如Transformer）；&lt;/p&gt;&#xA;&lt;p&gt;(2) 减小正则化系数，当模型出现欠拟合现象时，可以通过减小正则化中的惩罚系数来减缓欠拟合现象，这一点将在第3.10.4节中进行介绍。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;2. 如何解决过拟合问题&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;对于如何有效地缓解模型的过拟合现象，常见的做法主要分为以下4种方法：&lt;/p&gt;&#xA;&lt;p&gt;(1) 收集更多数据，这是一个最为有效但实际操作起来又是最为困难的一种方法。训练数据越多，在训练过程中也就越能够纠正噪声数据对模型所造成的影响，使模型不易过拟合，但是对于新数据的收集往往有较大的困难。&lt;/p&gt;&#xA;&lt;p&gt;(2) 降低模型复杂度，当训练数据过少时，使用较为复杂的模型极易产生过拟合现象，例如3.10.1节中的示例，因此可以通过适当减少模型的复杂度来达到缓解模型过拟合的现象。&lt;/p&gt;&#xA;&lt;p&gt;(3) 正则化方法，在出现过拟合现象的模型中加入正则化约束项，以此来降低模型过拟合的程度，这部分内容将在3.10.4节中进行介绍。&lt;/p&gt;&#xA;&lt;p&gt;(4) 集成方法，将多个模型集成在一起，以此来达到缓解模型过拟合的目的。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;3. 如何避免过拟合&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;为了避免训练出来的模型产生过拟合现象，在模型训练之前一般会将获得的数据集划分成两部分，即训练集与测试集，且两者一般为7∶3的比例。其中训练集用来训练模型（降低模型在训练集上的误差），然后用测试集来测试模型在未知数据上的泛化误差，观察是否产生了过拟合现象 [2]。&lt;/p&gt;&#xA;&lt;p&gt;但是由于一个完整的模型训练过程通常会先用训练集训练模型，再用测试集测试模型，而绝大多数情况下不可能第1次就选择了合适的模型，所以又会重新设计模型（如调整网络层数、正则化系数等）进行训练，然后用测试集进行测试，因此在不知不觉中，测试集也被当成了训练集在使用，所以这里还有另外一种数据的划分方式，即训练集、验证集（Validation Data）和测试集，且一般为7∶2∶1的比例，此时的测试集一般通过训练集和验证集选定模型后做最后测试所用。&lt;/p&gt;&#xA;&lt;p&gt;实际训练中应该选择哪种划分方式呢？这一般取决于训练者对模型的要求程度。如果要求严苛就划分为3份，如果不那么严格，则可以划分为2份，也就是说这两者并没硬性的标准。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3104-泛化误差的来源&#34;&gt;3.10.4 泛化误差的来源&lt;a class=&#34;anchor&#34; href=&#34;#3104-%e6%b3%9b%e5%8c%96%e8%af%af%e5%b7%ae%e7%9a%84%e6%9d%a5%e6%ba%90&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;根据第3.10.3节内容可以知道，模型产生过拟合的现象表现为在训练集上误差较小，而在测试集上误差较大，并且我们还讲到，之所以会产生过拟合现象是由于训练数据中可能存在一定的噪声，而我们在训练模型时为了尽可能地做到拟合每个样本点（包括噪声），往往就会使用复杂的模型。最终使训练出来的模型在很大程度上受到了噪声数据的影响，例如真实的样本数据可能更符合一条直线，但是由于个别噪声的影响使训练出来的是一条曲线，从而使模型在测试集上表现糟糕，因此，可以将这一过程看作由糟糕的训练集导致了糟糕的泛化误差。但是，如果仅仅从过拟合的表现形式来看，糟糕的测试集（噪声多）也可能导致糟糕的泛化误差。&lt;/p&gt;&#xA;&lt;p&gt;在接下来的内容中，我们将分别从这两个角度来介绍正则化（Regularization）方法中最常用的$\mathcal{l} _2$正则化是如何来解决这一问题的。&lt;/p&gt;&#xA;&lt;p&gt;这里以线性回归为例，我们首先来看一下在线性回归的目标函数后面再加上一个$\mathcal{l}_2$正则化项的形式。&#xA;&lt;/p&gt;&#xA;$$&#xA;J=\frac{1}{2m}\sum\limits_{i=1}^{m}{{{\left[ {{y}^{(i)}}-(\sum\limits_{j=1}^{n}{{{w}_{j}}x_{j}^{(i)}}+b) \right]}^{2}}}+\frac{\lambda }{2n}\sum\limits_{j=1}^{n}{{{({{w}_{j}})}^{2}}};\;\;(\lambda &gt;0)\tag{3-98}&#xA;$$&lt;p&gt;&#xA;在式(3-98)中的第2项便是新加入的$\mathcal{l}_2$正则化项（Regularization Term），那它有什么作用呢？根据&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/75c5fa7839174c16&#34;&gt;3.1.3节&lt;/a&gt;中的内容可知，当真实值与预测值之间的误差越小（表现为损失值趋于0）时，也就代表着模型的预测效果越好，并且可以通过最小化目标函数来达到这一目的。由式(3-98)可知，为了最小化目标函数$J$，第2项的结果也必将逐渐地趋于0。这使最终优化求解得到的$w_j$均会趋于0附近，进而得到一个平滑的预测模型。这样做的好处是什么呢？&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.11 超参数与交叉验证</title>
				<link>https://mlwithme.github.io/dl/chapter03/bcb64de5aa404f18/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/bcb64de5aa404f18/</guid>
				<description>&lt;h1 id=&#34;311-超参数与交叉验证&#34;&gt;3.11 超参数与交叉验证&lt;a class=&#34;anchor&#34; href=&#34;#311-%e8%b6%85%e5%8f%82%e6%95%b0%e4%b8%8e%e4%ba%a4%e5%8f%89%e9%aa%8c%e8%af%81&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在深度学习中，除了通过训练集根据梯度下降算法训练得到的权重参数之外，还有另外一类通过手动设置的超参数（Hyper Parameter），而超参数的选择对于模型最终的表现也至关重要。在接下来的这节内容中，我们将会介绍到目前为止我们已经接触过的几个超参数及其选择方式。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3111-超参数介绍&#34;&gt;3.11.1 超参数介绍&lt;a class=&#34;anchor&#34; href=&#34;#3111-%e8%b6%85%e5%8f%82%e6%95%b0%e4%bb%8b%e7%bb%8d&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在之前的介绍中，我们知道了模型中的权重参数可以通过训练集利用梯度下降算法求解得到，但超参数又是什么呢？所谓超参数是指那些不能通过数据集训练得到的参数，但它的取值同样会影响最终模型的效果，因此同样重要。到目前为止，我们一共接触过了4个超参数，只是第一次出现的时候我们并没有提起其名字，在这里再做一个细致的总结。这4个超参数分别是： 学习率$\alpha$ 、惩罚系数$\lambda$、网络层数、丢弃率。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. 学习率$\alpha$&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/97e1da1143cd4554&#34;&gt;3.3.3节&lt;/a&gt;中介绍梯度下降算法原理时，我们首次介绍了梯度下降算法的迭代更新公式，见式(3-12)，并且讲过$\alpha$ 的作用是用来控制每次向前跳跃的距离，较大的$\alpha$可以更快地跳到谷底并找到最优解，但是过大的$\alpha$同样能使目标函数在峡谷的两边来回振荡，以至于需要多次迭代才可以得到最优解，甚至可能因为出现梯度爆炸现象而使得目标函数发散。&lt;/p&gt;&#xA;&lt;p&gt;如图3-47所示为相同模型采用不同学习率后，经梯度下降算法在同一初始位置优化后的结果，其中黑色五角星表示全局最优解（Global Optimum），ite表示迭代次数。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;620&#34; src=&#34;https://mlwithme.github.io/images/dl/p4-20.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-47. 凸函数优化过程&#xA;&lt;/center&gt;&#xA;&lt;p&gt;从图3-47可以看出，当学习率为0.4时，模型大概在迭代12次后就基本达到了全局最优解。当学习率为3.5时，模型在大约迭代12次后同样能够收敛于全局最优解附近，但是，当学习率为4.1时，此时的模型已经处于了发散状态。可以发现，由于模型的目标函数为凸形函数（例如线性回归），所以尽管使用了较大的学习率3.5，目标函数依旧能够收敛，但在后面的学习过程中，遇到更多的情况便是非凸型的目标函数，此时的模型对于学习率的大小将会更加敏感。&lt;/p&gt;&#xA;&lt;p&gt;如图3-48所示为一个非凸形的目标函数，三者均从同一初始点开始进行迭代优化，只是各自采用了不同的学习率。其中黑色五角星表示全局最优解，ite表示迭代次数。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;620&#34; src=&#34;https://mlwithme.github.io/images/dl/p4-21.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-48. 非凸形函数优化过程&#xA;&lt;/center&gt;&#xA;&lt;p&gt;从图3-48可以看出，当采用较小的学习率0.02时，模型在迭代20次后陷入了局部最优解（Local Optimum），并且可以知道此时无论再继续迭代多少次，其依旧会收敛于此处，因为它的梯度已经开始接近于0，而使参数无法得到更新。当采用较大一点的学习率0.4时，模型在迭代4次后便能收敛于全局最优解附近。当采用学习率为0.6时，模型在这20次的迭代过程中总是来回振荡，并且没有一次接近于全局最优解。&lt;/p&gt;&#xA;&lt;p&gt;从上面两个示例的分析可以得出，学习率的大小对于模型的收敛性及收敛速度有着严重的影响，并且非凸函数在优化过程中对于学习率的敏感性更大。同时值得注意的是，所谓学习率过大或者过小，在不同模型间没有可比性。例如在上面凸函数的图示中学习率为0.4时可能还算小，但是在非凸函数的这个例子中0.4已经算是相对较大了。图示代码参见&lt;code&gt;Code/Chapter03/C18_HyperParams/visual.py&lt;/code&gt;文件。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;2. 惩罚系数$\lambda$&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;从&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/307f927c8a1245c5&#34;&gt;3.10.9节&lt;/a&gt;内容中正则化的实验结果可知，超参数$\lambda$表示对模型的惩罚力度。$\lambda$越大也就意味着对模型的惩罚力度越大，最终训练得到的模型也就相对越简单，在一定程度上可以缓解模型的过拟合现象。但是这并不代表 $\lambda$ 越大越好，过大的$\lambda$将会降低模型的拟合能力，使得最终得到结果呈现出欠拟合的状态，因此，在模型的训练过程中，也需要选择一个合适的$\lambda$来使模型的泛化能力尽可能好。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;3. 网络层数&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/18fdd1deff424a16&#34;&gt;3.5.8节&lt;/a&gt;内容中，我们介绍到我们可以通过增加网络模型的深度来提高模型的特征表达能力，以此来提高后续任务的精度。但是对于具体的层数也需要人为地进行设定，因此网络层数也是深度学习中的一个重要超参数。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;4. 丢弃率&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在第&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/307f927c8a1245c5&#34;&gt;3.10.12节&lt;/a&gt;内容中，我们介绍我们可以通过在训练网络时随机丢弃一部分神经元来近似达到集成模型的效果，以此来缓解模型的过拟合现象。但是从丢弃法的原理可知，对于参数神经元的丢弃率来说它同样是一个需要手动设定的超参数，不同的取值对模型也有不同的影响，因此需要我们根据经验或者交叉验证进行选择，不过通常情况下会将0.5作为默认值。&lt;/p&gt;&#xA;&lt;p&gt;经过上面的介绍，我们明白了超参数对于模型最终的性能有着重要的影响。那到底应该如何选择这些超参数呢？对于超参数的选择，首先可以列出各个参数的备选取值，例如$\alpha=[0.001,0.03,0.1,0.3,1]$，$\lambda=[0.1,0.3,1,3,10]$（通常可以以3的倍数进行扩大），然后根据不同的超参数组合训练得到不同的模型（例如这里就有25个备选模型），然后通过第3.11.2节所要介绍的交叉验证来确立模型。&lt;/p&gt;&#xA;&lt;p&gt;不过随着介绍的模型越来越复杂，就会出现更多的超参数组合，训练一个模型也会花费一定的时间，因此，对于模型调参的一个基本要求就是要理解各个参数的含义，这样才可能更快地排除不可能的参数取值组合，以便于更快地训练出可用的模型。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3112-模型选择&#34;&gt;3.11.2 模型选择&lt;a class=&#34;anchor&#34; href=&#34;#3112-%e6%a8%a1%e5%9e%8b%e9%80%89%e6%8b%a9&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;当在对模型进行改善时，自然而然地就会出现很多备选模型，而我们的目的便是尽可能地选择一个较好的模型。但如何选择一个好的模型呢？通常来讲有两种方式： 第1种便是&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/307f927c8a1245c5&#34;&gt;3.10.3节&lt;/a&gt;中介绍过的将整个数据集划分成3部分的方式； 第2种则是使用K折交叉验证（KFold Cross Validation）[1] 的方式。对于第1种方法，其步骤为先在训练集上训练不同的模型，然后在验证集上选择其中表现最好的模型，最后在测试集上测试模型的泛化能力，但是这种做法的缺点在于，对于数据集的划分可能恰好某一次划分出来的测试集含有比较怪异的数据，导致模型表现出来的泛化误差也很糟糕，此时就可以通过K折交叉验证来解决。&lt;/p&gt;&#xA;&lt;p&gt;如图3-49所示，以3折交叉验证为例，首先需要将整个完整的数据集分为训练集与测试集两部分，并且同时再将训练集划分成3份，每次选择其中两份作为训练数据，另外一份作为验证数据进行模型的训练与验证，最后选择平均误差最小的模型。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/p4-22.png&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-49. 交叉验证划分图&#xA;&lt;/center&gt;&#xA;&lt;p&gt;假设现在有4个不同的备选模型，其各自在不同验证集上的误差如表3-1所示。根据得到的结果，可以选择平均误差最小的模型2作为最终选择的模型，然后将其用于整个大的训练集训练一次，最后用测试集测试其泛化误差。当然，还有一种简单的交叉验证方式，即一开始并不划分出测试集，而是直接将整个数据划分成为K份进行交叉验证，然后选择平均误差最小的模型即可。&lt;/p&gt;&#xA;&lt;center&gt;&#xA;  表 3-1. 3折交叉验证划分结果&#xA;&lt;/center&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;650&#34; src=&#34;https://mlwithme.github.io/images/dl/p4-24.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;h2 id=&#34;3113-基于交叉验证的手写体分类&#34;&gt;3.11.3 基于交叉验证的手写体分类&lt;a class=&#34;anchor&#34; href=&#34;#3113-%e5%9f%ba%e4%ba%8e%e4%ba%a4%e5%8f%89%e9%aa%8c%e8%af%81%e7%9a%84%e6%89%8b%e5%86%99%e4%bd%93%e5%88%86%e7%b1%bb&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在详细介绍完模型超参数以及交叉验证的相关原理后，下面我们将通过一个实际的示例来介绍如何运用交叉验证去选择一个合适的深度学习模型。这里我们依旧以MNIST数据集为例进行介绍，完整示例代码可以参见&lt;code&gt;Code/Chapter03/C18_HyperParams/main.py&lt;/code&gt;文件。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. 载入数据&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;首先，需要载入原始数据，实现代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;load_dataset&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     data_train &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; MNIST(root&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;~/Datasets/MNIST&amp;#39;&lt;/span&gt;, train&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;True&lt;/span&gt;, download&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;True&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;                        , transform&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;transforms&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;ToTensor())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;     data_test &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; MNIST(root&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;~/Datasets/MNIST&amp;#39;&lt;/span&gt;, train&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;False&lt;/span&gt;, download&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;True&lt;/span&gt;,&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;                       transform&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;transforms&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;ToTensor())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; data_train, data_test&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第2~5行是分别载入训练数据和测试数据，同时这里需要注意的是由于需要通过交叉验证来选择模型所以这里暂时没有直接返回训练集和测试集对应的&lt;code&gt;DataLoader&lt;/code&gt;迭代器。&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.12 激活函数</title>
				<link>https://mlwithme.github.io/dl/chapter03/66dd7425cdd04565/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/66dd7425cdd04565/</guid>
				<description>&lt;h1 id=&#34;312-激活函数&#34;&gt;3.12 激活函数&lt;a class=&#34;anchor&#34; href=&#34;#312-%e6%bf%80%e6%b4%bb%e5%87%bd%e6%95%b0&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/75c5fa7839174c16&#34;&gt;3.1.6节&lt;/a&gt;内容中我们介绍到，神经网络中多次线性组合后的输出结果仍旧只是原始特征的线性组合它并没有增加模型的复杂度。为了增加模型的表达能力需要对每一层的输出结果通过一个激活函数（Activation Function）来进行一次非线性变换然后再将其作为下一层网络的输入。在深度学习中，常见的激活函数包括Sigmoid、Tanh、ReLU和LeakyReLU等，下面我们来分别进行介绍。以下所有图示及实现代码可以参见&lt;code&gt;Code/Chapter03/C19_Activation/main.py&lt;/code&gt;文件。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3121-sigmoid激活函数&#34;&gt;3.12.1 Sigmoid激活函数&lt;a class=&#34;anchor&#34; href=&#34;#3121-sigmoid%e6%bf%80%e6%b4%bb%e5%87%bd%e6%95%b0&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. 原理&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Sigmoid激活函数的作用是将神经元的输出值映射到区域$(0,1)$中，同时它是最常用的具有指数形式的激活函数，其计算过程如下所示&#xA;&lt;/p&gt;&#xA;$$&#xA;g(x)=\frac{1}{1+e^{-x}}\tag{3-114}&#xA;$$&lt;p&gt;&#xA;其导数为&#xA;&lt;/p&gt;&#xA;$$&#xA;g^{\prime}(x)=\frac{e^{-x}}{(1+e^{-x})^2}=g(x)(1-g(x))\tag{3-115}&#xA;$$&lt;p&gt;&#xA;进一步，根据式(3-114)和式(3-115)我们可以分别画出两者的函数图像，如图3-50所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&#xA;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/23021828210.jpg&#34;/&gt;&#xA;&lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 3-50. Sigmoid函数图像&#xA;&lt;/center&gt;&#xA;&lt;p&gt;在图3-50中，由于经过 Sigmoid函数非线性变换后，其值域将被限定在0到1的开区间内，可以发现当输入值在0附近时，Sigmoid激活函数就类似于一个线性函数；当输入值在函数两端时，将对输入形成抑制作用，即梯度趋于0附近。根据图 3-50中 Sigmoid 激活函数的导数$g^{\prime}(x)$的图像可知，$g^{\prime}(x)\in(0,\frac{1}{4})$，即当使用Sigmoid作为激活函数时，会减缓参数的更新速度。因此，Sigmoid 激活函数的最大缺点在于当神经元的输入值过大或者过小时都容易引起神经元的饱和现象，即梯度消失问题，使得网络模型的训练过程变慢甚至停止。通常，此时我们会对输入进行标准化操作，例如将每个特征维度进行归一化操作。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;2. 实现&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在清楚Sigmoid激活函数的基本原理之后，我们再来介绍如何实现与使用。根据式(3-114)可知，Sigmoid的实现代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;sigmoid&lt;/span&gt;(x):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;    &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt; (&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;exp(&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;x))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;进一步，需要将Sigmoid操作当做一个网络层来进行使用，因此需要构造一个继承自&lt;code&gt;nn.Module&lt;/code&gt;类，实现代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;class&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;MySigmoid&lt;/span&gt;(nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Module):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;forward&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, x):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; sigmoid(x)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;最后，可以通过如下方式来进行使用：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;test_Sigmoid&lt;/span&gt;():&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     x &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;randn([&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;], dtype&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;float32)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;     net &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Sequential(MySigmoid())&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;     y &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; net(x)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;     &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#4070a0&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Sigmoid前: &lt;/span&gt;&lt;span style=&#34;color:#70a0d0&#34;&gt;{&lt;/span&gt;x&lt;span style=&#34;color:#70a0d0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;     &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#4070a0&#34;&gt;f&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Sigmoid后: &lt;/span&gt;&lt;span style=&#34;color:#70a0d0&#34;&gt;{&lt;/span&gt;y&lt;span style=&#34;color:#70a0d0&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;上述代码运行结束后，便可以得到类似如下所示的结果：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; Sigmoid前: tensor([[&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;9.01e-02&lt;/span&gt;,  &lt;span style=&#34;color:#40a070&#34;&gt;1.11e+00&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;6.33e-01&lt;/span&gt;,  &lt;span style=&#34;color:#40a070&#34;&gt;3.26e-01&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;7.47e-01&lt;/span&gt;],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;                    [&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;8.38e-01&lt;/span&gt;,  &lt;span style=&#34;color:#40a070&#34;&gt;1.89e-01&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4.15e-01&lt;/span&gt;, &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;5.49e-01&lt;/span&gt;,  &lt;span style=&#34;color:#40a070&#34;&gt;1.11e-04&lt;/span&gt;]])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt; Sigmoid后: tensor([[&lt;span style=&#34;color:#40a070&#34;&gt;0.4775&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.7525&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.3467&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.5810&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.3214&lt;/span&gt;],&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;                    [&lt;span style=&#34;color:#40a070&#34;&gt;0.3034&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.5473&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.3977&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.3661&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.5000&lt;/span&gt;]])&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;当然，在PyTorch中还可以直接通过&lt;code&gt;nn.Sigmoid()&lt;/code&gt;来使用Sigmoid激活函数。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3122-tanh激活函数&#34;&gt;3.12.2 Tanh激活函数&lt;a class=&#34;anchor&#34; href=&#34;#3122-tanh%e6%bf%80%e6%b4%bb%e5%87%bd%e6%95%b0&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. 原理&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Tanh激活函数也叫做双曲正切激活函数，其作用效果与Sigmoid激活函数类似且本质上仍旧属于类 Sigmoid激活函数，都是使用指数来进行非线性变换。Tanh 激活函数会将神经元的输入值压缩到 $(-1,1)$中，与Sigmoid 相比Tanh 的激活值具有更大的激活范围。 其数学定义如下&#xA;&lt;/p&gt;</description>
			</item>
			<item>
				<title>3.13 多标签分类</title>
				<link>https://mlwithme.github.io/dl/chapter03/0d3dacfff4c04794/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter03/0d3dacfff4c04794/</guid>
				<description>&lt;h1 id=&#34;313-多标签分类&#34;&gt;3.13 多标签分类&lt;a class=&#34;anchor&#34; href=&#34;#313-%e5%a4%9a%e6%a0%87%e7%ad%be%e5%88%86%e7%b1%bb&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter03/18fdd1deff424a16&#34;&gt;3.5.5节&lt;/a&gt;内容中，我们介绍了在单标签分类问题中模型损失的度量方法，即交叉熵损失函数。但是在实际应用中我们还会遇到多标签分类（Multi-Label Class）的情况，即对于每个样本来说都可能存在不止一个正确标签的情况。例如在文本分类这一场景中，同一条文本可能会涉及到“体育”、“娱乐”等多个类别标签。在接下来的这篇文章中，我们将会详细介绍在多标签分类任务中两种常见的损失评估方法，以及在多标签分类场景中的模型评价指标。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3131-sigmoid损失&#34;&gt;3.13.1 Sigmoid损失&lt;a class=&#34;anchor&#34; href=&#34;#3131-sigmoid%e6%8d%9f%e5%a4%b1&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在多标签分类场景中，第1种损失衡量方式就是将原始输出层的Softmax操作替换为Sigmoid操作，然后通过计算输出层与标签之间的Sigmoid交叉熵来作为误差的衡量标准，具体计算公式为：&#xA;&lt;/p&gt;&#xA;$$&#xA;loss(y,\hat{y})=-\frac{1}{C} \sum_{i=1}^m\left[y^{(i)}\cdot\log\left(\frac{1}{1+\exp(-\hat{y}^{(i)})}\right)+\left(1-y^{(i)}\right)\cdot\log\left(\frac{\exp(-\hat{y}^{(i)})}{1+\exp(-\hat{y}^{(i)})}\right)\right]\tag{3-122}&#xA;$$&lt;p&gt;&#xA;其中$C$表示类别数量，$y^{(i)}$和$\hat{y}^{(i)}$均为一个向量，分别用来表示真实标签和未经任何激活函数处理的网络输出值。&lt;/p&gt;&#xA;&lt;p&gt;从式(3-122)可以发现，这种误差损失衡量方式其实就是在逻辑回归中用来衡量预测概率与真实标签之间误差的方法。&lt;/p&gt;&#xA;&lt;p&gt;在PyTorch中，可以通过&lt;code&gt;torch.nn&lt;/code&gt;模块中的&lt;code&gt;MultiLabelSoftMarginLoss&lt;/code&gt;类来完成损失的计算，示例代码如下所示：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;Sigmoid_loss&lt;/span&gt;(y_true, y_pred):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     loss &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;MultiLabelSoftMarginLoss(reduction&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;mean&amp;#39;&lt;/span&gt;)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;     &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(loss(y_pred, y_true))  &lt;span style=&#34;color:#60a0b0;font-style:italic&#34;&gt;# 0.5927&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#bb60d5&#34;&gt;__name__&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt;     y_true &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tensor([[&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;], [&lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;]], dtype&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;int16)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;7&lt;/span&gt;     y_pred &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tensor([[&lt;span style=&#34;color:#40a070&#34;&gt;0.2&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.5&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;], [&lt;span style=&#34;color:#40a070&#34;&gt;0.1&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.5&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0.8&lt;/span&gt;]], dtype&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;float32)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;8&lt;/span&gt;     Sigmoid_loss(y_true, y_pred)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第6~7行是构造了两个样本的预测结果和真实标签，且每个样本均有两个类别。同时，需要注意的是&lt;code&gt;MultiLabelSoftMarginLoss&lt;/code&gt;默认返回的是所有样本损失的均值，我们可以通过指定参数&lt;code&gt;reduction&lt;/code&gt;为&lt;code&gt;mean&lt;/code&gt;或&lt;code&gt;sum&lt;/code&gt;来指定返回的类型。&lt;/p&gt;&#xA;&lt;p&gt;对于上述计算过程，我们还可以通过如下代码来进行完成：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; l &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;(y_true &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;log(&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt; (&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;exp(&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;y_pred))) &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;       &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; (&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt; y_true) &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;log(torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;exp(&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;y_pred) &lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt; (&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;exp(&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;y_pred))))&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;mean()&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在完成模型的训练过程后，我们可以通过如下方式来得到模型的预测结果：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;prediction&lt;/span&gt;(logits, K):&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;     y_pred &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;argsort(&lt;span style=&#34;color:#666&#34;&gt;-&lt;/span&gt;logits, axis&lt;span style=&#34;color:#666&#34;&gt;=-&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;)[:, :K]&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;     &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;预测标签：&amp;#34;&lt;/span&gt;, y_pred)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt;     p &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; np&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;vstack([logits[r, c] &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;for&lt;/span&gt; r, c &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;enumerate&lt;/span&gt;(y_pred)])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;5&lt;/span&gt;     &lt;span style=&#34;color:#007020&#34;&gt;print&lt;/span&gt;(&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;预测概率：&amp;#34;&lt;/span&gt;, p)&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;6&lt;/span&gt; prediction(y_pred, &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第1行中K表示多标签的数量。运行结束以后，我们便可以得到如下所示结果：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt; 预测标签&lt;span style=&#34;&#34;&gt;：&lt;/span&gt; tensor([[&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;], [&lt;span style=&#34;color:#40a070&#34;&gt;3&lt;/span&gt;, &lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;]])&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt; 预测概率&lt;span style=&#34;&#34;&gt;：&lt;/span&gt; [[&lt;span style=&#34;color:#40a070&#34;&gt;0.5&lt;/span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;0.2&lt;/span&gt;] [&lt;span style=&#34;color:#40a070&#34;&gt;0.8&lt;/span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;0.5&lt;/span&gt;]]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述输出结果中，第1~2行便是每个样本对应每个类别的标签，且是以概率值递减进行排序&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
