Deep Learning Part Five RNNLM的学习和评价-24.4.30

news2024/11/24 11:41:44

准备好RNNLM所需要的层,我们现在来实现RNNLM,并对其进行训练,然后再评价一下它的结果的。

5.5.1 RNNLM的实现

这里我们将RNNLM使用的网络实现为SimpleRnnlm类,其层结构如下:

如图 5-30 所示,SimpleRnnlm 类是一个堆叠了 4 个 Time 层的神经网络。我们先来看一下初始化的代码:

import sys
sys.path.append('..')
import numpy as np
from common.time_layers import *

class SimpleRnnlm:
    def __init__(self, vocab_size, wordvec_size, hidden_size):
        V, D, H = vocab_size, wordvec_size, hidden_size
        rn = np.random.randn

        # 初始化权重
        embed_W = (rn(V, D) / 100).astype('f')
        rnn_Wx = (rn(D, H) / np.sqrt(D)).astype('f')
        rnn_Wh = (rn(H, H) / np.sqrt(H)).astype('f')
        rnn_b = np.zeros(H).astype('f')
        affine_W = (rn(H, V) / np.sqrt(H)).astype('f')
        affine_b = np.zeros(V).astype('f')

        # 生成层
        self.layers = [
            TimeEmbedding(embed_W),
            TimeRNN(rnn_Wx, rnn_Wh, rnn_b, stateful=True),
            TimeAffine(affine_W, affine_b)
        ]
        self.loss_layer = TimeSoftmaxWithLoss()
        self.rnn_layer = self.layers[1]

        # 将所有的权重和梯度整理到列表中
        self.params, self.grads = [], []
        for layer in self.layers:
            self.params += layer.params
            self.grads += layer.grads

拓展:

接着,我们来实现 forward() 方法、backward() 方法和 reset_state() 方法。

def forward(self, xs, ts):
    for layer in self.layers:
        xs = layer.forward(xs)
    loss = self.loss_layer.forward(xs, ts)
    return loss

def backward(self, dout=1):
    dout = self.loss_layer.backward(dout)
    for layer in reversed(self.layers):
        dout = layer.backward(dout)
    return dout

def reset_state(self):
    self.rnn_layer.reset_state()

从上述中,可以看出实现非常简单。在各个层中,正向传播和反向传播都正确地进行了实现。因此,我们只要以正确的顺序调用 forward()(或者 backward())即可。方便起见,这里将重设网络状态的方法实现为 reset_state()。以上就是对 SimpleRnnlm 类的说明。

5.5.3 RNNLM的学习代码

下面,我们使用 PTB 数据集进行学习,不过这里仅使用 PTB 数据集(训练数据)的前 1000 个单词。这是因为在本节实现的 RNNLM 中,即便使用所有的训练数据,也得不出好的结果。下一章我们将对它进行改进。

import sys
sys.path.append('..')
import matplotlib.pyplot as plt
import numpy as np
from common.optimizer import SGD
from dataset import ptb
from simple_rnnlm import SimpleRnnlm


# 设定超参数
batch_size = 10
wordvec_size = 100
hidden_size = 100 # RNN的隐藏状态向量的元素个数
time_size = 5 # Truncated BPTT的时间跨度大小
lr = 0.1
max_epoch = 100

# 读入训练数据(缩小了数据集)
corpus, word_to_id, id_to_word = ptb.load_data('train')
corpus_size = 1000
corpus = corpus[:corpus_size]
vocab_size = int(max(corpus) + 1)

xs = corpus[:-1] # 输入
ts = corpus[1:] # 输出(监督标签)
data_size = len(xs)
print('corpus size: %d, vocabulary size: %d' % (corpus_size, vocab_size))

# 学习用的参数
max_iters = data_size // (batch_size * time_size)
time_idx = 0
total_loss = 0
loss_count = 0
ppl_list = []

# 生成模型
model = SimpleRnnlm(vocab_size, wordvec_size, hidden_size)
optimizer = SGD(lr)

# ❶ 计算读入mini-batch的各笔样本数据的开始位置
jump = (corpus_size - 1) // batch_size
offsets = [i * jump for i in range(batch_size)]

for epoch in range(max_epoch):
    for iter in range(max_iters):
        # ❷ 获取mini-batch
        batch_x = np.empty((batch_size, time_size), dtype='i')
        batch_t = np.empty((batch_size, time_size), dtype='i')
        for t in range(time_size):
            for i, offset in enumerate(offsets):
                batch_x[i, t] = xs[(offset + time_idx) % data_size]
                batch_t[i, t] = ts[(offset + time_idx) % data_size]
            time_idx += 1

        # 计算梯度,更新参数
        loss = model.forward(batch_x, batch_t)
        model.backward()
        optimizer.update(model.params, model.grads)
        total_loss += loss
        loss_count += 1

    # ❸ 各个epoch的困惑度评价
    ppl = np.exp(total_loss / loss_count)
    print('| epoch %d | perplexity %.2f'
          % (epoch+1, ppl))
    ppl_list.append(float(ppl))
    total_loss, loss_count = 0, 0

只摘录了核心:

...
from common.trainer import RnnlmTrainer

...
model = SimpleRnnlm(vocab_size, wordvec_size, hidden_size)
optimizer = SGD(lr)
trainer = RnnlmTrainer(model, optimizer)

trainer.fit(xs, ts, max_epoch, batch_size, time_size)

如上所示,首先使用 model 和 optimizer 初始化 RnnlmTrainer 类,然后调用 fit(),完成学习。此时,RnnlmTrainer 类的内部将执行上一节进行的一系列操作,具体如下所示。

  • 按顺序生成 mini-batch
  • 调用模型的正向传播和反向传播
  • 使用优化器更新权重
  • 评价困惑度

使用Trainer的好处:

 使用 RnnlmTrainer 类,可以避免每次写重复的代码。本书的剩余部分都将使用 RnnlmTrainer 类学习 RNNLM。

5.6 小结

本章的主题是 RNN。RNN 通过数据的循环,从过去继承数据并传递到现在和未来。如此,RNN 层的内部获得了记忆隐藏状态的能力。本书中我们花了很多时间说明 RNN 层的结构,并实现了 RNN 层(和 Time RNN 层)。

本章还利用 RNN 创建了语言模型。语言模型给单词序列赋概率值。特别地,条件语言模型从已经出现的单词序列计算下一个将要出现的单词的概率。通过构成利用了 RNN 的神经网络,理论上无论多么长的时序数据,都可以将它的重要信息记录在 RNN 的隐藏状态中。但是,在实际问题中,这样一来,许多情况下学习将无法顺利进行。下一章我们将指出 RNN 存在的问题,并研究替代 RNN 的 LSTM 层或 GRU 层。这些层在处理时序数据方面非常重要,被广泛用于前沿研究。

本章所学的内容

  • RNN 具有环路,因此可以在内部记忆隐藏状态
  • 通过展开 RNN 的循环,可以将其解释为多个 RNN 层连接起来的神经网络,可以通过常规的误差反向传播法进行学习(= BPTT)
  • 在学习长时序数据时,要生成长度适中的数据块,进行以块为单位的 BPTT 学习(= Truncated BPTT)
  • Truncated BPTT 只截断反向传播的连接
  • 在 Truncated BPTT 中,为了维持正向传播的连接,需要按顺序输入数据
  • 语言模型将单词序列解释为概率
  • 理论上,使用 RNN 层的条件语言模型可以记忆所有已出现单词的信息

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

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

相关文章

Docker构建LNMP部署WordPress

前言 使用容器化技术如 Docker 可以极大地简化应用程序的部署和管理过程,本文将介绍如何利用 Docker 构建 LNMP 环境,并通过部署 WordPress 来展示这一过程。 目录 一、环境准备 1. 项目需求 2. 安装包下载 3. 服务器环境 4. 规划工作目录 5. 创…

无言:破局之道:顿悟+坚持——早读(逆天打工人爬取热门微信文章解读)

致无言 引言Python 代码第一篇 洞见 7年跟踪调查北京28个精英家庭:为什么顶尖大学孩子大多来自有钱家庭?第二篇 人民日报 来了!新闻早班车要闻社会政策 结尾 控制你的情绪 否则它将控制你 在紧张的游戏中 控制情绪 避免冲动行为 是每个玩家的…

Redis 实战1

SDS Redis 只会使用 C 字符串作为字面量, 在大多数情况下, Redis 使用 SDS (Simple Dynamic String,简单动态字符串)作为字符串表示。 比起 C 字符串, SDS 具有以下优点: 常数复杂度获取字符串…

设计模式之模板模式TemplatePattern(五)

一、模板模式介绍 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern), 在一个抽象类公开定义了执行它的方法的模板。它的子类可以更需要重写方法实现,但可以成为典型类中…

基于Springboot的校园食堂订餐系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的校园食堂订餐系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构…

在离线环境中将 CentOS 7.5 原地升级并迁移至 RHEL 7.9

《OpenShift / RHEL / DevSecOps 汇总目录》 说明 本文将说明如何在离线环境中将 CentOS 7.5 升级并迁移至 RHEL 7.9。为了简化准备过程,本文前面将在在线环境中安装用到的各种所需验证软件,而在后面升级迁移的时候再切换到由 ISO 构成的离线 Yum Repo…

前端工程化03-贝壳找房项目案例JavaScript常用的js库

4、项目实战(贝壳找房) 这个项目包含,基本的ajax请求调用,内容的渲染,防抖节流的基本使用,ajax请求工具类的封装 4.1、项目的接口文档 下述接口文档: 简述内容baseURL:http://123.207.32.32…

macOS sonoma 14.4.1编译JDK 12

macOS sonoma 14.4.1编译JDK 12 环境参考文档开始简述问题心路历程着手解决最终解决(前面有点啰嗦了,可以直接看这里) 记录一次靠自己看代码解决问题的经历(总之就是非常开心)。 首先,先diss一下bing,我差一点就放弃了。 环境 macOS sonom…

excel怎么删除条件格式规则但保留格式?

这个问题的意思就是要将设置的条件格式,转换成单元格格式。除了使用VBA代码将格式转换外,还可以用excel自己的功能来完成这个任务。 一、将条件格式“留下来” 1.设置条件格式 选中数据,点击开始选项卡,设置条件格式&#xff0…

2024五一数学建模C题煤矿深部开采冲击地压危险预测原创论文分享

大家好,从昨天肝到现在,终于完成了2024五一数学建模竞赛C题的完整论文啦。 实在精力有限,具体的讲解大家可以去讲解视频: 2024五一数学建模C题完整原创论文讲解,手把手保姆级教学!_哔哩哔哩_bilibili 202…

移动机器人系统与技术:自动驾驶、移动机器人、旋翼无人机

这本书全面介绍了机器人车辆的技术。它介绍了道路上自动驾驶汽车所需的概念。此外,读者可以在六足机器人的构造、编程和控制方面获得宝贵的知识。 这本书还介绍了几种不同类型旋翼无人机的控制器和空气动力学。它包括各种旋翼推进飞行器在不同空气动力学环境下的模…

ChatGPT的AI“记忆”可以记住付费客户的偏好

通过记住有关 ChatGPT Plus 订阅者的详细信息,OpenAI 的聊天机器人添加了更多个人助理风格的功能 OpenAI 在今年二月宣布了 “记忆 ”功能,该功能允许 ChatGPT 更永久地存储查询、提示和其他自定义功能。当时,只有 “一小部分 ”用户可以使用…

虚拟机网络桥接模式无法通信,获取到的ip为169.254.X.X

原因:VMware自动选择的网卡可能不对 解决:编辑-虚拟网络编辑器-更改桥接模式-选择宿主机物理网卡,断开虚拟机网络连接后重新连接即可

精简函数栈帧:优化创建和销毁过程的完全解析(建议收藏,提升内功)

🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专栏: C笔记 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 文章目录 【前文】一、函数栈帧的概念(stack frame&#xff…

uniapp 自定义相机插件(组件版、缩放、裁剪)组件 Ba-CameraView

自定义相机插件(组件版、缩放、裁剪) Ba-CameraView 简介(下载地址) Ba-CameraView 是一款自定义相机拍照组件,支持任意界面,支持裁剪 支持任意自定义界面支持手势缩放支持裁剪(手势拖动、比…

等级保护测评一般多长时间能做完?

一个二级或三级的系统,整体持续周期一到两个月 具体时间还要根据信息系统数量,及信息系统的规模,以及测评方与被测方的配合情况等,有所增减。 现场测评周期一般一周左右 小规模安全整改,包括管理制度策略配置技术&a…

【算法设计与分析】实验报告c++python实现(TSP问题、哈夫曼编码问题、顾客安排问题、最小生成树问题、图着色问题)

一、实验目的 1.加深学生对贪心算法设计方法的基本思想、基本步骤、基本方法的理解与掌握; 2.提高学生利用课堂所学知识解决实际问题的能力; 3.提高学生综合应用所学知识解决实际问题的能力。 二、实验任务 用贪心算…

基于Springboot的web后端开发三层架构上手实操

引言 我们拿到了xml文件 我们要将将xml文件中的数据加载并解析 完成数据的处理 并且返回给前端页面(result格式) 1.将xml文件放在resources目录下 xml是我们需要解析的文件 查看xml文件 2.在springboot中引入dom4j依赖 解析xml需要在springboot中引入dom4j依赖 这边我们…

iOS 创建依赖其他开源库的开源库

参考文章(感激各位大神前路的明灯) 参考文章一 参考项目 整体流程 流程简介 1)使用pod命令行创建本地项目和git仓库并回答终端里的四个问题 2)编辑podspec文件 3)将需要开源的代码添加到Development Pods文件夹中&am…

2024第84届中国(云南昆明)教育装备展示会

关于第84届中国教育装备展示会将在云南昆明举办! 谨此奉邀! 第84届中国教育装备展示会组委会 一、展会时间、地点 布展时间:2024年10月22日-24日 开展时间:2024年10月25日-27日 撤展时间:2024年10月27日 16:00-24:00 地点&a…