动手学深度学习9.3. 深度循环神经网络-笔记练习(PyTorch)

news2024/12/23 0:44:33

本节课程地址:58 深层循环神经网络【动手学深度学习v2】_哔哩哔哩_bilibili

本节教材地址:9.3. 深度循环神经网络 — 动手学深度学习 2.0.0 documentation (d2l.ai)

本节开源代码:...>d2l-zh>pytorch>chapter_multilayer-perceptrons>lstm.ipynb


深度循环神经网络

到目前为止,我们只讨论了具有一个单向隐藏层的循环神经网络。 其中,隐变量和观测值与具体的函数形式的交互方式是相当随意的。 只要交互类型建模具有足够的灵活性,这就不是一个大问题。 然而,对一个单层来说,这可能具有相当的挑战性。 之前在线性模型中,我们通过添加更多的层来解决这个问题。 而在循环神经网络中,我们首先需要确定如何添加更多的层, 以及在哪里添加额外的非线性,因此这个问题有点棘手。

事实上,我们可以将多层循环神经网络堆叠在一起, 通过对几个简单层的组合,产生了一个灵活的机制。 特别是,数据可能与不同层的堆叠有关。 例如,我们可能希望保持有关金融市场状况 (熊市或牛市)的宏观数据可用, 而微观数据只记录较短期的时间动态。

图9.3.1 描述了一个具有 L 个隐藏层的深度循环神经网络, 每个隐状态都连续地传递到当前层的下一个时间步和下一层的当前时间步。

函数依赖关系

我们可以将深度架构中的函数依赖关系形式化, 这个架构是由 图9.3.1中描述了 L 个隐藏层构成。 后续的讨论主要集中在经典的循环神经网络模型上, 但是这些讨论也适应于其他序列模型。

假设在时间步 t 有一个小批量的输入数据 \mathbf{X}_t \in \mathbb{R}^{n \times d}(样本数: n ,每个样本中的输入数: d )。 同时,将 l^\mathrm{th} 隐藏层(l=1,\ldots,L) 的隐状态设为 \mathbf{H}_t^{(l)} \in \mathbb{R}^{n \times h} (隐藏单元数: h ), 输出层变量设为 \mathbf{O}_t \in \mathbb{R}^{n \times q} (输出数: q )。 设置 \mathbf{H}_t^{(0)} = \mathbf{X}_t , 第 l 个隐藏层的隐状态使用激活函数 \phi_l ,则:

\mathbf{H}_t^{(l)} = \phi_l(\mathbf{H}_t^{(l-1)} \mathbf{W}_{xh}^{(l)} + \mathbf{H}_{t-1}^{(l)} \mathbf{W}_{hh}^{(l)} + \mathbf{b}_h^{(l)}), (9.3.1)

其中,权重 \mathbf{W}_{xh}^{(l)} \in \mathbb{R}^{h \times h} , \mathbf{W}_{hh}^{(l)} \in \mathbb{R}^{h \times h} 和 偏置 \mathbf{b}_h^{(l)} \in \mathbb{R}^{1 \times h}都是第 l 个隐藏层的模型参数。

最后,输出层的计算仅基于第 l 个隐藏层最终的隐状态:

\mathbf{O}_t = \mathbf{H}_t^{(L)} \mathbf{W}_{hq} + \mathbf{b}_q, (9.3.2)

其中,权重 \mathbf{W}_{hq} \in \mathbb{R}^{h \times q} 和偏置\mathbf{b}_q \in \mathbb{R}^{1 \times q}都是输出层的模型参数。

与多层感知机一样,隐藏层数目 L 和隐藏单元数目 h 都是超参数。 也就是说,它们可以由我们调整的。 另外,用门控循环单元或长短期记忆网络的隐状态 来代替 (9.3.1) 中的隐状态进行计算, 可以很容易地得到深度门控循环神经网络或深度长短期记忆神经网络。

简洁实现

实现多层循环神经网络所需的许多逻辑细节在高级API中都是现成的。 简单起见,我们仅示范使用此类内置函数的实现方式。 以长短期记忆网络模型为例, 该代码与之前在 9.2节 中使用的代码非常相似, 实际上唯一的区别是我们指定了层的数量, 而不是使用单一层这个默认值。 像往常一样,我们从加载数据集开始。

import torch
from torch import nn
from d2l import torch as d2l

batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)

像选择超参数这类架构决策也跟 9.2节 中的决策非常相似。 因为我们有不同的词元,所以输入和输出都选择相同数量,即vocab_size。 隐藏单元的数量仍然是256。 唯一的区别是,我们现在(通过num_layers的值来设定隐藏层数)。

vocab_size, num_hiddens, num_layers = len(vocab), 256, 2
num_inputs = vocab_size
device = d2l.try_gpu()
lstm_layer = nn.LSTM(num_inputs, num_hiddens, num_layers)
model = d2l.RNNModel(lstm_layer, len(vocab))
model = model.to(device)

[训练]与预测

由于使用了长短期记忆网络模型来实例化两个层,因此训练速度被大大降低了。

num_epochs, lr = 500, 2
d2l.train_ch8(model, train_iter, vocab, lr*1.0, num_epochs, device)

输出结果:
perplexity 1.0, 27727.4 tokens/sec on cpu
time travelleryou can show black is white by argument said filby
travelleryou can show black is white by argument said filby

小结

  • 在深度循环神经网络中,隐状态的信息被传递到当前层的下一时间步和下一层的当前时间步。
  • 有许多不同风格的深度循环神经网络, 如长短期记忆网络、门控循环单元、或经典循环神经网络。 这些模型在深度学习框架的高级API中都有涵盖。
  • 总体而言,深度循环神经网络需要大量的调参(如学习率和修剪) 来确保合适的收敛,模型的初始化也需要谨慎。

练习

  1. 基于我们在 8.5节 中讨论的单层实现, 尝试从零开始实现两层循环神经网络。

解:
代码如下:

def get_params_2(vocab_size, num_hiddens, device):
    num_inputs = num_outputs = vocab_size

    def normal(shape):
        return torch.randn(size=shape, device=device) * 0.01

    # 隐藏层参数
    # 第一层
    W_xh = normal((num_inputs, num_hiddens))
    W_hh1 = normal((num_hiddens, num_hiddens))
    b_h1 = torch.zeros(num_hiddens, device=device)
    # 第二层
    W_hh2 = normal((num_hiddens, num_hiddens))
    b_h2 = torch.zeros(num_hiddens, device=device)
    # 输出层参数
    W_hq = normal((num_hiddens, num_outputs))
    b_q = torch.zeros(num_outputs, device=device)
    # 附加梯度
    params = [W_xh, W_hh1, b_h1, W_hh2, b_h2, W_hq, b_q]
    for param in params:
        param.requires_grad_(True)
    return params

def init_rnn_state_2(batch_size, num_hiddens, device):
    return (torch.zeros((batch_size, num_hiddens), device=device), 
            torch.zeros((batch_size, num_hiddens), device=device),)

def rnn_2(inputs, state, params):
    W_xh, W_hh1, b_h1, W_hh2, b_h2, W_hq, b_q = params
    H1, H2, = state
    outputs = []
    for X in inputs:
        H1 = torch.tanh(torch.mm(X, W_xh) + torch.mm(H1, W_hh1) + b_h1)
        H2 = torch.tanh(torch.mm(H1, W_hh2) + b_h2)
        Y = torch.mm(H2, W_hq) + b_q
        outputs.append(Y)
    return torch.cat(outputs, dim=0), (H1, H2,)
batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)
vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
num_inputs = vocab_size
num_epochs, lr = 500, 1
net = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_params_2,
                      init_rnn_state_2, rnn_2)
d2l.train_ch8(net, train_iter, vocab, lr, num_epochs, device)

输出结果:
perplexity 1.0, 41299.2 tokens/sec on cpu
time traveller for so it will be convenient to speak of himwas e
traveller with a slight accession ofcheerfulness really thi

2. 在本节训练模型中,比较使用门控循环单元替换长短期记忆网络后模型的精确度和训练速度。

解:
使用GRU和LSTM的perplexity都是1.0,应该是二者的模型复杂度足够cover这个小的数据集了;
训练速度上,在CPU上运行是LSTM更快一些。

gru_layer = nn.GRU(num_inputs, num_hiddens, num_layers)
model = d2l.RNNModel(gru_layer, len(vocab))
model = model.to(device)
d2l.train_ch8(model, train_iter, vocab, lr*1.0, num_epochs, device)

输出结果:
perplexity 1.0, 18433.6 tokens/sec on cpu
time travelleryou can show black is white by argument said filby
travelleryou can show black is white by argument said filby

3. 如果增加训练数据,能够将困惑度降到多低?

解:
训练数据增加8.5节练习2中的《世界大战》数据集,困惑度仍可以降到1.0。
代码如下:

import re

d2l.DATA_HUB['time_machine'] = (d2l.DATA_URL + 'timemachine.txt',
                                '090b5e7e70c295757f55df93cb0a180b9691891a')
text = '/home/NAS/HUIDA/YaqinJiang/my/chapter_recurrent-neural-networks/36-0.txt'

with open(text, 'r') as f1, open(d2l.download('time_machine'), 'r') as f2:
    lines = f1.readlines() + f2.readlines()
for line in lines:
    re.sub('[^A-Za-z]+', ' ', line).strip().lower() 

def load_corpus(max_tokens=-1): 
    tokens = d2l.tokenize(lines, 'char')
    vocab = d2l.Vocab(tokens)
    corpus = [vocab[token] for line in tokens for token in line]

    if max_tokens > 0: 
        corpus = corpus[:max_tokens]
    return corpus, vocab

corpus, vocab = load_corpus()

class SeqDataLoader: 
    def __init__(self, batch_size, num_steps, use_random_iter, max_tokens):
        if use_random_iter:
            self.data_iter_fn = d2l.seq_data_iter_random
        else:
            self.data_iter_fn = d2l.seq_data_iter_sequential
        self.corpus, self.vocab = load_corpus(max_tokens)
        self.batch_size, self.num_steps = batch_size, num_steps

    def __iter__(self):
        return self.data_iter_fn(self.corpus, self.batch_size, self.num_steps)

def load_data(batch_size, num_steps, use_random_iter=False, max_tokens=10000):
    data_iter = SeqDataLoader(
        batch_size, num_steps, use_random_iter, max_tokens)
    return data_iter, data_iter.vocab

batch_size, num_steps = 32, 35
train_iter, vocab = load_data(batch_size, num_steps)
vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
num_inputs = vocab_size
num_epochs, lr = 500, 2
lstm_layer = nn.LSTM(num_inputs, num_hiddens, num_layers)
model = d2l.RNNModel(lstm_layer, len(vocab))
model = model.to(device)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)

输出结果:
perplexity 1.0, 26658.8 tokens/sec on cpu
time traveller has enobont of the clockwork that kept the plane
traveller and its to derstly and intellects vast and cool a

4. 在为文本建模时,是否可以将不同作者的源数据合并?有何优劣呢?

解:
可以将不同作者的源数据合并,优劣如下:
优势:合并多个数据源可以显著增加训练数据的量,有助于构建更为鲁棒性和泛化能力更强的模型。
劣势:

  • 合并数据通常需要额外的预处理步骤,如统一文本格式、处理不同编码标准等,这会增加数据处理的复杂性。
  • 不同来源的数据质量可能参差不齐,一些数据可能包含错误、不规范的语言表达或噪声,这可能会影响模型的训练效果。
  • 不同作者的写作风格和内容可能相差较大,若某种风格或内容占比不足,可能影响模型的预测能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2198109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机毕业设计 基于Flask+vue的博客系统的设计与实现 Python毕业设计 Python毕业设计选题 Flask框架 Vue【附源码+安装调试】

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

数据结构-4.5.KMP算法(旧版上)-朴素模式匹配算法的优化

朴素模式匹配算法最坏的情况: 一.实例: 第一轮匹配失败,开始下一轮的匹配: 不断的操作,最终匹配成功: 如上述图片所述,朴素模式匹配算法会导致时间开销增加, 优化思路:主…

Java:数据结构-List的介绍 ArrayList和顺序表(1)

一 List的介绍 1.什么是List? List是一个接口,继承于Collection。 Collection也是一个接口 Lterable也是一个接口,表示实现该接口的类是可以逐个元素遍历的类。 2.List的使用 List是一个接口,不能被实例化,ArrayL…

falcon调研的CSIG

CSIG (Congestion Signaling) C是Congestion, SIG是 Signaling的简写,的机制: 本质是带内遥测 沿着L2一路可以实现更新,原文:This summarizedinformation is collected over L2 CSIG-tags in a compare-and-replace manner acro…

谢希仁计算机网络 (四)—— 网络层

计算机网络(四)—— 网络层(1、2):网络层概述、网络层提供的两种服务 计算机网络(四)—— 网络层(1、2):网络层概述、网络层提供的两种服务_以下属于网络层范…

基于PHP+uniapp的民宿预订系统的微信小程序设计与实现 ea9i3

目录 项目介绍技术栈和环境说明具体实现截图php技术介绍文件解析微信开发者工具HBuilderXuniapp开发技术简介解决的思路性能/安全/负载方面数据访问方式PHP核心代码部分展示代码目录结构解析系统测试详细视频演示源码获取 项目介绍 总体上看,Android的民宿预订系统…

企业安全运行与维护(Enterprise Security Operation and Maintenance)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

.locked勒索病毒:数据安全的新威胁

导言 在数字时代,数据已成为企业和个人的核心资产,其价值无可估量。然而,随着网络技术的飞速发展,一种名为“.locked勒索病毒”的恶意软件悄然兴起,对全球范围内的数据安全构成了严重威胁。这种病毒以其独特的加密方式…

【RAG论文精读4】RAG论文综述1(2312.10997)-第2部分

收录于我的专栏:AI修炼之路 第1部分:【RAG论文精读3】RAG论文综述1(2312.10997)-第1部分 二、RAG概览 RAG研究范式不断演变,可以为三个阶段:原始RAG、进阶RAG和模块化RAG。 2.1 原始RAG Naive RAG&#xf…

Spring Boot快速入门:HelloWorld示例

Spring Boot是一个非常流行,受欢迎的框架,它不仅常用于构建传统的单体式MVC应用程序,同时也非常适合用于搭建微服务架构。对于 Web 应用程序,Spring Boot 提供了用于创建 REST API、处理 HTTP 请求和使用 Thymeleaf 等模板引擎呈现…

QD1-P1 HTML、CSS与JS三者之间的关系

今天开始学习前端基础,新建专题《前端学习笔记1》保存前端基础学习笔记。 专题文章命名以qd1开头。 源课程 视频教程:【Web前端-最通俗易懂HTML、CSS与JS合集 1天速成】 up:遥遥温柔乡 在B站随便搜索了一个前端课程,共91节&am…

美畅物联丨视频汇聚从“设”开始:海康威视摄像机设置详解

在运用畅联云平台进行视频汇聚与监控管理时,海康威视的安防摄像机凭借其卓越的性能与广泛的应用兼容性,成为了众多用户的首选产品。海康威视摄像机参数设置与调试对于实现高效的安防监控至关重要。今天,让我们一同深入学习海康摄像机的参数设…

【Unity实战篇】 接入百度翻译,实现文本自动翻译功能

前言【Unity实战篇】 接入百度自动翻译,实现文本自动翻译功能一、获取百度翻译开发平台的APPID和密钥二、Unity中接入自动翻译功能三、Unity中实现自动翻译文本Text功能总结前言 日常在做项目的过程中,游戏本地化几乎已经成为必不可少的一步。本篇文章将演示怎样在Unity中接入…

【万字长文】Word2Vec计算详解(三)

【万字长文】Word2Vec计算详解(三) 写在前面 第三部分介绍Word2Vec模型的两种优化方案。 【万字长文】Word2Vec计算详解(一)markdown行 9000 【万字长文】Word2Vec计算详解(二)markdown行 12000 【万字长文…

数据结构与算法篇(刷题篇 - 树)

目录 1. 二叉树的前序遍历(简单) 1.1. 题目描述 1.2. 解题思路 方法一:递归(推荐使用) 方法二:非递归(扩展思路) 2. 二叉树的中序遍历(中等) 2.1. 题目…

[简单实践]Noisy Print - 自制基于加性噪声模型的简易降噪器

NoisyPrint 最近在学习的过程中,突然想起一个在Adobe Audition中用过的功能。 为什么会想到这个功能呢,因为在我使用DeepFilter的过程中,我发现对于一些低信噪比的信号来说,DeepFilter很容易出现过拟合现象,导致音源…

大数据毕业设计选题推荐-电影票房数据分析系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

Linux云计算 |【第四阶段】RDBMS2-DAY1

主要内容: MySQL主从同步(概述、原理、构建主从同步)、主从同步结构类型(主多从、主从从、主主)、复制模式(异步、半同步)、启用半同步复制 一、MySQL主从同步 MySQL 主从同步(Mas…

工控风云 | 科东软件受邀参加2024 CCF工控“风云论坛”并做演讲

近日,CCF工业控制计算机专委会首届“风云论坛”在苏州CCF业务总部&学术交流中心成功召开。作为国内工业操作系统领军企业,科东软件受邀参加本次大会,并做“鸿道(Intewell)新型工业操作系统”主题演讲。 “要打好科技仪器设备、操作系统…

自动驾驶系列—超声波雷达技术详解:自动驾驶中的短距离感知利器

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…