LSTM 和 TCN 能记住多长时间的依赖关系?
ztj100 2025-01-01 23:50 34 浏览 0 评论
LSTM 是序列建模任务(例如语言建模和时间序列预测)中广泛使用的技术。 此类任务通常具有长期记忆和短期记忆,因此学习两种模式以进行准确预测和估计非常重要。 基于 Transformers 的技术正在兴起,这种技术有助于对长期依赖进行建模并且比lstm好得多,但由于需要大量数据的训练和部署复杂性,Transformer 不能用于每个应用程序。 在这篇文章中,我将在 LSTM 和 TCN 的长期信息学习方面进行比较。
本文假设读者对 LSTM 和 CNN 神经网络的模型理论和架构有初步的了解。
技术背景
LSTM是一种长期记忆神经网络,广泛用于学习序列数据(NLP、时间序列预测等)。由于递归神经网络(RNN)存在梯度消失问题,阻碍了网络学习长时间的依赖关系,而LSTM通过引入遗忘门、输入门和输出门来减少这个问题。有了这些门,它就有了代表长期记忆的cell状态,而hidden状态则代表短期记忆。遗憾的是,LSTM仍然不是一个保留长期信息的完美解决方案,因为遗忘门倾向于从之前的步骤中删除这些模式(信息衰减)——如果模式对50个步骤都不重要,为什么我要保留它?
Power Law Forget Gated LSTM (pLSTM)是英特尔公司和约翰霍普金斯大学的研究人员最近开发的。尽管LSTM有所改进,但遗忘机制表现出信息的指数衰减限制了它捕获长时间尺度信息的能力。由于 LSTM 中的信息衰减遵循指数模式,因此 pLSTM 向遗忘门添加了衰减因子 p,这允许 LSTM 控制信息衰减率,帮助其更好地学习长期依赖关系。
Temporal CNN (TCN)是一种简单的一维卷积网络,可以应用于时间序列数据而不是图像数据。这些层具有时间属性,用于学习数据中的全局和局部模式。卷积层还有助于改善模型延迟,因为预测可以并行化,不需要按顺序排列。由于每个预测只能依赖于其先前的预测,所以CNN 也是可以有因果关系的,不会有来自未来的数据泄漏。 TCN 使用深度神经网络和扩张卷积的组合构成了能够保存非常长的有效历史大小的模型。 TCN 有多种变体,例如基于注意力的 CNN,将 LSTM 与 CNN 相结合,并融合其他类型的架构,但在本篇文章中,我将使用普通的 TCN 以保持简单性。
合成数据
让我们从一个简单的加法函数开始:
Y = f(x?)+ f(x1)
每个人都可以设计自己的函数,现在我们用这个:我们的假设序列越长,LSTM就越难记住X?的值,例如,一个2的序列是第1和第2个元素的相加,而一个100的序列是第1(0)和第100(或-1)个元素的相加。序列越大,LSTM需要携带信息的步骤就越多。
import numpy as np
from tensorflow.keras.utils import Sequence
seq = 70
N = 1000
class DataGenerator(Sequence):
def __init__(self, seq, N, batch_size, to_fit=True):
self.seq = seq
self.N = N
self.to_fit = to_fit
self.batch_size = batch_size
def __len__(self):
return int(self.N / self.batch_size)
def __getitem__(self, index):
x = np.array([np.random.normal(0, 1, self.seq) for i in range(self.batch_size)])
if self.to_fit:
y = x[:, 0] + x[:, -1]
return x.reshape(list(x.shape) + [1]), y
return x
trainGen = DataGenerator(seq,N, 256)
validGen = DataGenerator(seq,N*.3, 256*.3)
LSTM 模型架构
我创建了一个普通的 LSTM并试验了超参数以及堆叠的 LSTM 层来验证我们的假设
from tensorflow.keras.layers import Input, LSTM, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.callbacks import ModelCheckpoint
X = Input(shape=(None,1))
LSTM_1 = LSTM(8, return_sequences=True, activation='softplus')(X)
LSTM_2 = LSTM(6, return_sequences=False, activation='softplus')(LSTM_1)
Y_hat = Dense(1)(LSTM_2)
model = Model(inputs=X, outputs=Y_hat)
print(model.compile(loss='mse'))
print(model.summary())
MODEL_NAME = 'lstm.hdf5'
checkpoint = ModelCheckpoint(MODEL_NAME, monitor='val_loss', verbose=1, save_best_only=True, mode='min')
callbacks_list = [checkpoint]
model.fit(trainGen, validation_data=validGen, epochs=1000, callbacks=callbacks_list, verbose=0)
model.load_weights(MODEL_NAME)
print(model.evaluate(validGen))
CNN模型架构
我创建了一个普通的 TCN 架构,并试验了超参数,例如 kernel_size、核大小和卷积数来验证我们的假设
from tensorflow.keras.layers import Input, Dense, Conv1D, Flatten
from tensorflow.keras.models import Model
from tensorflow.keras.callbacks import ModelCheckpoint
X = Input(shape=(seq,1))
CNN_1 = Conv1D(filters=3, kernel_size=seq, activation='softplus', padding='valid')(X)
FLATTEN_1 = Flatten()(CNN_1)
DENSE_1 = Dense(2, activation='softplus')(FLATTEN_1)
Y_HAT = Dense(1)(DENSE_1)
model = Model(inputs=X, outputs=Y_HAT)
print(model.compile(loss='mse'))
print(model.summary())
MODEL_NAME = 'cnn.hdf5'
checkpoint = ModelCheckpoint(MODEL_NAME, monitor='val_loss', verbose=1, save_best_only=True, mode='min')
callbacks_list = [checkpoint]
model.fit(trainGen, validation_data=validGen, epochs=1000, callbacks=callbacks_list, verbose=0)
model.load_weights(MODEL_NAME)
print(model.evaluate(validGen))
模型性能结果
MSE 是评估非偏态数据的一个很好的方法,但是解释起来不是很简单。 为简化起见,我们可以查看当 X 之一发生变化时 Y 的变化百分比(change函数)。 由于合成函数是可加的,将 X 中的一个改变 N% 应该会使 Y 发生 N/2% 的变化。其次, 我们使用blinding函数,将 X 中的任何一个设置为 0 时,我们可以根据 MSE 测量 Y 是否等于非零 X。 理论上,MSE应该是0.0
def change(test, perc, y_pred, model, idx):
testX_ = test.copy()
testX_[:,idx,:] *= 1+perc/100.
y_pred_ = model.predict(testX_).reshape(-1)
print(round(np.median((y_pred_ - y_pred)/y_pred)*100.,2))
def blinding(test, perc, y_pred, model, idx_on, idx_off):
testX_ = test.copy()[:10]
testX_[:,idx_off,:] = [np.array([0.0]) for i in range(10)]
testX_[:,idx_on,:] = [np.array([i/10.]) for i in range(10)]
print(
round(
np.mean(
(model.predict(testX_) - testX_[:,idx_on,:])**2.
),
3)
)
结果和结论
我独立地对 X[0] 和 X[-1] 应用了 50% 的变化,以了解 Y 的变化并计算第 0 次变化和第 -1 次变化列。 LSTM 能够记住从时间序列开始时多达 68 个序列长度的先验信息,但最终在第 69 个序列长度时忘记了,而 TCN 仍然能够做出准确的预测,因为我增加了内核大小,使得模型可以查看序列数据的初始值和结束值。 blinding函数的测试显示了相同的结果。 当序列长度为 69 的第 0 个值设置为 0 时,MSE 跳至 0.251%。 总体而言,LSTM 似乎对第 -1 次变化比对第 0 次变化更敏感。
这些结果与 pLSTM 作者在其信息衰减部分中描述的大体相同
在本文中,没有与 pLSTM 进行比较,因为还没有可用的开源实现,如果有机会我将根据论文实现并进行比较。
这里包含本文的全部源代码:github/dwipam/medium-3
pLstm论文:arxiv 2105.05944
作者:Dwipam Katariya
相关推荐
- SpringBoot整合SpringSecurity+JWT
-
作者|Sans_https://juejin.im/post/5da82f066fb9a04e2a73daec一.说明SpringSecurity是一个用于Java企业级应用程序的安全框架,主要包含...
- 「计算机毕设」一个精美的JAVA博客系统源码分享
-
前言大家好,我是程序员it分享师,今天给大家带来一个精美的博客系统源码!可以自己买一个便宜的云服务器,当自己的博客网站,记录一下自己学习的心得。开发技术博客系统源码基于SpringBoot,shiro...
- springboot教务管理系统+微信小程序云开发附带源码
-
今天给大家分享的程序是基于springboot的管理,前端是小程序,系统非常的nice,不管是学习还是毕设都非常的靠谱。本系统主要分为pc端后台管理和微信小程序端,pc端有三个角色:管理员、学生、教师...
- SpringBoot+LayUI后台管理系统开发脚手架
-
源码获取方式:关注,转发之后私信回复【源码】即可免费获取到!项目简介本项目本着避免重复造轮子的原则,建立一套快速开发JavaWEB项目(springboot-mini),能满足大部分后台管理系统基础开...
- Spring Boot的Security安全控制——认识SpringSecurity!
-
SpringBoot的Security安全控制在Web项目开发中,安全控制是非常重要的,不同的人配置不同的权限,这样的系统才安全。最常见的权限框架有Shiro和SpringSecurity。Shi...
- 前同事2024年接私活已入百万,都是用这几个开源的SpringBoot项目
-
前言不得不佩服SpringBoot的生态如此强大,今天给大家推荐几款优秀的后台管理系统,小伙伴们再也不用从头到尾撸一个项目了。SmartAdmin...
- 值得学习的15 个优秀开源的 Spring Boot 学习项目
-
SpringBoot算是目前Java领域最火的技术栈了,除了书呢?当然就是开源项目了,今天整理15个开源领域非常不错的SpringBoot项目供大家学习,参考。高富帅的路上只能帮你到这里了,...
- 开发企业官网就用这个基于SpringBoot的CMS系统,真香
-
前言推荐这个项目是因为使用手册部署手册非常...
- 2021年超详细的java学习路线总结—纯干货分享
-
本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础...
- jeecg-boot学习总结及使用心得(jeecgboot简单吗)
-
jeecg-boot学习总结及使用心得1.jeecg-boot是一个真正前后端分离的模版项目,便于二次开发,使用的都是较流行的新技术,后端技术主要有spring-boot2.x、shiro、Myb...
- 后勤集团原料管理系统springboot+Layui+MybatisPlus+Shiro源代码
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目描述后勤集团原料管理系统spr...
- 白卷开源SpringBoot+Vue的前后端分离入门项目
-
简介白卷是一个简单的前后端分离项目,主要采用Vue.js+SpringBoot技术栈开发。除了用作入门练习,作者还希望该项目可以作为一些常见Web项目的脚手架,帮助大家简化搭建网站的流程。...
- Spring Security 自动踢掉前一个登录用户,一个配置搞定
-
登录成功后,自动踢掉前一个登录用户,松哥第一次见到这个功能,就是在扣扣里边见到的,当时觉得挺好玩的。自己做开发后,也遇到过一模一样的需求,正好最近的SpringSecurity系列正在连载,就结...
- 收藏起来!这款开源在线考试系统,我爱了
-
大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!今天小编推荐一款基于Spr...
- Shiro框架:认证和授权原理(shiro权限认证流程)
-
优质文章,及时送达前言Shiro作为解决权限问题的常用框架,常用于解决认证、授权、加密、会话管理等场景。本文将对Shiro的认证和授权原理进行介绍:Shiro可以做什么?、Shiro是由什么组成的?举...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- SpringBoot整合SpringSecurity+JWT
- 「计算机毕设」一个精美的JAVA博客系统源码分享
- springboot教务管理系统+微信小程序云开发附带源码
- SpringBoot+LayUI后台管理系统开发脚手架
- Spring Boot的Security安全控制——认识SpringSecurity!
- 前同事2024年接私活已入百万,都是用这几个开源的SpringBoot项目
- 值得学习的15 个优秀开源的 Spring Boot 学习项目
- 开发企业官网就用这个基于SpringBoot的CMS系统,真香
- 2021年超详细的java学习路线总结—纯干货分享
- jeecg-boot学习总结及使用心得(jeecgboot简单吗)
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)