机器学习深度学习——序列模型(NLP启动!)

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er
🌌上期文章:机器学习&&深度学习——卷积神经网络(LeNet)
📚订阅专栏:机器学习&&深度学习
希望文章对你们有所帮助

现在多多少少是打下了一点基础了,因为我的本科毕业论文是NLP方向的,所以现在需要赶忙打好NLP模型所需要的知识,然后实现一些NLP方向的科研项目,用于我的9月份预推免。就剩一个月就要开始预推免了,大家一起加油!

序列模型

  • 引入
  • 统计工具
    • 自回归模型
    • 马尔可夫模型
    • 因果关系
  • 训练
  • 预测
  • 总结

引入

对于一部电影,随着时间的推移,人们对电影的看法会发生很大的变化。也就是说,因为时间上的连续性,一些事情的发生也是会互相影响的,如果这些序列重排就会失去意义。有几个例子:
1、音乐、语音、文本和视频都是连续的。
2、地震具有很强的相关性,即大地震发生后,很可能会有几次小余震。
3、人类之间的互动也是连续的,比如微博上互相打口水仗。
4、预测明天的股价要比过去的股价更困难(先见之明比时候诸葛亮要更难)。

统计工具

我们可以通过下式来进行预测:
x t 符合 P ( x t ∣ x t − 1 , . . . , x 1 ) x_t符合P(x_t|x_{t-1},...,x_1) xt符合P(xtxt1,...,x1)
其中,x是非独立同分布的,因为时间上具有连续性,导致不同时间上的预测可能也会有相关性

自回归模型

从上面的式子可以看出,数据的数量随着t而变化:输入数据的数量这个数字将会随着我们遇到的数据量的增加而增加。因此我们需要使得这个计算更加简单,有两种策略:
1、自回归模型
假设显示情况下,相当长的序列
x t − 1 , . . . , x 1 x_{t-1},...,x_1 xt1,...,x1
可能不是必要的,我们只需要满足某个长度τ的时间跨度,即使用观测序列
x t − 1 , . . . , x t − τ x_{t-1},...,x_{t-τ} xt1,...,xtτ
这样的好处是参数的数量总是不变的,至少在t>τ的时候是这样的,既然都是固定长度,那么我们就可以训练之前讲过的几乎所有模型了(线性模型,或者多层感知机等等)。这种模型被称为自回归模型,因此总是队自己执行回归。
2、潜变量自回归模型
如下图所示:
在这里插入图片描述
该图体现出,我们需要保留和更新对过去观测的总结:
h t h_t ht
并且同时更新预测
x t ^ \hat{x_t} xt^
这就产生了基于
x t ^ = P ( x t ∣ h t ) \hat{x_t}=P(x_t|h_t) xt^=P(xtht)
的估计,以及公式
h t = g ( h t − 1 , x t − 1 ) h_t=g(h_{t-1},x_{t-1}) ht=g(ht1,xt1)
更新的模型。
而由于h从未被观测到,所以这类模型也叫作潜变量自回归模型
而整个序列的估计值都将通过以下方式获得:
P ( x 1 , . . . , x T ) = ∏ t = 1 T P ( x t ∣ x t − 1 , . . . , x 1 ) P(x1,...,x_T)=\prod_{t=1}^TP(x_t|x_{t-1},...,x_1) P(x1,...,xT)=t=1TP(xtxt1,...,x1)

马尔可夫模型

我们之前在估计的时候,选择的是在当前时序的前τ个数,只要和当前时序之前的所有数计算得来的结果近似,就说序列满足马尔可夫条件。特别是当τ=1时,得到一个一阶马尔可夫模型:
P ( x ) = P ( x 1 , . . . , x T ) = ∏ t = 1 T P ( x t ∣ x t − 1 ) 当 P ( x 1 ∣ x 0 ) = P ( x 1 ) P(x)=P(x_1,...,x_T)=\prod_{t=1}^TP(x_t|x_{t-1})当P(x_1|x_0)=P(x_1) P(x)=P(x1,...,xT)=t=1TP(xtxt1)P(x1x0)=P(x1)

因果关系

原则上,将P(x)倒序展开也没啥问题,可以基于条件概率公式写成:
P ( x 1 , . . . , x T ) = ∏ t = T 1 P ( x t ∣ x t + 1 , . . . , x T ) P(x_1,...,x_T)=\prod_{t=T}^1P(x_t|x_{t+1},...,x_T) P(x1,...,xT)=t=T1P(xtxt+1,...,xT)
但是在物理上这并不好实现,毕竟理论上一般没有根据未来的事情推测过去的事情。

训练

首先生成一些数据,使用正弦函数和一些可加性噪声来生成序列数据。(现在开始用notebook了)

%matplotlib inline
import torch
from torch import nn
from d2l import torch as d2lT = 1000  # 总共产生1000个点
time = torch.arange(1, T + 1, dtype=torch.float32)
x = torch.sin(0.01 * time) + torch.normal(0, 0.2, (T,))
d2l.plot(time, [x], 'time', 'x', xlim=[1, 1000], figsize=(6, 3))

在这里插入图片描述
接下来,将该序列转换为特征-标签对,这里我们使用前600个“特征-标签”对进行训练:

tau = 4
features = torch.zeros((T - tau, tau))
for i in range(tau):features[:, i] = x[i: T - tau + i]
labels = x[tau:].reshape((-1, 1))batch_size, n_train = 16, 600
# 只有前n_train个样本用于训练
train_iter = d2l.load_array((features[:n_train], labels[:n_train]),batch_size, is_train=True)

在这里,我们使用一个相当简单的架构训练模型: 一个拥有两个全连接层的多层感知机,ReLU激活函数和平方损失。

# 初始化网络权重的函数
def init_weights(m):if type(m) == nn.Linear:nn.init.xavier_uniform_(m.weight)# 一个简单的多层感知机
def get_net():net = nn.Sequential(nn.Linear(4, 10),nn.ReLU(),nn.Linear(10, 1))net.apply(init_weights)return net# 平方损失。注意:MSELoss计算平方误差时不带系数1/2
loss = nn.MSELoss(reduction='none')

下面开始训练模型:

def train(net, train_iter, loss, epochs, lr):trainer = torch.optim.Adam(net.parameters(), lr)  # 一种内置的优化器,可自行去了解for epoch in range(epochs):for X, y in train_iter:trainer.zero_grad()l = loss(net(X), y)l.sum().backward()trainer.step()print(f'epoch {epoch + 1}, 'f'loss: {d2l.evaluate_loss(net, train_iter, loss):f}')net = get_net()
train(net, train_iter, loss, 5, 0.01)

运行结果:

epoch 1, loss: 0.061968
epoch 2, loss: 0.054118
epoch 3, loss: 0.051940
epoch 4, loss: 0.050062
epoch 5, loss: 0.050939

预测

训练损失看起来不大,那我们可以开始进行单步预测(也就是检查模型预测下一个时间步的能力):

onestep_preds = net(features)
d2l.plot([time, time[tau:]],[x.detach().numpy(), onestep_preds.detach().numpy()], 'time','x', legend=['data', '1-step preds'], xlim=[1, 1000],figsize=(6, 3))

结果:
在这里插入图片描述
单步预测的效果不错,即便预测的时间步超过了600+4(n_train+tau),结果看起来也还是可以的,但是如果我们继续向前迈进,那么接下来的预测值就要基于之前的预测值和原本值或者完全基于之前的预测值,即:
x ^ 605 = f ( x 601 , x 602 , x 603 , x 604 ) x ^ 606 = f ( x 602 , x 603 , x 604 , x ^ 605 ) x ^ 607 = f ( x 603 , x 604 , x ^ 605 , x ^ 606 ) x ^ 608 = f ( x 604 , x ^ 605 , x ^ 605 , x ^ 607 ) x ^ 609 = f ( x ^ 605 , x ^ 606 , x ^ 607 , x ^ 608 ) \hat{x}_{605}=f(x_{601},x_{602},x_{603},x_{604})\\ \hat{x}_{606}=f(x_{602},x_{603},x_{604},\hat{x}_{605})\\ \hat{x}_{607}=f(x_{603},x_{604},\hat{x}_{605},\hat{x}_{606})\\ \hat{x}_{608}=f(x_{604},\hat{x}_{605},\hat{x}_{605},\hat{x}_{607})\\ \hat{x}_{609}=f(\hat{x}_{605},\hat{x}_{606},\hat{x}_{607},\hat{x}_{608}) x^605=f(x601,x602,x603,x604)x^606=f(x602,x603,x604,x^605)x^607=f(x603,x604,x^605,x^606)x^608=f(x604,x^605,x^605,x^607)x^609=f(x^605,x^606,x^607,x^608)
因此我们必须使用我们自己的预测(而不是原始数据)来进行多步预测:

multistep_preds = torch.zeros(T)
multistep_preds[: n_train + tau] = x[: n_train + tau]
for i in range(n_train + tau, T):multistep_preds[i] = net(multistep_preds[i - tau:i].reshape((1, -1)))d2l.plot([time, time[tau:], time[n_train + tau:]],[x.detach().numpy(), onestep_preds.detach().numpy(),multistep_preds[n_train + tau:].detach().numpy()], 'time','x', legend=['data', '1-step preds', 'multistep preds'],xlim=[1, 1000], figsize=(6, 3))

结果:
在这里插入图片描述
预测不理想的原因是:预测误差不断累加。这种现象就像是24小时天气预报,超过24小时以后,精度会迅速下降。

总结

1、时序模型中,当前数据与之前观察到的数据相关
2、自回归模型使用自身过去数据预测未来
3、马尔可夫模型假设当前只跟最近少数数据相关,从而简化模型
4、潜变量模型使用潜变量来概括历史信息

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue消息订阅与发布,实现任意组件间通讯

第一步:下载第三方消息订阅与发布库,例如常用的pubsub.js,他可以在任何框架中使用包括vue、react、anglar等等。 命令:npm i pubsub-js 注意是pubsub-js(不是点); 第二步:引入库; import pubsub from pubsub-js 第…

Die2Die(D2D)和chip2chip(C2C)之间的高速互联接口

随着chiplet的兴起,Die2Die的高速互联越来越重要,相比于传统的C2C(chip2chip)的互联,D2D的片间距离很近(10mm量级),且这些小的chip(裸片)最终形成一个封装【多芯片模块(MCM)】。所以D2D的互联信道短&#x…

修改Egohands公开数据集,用于YOLOv5训练通用手部检测模型

〇、背景: 项目需要,需要利用摄像头对人手进行实时监测,最先考虑到的就是简单易用且高效的YOLOv5,很快找到了公开数据集:Egohands EgoHands: A Dataset for Hands in Complex Egocentric Interactions | IU Computer…

【人工智能前沿弄潮】—— SAM系列:SAM从提示生成物体mask

SAM从提示生成物体mask Segment Anything Model(SAM)根据指示所需的对象来预测对象掩码。该模型首先将图像转换为图像嵌入,从而可以从提示中高效地生成高质量的掩码。 SamPredictor类为模型提供了一个简单的接口来提示模型。用户可以首先使…

数据结构日记之《队列的定义》

队列的定义 一、队列的定义和特点二、队列的抽象数据类型定义三、例子 一、队列的定义和特点 队列 (queue) 是一种 先进先出(First In First Out, FIFO) 的线性表。它只允许在表的一端进行插入,而在另一端删除元素。这和日常生活中的排队是一致的,最早进…

uniapp+vue3项目中使用vant-weapp

创建项目 通过vue-cli命令行创建项目 Vue3/Vite版要求 node 版本^14.18.0 || >16.0.0 uni-app官网 (dcloud.net.cn) npx degit dcloudio/uni-preset-vue#vite my-vue3-project打开项目 点击顶部菜单栏终端/新建终端 执行安装依赖指令 yarn install 或 npm install 安装vant…

【uniapp】使用Vs Code开发uniapp:

文章目录 一、使用命令行创建uniapp项目:二、安装插件与配置:三、编译和运行:四、修改pinia: 一、使用命令行创建uniapp项目: 二、安装插件与配置: 三、编译和运行: 该项目下的dist》dev》mp-weixin文件导入微信开发者…

Redisson可重入锁原理

微信公众号访问地址:Redisson可重入锁原理 推荐文章: 1、使用原生Redis命令实现分布式锁 ​ 2、为什么引入Redisson分布式锁? 3、SpringBoot整合多数据源,并支持动态新增与切换(详细教程) 4、SpringBo…

3D Web轻量化引擎HOOPS Communicator如何实现对BIM桌面端的支持?

HOOPS Communicator是一款简单而强大的工业级高性能3D Web轻量化渲染开发包,其主要应用于Web领域,主要加载其专有的SCS、SC、SCZ格式文件;HOOPS还拥有另一个桌面端开发包HOOPS Visualize,主要加载HSF、HMF轻量化格式文件。两者虽然…

【QPSK信号生成】生成正交相移键控信号研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Kubernetes集群部署(第二篇)

安装flannel Master 节点NotReady 的原因就是因为没有使用任何的网络插件,此时Node 和Master的连接还不正常。目前最流行的Kubernetes 网络插件有Flannel、Calico、Canal、Weave 这里选择使用flannel。 flannel提取链接:https://pan.baidu.com/s/1fLJKh…

EXPLAIN使用分析

系列文章目录 文章目录 系列文章目录一、type说明二、MySQL中使用Show Profile1.查看当前profiling配置2.在会话级别修改profiling配置3.查看profile记录4.要深入查看某条查询执行时间的分布 一、type说明 我们只需要注意一个最重要的type 的信息很明显的提现是否用到索引&…