当前位置: 首页 > news >正文

网站建设实训报告目的网站突然被降权

网站建设实训报告目的,网站突然被降权,移动网站转码,php网站下载文件怎么做原文#xff1a;The Deep Learning with PyTorch Workshop 协议#xff1a;CC BY-NC-SA 4.0 译者#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】#xff0c;采用译后编辑#xff08;MTPE#xff09;流程来尽可能提升效率。 不要担心自己的形象#xff0c;只关心… 原文The Deep Learning with PyTorch Workshop 协议CC BY-NC-SA 4.0 译者飞龙 本文来自【ApacheCN 深度学习 译文集】采用译后编辑MTPE流程来尽可能提升效率。 不要担心自己的形象只关心如何实现目标。——《原则》生活原则 2.3.c 六、使用 RNN 分析数据序列 概述 本章扩展了循环神经网络的概念。 您将了解循环神经网络RNN的学习过程以及它们如何存储内存。 本章将介绍长短期记忆LSTM网络架构该架构使用短期和长期存储器来解决数据序列中的数据问题。 在本章的最后您将牢固地掌握 RNN 以及如何解决自然语言处理NLP数据问题。 简介 在前面的章节中介绍了不同的网络架构-从可以同时解决分类和回归问题的传统 ANN 到主要用于通过执行对象分类定位检测和分段任务来解决计算机视觉问题的 CNN 。 在最后一章中我们将探讨 RNN 的概念并解决序列数据问题。 这些网络架构能够保存上下文至关重要的序列数据这要归功于它们能够保存来自先前预测的信息称为内存。 这意味着例如当逐个单词分析句子时RNN 在处理最后一个单词时可以保留有关该单词第一个单词的信息。 本章将探讨 LSTM 网络架构它是一种 RNN可以同时存储长期和短期内存并且对于处理长数据序列例如视频剪辑特别有用。 本章还将探讨 NLP 的概念。 NLP 指的是计算机与人类语言的交互由于虚拟助手的兴起如今这已成为热门话题虚拟助手可以提供定制的客户服务。 本章将使用 NLP 进行情感分析其中包括分析句子后面的含义。 这有助于根据客户评论了解客户对产品或服务的看法。 注意 本章中提供的所有代码都可以在以下位置找到。 循环神经网络 就像人类不会每秒重新设置思想一样旨在理解人类语言的神经网络也不应这样做。 这意味着为了理解段落中甚至整个书中的每个单词您或模型需要理解之前的单词这可以帮助给可能具有不同含义的单词提供上下文。 到目前为止我们已经讨论了传统的神经网络无法执行此类任务因此创建了 RNN 的概念和网络架构。 正如我们之前简要解释的那样这些网络架构包含不同节点之间的环路。 这使信息可以在模型中保留更长的时间。 因此来自模型的输出既成为预测又是存储器当下一行已排序的文本通过模型时将使用该存储器。 这个概念可以追溯到 1980 年代尽管它只是在最近才变得流行这要归功于技术的进步这种进步导致机器的计算能力提高了并允许数据的收集以及对概念的发展。 1990 年代的 LSTM RNN增加了其应用范围。 由于 RNN 具有存储内部存储器的能力因此它们是最有前途的网络架构之一这使它们能够有效地处理数据序列并解决各种数据问题。 RNN 的应用 尽管我们已经很清楚地表明 RNN 最适合于数据序列例如文本音频片段和视频但仍然有必要解释 RNN 在现实生活中的不同应用。 这是通过使用 RNN 可以执行的不同任务的一些简要说明 NLP。这指的是机器代表人类语言的能力。这可能是深度学习中探索最多的领域之一也无疑是利用 RNN 时首选的数据问题。其思路是以文本作为输入数据来训练网络如诗词和书籍等目的是创建一个能够生成此类文本的模型。 NLP 通常用于创建聊天机器人虚拟助手。 通过从以前的人类对话中学习NLP 模型能够帮助一个人解决常见问题或疑问。 因此他们的句子表达能力仅限于他们在训练过程中所学到的内容这意味着他们只能回答所学的内容。 当您尝试通过在线聊天系统与银行联系时您可能会遇到这种情况在这种情况下通常您会在查询超出常规范围的那一刻将您转到人工运算符那里。 现实生活中聊天机器人的另一个常见示例是通过 Facebook Messenger 进行查询的餐馆 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zNOgJ04E-1681785396600)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_01.jpg)] 图 6.1Facebook 的 Messenger 聊天机器人 语音识别。与 NLP 类似语音识别试图理解和表示人类语言。然而这里的区别在于前者NLP是以文本的形式进行训练并产生输出而后者语音识别则使用音频片段。随着这一领域的发展以及大公司的兴趣这些模型能够理解不同的语言甚至不同的口音和发音。 语音识别设备的一个流行示例是 Alexa –来自亚马逊的语音激活虚拟助手模型 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-axkQ7VJ6-1681785396601)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_02.jpg)] 图 6.2亚马逊的 Alexa 机器翻译。这是指机器有效翻译人类语言的能力。据此输入是源语言如西班牙语输出是目标语言如英语。NLP 与机器翻译的主要区别在于在后者中输出是在将整个输入输入输入到模型后建立的。 随着全球化的兴起和当今休闲旅行的普及人们需要使用多种语言。 因此出现了能够在不同语言之间进行翻译的设备。 该领域的最新成果之一是 Google 的 Pixel Buds它可以实时执行翻译 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-egiO47p5-1681785396601)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_03.jpg)] 图 6.3Google 的像素芽 时间序列预测。RNN 的一个不太流行的应用是根据历史数据预测未来的数据点序列。由于 RNN 能够保留内部记忆使时间序列分析能够考虑过去的不同时间段来进行未来的预测或一系列预测因此 RNN 特别擅长这项任务。 这通常用于预测未来的收入或需求这有助于公司为不同的情况做好准备。 下图显示了每月销售额的预测 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pWAB009o-1681785396602)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_04.jpg)] 图 6.4每月销售额的预测数量 例如如果通过预测对几种保健产品的需求确定对一种产品的需求增加而对另一种产品的需求减少则公司可以决定生产更多的该产品以及更少的其他产品。 图像识别结合 CNNRNN 可以为图像提供标题或描述。 通过这些模型组合您可以检测图像中的所有对象从而确定图像的主要成分。 输出可以是图像中存在的对象的一组标签图像的描述或图像中相关对象的标题如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DQLJz5RQ-1681785396602)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_05.jpg)] 图 6.5使用 RNN 进行图像识别 RNN 如何工作 简而言之RNN 接受输入x并返回输出y。 在此输出不仅受输入影响而且还受过去输入的输入的整个历史影响。 输入的这种历史记录通常称为模型的内部状态或内存它们是遵循顺序并相互关联的数据序列例如时间序列它是一系列数据点例如销售 按月列出。 注意 请记住RNN 的一般结构可能会有所变化具体取决于当前的问题。 例如它们可以是一对多类型也可以是多对一类型正如我们在“第 2 章”“神经网络构建模块”中提到的那样。 要了解 RNN 的概念了解 RNN 与传统神经网络之间的区别非常重要。 传统的神经网络通常被称为前馈神经网络因为信息仅沿一个方向移动即从输入到输出而没有两次通过节点执行预测。 这些网络对过去所馈送的内容没有任何记忆这就是为什么它们不善于预测序列中接下来将发生什么。 另一方面在 RNN 中信息在循环中循环因此每次预测都通过考虑先前预测的输入和内存来进行。 它通过复制每个预测的输出并将其传递回网络以进行后续预测来工作。 这样RNN 就有两个输入-现在值和过去信息 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zZB9AZDr-1681785396602)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_06.jpg)] 图 6.6网络的图形表示其中 A 显示前馈神经网络B 显示 RNN 注意 传统 RNN 的内部记忆只是短期的。 但是我们将探索一种能够在以后存储长期和短期内存的架构。 通过使用来自先前预测的信息网络将按照一系列有序数据进行训练从而可以预测下一步。 这是通过将当前信息和上一步的输出合并为一个操作来实现的。 在下图中可以看到。 此操作的输出将成为预测以及后续预测的输入的一部分 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Axufi6Sb-1681785396603)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_07.jpg)] 图 6.7每个预测的 RNN 计算 如您所见节点内部发生的操作是任何其他神经网络的操作。 最初数据通过线性函数传递。 权重和偏差是在训练过程中要更新的参数。 接下来使用激活函数来破坏该输出的线性度。 在这种情况下这就是 tanh 函数因为多项研究表明对于大多数排序数据问题它可以获得更好的结果 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tlMZUBnP-1681785396603)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_08.jpg)] 图 6.8传统 RNN 的数学计算 此处M[t-1]是指从先前的预测得出的内存W和b是权重和偏差而E[t]表示当前事件。 考虑到这一学习过程让我们考虑一下过去两年中产品的销售数据。 RNN 能够预测下个月的销售量因为通过存储最近几个月的信息RNN 可以检查销售量是增加还是减少。 使用“图 6.7”可以通过获取上个月的销售额即当前事件和短期记忆代表最近一个月的数据来处理后面几个月的预测并将其合并。 此操作的输出将包含下个月的预测以及最近几个月的一些相关信息这些信息将反过来成为后续预测的新短期记忆。 此外重要的是要提到一些 RNN 架构例如 LSTM 网络也将能够考虑 2 年前甚至更早的数据因为它存储了长期内存。 这将使网络知道特定月份内的减少是否可能继续减少或开始增加。 稍后我们将更详细地探讨该主题。 输入和目标序列数据 考虑到目标是预测序列中的下一个元素因此目标矩阵通常是与输入数据相同的信息而目标则领先一步。 这意味着输入变量应包含序列的所有数据点最后一个值除外而目标变量应包含序列的所有数据点但第一个值除外即第一个值 目标变量应该是输入变量的第二个依此类推如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fHp4GE3w-1681785396603)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_09.jpg)] 图 6.9序列数据问题的输入变量和目标变量 练习 6.01为序列数据问题创建输入和目标变量 在本练习中您将使用虚拟数据集学习如何创建可用于解决排序数据问题的输入和目标变量。 请按照以下步骤完成此练习 注意 对于本章中的练习和活动您需要在本地计算机上安装 Python 3.7Jupyter 6.0Matplotlib 3.1NumPy 1.17Pandas 0.25 和 PyTorch 1.3最好是 PyTorch 1.4。 导入以下库 import pandas as pd import numpy as np import torch创建一个10×5大小的 Pandas DataFrame里面充满了从 0 到 100 的随机数。命名五列如下[Week1, Week2, Week3, Week4, Week5]。 确保将随机种子设置为0以便能够重现本书中显示的结果 np.random.seed(0) data pd.DataFrame(np.random.randint(0,100,size(10, 5)),columns[Week1,Week2,Week3,\Week4,Week5]) data注意 提醒一下在 Jupyter 笔记本中无需打印函数即可打印变量的值。 在其他编程平台上可能需要使用打印函数。 结果数据帧如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fGipydmV-1681785396603)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_10.jpg)] 图 6.10创建的DataFrame 创建一个输入变量和一个目标变量考虑到输入变量应该包含所有实例的所有值除了最后一列数据。目标变量应包含所有实例的所有值但第一列数据除外。 inputs data.iloc[:,:-1] targets inputs.shift(-1, axiscolumns, \fill_valuedata.iloc[:,-1:])打印输入变量以验证其内容如下图所示。 inputs输入变量应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w6CNXRJM-1681785396604)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_11.jpg)] 图 6.11输入变量 使用下面的代码打印出目标变量。 targets运行前面的代码将显示以下输出 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2kesxWYQ-1681785396604)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_12.jpg)] 图 6.12目标变量 注意 要访问此特定部分的源代码请参考这里。 您也可以通过这里在线运行此示例。 您必须执行整个笔记本才能获得所需的结果。 PyTorch 中的 RNN 在 PyTorch 中类似于任何其他层循环层在一行代码中定义。 然后将在网络的正向函数中调用此代码如以下代码所示 class RNN(nn.Module):def __init__(self, input_size, hidden_size, num_layers):super().__init__()self.hidden_size hidden_sizeself.rnn nn.RNN(input_size, hidden_size, num_layers,\batch_firstTrue)self.output nn.Linear(hidden_size, 1)def forward(self, x, hidden):out, hidden self.rnn(x, hidden)out out.view(-1, self.hidden_size)out self.output(out)return out, hidden在这里必须将循环层定义为采用输入中预期特征数的参数input_size 由用户定义的处于隐藏状态的特征数hidden_​​size 和循环层数num_layers。 注意 与其他任何神经网络类似隐藏大小是指该层中节点神经元的数量。 batch_first参数设置为True以定义输入和输出张量采用批序列和特征的形式。 在forward函数中输入通过循环层而这些层的输出被展平以便可以通过全连接层。 值得一提的是信息与隐藏状态内存一起通过 RNN 层传递。 此外这种网络的训练可以按以下方式处理 for i in range(1, epochs1):hidden Nonefor inputs, targets in batches:pred, hidden model(inputs, hidden)loss loss_function(pred, targets)optimizer.zero_grad()loss.backward()optimizer.step()对于每个周期隐藏状态都初始化为None。 这是因为在每个周期网络都会尝试将输入映射到目标给定一组参数时。 该映射应该与数据集中之前的运行没有任何偏差隐藏状态地发生。 接下来for循环遍历不同批量的数据。 在此循环内将进行预测并保存隐藏状态该状态将用作下一批的输入。 最后计算损失函数该函数用于更新网络参数。 然后该过程再次开始直到达到所需的周期数。 活动 6.01使用简单 RNN 的时间序列预测 对于此活动您将使用简单的 RNN 解决时间序列问题。 让我们考虑以下情况您的公司希望能够提前预测所有产品的需求。 这是因为生产每种产品都需要花费相当长的时间并且该过程花费大量金钱。 因此除非产品很可能被出售否则他们不希望在生产上花费金钱和时间。 为了预测未来需求他们为您提供了一个数据集其中包含去年销售中所有产品的每周需求在销售交易中。 请按照以下步骤完成此活动 注意 可以在这个页面上找到包含将在此活动中使用的数据集的 CSV 文件。 也可以从这里在线获取。 数据集和相关分析首次在此处发布Tan S.C., Lau J.P.S. (2014) Time Series Clustering: A Superior Alternative for Market Basket Analysis. In: Herawan T., Deris M., Abawajy J. (eds) Proceedings of the First International Conference on Advanced Data and Information Engineering (DaEng-2013). Lecture Notes in Electrical Engineering, vol 285. Springer, Singapore. 导入所需的库。 加载数据集并对其进行切片以使其包含所有行但仅包含索引 1 至 52 的列。 从整个数据集中绘制五个随机选择的产品的每周销售交易图。 进行随机采样时请使用0的随机种子以获得与当前活动相同的结果。 创建inputs和targets变量这些变量将被输入到网络中以创建模型。这些变量应具有相同的形状并转换为 PyTorch 张量。 input变量应包含除上周外所有周所有产品的数据因为模型的目的是预测最后一周。 target变量应比input变量领先一步 也就是说target变量的第一个值应该是输入变量的第二个依此类推直到target变量的最后一个值应该是最后一个input变量之外的一周。 创建一个包含网络架构的类 请注意全连接层的输出大小应为 1。 实例化包含模型的类函数。 输入输入大小每个循环层中的神经元数10和循环层数1。 定义损失函数优化算法和训练网络的周期数。 为此请使用均方误差损失函数Adam 优化器和 10,000 个周期。 使用for循环通过遍历所有周期来执行训练过程。 在每个周期都必须进行预测以及随后的损失函数计算和网络参数优化。 然后保存每个周期的损失。 绘制所有周期的损失。 使用散点图显示在训练过程的最后一个周期中获得的预测值与真实情况值即上周的销售交易的对比。 注意 此活动的解决方案可以在第 284 页上找到。 长短期记忆网络 如前所述RNN 仅存储短期内存。 在处理较长的数据序列时这是一个问题在这种情况下网络将信息从较早的步骤传输到最终步骤时会遇到麻烦。 例如以著名的诗人埃德加·艾伦·坡Edgar Alan Poe所写的诗《乌鸦》The Raven为例诗长超过 1000 个字。 试图使用传统的 RNN 来处理它以创建相似的相关诗歌为目标将导致该模型在前几段中遗漏了关键信息。 反过来这可能导致输出与诗歌的初始主题无关。 例如它可以忽略事件是在晚上发生的因此使新诗不是很吓人。 之所以无法保持长期记忆是因为传统的 RNN 遭受称为梯度消失的问题。 当用于更新网络参数以最小化损失函数的梯度变得非常小从而不再对网络的学习过程有所帮助时就会发生这种情况。 这通常发生在网络的前几层使网络忘记了一段时间。 因此开发了 LSTM 网络。 LSTM 网络可以像存储计算机一样存储内部存储器因此可以长时间记住信息。 也就是说它们根据需要读取写入和删除信息这是通过使用门来实现的。 这些门根据分配给每个信息位的重要性帮助网络决定保留哪些信息以及从内存中删除哪些信息是否打开门。 这非常有用因为它不仅可以存储更多信息作为长期记忆而且还有助于丢弃可能改变预测结果的无用信息例如句子中的文章。 LSTM 网络的应用 除了我们先前解释的应用之外LSTM 网络存储长期信息的能力还使数据科学家能够处理复杂的数据问题这些问题利用大数据序列作为输入下面将对其中的一些问题进行说明 文本生成生成任何文本例如您在此处阅读的文本都可以转换为 LSTM 网络的任务。 通过基于所有先前字母选择每个字母来工作。 使用大型文本例如著名书籍的文本来训练执行此任务的网络。 这是因为最终模型将创建一个文本该文本类似于受其训练的文本的书写样式。 例如以诗训练的模型将具有与您在与邻居交谈中期望的叙事不同的叙事。音乐生成就像可以将文本序列输入到网络中以生成相似的新文本一样也可以将一系列音符输入网络以生成新的音符序列。 跟踪先前的音符将有助于获得和谐的旋律而不仅仅是一系列随机的音符。 例如用披头士乐队的一首流行歌曲来馈送音频文件将产生一系列音符这些音符类似于乐队的和声。手写体的生成和识别这里每个字母也是所有先前字母的乘积这又将导致一组具有含义的手写字母。 同样LSTM 网络也可以用于识别手写文本其中一个字母的预测将取决于所有先前预测的字母。 例如在考虑先前的字母以及整个段落时识别难看的手写字母会更容易因为这有助于根据上下文缩小预测范围。 LSTM 网络如何工作 到目前为止已经明确了 LSTM 网络与传统 RNN 的区别在于它们具有长期记忆的能力。 但是必须指出的是随着时间的流逝非常古老的信息不太可能影响下一个输出。 考虑到这一点LSTM 网络还具有考虑数据位与底层上下文之间距离的能力以便也可以决定忘记一些不再相关的信息。 那么LSTM 网络如何决定何时记住和何时忘记 与传统的 RNN 不同LSTM 网络在每个节点中仅执行一次计算而 LSTM 网络执行四种不同的计算从而允许网络的不同输入即当前事件短期记忆和长期记忆项之间进行交互以得出结果。 要了解 LSTM 网络背后的过程请考虑用于管理网络中信息的四个门如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jKAYYE0X-1681785396604)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_13.jpg)] 图 6.13LSTM 网络门 上图中每个门的功能可以解释如下 学习门短期记忆也称为隐藏状态和当前事件都进入学习门在此分析信息并忽略所有不需要的信息。 在数学上这是通过使用线性函数和激活函数tanh将短期记忆和当前事件结合在一起来实现的。 它的输出乘以忽略因子从而删除所有不相关的信息。 为了计算忽略因子通过线性函数传递短期记忆和当前事件。 然后将它们通过 Sigmoid 激活函数压缩在一起 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dlykAhcL-1681785396604)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_14.jpg)] 图 6.14学习门中发生的数学计算 此处 STM[t-1]是指从先前的预测得出的短期记忆W和b是权重和偏差并且E[t]表示当前事件。 遗忘门长期存储也称为单元状态进入遗忘门其中删除了一些信息。 这是通过将长期记忆和遗忘因子相乘来实现的。 要计算遗忘因子请将短期记忆和当前事件通过线性函数和激活函数sigmoid传递 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rg0TXV3A-1681785396605)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_15.jpg)] 图 6.15遗忘门中发生的数学计算 此处 STM[t-1]是指从先前的预测中得出的短期记忆 LTM[t-1]是从先前的预测中得出的长期记忆 W和b是权重和偏差E[t]是指当前事件。 记忆门在记忆门中未被遗忘的长期记忆和从学习门保留的信息将被组合在记忆门中这将成为新的长期记忆。 从数学上讲这是通过对学习和遗忘门的输出求和来实现的 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a5hSB2wb-1681785396605)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_16.jpg)] 图 6.16记忆门中发生的数学计算 此处L[t]表示来自学习门的输出而F[t]表示来自遗忘门的输出。 使用门。这也称为输出门。在这里来自学习门和遗忘门的信息被合并到使用门中。该门利用所有相关信息进行预测也成为新的短期记忆。 这可以通过三个步骤实现。 首先它将线性函数和激活函数tanh应用于遗忘门的输出。 其次它将线性函数和激活函数Sigmoid应用于短期记忆和当前事件。 第三它将前面步骤的输出相乘。 第三步的输出将是新的短期记忆和当前步的预测 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BESVgFO6-1681785396605)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_17.jpg)] 图 6.17使用门中发生的数学计算 此处 STM[t-1]是指从先前的预测得出的短期记忆W和b是权重和偏差并且E[t]表示当前事件。 注意 尽管使用不同的激活函数和数学运算符似乎是任意的但这样做是因为已被证明可以处理大多数处理大型数据序列的数据问题。 对于模型执行的每个预测都完成了前面的过程。 例如对于构建用于创建文学作品的模型将对模型将产生的每个单个字母执行学习遗忘记忆和使用信息的过程如下图所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Zv1FFjU-1681785396606)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_18.jpg)] 图 6.18整个时间的 LSTM 网络过程 PyTorch 中的 LSTM 网络 在 PyTorch 中定义 LSTM 网络架构的过程与到目前为止我们讨论过的任何其他神经网络的过程相似。 但是重要的是要注意当处理与数字序列不同的数据序列时需要进行一些预处理才能为网络提供它可以理解和处理的数据。 考虑到这一点我们需要解释训练模型的一般步骤以便能够将文本数据作为输入并检索新的文本数据。 值得一提的是并非严格要求此处说明的所有步骤而是作为一个整体它们为使用 LSTM 与文本数据结合在一起提供了干净且可重用的代码。 预处理输入数据 第一步是将文本文件加载到代码中。 这些数据将经过一系列转换以便正确地输入到模型中。 这是必需的因为神经网络执行一系列数学计算才能得出输出这意味着所有输入都必须是数字。 另外将数据批量而不是一次全部馈入模型也是一个好习惯因为这有助于减少训练时间尤其是对于长数据集。 这些转换将在以下小节中进行说明。 数字标签 首先从输入数据中获得未重复字符的列表。 这些字符中的每一个都分配有一个数字。 然后考虑到必须始终用相同的数字表示相同的字母通过将每个字符替换为指定的数字来对输入数据进行编码。 例如给定以下字符和数字映射单词hello将被编码为 12334 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bb8NMPST-1681785396606)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_19.jpg)] 图 6.19字符和数字的映射 可以通过以下代码片段实现上述输出 text this is a test text! chars list(set(text)) indexer {char: index for (index, char) \in enumerate(chars)} indexed_data [] for c in text:indexed_data.append(indexer[c])代码的第二行创建一个包含文本字母即文本序列中的字母和字符的列表。 接下来使用每个字母或字符作为键并使用与其关联的数字表示作为值来创建字典。 最后通过对文本执行for循环可以将每个字母或字符替换为其数字表示形式从而将文本转换为数字矩阵。 生成批量 对于 RNN使用两个变量创建批量每个批量的序列数和每个序列的长度。 这些值用于将数据划分为矩阵这将有助于加快计算速度。 使用 24 个整数的数据集每批的序列数设置为 2序列长度等于 4除法如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PVXiAaDh-1681785396606)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_20.jpg)] 图 6.20RNN 的批量生成 如上图所示创建了三个批量–每个批量包含两个长度为 4 的序列。 对于x和y应完成此批生成过程其中前者是网络的输入后者是目标。 据此网络的思想是找到一种方法来映射x和y之间的关系考虑到y将领先一步。x。 x的批量是按照上图中说明的方法创建的。 然后将创建y的批量以使其与x的长度相同。 这是因为y的第一个元素将是x的第二个元素依此类推直到y的最后一个元素将是第一个元素x的数量 注意 您可以使用多种不同的方法来填充y的最后一个元素这里提到的是最常用的一种方法。 方法的选择通常是优先考虑的问题尽管某些数据问题可能从某种方法中受益而不是其他方法。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51AICa2a-1681785396606)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_21.jpg)] 图 6.21x和y批量的表示 批量的生成可以通过以下代码片段实现 x np.array(indexed_data).reshape((2,-1)) for b in range(0, x.shape[1], 5):batch x[:,b:b5]print(batch)首先将数字矩阵划分为多个序列根据需要。 接下来通过for循环可以将已排序的数据划分为指定长度的批量。 通过打印batch变量可以观察到结果。 注意 尽管生成批量被视为预处理数据的一部分但通常会在训练过程的for循环内部对其进行编程。 单热编码 将所有字符转换为数字不足以将其输入模型。 这是因为这种近似会给您的模型带来一些偏差因为转换为更高数值的字符将被视为更重要。 为避免这种情况优良作法是将不同批量编码为一热矩阵。 这包括创建一个具有零和一的三维矩阵其中零表示不存在事件而一个表示存在事件。 矩阵的最终形状应为one hot [number of sequences, sequence length, number of characters]。 这意味着对于批量中的每个元素它将创建一个长度等于整个文本中字符总数的值序列。 对于每个字符它将放置一个零但该位置存在一个零它将放置一个。 注意 您可以在这个页面中找到有关单热编码的更多信息。 这可以通过以下代码片段实现 batch np.array([[2 4 7 6 5][2 1 6 2 5]]) batch_flatten batch.flatten() onehot_flat np.zeros((batch.shape[0] \* batch.shape[1],len(indexer))) onehot_flat[range(len(batch_flatten)), batch_flatten] 1 onehot onehot_flat.reshape((batch.shape[0],\batch.shape[1], -1))首先将二维批量展平。 接下来创建一个矩阵并用零填充。 当我们需要在给定位置表示正确的字符时用零代替零。 最后展平的尺寸再次扩大。 练习 6.02预处理输入数据并创建单热矩阵 在本练习中您将预处理文本片段然后将其转换为单热矩阵。 请按照以下步骤完成此练习 导入 NumPy。 import numpy as np创建一个名为text的变量其中将包含文本样本Hello World!。 text Hello World!通过将每个字母映射到一个数字来创建一个字典。 chars list(set(text)) indexer {char: index for (index, char) \in enumerate(chars)} print(indexer)运行前面的代码将得到以下输出 {d: 0, o: 1, H: 2, : 3, e: 4, W: 5, !: 6, l: 7, r: 8}用我们在上一步中定义的数字对你的文本样本进行编码。 encoded [] for c in text:encoded.append(indexer[c])将编码变量转换为 NumPy 数组并对其进行重塑使句子被分成两个大小相同的序列。 encoded np.array(encoded).reshape(2,-1) encoded运行前面的代码将得到以下输出 array([[2, 4, 7, 7, 1, 3],[5, 1, 8, 7, 0, 6]])定义一个函数接收一个数字数组并创建一个单热矩阵。 def index2onehot(batch):batch_flatten batch.flatten()onehot_flat np.zeros((batch.shape[0] \* batch.shape[1], len(indexer)))onehot_flat[range(len(batch_flatten)), \batch_flatten] 1onehot onehot_flat.reshape((batch.shape[0], \batch.shape[1], -1))return onehot通过之前定义的函数将编码数组转换为单热矩阵。 one_hot index2onehot(encoded) one_hot输出应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZmZa8alV-1681785396606)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B16118_06_22.jpg)] 图 6.22示例文本的单热表示 注意 要访问此特定部分的源代码请参考这里。 您也可以通过这里在线运行此示例。 您必须执行整个笔记本才能获得所需的结果。 您已成功将一些示例文本转换为单热矩阵。 构建架构 与其他神经网络类似可以在一行代码中轻松定义 LSTM 层。 但是包含网络架构的类必须包含一个函数该函数允许初始化隐藏状态和单元状态即网络的两个内存。 LSTM 网络架构的示例如下 py class LSTM(nn.Module):def __init__(self, char_length, hidden_size, n_layers):super().__init__()self.hidden_size hidden_sizeself.n_layers n_layersself.lstm nn.LSTM(char_length, hidden_size, \n_layers, batch_firstTrue)self.output nn.Linear(hidden_size, char_length)def forward(self, x, states):out, states self.lstm(x, states)out out.contiguous().view(-1, self.hidden_size)out self.output(out)return out, statesdef init_states(self, batch_size):hidden next(self.parameters()).data.new(self.n_layers, \batch_size, self.hidden_size).zero_()cell next(self.parameters()).data.new(self.n_layers, \batch_size, self.hidden_size).zero_()states (hidden, cell)return states注意 同样当输入和输出张量采用批序列和特征的形式时batch_first参数设置为True。 否则无需定义它因为其默认值为False。 如我们所见LSTM 层在一行中定义将以下内容作为参数 输入数据中的特征数量即非重复字符的数量隐藏维数神经元LSTM 层数 与任何其他网络一样forward函数定义了在forward传递中通过层移动数据的方式。 最后定义一个函数以在每个周期将隐藏状态和单元状态初始化为零。 这是通过next(self.parameters()).data.new()实现的该方法获取模型的第一个参数并在括号内创建具有指定尺寸的相同类型的新张量 然后用零填充。 将hidden和cell状态都作为元组输入模型。 训练模型 一旦定义了损失函数和优化算法就该训练模型了。 这是通过采用与其他神经网络架构非常相似的方法来实现的如以下代码片段所示 # Step 1: for through epochs for e in range(1, epochs1):# Step 2: Memory initializedstates model.init_states(n_seq)# Step 3: for loop to split data in batches.for b in range(0, x.shape[1], seq_length):x_batch x[:,b:bseq_length]if b x.shape[1] - seq_length:y_batch x[:,b1:bseq_length]y_batch np.hstack((y_batch, indexer[.] \* np.ones((y_batch.shape[0],1))))else:y_batch x[:,b1:bseq_length1]Step 4: input data is converted to one-hot matrix.Inputs and targets are converted to tensors.x_onehot torch.Tensor(index2onehot(x_batch))y torch.Tensor(y_batch).view(n_seq * seq_length)Step 5: get a prediction and perform thebackward propagationpred, states model(x_onehot, states)loss loss_function(pred, y.long())optimizer.zero_grad()loss.backward(retain_graphTrue)optimizer.step()如前面的代码所示步骤如下 为了获得更好的模型有必要遍历数据多次因此需要设置多个周期。在每个周期必须初始化隐藏状态和单元状态。 这是通过调用该类中先前创建的函数来实现的。使用循环for将数据分批馈入模型。 if语句用于确定它是否是最后一批以便在句末添加句点以表示句点。输入数据被转换为一热矩阵。 输入和目标都将转换为 PyTorch 张量。通过对一批数据调用模型来获得网络的输出。 然后计算损失函数并优化参数。 执行预测 优良作法是为训练后的模型提供前几个字符以便执行具有某种目的的预测例如以单词on time on time开头的段落。 这些初始字符应在不执行任何预测的情况下馈送到模型中但目的是生成内存。 接下来将前一个字符和存储器馈入网络并通过 softmax 函数传递输出以便计算每个字符成为序列中下一个字符的概率。 最后从概率较高的角色中随机选择一个。 这可以通过以下代码片段实现 # Step 1 starter This is the starter text states None # Step 2 for ch in starter:x np.array([[indexer[ch]]])x index2onehot(x)x torch.Tensor(x)pred, states model(x, states) # Step 3 counter 0 while starter[-1] ! . and counter 50:counter 1x np.array([[indexer[starter[-1]]]])x index2onehot(x)x torch.Tensor(x)pred, states model(x, states)pred F.softmax(pred, dim1)p, top pred.topk(10)p p.detach().numpy()[0]top top.numpy()[0]index np.random.choice(top, pp/p.sum())# Step 4starter chars[index]print(starter)在上一个代码段中将执行以下步骤 起始句子已定义。for循环将开始句子的每个字符输入模型以便在进行预测之前更新模型的内存。只要循环和循环用于执行新字符的预测只要字符数不超过 50并且直到新字符是一个句点即可。每个新字符都添加到起始句子中以形成新的文本序列。 活动 6.02使用 LSTM 网络的文本生成 注意 可以在互联网上免费访问此活动中将使用的文本数据尽管您也可以在本书的 GitHub 存储库中找到它。 在本章的简介中提到了存储库的 URL。 在本活动中我们将使用《爱丽丝梦游仙境》 一书训练 LSTM 网络以便我们可以将一个起始语句输入模型并使其完成该语句。 请考虑以下情形您喜欢使生活更轻松的事物并决定建立一个模型来帮助您在编写电子邮件时完成句子。 为此您已决定使用一本流行的儿童读物来训练网络。 请按照以下步骤完成此活动 注意 值得一提的是尽管本次活动中的网络经过了足够的迭代训练以显示出令人满意的结果但并未对其进行训练和配置以实现最佳表现。 鼓励您使用它来提高性能。 导入所需的库。 打开并将爱丽丝梦游仙境中的文本读到笔记本中。 打印前 50 个字符和文本文件总长度的摘录。 创建一个变量该变量包含数据集中未重复字符的列表。 然后创建一个字典将每个字符映射到一个整数其中字符将是键而整数将是值。 将数据集中的每个字母编码为成对的整数。 打印数据集的前 50 个编码字符和编码版本的总长度。 创建一个接受批量并将其编码为单热点矩阵的函数。 创建一个定义网络架构的类。 该类应包含一个用于初始化 LSTM 层状态的附加函数。 请确定要从数据集中创建的批量数量请记住每个批量应包含 100 个序列每个批量的长度应为 50。接下来将编码数据拆分为 100 个序列。 使用 256 作为隐藏单元数总共两个循环层实例化模型。 定义损失函数和优化算法。使用 Adam 优化器和交叉熵损失。训练网络 20 个周期。 注意 根据您的资源训练过程将花费很长时间这就是为什么建议仅运行 20 个周期的原因。 但是本书的 GitHub 存储库中提供了可以在 GPU 上运行的代码的等效版本。 这将使您运行更多的周期并获得出色的表现。 在每一个周期数据必须被划分为 50 个序列长度的批次。这意味着每个周期将有 100 个序列每个序列的长度为 50。 注意 为输入和目标创建了批量 其中后者是前者的副本但领先一步。 绘制随时间推移的损失进度。 将下面的句子启动器输入到训练好的模型中并完成这个句子So she was considering in her own mind 。 注意 有关此活动的解决方案请参见第 290 页。 最后一句话会有所不同因为在选择每个字符时会有一个随机因素。 但是它应该看起来像这样 So she was considering in her own mind us on, said she whad se the sire.前面的句子没有意义因为网络没有经过足够的时间训练损失函数可能仍然是最小化的并且可以一次选择每个字符而无需长期存储以前创建的单词尽管如此我们可以看到仅 20 个周期后网络就已经能够形成一些有意义的单词。 自然语言处理 计算机擅长分析标准化数据例如财务记录或表中存储的数据库。 实际上它们具有比人类更好的能力因为它们能够一次分析数百个变量。 另一方面人类擅长分析非结构化数据例如语言除非计算机掌握了一套规则以帮助他们理解否则计算机就不会擅长这样做。 考虑到这一点对于人类语言而言计算机面临的最大挑战是即使在一台非常大的数据集上经过很长时间的训练之后计算机可以擅长分析人类语言但它们仍然无法理解句子背后的真实含义因为它们既不直观也不能够在两行之间阅读。 这意味着尽管人类能够理解说“他昨晚着火了真是个好游戏”的句子。 指某种运动的运动员的表现计算机会从字面意义上理解它-意味着它将把它解释为昨晚确实起火的人。 NLP 是人工智能AI的子字段它通过使计算机能够理解人类语言来工作。 尽管在某些情况下人类可能总是会做得更好但是 NLP 的主要目标是通过使计算机理解人类语言来使计算机与人类更接近。 这个想法是创建专注于特定领域的模型例如机器翻译和文本摘要。 任务的这种专业化有助于计算机开发一种模型该模型能够解决现实生活中的数据问题而无需一次处理所有复杂的人类语言。 情感分析是人类语言理解的这些领域之一近来非常流行。 情感分析 一般而言情感分析包括理解输入文本背后的情感。 考虑到随着社交媒体平台的普及公司每天收到的消息和评论的数量呈指数增长因此它变得越来越受欢迎。 这使得手动修改和实时响应每条消息的任务变得不可能这可能会损害公司的形象。 情感分析的重点是在忽略细节的同时提取句子的基本组成部分。 这有助于解决两个主要需求 确定客户最关心的产品或服务的关键方面。提取这些方面背后的感受以确定哪些因素引起正面和负面反应并相应地进行处理 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v3SCln2J-1681785396607)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B16118_06_23.jpg)] 图 6.23一个推文示例 从前面的屏幕截图中获取文本执行情感分析的模型可能会获得以下信息 AI作为推文的对象从中得到的happy的感觉decade作为对象情感的时间范围 如您所见情感分析的概念对于任何具有在线业务的公司而言都是关键的因为它能够以惊人的速度对需要立即关注的评论做出快速响应并且其准确率类似于人类。 。 作为情感分析的示例用例某些公司可能选择对每天收到的大量消息进行情感分析以便优先处理对包含抱怨或负面情感的消息的响应。 这不仅有助于减轻特定客户的负面情感 它还将帮助公司快速纠正错误并与客户建立信任关系。 下一部分将详细说明执行 NLP 进行情感分析的过程。 我们将解释单词嵌入的概念以及在 PyTorch 中开发此类模型所能执行的不同步骤这将是本章最后活动的目标。 PyTorch 中的情感分析 建立一个在 PyTorch 中执行情感分析的模型与我们迄今为止使用 RNN 所看到的非常相似。 不同之处在于在这种情况下将逐字处理文本数据。 本节将提供构建这种模型所需的步骤。 预处理输入数据 与其他任何数据问题一样您需要将数据加载到代码中同时要记住对不同的数据类型使用不同的方法。 除了将整个单词集转换为小写字母之外数据还经过一些基本的转换可让您将数据输入网络。 最常见的转换如下 消除标点符号。在为 NLP 目的逐字处理文本数据时删除任何标点符号。这样做是为了避免把同一个词当作两个独立的词因为其中一个词后面有句号、逗号或任何其他特殊字符。一旦实现了这一点就可以定义一个包含输入文本词汇的列表也就是整个词集。 这可以通过使用string模块的punctuation预初始化的字符串来完成该字符串提供了可用于在文本序列中标识它们的标点符号列表例如以下代码段 test pd.Series([Hey! This is example #1., \Hey! This is example #2., \Hey! This is example #3.]) for i in punctuation:test test.str.replace(i,)带编号的标签类似于前面介绍的映射字符的过程词汇表中的每个单词都映射到一个整数该整数将用于替换输入文本的单词以便将它们输入网络 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ow3Xo5Mc-1681785396607)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B16118_06_24.jpg)] 图 6.24单词和数字的映射 PyTorch 无需执行一次性编码而是将单词嵌入单行代码这些代码可以在包含网络架构的类中定义将在下面进行解释。 构建架构 同样定义网络架构的过程与我们到目前为止研究的过程非常相似。 但是正如我们前面提到的网络还应包括一个嵌入层该嵌入层将获取输入数据已转换为数字表示形式并为每个单词分配相关程度。 也就是说这些值将在训练过程中更新直到最相关的单词被加权更高为止。 以下是架构的示例 class LSTM(nn.Module):def __init__(self, vocab_size, embed_dim, \hidden_size, n_layers):super().__init__()self.hidden_size hidden_sizeself.embedding nn.Embedding(vocab_size, embed_dim)self.lstm nn.LSTM(embed_dim, hidden_size, n_layers)self.output nn.Linear(hidden_size, 1)def forward(self, x, states):out self.embedding(x)out, states self.lstm(out, states)out out.contiguous().view(-1, self.hidden_size)out self.output(out)return out, states如您所见嵌入层将整个词汇表的长度以及用户设置的嵌入维度作为参数。 嵌入尺寸将是 LSTM 层的输入尺寸。 其余的架构将保持与以前相同。 训练模型 最后在定义了损失函数和优化算法之后训练模型的过程与任何其他神经网络相同。 根据研究的需要和目的可以将数据分为不同的组。 接下来您必须设置周期数和将数据分成批量的方法。 通常在处理每批数据时保留网络内存但随后在每个周期将其初始化为零。 通过对一批数据调用模型来获得网络的输出。 然后计算损失函数并优化参数。 活动 6.03用于情感分析的 NLP 您将用于此活动的数据集称为情感标记句子数据集可从 UC Irvine 机器学习存储库中获得。 注意 可以在这里找到该活动的数据集。 也可以从这里在线获取。 数据集和相关分析首次在此处发布使用深度特征从组到单个标签Kotzias 等KDD 2015 在此活动中将使用 LSTM 网络分析一组评论以确定其背后的观点。 让我们考虑以下情况您在一家互联网提供商的公共关系部门工作并且审查您在公司的社交媒体资料中遇到的每个查询的过程都将花费很长时间。 最大的问题是与服务有问题的客户相比没有服务的客户缺乏耐心因此您需要确定响应的优先级以便首先解决他们。 当您在业余时间喜欢编程时您决定尝试构建一个神经网络该网络能够确定消息是消极还是肯定。 请按照以下步骤完成此活动 注意 值得一提的是此活动中的数据并未分为不同的数据集以使模型可以进行微调和测试。 这是因为此活动的主要重点是实现创建能够执行情感分析的模型的过程。 导入所需的库。 加载包含来自亚马逊的 1,000 条产品评论的数据集并与标签 0对于负面评论或 1对于正面评论配对。 将数据分成两个变量-一个包含评论另一个包含标签。 从评论中删除标点符号。 创建一个包含整个评论集的词汇表的变量。 此外创建一个字典将每个单词映射到一个整数其中单词将作为键而整数将是值。 通过将评论中的每个单词替换为其成对的整数来对评论数据进行编码。 创建一个包含网络架构的类。确保你包含一个嵌入层。 注意 由于在训练过程中不会批量输入数据因此无需返回forward函数中的状态。 但是这并不意味着该模型将没有内存而是因为该内存不依赖于下一个审阅因此该内存用于单独处理每个审阅。 使用 3 个 LSTM 层的 64 个嵌入尺寸和 128 个神经元实例化模型。 定义损失函数优化算法以及要训练的周期数。 例如您可以将二进制交叉熵损失用作损失函数Adam 优化器并训练 10 个周期。 创建一个for循环该循环将经历不同的周期并分别经历每个审核。 对于每次审核都要进行预测计算损失函数并更新网络参数。 此外根据该训练数据计算网络的准确率。 随时间绘制损失和准确率。 最终的精度图将如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bf7f7pWQ-1681785396607)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B16118_06_25.jpg)] 图 6.25显示准确率得分进度的图 注意 可以在第 298 页上找到此活动的解决方案。 总结 在本章中我们讨论了 RNN。 开发这种类型的神经网络是为了解决与序列数据有关的问题。 这意味着单个实例不包含所有相关信息因为这取决于先前实例中的信息。 有几种适合这种类型描述的应用。 例如如果没有文本其余部分的上下文则文本或语音的特定部分可能意义不大。 但是即使 NLP 在 RNN 中得到了最多的研究在其他应用中文本的上下文也很重要例如预测视频处理或音乐相关的问题。 RNN 的工作方式非常聪明。 网络不仅输出结果而且还输出一个或多个通常称为内存的值。 该内存值用作将来预测的输入。 当处理涉及非常大序列的数据问题时传统的 RNN 会出现一个称为梯度消失问题的问题。 在这里梯度变得非常小因此它们不再对网络的学习过程有所贡献而这种学习过程通常发生在网络的较早层中从而导致网络无法长期存储。 为了解决这个问题开发了 LSTM 网络。 这种网络架构能够存储两种类型的内存因此得名。 此外在此网络中进行的数学计算允许它仅通过存储过去的相关信息来忘记信息。 最后解释了一个非常流行的 NLP 任务情感分析。 在此任务中重要的是要理解文本提取背后的情感。 对于机器而言这是一个非常困难的问题因为人们可以使用许多不同的单词和表达形式例如讽刺来描述事件背后的情感。 但是由于社交媒体使用量的增加这导致需要更快地处理文本数据这个问题在投入大量时间和金钱来创建多个近似值以解决该问题的大公司中变得非常普遍如图所示。 本章的最后活动。 既然您已经遍历了本书的所有章节您将对不同的深度神经网络架构有广泛的了解这些架构可用于使用 PyTorch 解决各种数据问题。 本书中说明的架构也可以用于解决其他数据问题。 七、附录 1.深度学习和 PyTorch 简介 活动 1.01创建单层神经网络 解决方案 导入所需的库包括 pandas用于导入 CSV 文件。 import pandas as pd import torch import torch.nn as nn import matplotlib.pyplot as plt读取包含数据集的 CSV 文件。 data pd.read_csv(SomervilleHappinessSurvey2015.csv)将输入特征与目标分开。注意目标位于 CSV 文件的第一列。将值转换为张量确保值转换为浮点数。 x torch.tensor(data.iloc[:,1:].values).float() y torch.tensor(data.iloc[:,:1].values).float()定义模型的架构并将其存储在一个名为model的变量中。记住要创建一个单层模型。 model nn.Sequential(nn.Linear(6, 1),nn.Sigmoid())定义要使用的损失函数。使用 MSE 损失函数。 loss_function torch.nn.MSELoss()定义你模型的优化器。使用亚当优化器和学习率0.01。 optimizer torch.optim.Adam(model.parameters(), lr0.01)运行优化 100 次迭代。每迭代 10 次打印并保存损失值。 losses [] for i in range(100):y_pred model(x)loss loss_function(y_pred, y)losses.append(loss.item())optimizer.zero_grad()loss.backward()optimizer.step()if i%10 0:print(loss.item())最终损失应约为0.24。 做一个线图来显示每个迭代步骤的损失值。 plt.plot(range(0,100), losses) plt.show()结果图应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xnWkKAKH-1681785396607)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_01_04.jpg)] 图 1.4整个训练过程中的损失函数 这意味着训练过程能够使损失函数最小化这意味着结果模型将可能能够绘制出市民对城市服务的满意度与他们对行政管理是否满意之间的关系。 注意 要访问此特定部分的源代码请参考这里。 您也可以通过这里在线运行此示例。 您必须执行整个笔记本才能获得所需的结果。 2.神经网络的构建块 活动 2.01执行数据准备 解决方案 导入所需的库。 import pandas as pd使用 pandas加载.csv文件。 data pd.read_csv(YearPredictionMSD.csv, nrows50000) data.head()注意 为避免内存限制在读取文本文件时请使用nrows自变量以读取整个数据集的较小部分。 在前面的示例中我们正在读取前 50,000 行。 输出如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j2lIbaR6-1681785396608)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_02_33.jpg)] 图 2.33YearPredictionMSD.csv 核实数据集中是否存在任何定性数据。 cols data.columns num_cols data._get_numeric_data().columns list(set(cols) - set(num_cols))输出应为空列表这意味着没有定性特征。 检查是否有缺失值。 如果在先前用于此目的的代码行中添加一个附加的sum()函数则将获得整个数据集中的缺失值之和而无需按列进行区分 data.isnull().sum().sum()输出应为0这意味着所有特征均不包含缺失值。 检查是否有异常值。 outliers {} for i in range(data.shape[1]):min_t data[data.columns[i]].mean() \- (3 * data[data.columns[i]].std())max_t data[data.columns[i]].mean() \ (3 * data[data.columns[i]].std())count 0for j in data[data.columns[i]]:if j min_t or j max_t:count 1percentage count/data.shape[0]outliers[data.columns[i]] %.3f % percentage print(outliers)输出字典应显示所有特征均不包含代表超过 5% 数据的离群值。 将特征从目标数据中分离出来。 X data.iloc[:, 1:] Y data.iloc[:, 0]使用标准化方法对特征数据进行重新缩放。 X (X - X.mean())/X.std() X.head()输出如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k9zn7jC8-1681785396608)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_02_34.jpg)] 图 2.34重新缩放的特征数据 将数据分成三组训练、验证和测试。使用你喜欢的方法。 from sklearn.model_selection import train_test_split X_shuffle X.sample(frac1, random_state0) Y_shuffle Y.sample(frac1, random_state0) x_new, x_test, \ y_new, y_test train_test_split(X_shuffle, \Y_shuffle, \test_size0.2, \random_state0) dev_per x_test.shape[0]/x_new.shape[0] x_train, x_dev, \ y_train, y_dev train_test_split(x_new, \y_new, \test_sizedev_per, \random_state0)打印所得形状如下。 print(x_train.shape, y_train.shape) print(x_dev.shape, y_dev.shape) print(x_test.shape, y_test.shape)输出应如下所示 (30000, 90) (30000, ) (10000, 90) (10000, ) (10000, 90) (10000, )注意 要访问此特定部分的源代码请参考这里。 您也可以通过这里在线运行此示例。 您必须执行整个笔记本才能获得所需的结果。 活动 2.02为回归问题开发深度学习解决方案 解决方案 导入所需的库。 import torch import torch.nn as nn将我们在上一个活动中创建的所有三组数据的特征从目标中分割出来。将DataFrame转换为张量。 x_train torch.tensor(x_train.values).float() y_train torch.tensor(y_train.values).float() x_dev torch.tensor(x_dev.values).float() y_dev torch.tensor(y_dev.values).float() x_test torch.tensor(x_test.values).float() y_test torch.tensor(y_test.values).float()定义网络的架构。可以自由尝试不同的层数和每层单元数的组合。 model nn.Sequential(nn.Linear(x_train.shape[1], 10), \nn.ReLU(), \nn.Linear(10, 7), \nn.ReLU(), \nn.Linear(7, 5), \nn.ReLU(), \nn.Linear(5, 1))定义损失函数和优化器算法。 loss_function torch.nn.MSELoss() optimizer torch.optim.Adam(model.parameters(), lr0.01)使用for循环来训练网络迭代步数为 3000 步。 for i in range(3000):y_pred model(x_train).squeeze()loss loss_function(y_pred, y_train)optimizer.zero_grad()loss.backward()optimizer.step()if i%250 0:print(i, loss.item())通过对测试集的第一个实例进行预测并与真实情况进行比较来测试你的模型。 pred model(x_test[0]) print(Ground truth:, y_test[0].item(), \Prediction:, pred.item())您的输出应类似于以下内容 Ground truth: 1995.0 Prediction: 1998.0279541015625注意 要访问此特定部分的源代码请参考这里。 您也可以通过这里在线运行此示例。 您必须执行整个笔记本才能获得所需的结果。 3.使用 DNN 的分类问题 活动 3.01构建人工神经网络 解 导入以下库 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.utils import shuffle from sklearn.metrics import accuracy_score import torch from torch import nn, optim import torch.nn.functional as F import matplotlib.pyplot as plt torch.manual_seed(0)读取之前准备好的数据集该数据集应该命名为dccc_prepared.csv。 data pd.read_csv(dccc_prepared.csv) data.head()输出应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfGW7iwL-1681785396608)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_03_14.jpg)] 图 3.14dccc_prepared.csv 将特征与目标分开。 X data.iloc[:,:-1] y data[default payment next month]使用 scikit-learn 的train_test_split函数将数据集分割成训练集、验证集和测试集。使用 60:20:20 的分割比例。将random_state设置为 0。 X_new, X_test, \ y_new, y_test train_test_split(X, y, test_size0.2, \random_state0) dev_per X_test.shape[0]/X_new.shape[0] X_train, X_dev, \ y_train, y_dev train_test_split(X_new, y_new, \test_sizedev_per, \random_state0)您可以使用以下代码打印每个集合的最终形状 print(Training sets:,X_train.shape, y_train.shape) print(Validation sets:,X_dev.shape, y_dev.shape) print(Testing sets:,X_test.shape, y_test.shape)每个集合的最终形状如下所示 Training sets: (28036, 22) (28036,) Validation sets: (9346, 22) (9346,) Testing sets: (9346, 22) (9346,)将验证集和测试集转换为张量记住特征矩阵应该是float类型而目标矩阵不应该。训练集暂不转换因为它们将进行进一步的转换。 X_dev_torch torch.tensor(X_dev.values).float() y_dev_torch torch.tensor(y_dev.values) X_test_torch torch.tensor(X_test.values).float() y_test_torch torch.tensor(y_test.values)构建一个自定义模块类用于定义网络的层。包括一个前向函数指定将应用于每层输出的激活函数。对所有层都使用 ReLU除了输出你应该使用log_softmax。 class Classifier(nn.Module):def __init__(self, input_size):super().__init__()self.hidden_1 nn.Linear(input_size, 10)self.hidden_2 nn.Linear(10, 10)self.hidden_3 nn.Linear(10, 10)self.output nn.Linear(10, 2)def forward(self, x):z F.relu(self.hidden_1(x))z F.relu(self.hidden_2(z))z F.relu(self.hidden_3(z))out F.log_softmax(self.output(z), dim1)return out实例化模型并定义训练模型所需的所有变量。设置周期数为50批次大小为128。使用0.001的学习率。 model Classifier(X_train.shape[1]) criterion nn.NLLLoss() optimizer optim.Adam(model.parameters(), lr0.001) epochs 50 batch_size 128使用训练集的数据来训练网络。使用验证集来衡量表现。要做到这一点请保存每个周期的训练集和验证集的损失和准确率。 train_losses, dev_losses, \ train_acc, dev_acc [], [], [], [] for e in range(epochs):X_, y_ shuffle(X_train, y_train)running_loss 0running_acc 0iterations 0for i in range(0, len(X_), batch_size):iterations 1b i batch_sizeX_batch torch.tensor(X_.iloc[i:b,:].values).float()y_batch torch.tensor(y_.iloc[i:b].values)pred model(X_batch)loss criterion(pred, y_batch)optimizer.zero_grad()loss.backward()optimizer.step()running_loss loss.item()ps torch.exp(pred)top_p, top_class ps.topk(1, dim1)running_acc accuracy_score(y_batch, top_class)dev_loss 0acc 0with torch.no_grad():pred_dev model(X_dev_torch)dev_loss criterion(pred_dev, y_dev_torch)ps_dev torch.exp(pred_dev)top_p, top_class_dev ps_dev.topk(1, dim1)acc accuracy_score(y_dev_torch, top_class_dev)train_losses.append(running_loss/iterations)dev_losses.append(dev_loss)train_acc.append(running_acc/iterations)dev_acc.append(acc)print(Epoch: {}/{}.. .format(e1, epochs),\Training Loss: {:.3f}.. \.format(running_loss/iterations),\Validation Loss: {:.3f}.. .format(dev_loss), \Training Accuracy: {:.3f}.. \.format(running_acc/iterations), \Validation Accuracy: {:.3f}.format(acc))绘出两组的损失。 fig plt.figure(figsize(15, 5)) plt.plot(train_losses, labelTraining loss) plt.plot(dev_losses, labelValidation loss) plt.legend(frameonFalse, fontsize15) plt.show()考虑到打乱训练数据可能会得出略有不同的结果结果图应与此处显示的图相似尽管有所不同。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e6o40pQp-1681785396612)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_03_15.jpg)] 图 3.15显示训练和验证损失的图 绘制两组的精度。 fig plt.figure(figsize(15, 5)) plt.plot(train_acc, labelTraining accuracy) plt.plot(dev_acc, labelValidation accuracy) plt.legend(frameonFalse, fontsize15) plt.show()这是从此代码段派生的图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CuT1TXgN-1681785396613)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_03_16.jpg)] 图 3.16显示集合精度的图 注意 要访问此特定部分的源代码请参考这里。 您也可以通过这里在线运行此示例。 您必须执行整个笔记本才能获得所需的结果。 练习 3.02提高模型的表现 解 导入你在上一个活动中使用的相同的库。 import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.utils import shuffle from sklearn.metrics import accuracy_score import torch from torch import nn, optim import torch.nn.functional as F import matplotlib.pyplot as plt torch.manual_seed(0)加载数据并从目标中拆分特征。接下来使用 60:20:20 的分割比例将数据分割成三个子集训练、验证和测试。最后将验证和测试集转换为 PyTorch 张量就像您在上一个活动中所做的那样。 data pd.read_csv(dccc_prepared.csv) X data.iloc[:,:-1] y data[default payment next month] X_new, X_test, \ y_new, y_test train_test_split(X, y, test_size0.2, \random_state0) dev_per X_test.shape[0]/X_new.shape[0] X_train, X_dev, \ y_train, y_dev train_test_split(X_new, y_new, \test_sizedev_per, \random_state0) X_dev_torch torch.tensor(X_dev.values).float() y_dev_torch torch.tensor(y_dev.values) X_test_torch torch.tensor(X_test.values).float() y_test_torch torch.tensor(y_test.values)考虑到该模型存在较高的偏差重点应放在增加周期的数量上或通过在每层中增加额外的层或单元来增加网络的规模。目标应该是将验证集的准确率近似到 80%。 之后将显示表现最佳的模型该模型是在几次微调尝试之后实现的。 首先定义模型架构和正向传播如以下代码片段所示 class Classifier(nn.Module):def __init__(self, input_size):super().__init__()self.hidden_1 nn.Linear(input_size, 100)self.hidden_2 nn.Linear(100, 100)self.hidden_3 nn.Linear(100, 50)self.hidden_4 nn.Linear(50,50)self.output nn.Linear(50, 2)self.dropout nn.Dropout(p0.1)def forward(self, x):z self.dropout(F.relu(self.hidden_1(x)))z self.dropout(F.relu(self.hidden_2(z)))z self.dropout(F.relu(self.hidden_3(z)))z self.dropout(F.relu(self.hidden_4(z)))out F.log_softmax(self.output(z), dim1)return out接下来定义训练过程的不同参数。 这包括损失函数优化算法批量大小和周期数如以下代码所示 model Classifier(X_train.shape[1]) criterion nn.NLLLoss() optimizer optim.Adam(model.parameters(), lr0.001) epochs 4000 batch_size 128最后按照以下代码片段处理训练过程 train_losses, dev_losses, train_acc, dev_acc [], [], [], [] x_axis [] for e in range(1, epochs 1):X_, y_ shuffle(X_train, y_train)running_loss 0running_acc 0iterations 0for i in range(0, len(X_), batch_size):iterations 1b i batch_sizeX_batch torch.tensor(X_.iloc[i:b,:].values).float()y_batch torch.tensor(y_.iloc[i:b].values)log_ps model(X_batch)loss criterion(log_ps, y_batch)optimizer.zero_grad()loss.backward()optimizer.step()running_loss loss.item()ps torch.exp(log_ps)top_p, top_class ps.topk(1, dim1)running_acc accuracy_score(y_batch, top_class)dev_loss 0acc 0with torch.no_grad():model.eval()log_dev model(X_dev_torch)dev_loss criterion(log_dev, y_dev_torch)ps_dev torch.exp(log_dev)top_p, top_class_dev ps_dev.topk(1, dim1)acc accuracy_score(y_dev_torch, top_class_dev)model.train()if e%50 0 or e 1:x_axis.append(e)train_losses.append(running_loss/iterations)dev_losses.append(dev_loss)train_acc.append(running_acc/iterations)dev_acc.append(acc)print(Epoch: {}/{}.. .format(e, epochs), \Training Loss: {:.3f}.. \.format(running_loss/iterations), \Validation Loss: {:.3f}.. .format(dev_loss),\Training Accuracy: {:.3f}.. \.format(running_acc/iterations), \Validation Accuracy: {:.3f}.format(acc))注意 可以在以前共享的 GitHub 存储库中找到此活动随附的 Jupyter 笔记本。 在那里您会发现对模型进行微调的各种尝试及其结果。 表现最佳的模型可以在笔记本电脑的末尾找到。 绘制两组数据的损失和准确率。 注意 请记住此处显示的结果与您的结果不完全匹配。 这主要是由于训练网络时使用了打乱函数。 使用以下代码绘制损失 fig plt.figure(figsize(15, 5)) plt.plot(x_axis,train_losses, labelTraining loss) plt.plot(x_axis, dev_losses, labelValidation loss) plt.legend(frameonFalse , fontsize15) plt.show()运行前面的代码将显示以下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cAMgzEwx-1681785396613)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_03_17.jpg)] 图 3.17显示集合损失的图 使用以下代码来绘制精度 fig plt.figure(figsize(15, 5)) plt.plot(x_axis, train_acc, labelTraining accuracy) plt.plot(x_axis, dev_acc, labelValidation accuracy) plt.legend(frameonFalse , fontsize15) plt.show()运行前面的代码将显示以下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kKYcj9Ca-1681785396613)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_03_18.jpg)] 图 3.18显示集合精度的图 使用表现最好的模型对测试集在微调过程中不应该使用进行预测。通过计算模型在该集上的准确率将预测结果与基本事实进行比较。 model.eval() test_pred model(X_test_torch) test_pred torch.exp(test_pred) top_p, top_class_test test_pred.topk(1, dim1) acc_test accuracy_score(y_test_torch, top_class_test) print(acc_test)通过模型架构和此处定义的参数获得的精度应为 80% 左右。 注意 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。 活动 3.03使用模型 解决方案 打开用于上一个活动的 Jupyter 笔记本。 复制包含最佳表现模型架构的类并将其保存在 Python 文件中。确保导入了 PyTorch 所需的库和模块并将其命名为final_model.py。将其命名为final_model.py。 该文件应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MGcHGKsD-1681785396613)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_03_19.jpg)] 图 3.19final_model.py的屏幕截图 在 Jupyter 笔记本中保存表现最好的模型。请务必保存与输入单元相关的信息以及模型的参数。将其命名为checkpoint.pth。 checkpoint {input: X_train.shape[1], \state_dict: model.state_dict()} torch.save(checkpoint, checkpoint.pth)打开一个新的 Jupyter 笔记本。 导入 PyTorch以及我们在“步骤 2”中创建的 Python 文件。 import torch import final_model创建一个加载模型的函数。 def load_model_checkpoint(path):checkpoint torch.load(path)model final_model.Classifier(checkpoint[input])model.load_state_dict(checkpoint[state_dict])return model model load_model_checkpoint(checkpoint.pth)通过将以下张量输入到你的模型中进行预测。 example torch.tensor([[0.0606, 0.5000, 0.3333, 0.4828, \0.4000, 0.4000, 0.4000, 0.4000, \0.4000, 0.4000, 0.1651, 0.0869, \0.0980, 0.1825, 0.1054, 0.2807, \0.0016, 0.0000, 0.0033, 0.0027, \0.0031, 0.0021]]).float() pred model(example) pred torch.exp(pred) top_p, top_class_test pred.topk(1, dim1)通过打印top_class_test我们可以获得模型的预测在这种情况下该预测等于1是。 使用 JIT 模块转换模型。 traced_script torch.jit.trace(model, example, check_traceFalse)通过输入“步骤 7”的相同张量到模型的跟踪脚本中进行预测。 prediction traced_script(example) prediction torch.exp(prediction) top_p_2, top_class_test_2 prediction.topk(1, dim1)通过打印top_class_test_2我们从模型的跟踪脚本表示中获得了预测该预测再次等于1是。 打开一个新的 Jupyter 笔记本并导入所需的库来使用 Flask 创建一个 API以及加载保存的模型的库。 import flask from flask import request import torch import final_model初始化 Flask 应用。 app flask.Flask(__name__) app.config[DEBUG] True定义一个函数加载保存的模型然后实例化模型。 def load_model_checkpoint(path):checkpoint torch.load(path)model final_model.Classifier(checkpoint[input])model.load_state_dict(checkpoint[state_dict])return model model load_model_checkpoint(checkpoint.pth)定义 API 的路由为/prediction并将方法设置为POST。然后定义接收POST数据的函数并将其反馈给模型进行预测。 app.route(/prediction, methods[POST]) def prediction():body request.get_json()example torch.tensor(body[data]).float()pred model(example)pred torch.exp(pred)_, top_class_test pred.topk(1, dim1)top_class_test top_class_test.numpy()return {status:ok, result:int(top_class_test[0][0])}运行 Flask 应用。 app.run(debugTrue, use_reloaderFalse)使用为 API 开发而创建的平台 Postman可以测试 API。 要向 Postman 提交成功的请求标头的Content-Type应当等于application/json。 结果输出应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZPO10xAa-1681785396613)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_03_13.jpg)] 图 3.20应用运行后的屏幕截图 注意 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。 4.卷积神经网络 活动 4.01针对图像分类问题构建 CNN 解决方案 导入所需的库。 import numpy as np import torch from torch import nn, optim import torch.nn.functional as F from torchvision import datasets import torchvision.transforms as transforms from torch.utils.data.sampler import SubsetRandomSampler from sklearn.metrics import accuracy_score import matplotlib.pyplot as plt设置要对数据进行的变换将数据转换为张量并对像素值进行归一化。 transform \transforms.Compose([transforms.ToTensor(), \transforms.Normalize((0.5, 0.5, 0.5),\(0.5, 0.5, 0.5))])设置批量大小为 100 张图像并从 CIFAR10 数据集下载训练和测试数据。 batch_size 100 train_data datasets.CIFAR10(data, trainTrue, \downloadTrue, \transformtransform) test_data datasets.CIFAR10(data, trainFalse, \downloadTrue, \transformtransform)前面的代码将下载可通过 PyTorch 的Torchvision包获得的训练和测试数据集。 根据上一步中定义的转换对数据集进行转换。 使用 20% 的验证大小定义训练和验证采样器用于将数据集划分为这两组。 dev_size 0.2 idx list(range(len(train_data))) np.random.shuffle(idx) split_size int(np.floor(dev_size * len(train_data))) train_idx, dev_idx idx[split_size:], idx[:split_size] train_sampler SubsetRandomSampler(train_idx) dev_sampler SubsetRandomSampler(dev_idx)为了将训练集分为两组训练和验证为每个组定义了一个索引列表然后可以使用SubsetRandomSampler函数对其进行随机采样。 使用DataLoader()函数来定义要使用的每一组数据的批次。 train_loader \ torch.utils.data.DataLoader(train_data, \batch_sizebatch_size, \samplertrain_sampler) dev_loader \ torch.utils.data.DataLoader(train_data, \batch_sizebatch_size, \samplerdev_sampler) test_loader \ torch.utils.data.DataLoader(test_data, \batch_sizebatch_size)PyTorch 的DataLoader函数用于创建批量这些批量将在开发过程的训练验证和测试阶段馈送到模型中。 定义你的网络架构。使用以下信息进行定义。 Conv1卷积层将彩色图像作为输入并将其通过大小为 3 的 10 个过滤器。应将填充和跨步都设置为 1。 Conv2一个卷积层它将输入数据通过大小为 3 的 20 个过滤器传递。填充和跨距都应设置为 1。 Conv3一个卷积层它将输入数据通过大小为 3 的 40 个过滤器传递。填充和跨距都应设置为 1。 在每个卷积层之后使用 ReLU 激活函数。 在每个卷积层之后使用池化层过滤器大小和步幅为 2。 展平图像后使用掉落项设置为 20%。 Linear1一个全连接层接收上一层的展平矩阵作为输入并生成 100 个单元的输出。 为此层使用 ReLU 激活函数。 此处的丢弃期限设置为 20%。 Linear2一个全连接层可生成 10 个输出每个类标签一个。 将log_softmax激活函数用于输出层 class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 nn.Conv2d(3, 10, 3, 1, 1)self.conv2 nn.Conv2d(10, 20, 3, 1, 1)self.conv3 nn.Conv2d(20, 40, 3, 1, 1)self.pool nn.MaxPool2d(2, 2)self.linear1 nn.Linear(40 * 4 * 4, 100)self.linear2 nn.Linear(100, 10)self.dropout nn.Dropout(0.2)def forward(self, x):x self.pool(F.relu(self.conv1(x)))x self.pool(F.relu(self.conv2(x)))x self.pool(F.relu(self.conv3(x)))x x.view(-1, 40 * 4 * 4)x self.dropout(x)x F.relu(self.linear1(x))x self.dropout(x)x F.log_softmax(self.linear2(x), dim1)return x前面的代码段包含一个定义了网络架构的类__init__方法以及在信息正向传播过程中所遵循的步骤forward方法。 定义训练模型所需的所有参数。设置周期数为50。 model CNN() loss_function nn.NLLLoss() optimizer optim.Adam(model.parameters(), lr0.001) epochs 50我们为此练习选择的优化器是 Adam。 同样负对数似然率用作损失函数如本书前一章所述。 如果您的计算机具有可用的 GPU则应按以下步骤完成模型的实例化 model CNN().to(cuda)训练你的网络并确保保存训练集和验证集的损失和准确率的值。 train_losses, dev_losses, train_acc, dev_acc [], [], [], [] x_axis [] # For loop through the epochs for e in range(1, epochs1):losses 0acc 0iterations 0model.train()For loop through the batches (created usingthe train loader)for data, target in train_loader:iterations 1# Forward and backward pass of the training datapred model(data)loss loss_function(pred, target)optimizer.zero_grad()loss.backward()optimizer.step()losses loss.item()p torch.exp(pred)top_p, top_class p.topk(1, dim1)acc accuracy_score(target, top_class)dev_losss 0dev_accs 0iter_2 0# Validation of model for given epochif e%5 0 or e 1:x_axis.append(e)with torch.no_grad():model.eval()For loop through the batches ofthe validation setfor data_dev, target_dev in dev_loader:iter_2 1dev_pred model(data_dev)dev_loss loss_function(dev_pred, target_dev)dev_losss dev_loss.item()dev_p torch.exp(dev_pred)top_p, dev_top_class dev_p.topk(1, dim1)dev_accs accuracy_score(target_dev, \dev_top_class)# Losses and accuracy are appended to be printedtrain_losses.append(losses/iterations)dev_losses.append(dev_losss/iter_2)train_acc.append(acc/iterations)dev_acc.append(dev_accs/iter_2)print(Epoch: {}/{}.. .format(e, epochs), \Training Loss: {:.3f}.. \.format(losses/iterations), \Validation Loss: {:.3f}.. \.format(dev_losss/iter_2), \Training Accuracy: {:.3f}.. \.format(acc/iterations), \Validation Accuracy: {:.3f}\.format(dev_accs/iter_2))如果您的计算机具有可用的 GPU则对前面的代码进行一些修改如下所示 train_losses, dev_losses, train_acc, dev_acc [], [], [], [] x_axis [] # For loop through the epochs for e in range(1, epochs1):losses 0acc 0iterations 0model.train()For loop through the batches(created using the train loader)for data, target in train_loader:iterations 1# Forward and backward pass of the training datapred model(data.to(cuda))loss loss_function(pred, target.to(cuda))optimizer.zero_grad()loss.backward()optimizer.step()losses loss.item()p torch.exp(pred)top_p, top_class p.topk(1, dim1)acc accuracy_score(target.to(cpu), \top_class.to(cpu))dev_losss 0dev_accs 0iter_2 0# Validation of model for given epochif e%5 0 or e 1:x_axis.append(e)with torch.no_grad():model.eval()For loop through the batches ofthe validation setfor data_dev, target_dev in dev_loader:iter_2 1dev_pred model(data_dev.to(cuda))dev_loss loss_function(dev_pred, \target_dev.to(cuda))dev_losss dev_loss.item()dev_p torch.exp(dev_pred)top_p, dev_top_class dev_p.topk(1, dim1)dev_accs \accuracy_score(target_dev.to(cpu), \dev_top_class.to(cpu))# Losses and accuracy are appended to be printedtrain_losses.append(losses/iterations)dev_losses.append(dev_losss/iter_2)train_acc.append(acc/iterations)dev_acc.append(dev_accs/iter_2)print(Epoch: {}/{}.. .format(e, epochs), \Training Loss: {:.3f}.. \.format(losses/iterations), \Validation Loss: {:.3f}.. \.format(dev_losss/iter_2), \Training Accuracy: {:.3f}.. \.format(acc/iterations), \Validation Accuracy: {:.3f}\.format(dev_accs/iter_2))绘制这两组数据的损失和精度。要绘制损失请使用以下代码。 plt.plot(x_axis,train_losses, labelTraining loss) plt.plot(x_axis, dev_losses, labelValidation loss) plt.legend(frameonFalse) plt.show()结果图应类似于以下内容 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W4t6Ed2h-1681785396614)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_04_23.jpg)] 图 4.23结果图显示了集合的损失 要绘制精度请使用以下代码 plt.plot(x_axis, train_acc, labelTraining accuracy) plt.plot(x_axis, dev_acc, labelValidation accuracy) plt.legend(frameonFalse) plt.show()该图应类似于以下内容 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iomwROIm-1681785396614)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_04_24.jpg)] 图 4.24结果图显示了集合的准确率 可以看出在第 15 个周期之后过拟合开始影响模型。 在测试集上检查模型的准确率。 model.eval() iter_3 0 acc_test 0 for data_test, target_test in test_loader:iter_3 1test_pred model(data_test)test_pred torch.exp(test_pred)top_p, top_class_test test_pred.topk(1, dim1)acc_test accuracy_score(target_test, top_class_test) print(acc_test/iter_3)使用我们之前创建的数据加载器可以对测试集数据进行图像分类以估计模型在看不见数据上的准确率。 如果您的计算机具有可用的 GPU则对前面的代码进行一些修改如下所示 model.eval() iter_3 0 acc_test 0 for data_test, target_test in test_loader:iter_3 1test_pred model(data_test.to(cuda))test_pred torch.exp(test_pred)top_p, top_class_test test_pred.topk(1, dim1)acc_test accuracy_score(target_test .to(cpu), \top_class_test .to(cpu)) print(acc_test/iter_3)测试集的准确率与其他两组所达到的准确率非常相似这意味着该模型能够对看不见的数据表现出同样出色的表现。 它应该在 72% 左右。 注意 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。 要访问此源代码的 GPU 版本请参考这里。 此版本的源代码无法作为在线交互示例使用需要通过 GPU 设置在本地运行。 活动 4.02实现数据扩充 解决方案 复制之前活动中的笔记本。 为了完成此活动按照以下步骤除了修改tranforms值之外不会更改任何代码。 修改transform变量的定义使其除了对数据进行归一化和转换为张量外还包括以下转换 对于训练/验证集请使用RandomHorizo​​ntalFlip函数其概率为 50%0.5并使用RandomGrayscale函数其概率为 10%0.1。 对于测试集请勿添加任何其他转换 transform \ {train: transforms.Compose([\transforms.RandomHorizontalFlip(0.5), \transforms.RandomGrayscale(0.1),\transforms.ToTensor(),\transforms.Normalize((0.5, 0.5, 0.5), \(0.5, 0.5, 0.5))]),\ test: transforms.Compose([\transforms.ToTensor(),\transforms.Normalize((0.5, 0.5, 0.5), \(0.5, 0.5, 0.5))])}训练模型 100 个周期。 如果您的计算机具有可用的 GPU请确保使用代码的 GPU 版本来训练模型。 在训练和验证集上得出的损失和准确率图应与此处显示的图相似 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBDv8cLc-1681785396614)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_04_25.jpg)] 图 4.25结果图显示了集合的损失 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-elyW6mCl-1681785396614)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_04_26.jpg)] 图 4.26结果图显示了集合的准确率 通过添加数据扩充可以改善模型的表现并减少发生的过拟合。 计算所得模型在测试集上的精度。 该模型在测试设备上的表现提高了约 75%。 注意 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。 要访问此源代码的 GPU 版本请参考这里。 此版本的源代码无法作为在线交互示例使用需要通过 GPU 设置在本地运行。 活动 4.03实现批量标准化 解决方案 复制之前活动中的笔记本。 要完成此活动按照以下步骤除了在网络架构中添加一些层之外不会更改任何代码。 将批量归一化添加到每个卷积层以及第一个全连接层。 网络的最终架构应如下 class CNN(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 nn.Conv2d(3, 10, 3, 1, 1)self.norm1 nn.BatchNorm2d(10)self.conv2 nn.Conv2d(10, 20, 3, 1, 1)self.norm2 nn.BatchNorm2d(20)self.conv3 nn.Conv2d(20, 40, 3, 1, 1)self.norm3 nn.BatchNorm2d(40)self.pool nn.MaxPool2d(2, 2)self.linear1 nn.Linear(40 * 4 * 4, 100)self.norm4 nn.BatchNorm1d(100)self.linear2 nn.Linear(100, 10)self.dropout nn.Dropout(0.2)def forward(self, x):x self.pool(self.norm1(F.relu(self.conv1(x))))x self.pool(self.norm2(F.relu(self.conv2(x))))x self.pool(self.norm3(F.relu(self.conv3(x))))x x.view(-1, 40 * 4 * 4)x self.dropout(x)x self.norm4(F.relu(self.linear1(x)))x self.dropout(x)x F.log_softmax(self.linear2(x), dim1)return x训练模型 100 个周期。 如果您的计算机具有可用的 GPU请确保使用代码的 GPU 版本来训练模型。 训练和验证集的损失和准确率的结果图应类似于此处所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GxSlaLfk-1681785396614)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_04_27.jpg)] 图 4.27结果图显示集合的损失 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-115lZfOf-1681785396615)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_04_28.jpg)] 图 4.28结果图显示集合的损失 尽管过拟合再次引入了模型但是我们可以看到两组的表现都有所提高。 注意 尽管本章未对此进行探讨但理想的步骤是为网络架构添加丢弃以减少高方差。 随意尝试一下看看您是否能够进一步提高性能。 计算所得模型在测试集上的精度。 该模型在测试设备上的表现已提高了约 78%。 注意 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。 要访问此源代码的 GPU 版本请参考这里。 此版本的源代码无法作为在线交互示例使用需要通过 GPU 设置在本地运行。 5.样式迁移 活动 5.01执行样式迁移 解决方案 导入所需的库。 import numpy as np import torch from torch import nn, optim from PIL import Image import matplotlib.pyplot as plt from torchvision import transforms, models如果您的计算机具有可用的 GPU请确保定义一个名为device的变量该变量将有助于为 GPU 分配一些变量如下所示 device cuda指定要对输入图像进行的变换。请确保将它们调整为相同的大小将它们转换为张力并将它们标准化。 imsize 224 loader \ transforms.Compose([transforms.Resize(imsize), \transforms.ToTensor(),\transforms.Normalize((0.485, 0.456, 0.406), \(0.229, 0.224, 0.225))])定义一个图像加载器函数。它应该打开图像并加载它。调用图像加载器函数来加载两个输入图像。 def image_loader(image_name):image Image.open(image_name)image loader(image).unsqueeze(0)return image content_img image_loader(images/landscape.jpg) style_img image_loader(images/monet.jpg)如果您的计算机有可用的 GPU请改用以下代码段 def image_loader(image_name):image Image.open(image_name)image loader(image).unsqueeze(0)return image content_img image_loader(images/landscape.jpg).to(device) style_img image_loader(images/monet.jpg).to(device)为了能够显示图像设置变换以恢复图像的归一化并将张量转换为PIL图像。 unloader transforms.Compose([\transforms.Normalize((-0.485/0.229, \-0.456/0.224, \-0.406/0.225), \(1/0.229, 1/0.224, 1/0.225)),\transforms.ToPILImage()])创建一个函数tensor2image它能够在张量上执行前面的变换。对两幅图像调用该函数并绘制结果。 def tensor2image(tensor):image tensor.clone()image image.squeeze(0)image unloader(image)return image plt.figure() plt.imshow(tensor2image(content_img)) plt.title(Content Image) plt.show() plt.figure() plt.imshow(tensor2image(style_img)) plt.title(Style Image) plt.show()如果您的计算机有可用的 GPU请改用以下代码段 def tensor2image(tensor):image tensor.to(cpu).clone()image image.squeeze(0)image unloader(image)return image plt.figure() plt.imshow(tensor2image(content_img)) plt.title(Content Image) plt.show() plt.figure() plt.imshow(tensor2image(style_img)) plt.title(Style Image) plt.show()加载 VGG-19 模型。 model models.vgg19(pretrainedTrue).features for param in model.parameters():param.requires_grad_(False)创建一个字典用于将相关层的索引键映射到名称值。然后创建一个函数来提取相关层的特征映射。用它们来提取两个输入图像的特征。 以下函数应为每个相关层提取给定图像的特征 relevant_layers {0: conv1_1, 5: conv2_1, \10: conv3_1, 19: conv4_1, \21: conv4_2, 28: conv5_1} def features_extractor(x, model, layers):features {}for index, layer in model._modules.items():x layer(x)if index in layers:features[layers[index]] xreturn features接下来应该为内容和样式图像调用该函数 content_features features_extractor(content_img, \model, \relevant_layers) style_features features_extractor(style_img, model, \relevant_layers)计算风格特征的 Gram 矩阵。同时创建初始目标图像。 以下代码段为用于提取样式特征的每个层创建了 gram 矩阵 style_grams {} for i in style_features:layer style_features[i]_, d1, d2, d3 layer.shapefeatures layer.view(d1, d2 * d3)gram torch.mm(features, features.t())style_grams[i] gram接下来创建初始目标图像作为内容图像的克隆 target_img content_img.clone().requires_grad_(True)如果您的计算机有可用的 GPU请改用以下代码段 target_img content_img.clone().requires_grad_(True).to(device)设置不同样式层的权重以及内容和样式损失的权重。 style_weights {conv1_1: 1., conv2_1: 0.8, \conv3_1: 0.6, conv4_1: 0.4, \conv5_1: 0.2} alpha 1 beta 1e5运行模型 500 次迭代。在开始训练模型之前定义 Adam 优化算法以0.001作为学习率。 注意 为了获得本书所示的最终目标图像该代码运行了 5,000 次迭代而没有 GPU 则需要很长时间才能运行。 但是要欣赏输出图像中开始发生的更改尽管鼓励您测试不同的训练时间但只需运行 500 次迭代就足够了。 print_statement 500 optimizer torch.optim.Adam([target_img], lr0.001) iterations 5000 for i in range(1, iterations1):# Extract features for all relevant layerstarget_features features_extractor(target_img, model, \relevant_layers)# Calculate the content losscontent_loss torch.mean((target_features[conv4_2] \- content_features[conv4_2])**2)# Loop through all style layersstyle_losses 0for layer in style_weights:# Create gram matrix for that layertarget_feature target_features[layer]_, d1, d2, d3 target_feature.shapetarget_reshaped target_feature.view(d1, d2 * d3)target_gram torch.mm(target_reshaped, \target_reshaped.t())style_gram style_grams[layer]# Calculate style loss for that layerstyle_loss style_weights[layer] * \torch.mean((target_gram - \style_gram)**2)#Calculate style loss for all layersstyle_losses style_loss / (d1 * d2 * d3)# Calculate the total losstotal_loss alpha * content_loss beta * style_losses# Perform back propagationoptimizer.zero_grad()total_loss.backward()optimizer.step()# Print the target imageif i % print_statement 0 or i 1:print(Total loss: , total_loss.item())plt.imshow(tensor2image(target_img))plt.show()绘制内容、风格、目标的图片比较结果。 fig, (ax1, ax2, ax3) plt.subplots(1, 3, figsize(15, 5)) ax1.imshow(tensor2image(content_img)) ax2.imshow(tensor2image(target_img)) ax3.imshow(tensor2image(style_img)) plt.show()从此代码段派生的图应类似于此处显示的图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N2a7UpvC-1681785396615)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_05_11.jpg)] 图 5.11输出图 注意 要查看高质量彩色图像请访问本书的 GitHub 存储库网址为 https://packt.live/2KcORcw。 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。 要访问此源代码的 GPU 版本请参考这里。 此版本的源代码无法作为在线交互示例使用需要通过 GPU 设置在本地运行。 6.使用 RNN 分析数据序列 活动 6.01使用简单 RNN 的时间序列预测 解决方案 导入所需的库具体如下 import pandas as pd import matplotlib.pyplot as plt import torch from torch import nn, optim加载数据集然后对其进行切片使其包含所有的行但只包含索引 1 到 52 的列。 data pd.read_csv(Sales_Transactions_Dataset_Weekly.csv) data data.iloc[:,1:53] data.head()输出如下 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WzFRD3eg-1681785396615)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_26.jpg)] 图 6.26显示索引 1 到 52 列的数据集 绘制从整个数据集中随机选择的五种产品的每周销售交易情况。在进行随机采样时使用随机种子0以达到与当前活动相同的结果。 plot_data data.sample(5, random_state0) x range(1,53) plt.figure(figsize(10,5)) for i,row in plot_data.iterrows():plt.plot(x,row) plt.legend(plot_data.index) plt.xlabel(Weeks) plt.ylabel(Sales transactions per product) plt.show()结果图应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bXVKykSf-1681785396615)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_27.jpg)] 图 6.27输出图 创建input和target变量这些变量将被输入到网络中以创建模型。这些变量应具有相同的形状并转换为 PyTorch 张量。 input变量应包含除上周外的所有星期的所有产品数据因为模型的目的是预测最后一周。 target变量应比input变量领先一步 也就是说target变量的第一个值应该是输入变量中的第二个依此类推直到target变量的最后一个值应该被留在input变量之外 data_train data.iloc[:,:-1] inputs torch.Tensor(data_train.values).unsqueeze(1) targets data_train.shift(-1, axiscolumns, \fill_valuedata.iloc[:,-1])\.astype(dtype float32) targets torch.Tensor(targets.values)创建一个包含网络架构的类。注意全连接层的输出大小应该是1。 class RNN(nn.Module):def __init__(self, input_size, hidden_size, num_layers):super().__init__()self.hidden_size hidden_sizeself.rnn nn.RNN(input_size, hidden_size, \num_layers, batch_firstTrue)self.output nn.Linear(hidden_size, 1)def forward(self, x, hidden):out, hidden self.rnn(x, hidden)out out.view(-1, self.hidden_size)out self.output(out)return out, hidden与之前的活动一样该类包含__init__方法以及网络架构以及forward方法该方法确定信息在各层之间的流动。 实例化包含模型的类函数。输入输入大小、每个循环层的神经元数量10和循环层数量1。 model RNN(data_train.shape[1], 10, 1) model运行前面的代码将显示以下输出 RNN((rnn): RNN(51, 10, batch_firstTrue)(output): Linear(in_features10, out_features1, biasTrue) )定义一个损失函数一个优化算法以及训练网络的周期数。使用 MSE 损失函数、Adam 优化器和 10,000 个周期来完成这一任务。 loss_function nn.MSELoss() optimizer optim.Adam(model.parameters(), lr0.001) epochs 10000使用for循环来执行训练过程经历所有的周期。在每个周期中必须进行预测以及随后的损失函数计算和网络参数的优化。保存每个周期的损失。 注意 考虑到没有批量用于遍历数据集hidden量实际上并未在批量之间传递而是在处理序列的每个元素时使用隐藏状态但是为了清楚起见它留在这里。 losses [] for i in range(1, epochs1):hidden Nonepred, hidden model(inputs, hidden)target targets[:,-1].unsqueeze(1)loss loss_function(targets, pred)optimizer.zero_grad()loss.backward()optimizer.step()losses.append(loss.item())if i%1000 0:print(epoch: , i, ... Loss function: , losses[-1])输出应如下所示 epoch: 1000 ... Loss function: 58.48879623413086 epoch: 2000 ... Loss function: 24.934917449951172 epoch: 3000 ... Loss function: 13.247632026672363 epoch: 4000 ... Loss function: 9.884735107421875 epoch: 5000 ... Loss function: 8.778228759765625 epoch: 6000 ... Loss function: 8.025042533874512 epoch: 7000 ... Loss function: 7.622503757476807 epoch: 8000 ... Loss function: 7.4796295166015625 epoch: 9000 ... Loss function: 7.351718902587891 epoch: 10000 ... Loss function: 7.311776161193848将所有周期的损失绘制如下 x_range range(len(losses)) plt.plot(x_range, losses) plt.xlabel(epochs) plt.ylabel(Loss function) plt.show()结果图应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jz5c39sB-1681785396616)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_28.jpg)] 图 6.28显示所有周期的损失的图 使用散点图显示在训练过程的最后一个周期中获得的预测值与真实情况值即上周的销售交易的对比。 x_range range(len(data)) target data.iloc[:,-1].values.reshape(len(data),1) plt.figure(figsize(15,5)) plt.scatter(x_range[:20], target[:20]) plt.scatter(x_range[:20], pred.detach().numpy()[:20]) plt.legend([Ground truth, Prediction]) plt.xlabel(Product) plt.ylabel(Sales Transactions) plt.xticks(range(0, 20)) plt.show()最终图应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6M6lvupF-1681785396616)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_29.jpg)] 图 6.29显示预测的散点图 注意 要访问此特定部分的源代码请参考这里。 您也可以通过这里在线运行此示例。 您必须执行整个笔记本才能获得所需的结果。 活动 6.02使用 LSTM 网络生成文本 解决方案 导入所需的库具体如下 import math import numpy as np import matplotlib.pyplot as plt import torch from torch import nn, optim import torch.nn.functional as F打开并将《爱丽丝梦游仙境》中的文字读入笔记本。打印前 50 个字符的摘要和文本文件的总长度。 with open(alice.txt, r, encodinglatin1) as f:data f.read() print(Extract: , data[:50]) print(Length: , len(data))创建一个变量其中包含数据集中未重复的字符列表。然后创建一个字典将每个字符映射到一个整数其中字符将是键整数将是值。 chars list(set(data)) indexer {char: index for (index, char) in enumerate(chars)} The output should look as follows:输出应如下所示 Extract: ALICE was beginning to get very tired of sitting b Length: 145178将数据集的每个字母编码为其配对的整数。打印前 50 个编码字符和数据集编码版本的总长度。 indexed_data [] for c in data:indexed_data.append(indexer[c]) print(Indexed extract: , indexed_data[:50]) print(Length: , len(indexed_data))输出如下 Indexed extract: [51, 52, 29, 38, 28, 25, 11, 59, 39, 25, 16, 53, 2, 1, 26, 26, 1, 26, 2, 25, 56, 60, 25, 2, 53, 56, 25, 23, 53, 7, 45, 25, 56, 1, 7, 53, 13, 25, 60, 14, 25, 39, 1, 56, 56, 1, 26, 2, 25, 16] Length: 145178创建一个函数接收一个批量并将其编码为单热矩阵。 def index2onehot(batch):batch_flatten batch.flatten()onehot_flat np.zeros((batch.shape[0] \* batch.shape[1],len(indexer)))onehot_flat[range(len(batch_flatten)), batch_flatten] 1onehot onehot_flat.reshape((batch.shape[0], \batch.shape[1], -1))return onehot此函数采用二维矩阵并将其展平。 接下来它创建一个平坦矩阵的形状和包含字母的字典长度的零填充矩阵在“步骤 3”中创建。 接下来它用一个字符填充对应于批量中每个字符的字母。 最后它对矩阵进行整形以使其为三维。 创建一个定义网络架构的类。这个类应该包含一个额外的函数用于初始化 LSTM 层的状态。 class LSTM(nn.Module):def __init__(self, char_length, hidden_size, n_layers):super().__init__()self.hidden_size hidden_sizeself.n_layers n_layersself.lstm nn.LSTM(char_length, hidden_size,\n_layers, batch_firstTrue)self.output nn.Linear(hidden_size, char_length)def forward(self, x, states):out, states self.lstm(x, states)out out.contiguous().view(-1, self.hidden_size)out self.output(out)return out, statesdef init_states(self, batch_size):hidden next(self.parameters())\.data.new(self.n_layers, batch_size, \self.hidden_size).zero_()cell next(self.parameters())\.data.new(self.n_layers,batch_size, \self.hidden_size).zero_()states (hidden, cell)return states This class contains an __init__ method where the此类包含__init__方法其中定义了网络的架构forward方法用于确定通过层的数据流以及init_state用零初始化隐藏状态和单元状态的方法。 确定要从数据集中创建的批次数量记住每个批次应该包含 100 个序列每个序列的长度为 50 个。接下来将编码后的数据分成 100 个序列。 # Number of sequences per batch n_seq 100 seq_length 50 n_batches math.floor(len(indexed_data) \/ n_seq / seq_length) total_length n_seq * seq_length * n_batches x indexed_data[:total_length] x np.array(x).reshape((n_seq,-1))通过使用256作为共两个循环层的隐藏单元数来实例化你的模型。 model LSTM(len(chars), 256, 2) model运行前面的代码将显示以下输出 LSTM((lstm): LSTM(70, 256, num_layers2, batch_firstTrue)(output): Linear(in_features256, out_features70, biasTrue) )如果您的计算机有可用的 GPU请确保使用以下代码片段将模型分配给 GPU model LSTM(len(chars), 256, 2).to(cuda)定义损失函数和优化算法。使用 Adam 优化器和交叉熵损失来完成。训练网络20周期。 loss_function nn.CrossEntropyLoss() optimizer optim.Adam(model.parameters(), lr0.001) epochs 20如果您的机器有可用的 GPU请尝试运行500周期的训练过程 epochs 500在每个周期数据必须被划分为序列长度为 50 的批次。这意味着每个周期将有 100 个批次每个批次的序列长度为 50。 losses [] for e in range(1, epochs1):states model.init_states(n_seq)batch_loss []for b in range(0, x.shape[1], seq_length):x_batch x[:,b:bseq_length]if b x.shape[1] - seq_length:y_batch x[:,b1:bseq_length]y_batch np.hstack((y_batch, indexer[.] \* np.ones((y_batch.shape[0],1))))else:y_batch x[:,b1:bseq_length1]x_onehot torch.Tensor(index2onehot(x_batch))y torch.Tensor(y_batch).view(n_seq * seq_length)pred, states model(x_onehot, states)loss loss_function(pred, y.long())optimizer.zero_grad()loss.backward(retain_graphTrue)optimizer.step()batch_loss.append(loss.item())losses.append(np.mean(batch_loss))if e%2 0:print(epoch: , e, ... Loss function: , losses[-1])输出应如下所示 epoch: 2 ... Loss function: 3.1667490992052802 epoch: 4 ... Loss function: 3.1473221943296235 epoch: 6 ... Loss function: 2.897721455014985 epoch: 8 ... Loss function: 2.567064647016854 epoch: 10 ... Loss function: 2.4197753791151375 epoch: 12 ... Loss function: 2.314083896834275 epoch: 14 ... Loss function: 2.2241266349266313 epoch: 16 ... Loss function: 2.1459227183769487 epoch: 18 ... Loss function: 2.0731402758894295 epoch: 20 ... Loss function: 2.0148646708192497如果您的计算机具有可用的 GPU则用于训练网络的等效代码段如下所示 losses [] for e in range(1, epochs1):states model.init_states(n_seq)batch_loss []for b in range(0, x.shape[1], seq_length):x_batch x[:,b:bseq_length]if b x.shape[1] - seq_length:y_batch x[:,b1:bseq_length]y_batch np.hstack((y_batch, indexer[.] \* np.ones((y_batch.shape[0],1))))else:y_batch x[:,b1:bseq_length1]x_onehot torch.Tensor(index2onehot(x_batch))\.to(cuda)y torch.Tensor(y_batch).view(n_seq * \seq_length).to(cuda)pred, states model(x_onehot, states)loss loss_function(pred, y.long())optimizer.zero_grad()loss.backward(retain_graphTrue)optimizer.step()batch_loss.append(loss.item())losses.append(np.mean(batch_loss))if e%50 0:print(epoch: , e, ... Loss function: , \losses[-1])将训练过程运行 500 个周期的结果如下 epoch: 50 ... Loss function: 1.5207843986050835 epoch: 100 ... Loss function: 1.006190665836992 epoch: 150 ... Loss function: 0.5197970939093622 epoch: 200 ... Loss function: 0.24446514968214364 epoch: 250 ... Loss function: 0.0640328845073437 epoch: 300 ... Loss function: 0.007852113484565553 epoch: 350 ... Loss function: 0.003644719101681278 epoch: 400 ... Loss function: 0.006955199634078248 epoch: 450 ... Loss function: 0.0030021724242973945 epoch: 500 ... Loss function: 0.0034294885518992768可以看出通过将训练过程运行更多的时间段损失函数将达到较低的值。 绘制损失随时间推移的进展情况。 x_range range(len(losses)) plt.plot(x_range, losses) plt.xlabel(epochs) plt.ylabel(Loss function) plt.show()该图表应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6D8ImFMb-1681785396616)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_30.jpg)] 图 6.30显示损失函数进度的图表 如我们所见在 20 个周期之后损失函数仍然可以减少这就是为什么强烈建议训练更多周期以便从模型中获得良好结果的原因。 将下面的句子starter输入到训练好的模型中让它来完成这个句子So she was considering in her own mind 。 starter So she was considering in her own mind states None如果您的计算机具有可用的 GPU则将模型分配回 CPU 以执行预测 model model.to(cpu)首先for循环的将种子输入模型以便可以生成内存。 接下来执行预测如以下代码片段所示 for ch in starter:x np.array([[indexer[ch]]])x index2onehot(x)x torch.Tensor(x)pred, states model(x, states) counter 0 while starter[-1] ! . and counter 100:counter 1x np.array([[indexer[starter[-1]]]])x index2onehot(x)x torch.Tensor(x)pred, states model(x, states)pred F.softmax(pred, dim1)p, top pred.topk(10)p p.detach().numpy()[0]top top.numpy()[0]index np.random.choice(top, pp/p.sum())starter chars[index] print(starter)注意 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。 要访问此源代码的 GPU 版本请参考这里。 此版本的源代码无法作为在线交互示例使用需要通过 GPU 设置在本地运行。 活动 6.03用于情感分析的 NLP 解决方案 导入所需的库。 import pandas as pd import numpy as np import matplotlib.pyplot as plt from string import punctuation from sklearn.metrics import accuracy_score import torch from torch import nn, optim import torch.nn.functional as F加载包含亚马逊 1,000 条产品评论的数据集这些评论与0(负面评论)或1(正面评论)的标签配对。将数据分离成两个变量–一个包含评论另一个包含标签。 data pd.read_csv(amazon_cells_labelled.txt, sep\t, \headerNone) reviews data.iloc[:,0].str.lower() sentiment data.iloc[:,1].values去掉评论中的标点符号。 for i in punctuation:reviews reviews.str.replace(i,)创建一个变量包含整个评论集的词汇量。此外创建一个字典将每个单词映射到一个整数其中单词将是键整数将是值。 words .join(reviews) words words.split() vocabulary set(words) indexer {word: index for (index, word) \in enumerate(vocabulary)}通过将评论中的每个词替换为其配对的整数来对评论数据进行编码。 indexed_reviews [] for review in reviews:indexed_reviews.append([indexer[word] \for word in review.split()])创建一个包含网络架构的类。确保你包含一个嵌入层。 class LSTM(nn.Module):def __init__(self, vocab_size, embed_dim, \hidden_size, n_layers):super().__init__()self.hidden_size hidden_sizeself.embedding nn.Embedding(vocab_size, embed_dim)self.lstm nn.LSTM(embed_dim, hidden_size, \n_layers, batch_firstTrue)self.output nn.Linear(hidden_size, 1)def forward(self, x):out self.embedding(x)out, _ self.lstm(out)out out.contiguous().view(-1, self.hidden_size)out self.output(out)out out[-1,0]out torch.sigmoid(out).unsqueeze(0)return out返回 该类包含用于定义网络架构的__init__方法和用于确定数据流经不同层的方式的forward方法。 使用 64 个嵌入维度和 128 个神经元为三个 LSTM 层实例化模型。 model LSTM(len(vocabulary), 64, 128, 3) model运行前面的代码将显示以下输出 LSTM((embedding): Embedding(1905, 64)(lstm): LSTM(64, 128, num_layers3, batch_firstTrue)(output): Linear(in_features128, out_features1, biasTrue) )定义损失函数优化算法以及训练的周期数。例如您可以使用二进制交叉熵损失作为损失函数Adam 优化器并训练 10 个周期。 loss_function nn.BCELoss() optimizer optim.Adam(model.parameters(), lr0.001) epochs 10创建一个for循环通过不同的周期并分别通过每一个单次评论。对于每一个评论进行预测计算损失函数并更新网络的参数。此外计算该训练数据上网络的准确率。 losses [] acc [] for e in range(1, epochs1):single_loss []preds []targets []for i, r in enumerate(indexed_reviews):if len(r) 1:continuex torch.Tensor([r]).long()y torch.Tensor([sentiment[i]])pred model(x)loss loss_function(pred, y)optimizer.zero_grad()loss.backward()optimizer.step()final_pred np.round(pred.detach().numpy())preds.append(final_pred)targets.append(y)single_loss.append(loss.item())losses.append(np.mean(single_loss))accuracy accuracy_score(targets,preds)acc.append(accuracy)if e%1 0:print(Epoch: , e, ... Loss function: , losses[-1], \... Accuracy: , acc[-1])与以前的活动一样训练过程包括进行预测将其与基本事实进行比较以计算损失函数并执行反向传播以最小化损失函数。 绘制损失和精度随时间的进展情况。以下代码用于绘制损失函数。 x_range range(len(losses)) plt.plot(x_range, losses) plt.xlabel(epochs) plt.ylabel(Loss function) plt.show()该图应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lDlw117m-1681785396616)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_31.jpg)] 图 6.31显示损失函数进度的图 以下代码用于绘制准确率得分 x_range range(len(acc)) plt.plot(x_range, acc) plt.xlabel(epochs) plt.ylabel(Accuracy score) plt.show()该图应如下所示 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3UL2S81m-1681785396617)(https://gitcode.net/apachecn/apachecn-dl-zh/-/raw/master/docs/dl-pt-workshop/img/B15778_06_32.jpg)] 图 6.32显示准确率得分进度的图 注意 要访问此特定部分的源代码请参考这里。 本部分当前没有在线交互示例需要在本地运行。
http://www.hkea.cn/news/14350455/

相关文章:

  • 哈尔滨建筑专业网站移动网站建设推广
  • 概述网站建设的流程永久无限免费看的app
  • 列出寻找网站关键词的几种途径wordpress 增加数据表
  • 站长工具无吗经典高端旅游定制网站
  • 东莞企业网站seo手机端网站开发教程
  • 找人做网站需要注意什么权大师的网站是哪个公司做的
  • 网站seo 优帮云律师论坛网站模板
  • 长沙优化网站方法网站建设各模块功能简述
  • 企业电子网站的建设案例济南哪里有网站建设公司
  • cms类型网站开发住房城乡建设厅官方网站
  • 展示型网站制作公司规模以上工业企业的标准是什么
  • 包头焦点网站建设基于asp的医疗网站开发
  • top的域名网站做视频的教学直播网站
  • 网站订单模板企业建设网站的资金策划
  • 企业网站建设免费会计培训
  • 上海信息科技有限公司软件网站开发wordpress文章不显示发布时间
  • 做英语作业的网站企业网站站内优化
  • 建设家具网站的目的及功能定位做引流去那些网站好
  • html5简单网页大作业seo优化心得
  • 胶州为企业做网站的公司网站建设相关费用预算推广
  • 西安大网站建设公司wordpress快速登录插件
  • 视频封面制作网站企业宣传文案模板
  • 在哪里创建网站平台wordpress改造微博主题
  • 网站安全检测工具网站做友链有行业要求吗
  • 网站建设合同附加协议中关村在线手机对比平台
  • 企业网站的建立wordpress 待办事项
  • 国际新闻最新消息今天乌克兰与俄罗斯视频自建网站怎么做优化
  • 如何知道网站有没有备案南京网络营销
  • 盐城做网站的公司地址wordpress客户端配置
  • 做电商网站都需要学什么软件装饰公司哪家口碑好