<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>第 8 章 时序与模型融合 on 《从零学AI指南手册》</title>
		<link>https://mlwithme.github.io/dl/chapter08/</link>
		<description>Recent content in 第 8 章 时序与模型融合 on 《从零学AI指南手册》</description>
		<generator>Hugo</generator>
		<language>zh_CN</language>
		
		
		
		
			<atom:link href="https://mlwithme.github.io/dl/chapter08/index.xml" rel="self" type="application/rss+xml" />
			<item>
				<title>8.1 TextCNN网络</title>
				<link>https://mlwithme.github.io/dl/chapter08/2be88fbc08a5418f/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter08/2be88fbc08a5418f/</guid>
				<description>&lt;h1 id=&#34;第-8-章-时序与模型融合&#34;&gt;第 8 章 时序与模型融合&lt;a class=&#34;anchor&#34; href=&#34;#%e7%ac%ac-8-%e7%ab%a0-%e6%97%b6%e5%ba%8f%e4%b8%8e%e6%a8%a1%e5%9e%8b%e8%9e%8d%e5%90%88&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;经过第4章和第7章内容的介绍，我们对于深度学习中常见的两种网络结构CNN和RNN已经有了清晰的认识。CNN主要应用于处理在空间位置上具有相互依关系的特征数据，而RNN则主要应用于处理在时间维度上具有前后依赖的特征数据。可尽管如此，我们依旧可以根据CNN或者其与RNN的相应结合体来完成时序数据的特征提取过程。在本章内容中，我们将会介绍多种基于CNN和RNN的变体模型以及相应的应用案例。&lt;/p&gt;&#xA;&lt;h1 id=&#34;81-textcnn网络&#34;&gt;8.1 TextCNN网络&lt;a class=&#34;anchor&#34; href=&#34;#81-textcnn%e7%bd%91%e7%bb%9c&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;虽然CNN主要用于对输入矩阵相邻空间位置上的信息进行特征编码，但是其同样可以通过多尺度的卷积窗口来刻画时序数据在序列上的特征信息，例如比较经典的TextCNN[1]文本分类模型。TextCNN的核心思想便是基于词的粒度将每个词通过一个固定长度的向量来表示（即词向量，相关内容将在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter09/d4703d990f8d4fed&#34;&gt;9.2节&lt;/a&gt;内容中进行介绍）；然后再将一个句子中所有词的词向量垂直堆叠构成一个$n\times d$的矩阵，其中$n$表示该句中词的个数，$d$表示词向量的维度；最后再采用固定宽度的多尺度卷积核（$m\times d$）进行特征提取并完成后续任务。&lt;/p&gt;&#xA;&lt;h2 id=&#34;811-textcnn结构&#34;&gt;8.1.1 TextCNN结构&lt;a class=&#34;anchor&#34; href=&#34;#811-textcnn%e7%bb%93%e6%9e%84&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;TextCNN利用卷积操作对文本进行局部特征提取，通过不同大小的卷积核捕捉不同长度的局部特征，从而识别出文本中的关键信息。在TextCNN中，整个网络模型总体上分为3层，卷积层、池化层和全连接分类层，网络结构如图8-1所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;580&#34; src=&#34;https://mlwithme.github.io/images/dl/23052759217.jpg&#34;/&gt;&lt;/div&gt;&lt;center&gt;图 8-1 TextCNN网络结构图&lt;/center&gt;&#xA;&lt;p&gt;在图8-1中，最左侧为一个$8\times4$的特征矩阵，其中每一行均为一个4维向量，每个向量表示词表中固定的一个词。基于这样的表示方法，对于任意文本来说我们都可以将其表示成一个固定宽度特征矩阵，并且此时我们可以将其看做是一个单通道的特征图。进一步，TextCNN采用了3个不同窗口长度（分别为3、4、和5）的卷积核进行卷积处理。此时，由于卷积核的宽度同特征图的宽度一致，因此卷积结束后得到的便是一个一维的向量。可以看出，基于这样的卷积操作本质上也可以看作是在对文本的局部序列信息进行特征提取，其长度便依赖于卷积核的窗口长度。&lt;/p&gt;&#xA;&lt;p&gt;在完成卷积操作完成之后，再通过最大化池化操作对每个特征图进行特征提取，此时的每个通道将会变成一个标量值。最后，再将所有结果拼接起来得到一个向量作为文本的特征表示，并追加一个分类层完成后续的分类任务。虽然TextCNN网络结构看似比较简单，但是在实际运用中往往都能取得较好的结果，并且训练速度快不容易过拟合。&lt;/p&gt;&#xA;&lt;h2 id=&#34;812-文本分词&#34;&gt;8.1.2 文本分词&lt;a class=&#34;anchor&#34; href=&#34;#812-%e6%96%87%e6%9c%ac%e5%88%86%e8%af%8d&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter07/4bf3ecf7b21e45fb&#34;&gt;7.6节&lt;/a&gt;内容中我们使用了以单个字为粒度再加上一个词嵌入层的方式来表示文本，接下来我们再来看如何以词为粒度加词嵌入层来表示文本。当然，如果是英文语料的话就不存在字和词的差异了。&lt;/p&gt;&#xA;&lt;p&gt;所谓分词指的是将一句话以中文语义的角度来对其进行分割，然后得到一个小词元。例如对于如下文本来说&lt;/p&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;《活着》是余华的小说，描绘了中国农民的苦难与坚韧。通过主人公福贵的生活经历，展现了战乱、饥饿和政治运动对人民的摧残，同时传递了关于家庭、希望和人性的深刻思考。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;其分词后的结果为&lt;/p&gt;&#xA;&lt;blockquote class=&#39;book-hint &#39;&gt;&#xA;&lt;p&gt;《/活着/》/是/余华/的/小说/，/描绘/了/中国/农民/的/苦难/与/坚韧/。/通过/主人公/福贵/的/生活/经历/，/展现/了/战乱/、/饥饿/和/政治/运动/对/人民/的/摧残/，/同时/传递/了/关于/家庭/、/希望/和/人性/的/深刻/思考/。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&lt;p&gt;然后再以词为单位进行词频统计构造词表并对文本进行向量化。&lt;/p&gt;&#xA;&lt;p&gt;在文本处理中，&lt;code&gt;jieba&lt;/code&gt;是一款常用的开源分词工具[3]，可以通过命令&lt;code&gt;pip install jieba&lt;/code&gt;进行安装。同时，&lt;code&gt;jieba&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;import&lt;/span&gt; &lt;span style=&#34;color:#0e84b5;font-weight:bold&#34;&gt;jieba&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;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;3&lt;/span&gt;     sen &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;今天天气晴朗，阳光明媚，微风轻拂着脸庞，我独自漫步在河边的小径上。&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;4&lt;/span&gt;     segs &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; jieba&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cut(sen)&#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;     result &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;/&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;join(segs)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第4行便是对原始文本进行分词处理并返回一个迭代器。第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:#666&#34;&gt;/&lt;/span&gt;天气晴朗&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;阳光明媚&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;微风&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;轻拂&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;着&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;脸庞&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;我&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;独自&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;漫步&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;在&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;河边&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;的&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;小径&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;上&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;。&lt;/span&gt;&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;&#xA;&lt;p&gt;虽然通过上述方式可以完成句子在词粒度层面的分割，但是对于有的词语来讲可以有不同的分词方法。此时，可以通过在上面的&lt;code&gt;cut&lt;/code&gt;函数中指定全分词模式，即&lt;code&gt;jieba.cut(sen, cut_all=True)&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:#666&#34;&gt;/&lt;/span&gt;今天天气&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;天天&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;天气&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;天气晴朗&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;晴朗&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;阳光&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;阳光明媚&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;光明&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;明媚&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;微风&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;轻拂&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;着&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;脸庞&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;，&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;我&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;独自&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;漫步&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;在&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;河边&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;的&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;小径&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;上&lt;span style=&#34;color:#666&#34;&gt;/&lt;/span&gt;&lt;span style=&#34;&#34;&gt;。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在实际运用中可以根据情况来选择不同的模式。当然，&lt;code&gt;jieba&lt;/code&gt;除了可以做分词处理之外，还提供了关键词抽取、词性标注和新词发现等功能，有需要的读者可以自行查阅学习。&lt;/p&gt;&#xA;&lt;h2 id=&#34;813-textcnn实现&#34;&gt;8.1.3 TextCNN实现&lt;a class=&#34;anchor&#34; href=&#34;#813-textcnn%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在清楚TextCNN模型的相关原理后，我们再来看如何借助PyTorch快速实现该模型。 以下完整示例代码可以参见&lt;code&gt;Code/Chapter08/C01_TextCNN/TextCNN.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;首先需要实现模型的整个前向传播过程。从图8-1可知，整个模型整体分为词嵌入层、卷积层、池化层和全连接4个部分，实现代码如下所示：&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;TextCNN&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;__init__&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, vocab_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2000&lt;/span&gt;, embedding_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;512&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;                  window_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;None&lt;/span&gt;, out_channels&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;, fc_hidden_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;128&lt;/span&gt;, num_classes&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;10&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&#34;&gt;super&lt;/span&gt;(TextCNN, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;)&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#06287e&#34;&gt;__init__&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; window_size &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;None&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;             window_size &lt;span style=&#34;color:#666&#34;&gt;=&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;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;7&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;vocab_size &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; vocab_size&#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&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;embedding_size &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; embedding_size&#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;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;window_size &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; window_size&#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;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; out_channels&#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;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;fc_hidden_size &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; fc_hidden_size&#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;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;num_classes &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; num_classes&#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:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;token_embedding &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Embedding(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;vocab_size, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;embedding_size)&#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:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;convs &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; [nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Conv2d(&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, out_channels, &#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;15&lt;/span&gt;                       kernel_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;(k, embedding_size)) &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;for&lt;/span&gt; k &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;in&lt;/span&gt; window_size]&#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;16&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;max_pool &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;AdaptiveMaxPool2d((&lt;span style=&#34;color:#40a070&#34;&gt;1&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;17&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;classifier &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Sequential(&#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;18&lt;/span&gt;             nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(&lt;span style=&#34;color:#007020&#34;&gt;len&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;window_size) &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;num_classes))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第5~12行是初始化相关模型超参数。第13行是实例化一个词嵌入层，即一个二维权重矩阵，其中每一行均为词表中每个词对应的唯一向量表示。第14~15行则是根据不同卷积窗口长度实例化多个卷积层。第16行是实例化一个自适应的最大池化层，其输出形状为&lt;code&gt;[1,1]&lt;/code&gt;，并且由于池化层没有参数所以多个卷积层可以共享同一个池化层。第17~18行是实例化一个分类层，其输入维度为卷积层的个数乘以每个卷积层输出的特征图通道数。&lt;/p&gt;</description>
			</item>
			<item>
				<title>8.2 TextRNN网络</title>
				<link>https://mlwithme.github.io/dl/chapter08/9023d1f822a54226/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter08/9023d1f822a54226/</guid>
				<description>&lt;h1 id=&#34;82-textrnn网络&#34;&gt;8.2 TextRNN网络&lt;a class=&#34;anchor&#34; href=&#34;#82-textrnn%e7%bd%91%e7%bb%9c&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter07/ec8ff069aadc49b9&#34;&gt;7.2节&lt;/a&gt;内容中，我们详细介绍了如何通过RNN模型来完成文本分类任务，且当时使用的是one-hot编码形式来表示原始文本。在接下来的这节内容中，我们将会再次介绍基于RNN结构的文本分类模型TextRNN。准确来说TextRNN并不是一个某一个特定模型的名称，而是一系列以RNN模型为基础所构造的一类模型的总称。&lt;/p&gt;&#xA;&lt;h2 id=&#34;821-textrnn结构&#34;&gt;8.2.1 TextRNN结构&lt;a class=&#34;anchor&#34; href=&#34;#821-textrnn%e7%bb%93%e6%9e%84&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;TextRNN模型的主要思想是通过循环神经网络结构将文本数据的每个词或字符作为输入，并在每个时间步骤中更新隐藏状态，以对整个序列进行特征提取。具体而言，TextRNN会先将文本序列通过一个嵌入层将one-hot编码形式的稀疏向量转换为稠密向量（Dense Vector）来表示每个词或字符；然后再将其输入到RNN中进行特征提取；最后再将提取得到的特征进行组合并完成后续的分类任务[1]。对于TextRNN模型，其整体结构如图8-2所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;420&#34; src=&#34;https://mlwithme.github.io/images/dl/23052884920.jpg&#34;/&gt;&lt;/div&gt;&lt;center&gt;图 8-2 TextRNN网络结构图&lt;/center&gt;&#xA;&lt;p&gt;如图8-2所示，从下往上第1层是嵌入层；第2层的RNN层，既可以是原始RNN也可以是后续的各种变体LSTM、GRU和BiRNN等；第3层则是选取RNN的输出特征，既可以是只取最后一个时刻，也可以是取所有时刻的均值或者求和等；第4层则是最后的一个分类层。&lt;/p&gt;&#xA;&lt;h2 id=&#34;822-textrnn实现&#34;&gt;8.2.2 TextRNN实现&lt;a class=&#34;anchor&#34; href=&#34;#822-textrnn%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在清楚TextRNN模型的相关原理后，我们再来看如何借助PyTorch快速实现该模型。 以下完整示例代码可以参见&lt;code&gt;Code/Chapter08/C02_TextRNN/TextRNN.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;首先需要实现模型的整个前向传播过程。从图8-2可知，整个模型整体分为3个大的部分，词嵌入层、循环神经网络层和全连接，实现代码如下所示：&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;TextRNN&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;__init__&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, config):&#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;super&lt;/span&gt;(TextRNN, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;)&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#06287e&#34;&gt;__init__&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;if&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;RNN&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;5&lt;/span&gt;             rnn_cell &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;RNN&#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;elif&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;LSTM&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;7&lt;/span&gt;             rnn_cell &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;LSTM&#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;elif&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;GRU&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;9&lt;/span&gt;             rnn_cell &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;GRU&#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;font-weight:bold&#34;&gt;else&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;             &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;ValueError&lt;/span&gt;(&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Unrecognized RNN cell type: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type)&#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;         out_hidden_size &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;hidden_size &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#007020&#34;&gt;int&lt;/span&gt;(config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;bidirectional) &lt;span style=&#34;color:#666&#34;&gt;+&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;13&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;config &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; config&#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:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;token_embedding &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Embedding(config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;top_k, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;embedding_size)&#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;15&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;rnn &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; rnn_cell(config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;embedding_size, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;hidden_size, num_layers&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;num_layers,&#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;16&lt;/span&gt;                             batch_first&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;, bidirectional&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;bidirectional)&#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;17&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;classifier &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;LayerNorm(out_hidden_size),&#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;18&lt;/span&gt;                 nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(out_hidden_size, out_hidden_size),nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;ReLU(inplace&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;19&lt;/span&gt;                 nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Dropout(&lt;span style=&#34;color:#40a070&#34;&gt;0.5&lt;/span&gt;),nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Linear(out_hidden_size, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;num_classes))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第2行中&lt;code&gt;config&lt;/code&gt;表示一个实例化的配置类对象，通过这样的方式可以更便捷的管理模型参数，具体可参见&lt;a href=&#34;https://mlwithme.github.io/dl/chapter05/4557a6f03dec4475&#34;&gt;5.1节&lt;/a&gt;内容。第4~11行是根据对应的参数返回相应的循环记忆单元。第12行是计算循环神经网络输出结的维度，即在双向结构中该维度为单向结构的2倍，具体可参见&lt;a href=&#34;https://mlwithme.github.io/dl/chapter07/b6e5ccb6cd064f74?id=_753-%e6%a8%a1%e5%9e%8b%e5%ae%9e%e7%8e%b0&#34;&gt;7.5.3节&lt;/a&gt;内容。第14行是实例化得到一个词嵌入层。第15~16行是根据对应参数实例化得到循环记忆单元。第17~19行则是由两个全连接构成的分类层。&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;forward&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, x, labels&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;None&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; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;token_embedding(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;         x, _ &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;rnn(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;4&lt;/span&gt;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cat_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;last&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;5&lt;/span&gt;             x &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; x[:, &lt;span style=&#34;color:#666&#34;&gt;-&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;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;elif&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cat_type &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;7&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;mean(x, dim&lt;span style=&#34;color:#666&#34;&gt;=&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;8&lt;/span&gt;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;elif&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cat_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;sum&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;9&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;sum(x, dim&lt;span style=&#34;color:#666&#34;&gt;=&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;10&lt;/span&gt;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;else&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;             &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;ValueError&lt;/span&gt;(&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Unrecognized cat_type: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cat_type)&#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;         logits &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;classifier(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;13&lt;/span&gt;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;if&lt;/span&gt; labels &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;is&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;not&lt;/span&gt; &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;None&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;             loss_fct &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;CrossEntropyLoss(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;15&lt;/span&gt;             loss &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; loss_fct(logits, labels)&#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;16&lt;/span&gt;             &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; loss, logits&#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;17&lt;/span&gt;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;else&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;18&lt;/span&gt;             &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; logits&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第2行是词嵌入层的输出结果，形状为&lt;code&gt;[batch_size, src_len, embedding_size]&lt;/code&gt;。第3行是RNN计算后的输出结果，形状为&lt;code&gt;[batch_size, src_len, out_hidden_size]&lt;/code&gt;。第4~11行是根据不同的组合方式对循环神经网络的输出结果进行组合，形状为&lt;code&gt;[batch_size, out_hidden_size]&lt;/code&gt;。第12行则是最后的分类层，输出结果形状为&lt;code&gt;[batch_size, num_classes]&lt;/code&gt;。第13~18行则是根据条件返回对应的处理结果。&lt;/p&gt;</description>
			</item>
			<item>
				<title>8.3 CNN-RNN网络</title>
				<link>https://mlwithme.github.io/dl/chapter08/9edd7db2d439402f/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter08/9edd7db2d439402f/</guid>
				<description>&lt;h1 id=&#34;83-cnn-rnn网络&#34;&gt;8.3 CNN-RNN网络&lt;a class=&#34;anchor&#34; href=&#34;#83-cnn-rnn%e7%bd%91%e7%bb%9c&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在前面两节内容中，我们分别介绍了通过CNN和RNN来对文本数据进行特征提取的建模方法，前者是从序列局部的角度来捕捉文本序列前后之间的依赖关系，而后者则是利用了RNN固有的特性来对序列数据进行特征提取。总的来说两者各有优势，在提取特征方面有不同的侧重点，因此把CNN和RNN模型进行组合也成为了一种非常流行的做法[1] [2] [3] [4] [5] [6]。&lt;/p&gt;&#xA;&lt;p&gt;在本节内容中我们将会详细介绍两种以CNN和RNN为基础模块的CNN-RNN模型，即：①以先CNN再RNN的顺序对时序数据进行特征提取[1] [2]；②以先RNN再CNN的顺序进行[3] [4] [5]。&lt;/p&gt;&#xA;&lt;h2 id=&#34;831-c-lstm结构&#34;&gt;8.3.1 C-LSTM结构&lt;a class=&#34;anchor&#34; href=&#34;#831-c-lstm%e7%bb%93%e6%9e%84&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;从名字也可以看出C-LSTM模型是以先CNN再RNN的顺序对时序数据进行特征提取。C-LSTM模型的核心思想在于先利用CNN局部特征提取的能力来抽取文本中短语粒度的特征表示，然后再利用LSTM对卷积后的特征图进行时序上的语义理解，最后得到整个文本的特征表示[1]。如图8-3所示便是C-LSTM模型对应的网络结构图。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;450&#34; src=&#34;https://mlwithme.github.io/images/dl/23060101020.jpg&#34;/&gt;&lt;/div&gt;&lt;center&gt;图 8-3 C-LSTM网络结构图&lt;/center&gt;&#xA;&lt;p&gt;如图8-3所示，最左侧为一个$8\times4$的特征矩阵，其含义同&lt;a href=&#34;https://mlwithme.github.io/dl/chapter08/2be88fbc08a5418f?id=_811-textcnn%e7%bd%91%e7%bb%9c%e7%bb%93%e6%9e%84&#34;&gt;8.1.1节&lt;/a&gt;中的一致，这里不再赘述。进一步，C-LSTM模型采用了多卷积核卷积对其进行局部特征提取，这可以看作是短语层面的语义信息。此时得到的特征图有两方面的含义：①对于特征图的每一行（即每次卷积窗口滑动后计算得到的结果）来说它表示的仍旧是具有前后时序关系的序列特征，只是获得的更大粒度的语义信息；②对于特征图的每个通道来说可以看作是同一时刻多个维度的语义信息。因此，C-LSTM模型最后会对卷积后的结果进行重构并作为LSTM的输入进行时序上的特征提取。&lt;/p&gt;&#xA;&lt;p&gt;除此之外，类似的还有CNN-LSTM模型[2]，其结构整体上与C-LSTM类似，仅仅只是在CNN处理后还加入了一个特定的池化层。&lt;/p&gt;&#xA;&lt;h2 id=&#34;832-c-lstm实现&#34;&gt;8.3.2 C-LSTM实现&lt;a class=&#34;anchor&#34; href=&#34;#832-c-lstm%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在清楚C-LSTM模型的相关原理后，我们再来看如何借助PyTorch实现该模型。 以下完整示例代码可以参见&lt;code&gt;Code/Chapter08/C03_CLSTM/CLSTM.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;首先实现模型的整个前向传播过程。从图8-3可知，整个模型整体分为4个大的部分，词嵌入层、卷积层和循环神经网络层以及后续的分类层，实现代码如下所示：&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;CLSTM&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;__init__&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, config):&#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;super&lt;/span&gt;(CLSTM, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;)&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#06287e&#34;&gt;__init__&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;if&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;RNN&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;5&lt;/span&gt;             rnn_cell &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;RNN&#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;elif&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;LSTM&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;7&lt;/span&gt;             rnn_cell &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;LSTM&#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;elif&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type &lt;span style=&#34;color:#666&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#39;GRU&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;9&lt;/span&gt;             rnn_cell &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;GRU&#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;font-weight:bold&#34;&gt;else&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;             &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;raise&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;ValueError&lt;/span&gt;(&lt;span style=&#34;color:#4070a0&#34;&gt;&amp;#34;Unrecognized RNN cell type: &amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cell_type)&#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;         out_hidden_size &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;hidden_size &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; (&lt;span style=&#34;color:#007020&#34;&gt;int&lt;/span&gt;(config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;bidirectional) &lt;span style=&#34;color:#666&#34;&gt;+&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;13&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;config &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; config&#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:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;token_embedding &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Embedding(config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;vocab_size, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;embedding_size)&#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;15&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;conv &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Conv2d(&lt;span style=&#34;color:#40a070&#34;&gt;1&lt;/span&gt;, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels,&#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;16&lt;/span&gt;                               kernel_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;(config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;window_size, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;embedding_size))&#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;17&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;rnn &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; rnn_cell(config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;hidden_size, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;num_layers,&#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;18&lt;/span&gt;                             batch_first&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;, bidirectional&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;bidirectional)&#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;19&lt;/span&gt;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;classifier &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(out_hidden_size, config&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;num_classes))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第4~11行是根据对应的参数返回相应的循环记忆单元。第12行是计算循环神经网络输出结的维度，即在双向结构中该维度为单向结构的2倍，具体可参见&lt;a href=&#34;https://mlwithme.github.io/dl/chapter07/b6e5ccb6cd064f74?id=_753-%e6%a8%a1%e5%9e%8b%e5%ae%9e%e7%8e%b0&#34;&gt;7.5.3节&lt;/a&gt;内容。第14行是实例化得到一个词嵌入层。第15~16行是实例化得到一个卷积层。第17~18行是根据对应参数实例化得到循环记忆单元。第19行则是由一个全连接构成的分类层。&lt;/p&gt;</description>
			</item>
			<item>
				<title>8.4 ConvLSTM网络</title>
				<link>https://mlwithme.github.io/dl/chapter08/19c2b86e85f2461e/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter08/19c2b86e85f2461e/</guid>
				<description>&lt;h1 id=&#34;84-convlstm网络&#34;&gt;8.4 ConvLSTM网络&lt;a class=&#34;anchor&#34; href=&#34;#84-convlstm%e7%bd%91%e7%bb%9c&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter08/9edd7db2d439402f&#34;&gt;8.3节&lt;/a&gt;内容中，我们介绍了几种将CNN和RNN进行结合的时序模型，包括串行的方式将CNN和RNN进行结合、以并行的方式将CNN和RNN进行结合。同时，在这些任务场景中序列样本所拥有的一个共同特点便是对于每个序列中的每个时刻来说，其特征表示均为一个向量。但是在现实情况中，还有一类时序数据是以数据帧的形式而存在，即每一时刻均为一个三维（或二维）矩阵。这样的数据也被称为时空（Spatiotemporal）数据，例如最常见的视频数据。因此，在本节内容中，我们将会介绍另外一种结合CNN和RNN的深度学习模型ConvLSTM来解决这一问题[1]。&lt;/p&gt;&#xA;&lt;h2 id=&#34;841-convlstm动机&#34;&gt;8.4.1 ConvLSTM动机&lt;a class=&#34;anchor&#34; href=&#34;#841-convlstm%e5%8a%a8%e6%9c%ba&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在气象学领域中，对于如何能够准确地预测未来短时间（如0~6小时）内的降雨情况一直以来就是一个热门的研究方向。通常，研究者会根据实时拍摄得到的雷达回波数据（Radar Echo Data）作为输入序列来预测接下来一段时间内的降雨情况。得益于深度学习的发展，有研究者提出了基于循环神经网络和卷积神经网络的预测模型。尽管通过这样的结合方式也能够建模完成这一预测任务，但是模型并没有充分考虑到时空数据中的空间依赖关系（Spatial Correlation）。&lt;/p&gt;&#xA;&lt;p&gt;基于这样的动机，施行健等人[1]在2015年提出了一种融合CNN和LSTM的时序预测模型ConvLSTM。ConvLSTM模型的动机是通过将CNN和LSTM结合起来克服传统RNN和CNN各自的局限性。ConvLSTM引入了空间上的卷积操作和时间上的循环操作，同时保留了LSTM中的记忆单元和门控机制，能够捕捉到时间和空间上的特征，考虑到时序数据的长期依赖性和空间结构的局部相关性。因此,ConvLSTM可以有效地用于处理时空数据，例如视频数据、雷达数据等。&lt;/p&gt;&#xA;&lt;h2 id=&#34;842-convlstm结构&#34;&gt;8.4.2 ConvLSTM结构&lt;a class=&#34;anchor&#34; href=&#34;#842-convlstm%e7%bb%93%e6%9e%84&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;从整体上看，ConvLSTM的模型结构主要分为两部分：在时序结构上遵循典型的RNN网络结构；在空间结构上遵循CNN的特征提取方式。简单来说，ConvLSTM模型就等价于将LSTM中的所有全连接结构替换为卷积结构，同时采用了基于窥视连接的结构（详见&lt;a href=&#34;https://mlwithme.github.io/dl/chapter07/4112672112224dc1&#34;&gt;7.4.5节&lt;/a&gt;内容）。如图8-5所示便是ConvLSTM的循环记忆单元。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/230611133922.jpg&#34;/&gt;&lt;/div&gt;&lt;center&gt;图 8-5 ConvLSTM结构图&lt;/center&gt;&#xA;&lt;p&gt;如图8-5所示便是ConvLSTM的记忆单元结构图，总体上同LSTM类似包含有4个门结构，因此这部分内容不在赘述参考&lt;a href=&#34;https://mlwithme.github.io/dl/chapter07/b4c5ddcc9e904238&#34;&gt;7.3节&lt;/a&gt;内容即可。对于ConvLSTM来说，其唯一变化的地方在于各个门控单元的计算方式，具体计算过程如式(8-1)所示。&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;f_t&amp;=\sigma([h_{t-1},x_t,C_{t-1}]\ast W_f+b_f)\\[2ex]&#xA;i_t&amp;=\sigma([h_{t-1},x_t,C_{t-1}]\ast W_i+b_i)\\[2ex]&#xA;\tilde{C_t}&amp;=\tanh([h_{t-1},x_t]\ast W_c+b_c)\\[2ex]&#xA;C_t&amp;=f_t\odot C_{t-1}\oplus  i_t\odot\tilde{C_t}\\[2ex]&#xA;o_t&amp;=\sigma([h_{t-1},x_t,C_{t}]\ast W_o+b_o)\\[2ex]&#xA;h_t&amp;=o_t\odot\tanh(C_t)&#xA;\end{aligned}\tag{8-1}&#xA;$$&lt;p&gt;在式(8-1)中，$\ast$ 表示卷积操作，$W_f$、$W_i$、$W_c$和$W_o$均为卷积核，因此ConvLSTM模型的输入将是一个5维张量，即&lt;code&gt;[batch_size,time_step,in_channels,height,width]&lt;/code&gt;。由此可知，$x_t$的形状为&lt;code&gt;[batch_size,in_channels,height,width]&lt;/code&gt;；$h_t$和$C_t$的形状均为&lt;code&gt;[batch_size,out_channels,height,width]&lt;/code&gt;；$[h_{t-1},x_t]$的形状为&lt;code&gt;[batch_size,in_channels+out_channels,height,width]&lt;/code&gt;；$[h_{t-1},x_t,C_{t-1}]$的形状为&lt;code&gt;[batch_size,in_channels+out_channels*2,height,width]&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;同时，由于循环神经网络可以在时间维度和网络层数两个方向展开，因此在ConvLSTM记忆单元中每次卷积之前都会进行填充，以保证每次卷积后特征图的长和宽不发生改变，所以$f_t$、$i_t$和$o_t$的形状均为&lt;code&gt;[batch_size, out_channels, height, width]&lt;/code&gt;。对于ConvLSTM来说，其同样类似于RNN模型，因此也可以根据&lt;a href=&#34;https://mlwithme.github.io/dl/chapter07/88ba4e03337b4233?id=_714-rnn%e7%b1%bb%e5%9e%8b&#34;&gt;7.1.4节&lt;/a&gt;中的结构来构造网络模型并完成相关下游任务。&lt;/p&gt;&#xA;&lt;h2 id=&#34;843-convlstm实现&#34;&gt;8.4.3 ConvLSTM实现&lt;a class=&#34;anchor&#34; href=&#34;#843-convlstm%e5%ae%9e%e7%8e%b0&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在清楚ConvLSTM模型的相关原理之后，我们再来看如何借助PyTorch快速实现ConvLSTM模型。由于PyTorch框架中的&lt;code&gt;nn&lt;/code&gt;模块并没有实现ConvLSTM模型，因此需要我们自己动手进行实现。以下完整示例代码可以参见&lt;code&gt;Code/Chapter08/C05_ConvLSTM/ConvLSTM.py&lt;/code&gt;文件。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;1. &lt;code&gt;ConvLSTMCell&lt;/code&gt;实现&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;为了便于实现这里以不带窥视连接的结构进行介绍。首先，需要实现一个单独的ConvLSTM记忆单元的前向传播过程，示例代码如下所示：&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;ConvLSTMCell&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;__init__&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, in_channels, out_channels, kernel_size, bias):&#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;super&lt;/span&gt;(ConvLSTMCell, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;)&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#06287e&#34;&gt;__init__&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&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;in_channels &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; in_channels&#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;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; out_channels&#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;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;kernel_size &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; kernel_size&#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;         &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;padding &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; kernel_size[&lt;span style=&#34;color:#40a070&#34;&gt;0&lt;/span&gt;] &lt;span style=&#34;color:#666&#34;&gt;//&lt;/span&gt; &lt;span style=&#34;color:#40a070&#34;&gt;2&lt;/span&gt;, kernel_size[&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;2&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&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;bias &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; bias&#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;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;conv &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; nn&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;Conv2d(in_channels&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;in_channels &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels,&#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; &#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9; out_channels&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#40a070&#34;&gt;4&lt;/span&gt; &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels,kernel_size&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;kernel_size,&#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;                 padding&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;padding,bias&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;bias)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第1行中&lt;code&gt;in_channels&lt;/code&gt;表示输入特征图的通道数，&lt;code&gt;out_channels&lt;/code&gt;表示输出特征图的通道数，&lt;code&gt;kernel_size&lt;/code&gt;表示卷积核的窗口大小为一个元组。第7行用于计算填充的数量，以保证每次卷积后特征图的大小不发生变化，其计算规则可见&lt;a href=&#34;https://mlwithme.github.io/dl/chapter04/762f60de801a4ccd?id=_432-%e5%bd%a2%e7%8a%b6%e8%ae%a1%e7%ae%97&#34;&gt;4.3.2节&lt;/a&gt;内容；同时，为了提高计算效率，对于ConvLSTM中所有卷积操作可以在一个&lt;code&gt;Conv2d&lt;/code&gt;实例中完成，第9~10行中&lt;code&gt;in_channels&lt;/code&gt;和&lt;code&gt;out_channels&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;forward&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, input_tensor, last_state):&#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;         h_last, c_last &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; last_state&#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;         combined_input &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;cat([input_tensor, h_last], dim&lt;span style=&#34;color:#666&#34;&gt;=&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;         combined_conv &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;conv(combined_input)&#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;         cc_i, cc_f, cc_o, cc_g &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;split(combined_conv, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels, dim&lt;span style=&#34;color:#666&#34;&gt;=&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;         i &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;sigmoid(cc_i)&#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;         f &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;sigmoid(cc_f)&#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;         o &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;sigmoid(cc_o)&#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;         g &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tanh(cc_g)&#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;         c_next &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; f &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; c_last &lt;span style=&#34;color:#666&#34;&gt;+&lt;/span&gt; i &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; g&#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;         h_next &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; o &lt;span style=&#34;color:#666&#34;&gt;*&lt;/span&gt; torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;tanh(c_next)&#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;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; h_next, c_next&#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; &#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:#007020;font-weight:bold&#34;&gt;def&lt;/span&gt; &lt;span style=&#34;color:#06287e&#34;&gt;init_hidden&lt;/span&gt;(&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;, batch_size, image_size):&#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;15&lt;/span&gt;         height, width &lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt; image_size&#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;16&lt;/span&gt;         &lt;span style=&#34;color:#007020;font-weight:bold&#34;&gt;return&lt;/span&gt; (torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;zeros(batch_size, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels, &#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;17&lt;/span&gt;         &#x9;&#x9;height, width, device&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;conv&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;weight&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;device),&#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;18&lt;/span&gt;                 torch&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;zeros(batch_size, &lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;out_channels, &#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;19&lt;/span&gt;                 height, width, device&lt;span style=&#34;color:#666&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#007020&#34;&gt;self&lt;/span&gt;&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;conv&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;weight&lt;span style=&#34;color:#666&#34;&gt;.&lt;/span&gt;device))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在上述代码中，第1行&lt;code&gt;input_tensor&lt;/code&gt;表示当前时刻的输入形状为&lt;code&gt;[batch_size, in_channels, height, width]&lt;/code&gt;。第2行&lt;code&gt;last_state&lt;/code&gt;表示上一个时刻的输出，包含$h_{t-1}$和$C_{t-1}$两个部分形状均为&lt;code&gt;[batch_size, out_channels, height, width]&lt;/code&gt;。第3行表示将$h_{t-1}$和$x_t$进行拼接，形状为&lt;code&gt;[batch_size, in_channels+out_channels, height, width]&lt;/code&gt;。第4行为同时计算4个部分的卷积运算。第5行是将卷积运算后的整体结果在&lt;code&gt;dim=1&lt;/code&gt;这个维度上按照&lt;code&gt;self.out_channels&lt;/code&gt;的大小分割，即分割成4个部分，因为卷积运算后的通道数为&lt;code&gt;4 * self.out_channels&lt;/code&gt;。第6~12行则是进行相关状态的计算输出。第14~19行是定义一个方法来实现初始时刻的初始化过程。&lt;/p&gt;</description>
			</item>
			<item>
				<title>8.5 3DCNN网络</title>
				<link>https://mlwithme.github.io/dl/chapter08/1e6da79bf7b44c20/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter08/1e6da79bf7b44c20/</guid>
				<description>&lt;h1 id=&#34;85-3dcnn网络&#34;&gt;8.5 3DCNN网络&lt;a class=&#34;anchor&#34; href=&#34;#85-3dcnn%e7%bd%91%e7%bb%9c&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在&lt;a href=&#34;https://mlwithme.github.io/dl/chapter08/19c2b86e85f2461e&#34;&gt;8.4节&lt;/a&gt;内容中，我们详细介绍了一种用于对时空数据进行特征提取的ConvLSTM模型，其有效地结合了RNN和CNN各自的优点对输入数据在时间和空间两个维度进行建模。在接下来的这节内容中将会介绍另外一种拓展自传统卷积网络的3D卷积模型来对时空数据进行特征提取。&lt;/p&gt;&#xA;&lt;h2 id=&#34;851-3dcnn动机&#34;&gt;8.5.1 3DCNN动机&lt;a class=&#34;anchor&#34; href=&#34;#851-3dcnn%e5%8a%a8%e6%9c%ba&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;在传统的卷积神经网络中，卷积操作可以直接用于对二维图像数据进行特征提取，但是对于类似视频这样的时空数据却不能对其时间维度上的信息进行建模。在时空数据中，原始数据是由一系列连续的帧（二维图像）组成，每一帧内部包含了空间信息，而帧与帧之间还存在时间关系，因此传统的二维CNN只能对单独的帧进行处理而无法捕捉到帧与帧之间的时序特征。&lt;/p&gt;&#xA;&lt;p&gt;基于这样的动机，姬水旺[1]等人在2014年提出了一种同时能够考虑时序信息的卷积模型（3D Convolutional Neural Network, 3DCNN）。3DCNN的基本结构与传统的CNN类似，由多个卷积层、池化层和全连接层组成，但是3DCNN在卷积操作中使用了3D卷积核，同时在池化操作中同时考虑了时间和空间维度，这使得3DCNN能够捕捉数据中的时空特征并在处理时间序列或空间序列数据时更加有效。&lt;/p&gt;&#xA;&lt;h2 id=&#34;852-3dcnn结构&#34;&gt;8.5.2 3DCNN结构&lt;a class=&#34;anchor&#34; href=&#34;#852-3dcnn%e7%bb%93%e6%9e%84&#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;在3DCNN中，其核心部分便是其中的三维卷积操作。根据&lt;a href=&#34;Ch08.4_ConvLSTM?id=_842-convlstm%e5%8e%9f%e7%90%86&#34;&gt;8.4.2节&lt;/a&gt;内容可知，时空数据一共包含有4个维度，即长度、宽度、通道数和时序长度。因此，在3DCNN中卷积层对输入数据进行卷积操作时除了像二维卷积一样需要在长度和宽上进行滑动，还需要以固定深度在时序长度这个维度上进行滑动，并在每个位置上与输入数据进行逐元素相乘求和，从而生成输出特征图。&lt;/p&gt;&#xA;&lt;p&gt;如图8-7所示，从上到下依次为2D卷积对单帧数据、2D卷积对多帧数据和3D卷积对多帧数据的特征提取过程。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;350&#34; src=&#34;https://mlwithme.github.io/images/dl/230618160432.jpg&#34;/&gt; &lt;/div&gt;&#xA;&lt;center&gt;&#xA;  图 8-7 2D卷积与3D卷积对比图[2]&#xA;&lt;/center&gt;&#xA;&lt;p&gt;在图8-7(a)中，使用卷积核通道数为单个数据帧帧通道数的2D维卷积对单帧数据进行特征提取后得到的仍旧只是一个数据帧；在图8-7(b)中，使用卷积核通道数为单帧通道数乘以数据帧数的2D卷积后得到的也只是一个数据帧；在图8-7(c)中，使用卷积核通道数为$d(d&lt;L)$，且同时在数据帧这个维度上进行滑动的3D卷积对多帧数据进行特征提取后得到的还是一个多帧数据。具体地，对于图8-7(c)中的卷积过程进一步还可以细化为图8-8中的形式。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;600&#34; src=&#34;https://mlwithme.github.io/images/dl/230617202815.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图8-8 3D卷积计算示例图&lt;/center&gt;&#xA;&lt;p&gt;如图8-8所示，左侧为原始的输入数据和卷积核，对于输入数据来说一共包含有5帧，其中每一帧中有2个特征通道；右侧为3D卷积计算结果后的结果，一共包含有4帧，每一帧有3个特征通道。由此可知，对于3D卷积来说卷积核可通过长度、宽度、通道数、深度和卷积核个数这个5个维度来进行表示。例如对于图8-8中的示例来说，该卷积核的长度和宽度均为$k$、通道数和深度均为2、卷积核的个数为3（对应的便是输出的3个通道）。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;2. 计算示例&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在清楚3D卷积的计算原理后我们再通过一个实际的计算示例来体会整个计算过程。现在假定原始输入数据有3帧，其中每一帧有2个特征通道，长宽均为5，即形状为&lt;code&gt;[in_channels, frame_len, height, width]&lt;/code&gt;；卷积核个数为2，长宽均为3，深度为2，即形状为&lt;code&gt;[out_channels, in_channels, depth, height, width]&lt;/code&gt;。整体相关信息如图8-9所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;600&#34; src=&#34;https://mlwithme.github.io/images/dl/230618101329.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图8-9 3D卷积输入和卷积核示意图&lt;/center&gt;&#xA;&lt;p&gt;如图8-9所示，左侧便是原始的输入数据帧，其形状为&lt;code&gt;[2,3,5,5]&lt;/code&gt;；右侧有为卷积核与偏置，其中卷积核的形状为&lt;code&gt;[2,2,2,3,3]&lt;/code&gt;。由此可知，在不进行填充的情况下，3D卷积最终计算完成后特征图一共包含有2帧，每一帧的长宽均为3，特征通道数为2。&lt;/p&gt;&#xA;&lt;p&gt;进一步，3D卷积的计算过程可以通过图8-10来进行表示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;600&#34; src=&#34;https://mlwithme.github.io/images/dl/230618101422.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图8-10 3D卷积计算示意图&lt;/center&gt;&#xA;&lt;p&gt;如图8-10所示，对于第1个卷积核来说，第1帧的第1个值3的计算过程如式(8-2)所示。&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;&amp;(8\cdot1+2\cdot1+5\cdot1+9\cdot1)+(3\cdot1+7\cdot1+6\cdot1+6\cdot1)+\\[2ex]&amp;(1\cdot1+2\cdot1+2\cdot1+2\cdot1+1\cdot1)+(1\cdot1+5\cdot1+5\cdot1+4\cdot2)-70=3&#xA;\end{aligned}\tag{8-2}&#xA;$$&lt;p&gt;&#xA;可以发现，其计算过程同2D卷积类似，即卷积核每个位置上与输入数据进行逐元素相乘求和。&lt;/p&gt;&#xA;&lt;p&gt;&lt;subscribe&gt;46&lt;/subscribe&gt;&lt;/p&gt;&#xA;&lt;br&gt;&#xA;&lt;br&gt;&#xA;&lt;br&gt;</description>
			</item>
			<item>
				<title>8.6 STResNet网络</title>
				<link>https://mlwithme.github.io/dl/chapter08/5f426a9190e7454b/</link>
				<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
				<guid>https://mlwithme.github.io/dl/chapter08/5f426a9190e7454b/</guid>
				<description>&lt;h1 id=&#34;86-stresnet网络&#34;&gt;8.6 STResNet网络&lt;a class=&#34;anchor&#34; href=&#34;#86-stresnet%e7%bd%91%e7%bb%9c&#34;&gt;#&lt;/a&gt;&lt;/h1&gt;&#xA;&lt;p&gt;在前面几节内容中， 我们陆续介绍了多种通过结合CNN和RNN的模型来对时序数据进行建模，并且从第8.4节内容开始还首次引入了基于时空数据相关任务。不管是&lt;a href=&#34;https://mlwithme.github.io/dl/chapter08/19c2b86e85f2461e&#34;&gt;8.4节&lt;/a&gt;中介绍的ConvLSTM模型还是&lt;a href=&#34;https://mlwithme.github.io/dl/chapter08/1e6da79bf7b44c20&#34;&gt;8.5节&lt;/a&gt;中引入的3DCNN模型，为了能同时提取时空数据在时间和空间两个维度的特征信息均从模型本身进行了改进。在本节内容中，我们将会介绍一种通过改进任务建模方式而仅依靠2DCNN来进行时空数据特征提取的模型，并同时介绍如何对多个子模块的输出结果进行融合。&lt;/p&gt;&#xA;&lt;h2 id=&#34;861-stresnet动机&#34;&gt;8.6.1 STResNet动机&lt;a class=&#34;anchor&#34; href=&#34;#861-stresnet%e5%8a%a8%e6%9c%ba&#34;&gt;#&lt;/a&gt;&lt;/h2&gt;&#xA;&lt;p&gt;尽管已有的时序模型例如3DCNN或者是ConvLSTM也能够用于提取时空数据在时间和空间两个维度上的特征信息，但是在流量预测这个场景中却不能有效得捕捉到在时间维度上的周期或者是趋势信息。例如在交通流量这一场景中，传统的时序模型只能提取到时空数据在紧邻若干时间内容的时序信息，但显然在这个场景中交通流量还具有周期规律或者趋势性。&lt;/p&gt;&#xA;&lt;p&gt;通常来说，交通流量数据在相邻时刻间、连续多天的同一时间段以及在长期趋势上都具有一定的规律性。同时，在这一场景中当天是否为节假日也会对交通流量的预测结果产生极大的影响。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;550&#34; src=&#34;https://mlwithme.github.io/images/dl/230620160413.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图 8-13 交通流量数据趋势图&lt;/center&gt;&#xA;&lt;p&gt;如图8-13所示，左图展示了以周为单位节假日和非节假日的流量变化图；右图展示了以周为单位不同时间段的流量变化趋势。从图8-13中的结果可以看出，不管在哪种情况下流量数据都具有一定的周期或者规律性。&lt;/p&gt;&#xA;&lt;p&gt;基于这样的动机，郑宇[1]等人在2017年提出了一种能够同时提取时空数据在邻近性（Closeness )、周期性（Period）和趋势性（Trend）上的时序特征，并同时考虑到节假日及天气状况等额外信息的时空模型（Spatio Temporal ResNet, STResNet）。该模型以残差模块为基础，通过构建不同的子模块来对不同的采样数据进行特征提取，然后再将各个模块的结果进行融合以实现上述目的。&lt;/p&gt;&#xA;&lt;h2 id=&#34;862-任务背景&#34;&gt;8.6.2 任务背景&lt;a class=&#34;anchor&#34; href=&#34;#862-%e4%bb%bb%e5%8a%a1%e8%83%8c%e6%99%af&#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;交通流量（Traffic Flow）预测任务是指使用历史数据和其他相关信息来预测特定区域或道路上未来的交通流量情况。它的目标是估计未来某一时间段内的车辆数量、速度和拥堵状况等交通指标，并且通常可以通过交通传感器、视频监控、GPS设备、移动应用程序等方式获取交通流量原始数据。在论文[1]中，作者使用了GPS原始数据来构建对应的数据集并用于模型训练。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;500&#34; src=&#34;https://mlwithme.github.io/images/dl/230620201920.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图 8-14 网格划分及流量图&lt;/center&gt;&#xA;&lt;p&gt;如图8-14（左）所示，将整个城市以经纬度划分为大小为$32\times32$的方格，然后再根据GPS轨迹以半小时为间隔统计得到每个格子中的流入流出量并看做是两个通道，这样便得到了整个城市各个区域在每个时刻的流量分布情况。进一步，图8-14（右）便是某一时刻的流入交通流量分布情况。经过这样的处理，我们便得到了一系列具有时序关系的图片数据，而任务的目的便是将前$T$个时间片（时刻）的流量作为输入，然后预测第$T+1$时刻的流入流出流量。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;2. 样本采样&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;为了使得STResNet模型具备提取时空数据在时间维度上的近邻性、周期性和趋势性，作者以不同的时间间隔对原始数据进行了采样，然后再将这3部分采样得到的数据输入到3个由残差网络构建的子模型中进行空间上的特征提取，并将三部分的输出融合作为整体的特征表示。具体采样方式如图8-15所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;600&#34; src=&#34;https://mlwithme.github.io/images/dl/230620210144.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图 8-15 数据采样图&lt;/center&gt;&#xA;&lt;p&gt;如图8-15所示便是原始构建完成的流量数据，每个时间片的流量情况用一个形状为&lt;code&gt;[2,32,32]&lt;/code&gt;的矩阵来进行表示。例如以预测时刻片$t_i$的流量为例，可以取$t_i$的前3个时间片$t_{i-1},t_{i-2},t_{i-3}$来模拟邻近性、取$t_{i}$前一天同时刻的时间片$t_j$来模拟周期性、取$t_i$前一周同时刻的时间片$t_k$来模拟趋势性，并将这3部分作为一个样本同时输入到3个子模块中。最后，再将窗口向右滑动一个时间片来构建下一个样，即$t_i,t_{i-1},t_{i-2}$作为近邻性的输入、$t_{j+1}$作为周期性的输入、$t_{k+1}$作为趋势性的输入，然后预测第$t_{i+1}$时刻的交通流量。当然，这3部分的采样方法以及连续时间片的长度都可以作为超参数进行调整，详见第8.6.4节代码实现。&lt;/p&gt;&#xA;&lt;p&gt;同时，为了考虑到其它额外因素对最终预测结果的影响，因此作者：①使用了一个8维向量来表示当天是否为工作日，其中前7个维度为独热编码表示当天是星期几，第8个维度表示当天是否为工作日；②使用了一个维度来表示当天是否为节假日；③使用了一个19维向量来表示天气状况，其中前17个维度同样也为独热编码用于表示其中一种天气情况，最后两个维度则表示风速和温度。最终，用这个28维向量来表示除了流量数据之外的额外因素。&lt;/p&gt;&#xA;&lt;h2 id=&#34;863-stresnet结构&#34;&gt;8.6.3 STResNet结构&lt;a class=&#34;anchor&#34; href=&#34;#863-stresnet%e7%bb%93%e6%9e%84&#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;在介绍完任务背景之后接下来开始介绍STResNet模型的原理。STResNet模型整体上可以分为4个部分，其中前3个部分以不同间隔采样的流量数据作为输入通过3个深度残差网络子模块来提取时空数据在时间维度和空间维度上的特征信息，第4个部分则是一个浅层的全连接网络用于考虑节假日和天气等因素对预测结果的影响。整体结构如图8-16所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/230620194254.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图 8-16 STResNet网络结构图&lt;/center&gt;&#xA;&lt;p&gt;如图8-16所示，右侧部分3个相同的结构便是用于提取时刻数据特征的深度残差网络模块，从右至左依次用于对邻近性、周期性和趋势性采样数据在空间上特征提取，然后再将这3部分的结果融合得到流量数据在时间上的特征信息，从而得到$X_{\text{Res}}$来表征整体流量数据的时空特征信息。左侧部分则是用于处理天气等额外信息对预测结果的影响。最终，将两部分的结果相加经过$\tanh$非线性变换后便得到了整个模型的预测输出。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;2. 残差模块&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;深度残差模块主要由多个残差单元所构成，并且首尾各插入了一个单独的卷积层来调整特征图的通道数。对于每一个残差单元来说，其由两个卷积层所构成并且还加入了批归一化层，如图8-17所示。&lt;/p&gt;&#xA;&lt;div align=center&gt;&lt;img width=&#34;400&#34; src=&#34;https://mlwithme.github.io/images/dl/230621193845.jpg&#34;/&gt; &lt;/div&gt;&lt;center&gt;图 8-17 残差单元结构图&lt;/center&gt;&#xA;&lt;p&gt;如图8-17所示便是STResNet模型中的残差单元。在整个残差模块中，卷积核的大小均是$3\times3$，且除了&lt;code&gt;Conv2&lt;/code&gt;之外所有卷积层的卷积核个数均为64，&lt;code&gt;Conv2&lt;/code&gt;的卷积核个数则为2，因为预测输出包含两个通道。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;3. 模型融合&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;对于每个残差模块来说，其输出的结果均为一个形状为&lt;code&gt;[2,32,32]&lt;/code&gt;的特征图，因此作者采用了式(8-4)所示的方式进行融合&#xA;&lt;/p&gt;&#xA;$$&#xA;X_{\text{Res}}=W_c\odot X_c+W_p\odot X_p+W_q\odot X_q\tag{8-5}&#xA;$$&lt;p&gt;&#xA;其中$X_c$、$X_p$和$X_q$分别为3个残差模块的输出结果，$W_c$、$W_p$和$W_q$为3个可学习的权重矩阵形状均为&lt;code&gt;[2,32,32]&lt;/code&gt;，$\odot$表示按位乘。&lt;/p&gt;&#xA;&lt;p&gt;在对外部因素进行处理时使用了两个全连接层，由于这部分原始输入整体上是由独热编码构成，所以第1个全连接层还可以近似看成一个嵌入层。为了匹配最后的输出形状，在第2个全连接层中权重参数的维度则必须为$2\times32\times32$，然后再将输出$X_{\text{Ext}}$变形为&lt;code&gt;[2,32,32]&lt;/code&gt;并直接与$X_{\text{Res}}$按位相加得到融合后的结果。最后，为了使得模型能够快速收敛作者还使用了$\tanh$非线性变换，这也就意味着输入模型的交通流量数据需要先做$[-1,1]$的标准化，然后在实际推理过程中再将预测结果还原，计算过程如式(8-6)所示。&#xA;&lt;/p&gt;&#xA;$$&#xA;\begin{aligned}&#xA;y=2\cdot\frac{x-\min}{\max-\min}-1&#xA;\end{aligned}\tag{8-6}&#xA;$$&lt;p&gt;&#xA;对于不同模块间输出结果的融合一般常见的有：①在某个维度进行拼接；②直接以按位加的方式进行处理；③先以按位乘的方式作用一个可学习的权重参数再进行按位加处理；④先以矩阵乘法的方式将不同模块的输出变换到同一个维度再按位加处理。通常来说，先作用一个可学习参数再进行按位加是一个比较好的选择。&lt;/p&gt;</description>
			</item>
	</channel>
</rss>
