Python----循环神经网络(基于DNN的时序预测+NLP自然语言处理)

一、DNN的时序预测与缺陷

序列依赖捕获能力有限

传统的全连接DNN(如多层感知机,MLP)在处理时间序列时,难以有效捕获前后序列中的长距离依赖。这是因为DNN本身没有显式设计用来处理顺序信息的机制,序列中的长时依赖容易被“遗忘”。

模型难以捕获复杂的时序关系

时间序列数据常带有非线性、动态变化和多尺度特性,而普通DNN的表达能力和拟合能力有限,需要网络架构的深层设计或者加入其他机制(如注意力机制)才能改善。

对长序列的数据不足和样本效率低

深度学习模型通常需要大量数据来实现良好的泛化性能,尤其是复杂的时序数据。缺乏充分数据时,模型容易出现过拟合或无法有效学习序列的潜在特征。

序列的非平稳性和噪声影响

很多时间序列具有非平稳性(如季节性、趋势性变化)以及噪声干扰,普通DNN难以区分信号与噪声,导致预测性能下降。

训练难度与计算成本高

深度神经网络的训练涉及复杂的参数优化过程,对硬件资源和时间成本要求高。特别是在实时预测场景中,延迟可能成为瓶颈。

泛化能力及迁移学习受限

被训练的模型在特定时间段或环境下表现良好,但面对环境变化、数据漂移时,性能可能迅速下降。迁移学习的效果也有限,需重新训练模型。

缺乏可解释性

深度模型的“黑箱”特性使得其预测过程难以解释,在某些关键应用(如金融、医疗)中,缺乏可解释性限制了其应用拓展。

模型的稳定性和鲁棒性不足

对极端异常值或突发事件的鲁棒性不足,可能导致模型输出不稳定或误判。

二、NLP介绍

        自然语言处理(Natural Language Processing,NLP)是人工智能领域的一个分支,专注于使计算机能够理解、分析和生成人类自然语言的文本或语音数据。

        NLP致力于构建能够处理自然语言的智能系统,使计算机能够与人类进行自然而流畅的交流,而不仅仅是执行预定义的任务。以下是关于NLP的一些关键概念和应用:

        1. 文本分析:NLP技术可用于文本分析,包括文本分类、情感分析、主题建模和实体识别。文本分类涉及将文本分为不同的类别,情感分析用于识别文本中的情感或情感倾向,主题建模用于发现文本数据中的主题,而实体识别则是识别文本中的具体实体,如人名、地名和日期。

        2. 语言生成:NLP可以用于生成自然语言文本,包括自动摘要生成、机器翻译和对话系统。这些任务要求计算机生成与人类语言类似的文本,可以帮助自动化生成摘要、翻译文本,或实现自动对话。

        3. 机器翻译:NLP技术被广泛用于机器翻译,即将一种语言的文本翻译成另一种语言。这包括基于统计方法或神经网络的机器翻译系统。

        4. 对话系统:对话系统(Chatbots)是NLP应用的一部分,它们被用于模拟人类对话。这些系统可以用于在线客服、虚拟助手和智能聊天机器人。

        5. 自然语言理解:NLP还包括自然语言理解(Natural Language Understanding,NLU),用于将文本数据转化为计算机可理解的结构化信息。NLU可以帮助计算机理解用户的意图,从而执行相应的操作。

        6. 信息检索:NLP技术用于信息检索,帮助用户通过搜索引擎找到相关的文档、网页或信息。关键词提取、文档检索和排名是信息检索的关键组成部分,例如B站很多视频中评论区的AI助理,提取时间线和主要内容。

        7. 情感分析:情感分析是NLP中的一个重要任务,用于确定文本中的情感极性,例如正面、负面或中性情感。它在社交媒体监测、市场调研和舆情分析方面具有广泛的应用,例如某件商品的评论提取商品的。

        NLP的发展在人工智能领域引发了广泛的兴趣和研究,以改善计算机在处理自然语言方面的能力,使其在文本理解、生成和对话方面取得更大的进展。深度学习技术,特别是循环神经网络(RNN)和变换器(Transformer)架构,已经在NLP任务中取得了显著的成功,推动了自然语言处理的发展。

三、基于DNN的时序预测

3.1、数据操作

import numpy as np
import torch
import torch.nn as nn

# 原始文本
text = "hey how are you"

# 初始化输入和输出序列的列表
input_seq = []
output_seq = []

# 定义滑动窗口大小
windows = 5

# 构建输入和输出序列
for i in range(0, len(text) - windows, 1):
    # 当前窗口内的字符作为输入序列
    input_seq.append(text[i:i + windows])
    # 紧接着窗口后的字符作为输出(目标)
    output_seq.append(text[i + windows])

# 输出所有的输入序列
print(input_seq)
# 输出对应的目标字符序列
print(output_seq)

# 获取文本中的所有唯一字符(集合一般无序)
charts = set(text)
print(charts)

# 将字符集合排序,保持一致的索引顺序
charts = sorted(charts)
print(charts)

# 创建字符到索引的映射字典
char2int = {char: idx for idx, char in enumerate(charts)}
print(char2int)

# 创建索引到字符的映射字典(逆映射)
int2char = {idx: char for idx, char in enumerate(charts)}
print(int2char)

# 将输入字符序列转换为对应的索引列表
input_seq = [[char2int[char] for char in seq] for seq in input_seq]
print(input_seq)

# 将输出目标字符序列转换为索引列表
output_seq = [[char2int[char] for char in seq] for seq in output_seq]
print(output_seq)


# 创建输入的特征矩阵(one-hot编码)
features = np.zeros((len(input_seq), len(charts)), dtype=np.float32)
for i, seq in enumerate(input_seq):
    # 对每个字符索引,设置对应位置为1
    features[i, seq] = 1

print(features)
# 转换为torch张量
input_seq = torch.tensor(features, dtype=torch.float32)

# 创建输出的标签矩阵(one-hot编码)
features = np.zeros((len(output_seq), len(charts)), dtype=np.float32)
for i, seq in enumerate(output_seq):
    features[i, seq] = 1

print(features)
# 转换为torch张量
output_seq = torch.tensor(features, dtype=torch.float32)

3.2、构建网络 

# 定义神经网络模型
class Model(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super().__init__()
        # 第一层全连接线性变换
        self.fc1 = nn.Linear(input_size, hidden_size)
        # 第二层全连接线性变换
        self.fc2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        # 输入经过第一层+ReLU激活
        x = nn.functional.relu(self.fc1(x))
        # 输出层
        x = self.fc2(x)
        return x

# 实例化模型:输入大小为所有字符的个数(one-hot长度)
# 隐藏层大小为32
# 输出大小也是所有字符的个数(预测下一字符的分布)
model = Model(len(charts), 32, len(charts))

3.3、损失函数优化器 

# 交叉熵损失
cri = nn.CrossEntropyLoss()
# Adam优化器
optim = torch.optim.Adam(model.parameters(), lr=0.001)

3.4、训练模型

# 训练模型(迭代1000次)
for epoch in range(1000):
    # 前向传播:输入模型,得到输出
    output = model(input_seq)
    # 计算损失(注意:这里的输出是未经过softmax,满足CrossEntropyLoss输入要求)
    loss = cri(output, output_seq)

    # 梯度清零
    optim.zero_grad()
    # 反向传播
    loss.backward()
    # 参数更新
    optim.step()

    # 每个epoch输出当前损失值
    print(epoch, loss.item())

3.5、预测数据 

# 测试预测:给定一个新字符序列
input_text = 'hey h'
# 将字符转换为对应索引
input_text = [char2int[char] for char in input_text]

# 创建一个全为0的特征向量(大小等于所有字符数)
features = np.zeros((len(charts)), dtype=np.float32)
# 将序列中的每个字符位置置为1(one-hot)
for seq in input_text:
    features[seq] = 1.0

# 转换为Tensor
input_text = torch.tensor(features, dtype=torch.float32)

# 用模型预测
out = model(input_text)
# 获取预测的概率最大的字符的索引
re = int2char[torch.argmax(out).item()]
print(re)

3.6、完整代码 

import numpy as np
import torch
import torch.nn as nn

# 原始文本
text = "hey how are you"

# 初始化输入和输出序列的列表
input_seq = []
output_seq = []

# 定义滑动窗口大小
windows = 5

# 构建输入和输出序列
for i in range(0, len(text) - windows, 1):
    # 当前窗口内的字符作为输入序列
    input_seq.append(text[i:i + windows])
    # 紧接着窗口后的字符作为输出(目标)
    output_seq.append(text[i + windows])

# 输出所有的输入序列
print(input_seq)
# 输出对应的目标字符序列
print(output_seq)

# 获取文本中的所有唯一字符(集合一般无序)
charts = set(text)
print(charts)

# 将字符集合排序,保持一致的索引顺序
charts = sorted(charts)
print(charts)

# 创建字符到索引的映射字典
char2int = {char: idx for idx, char in enumerate(charts)}
print(char2int)

# 创建索引到字符的映射字典(逆映射)
int2char = {idx: char for idx, char in enumerate(charts)}
print(int2char)

# 将输入字符序列转换为对应的索引列表
input_seq = [[char2int[char] for char in seq] for seq in input_seq]
print(input_seq)

# 将输出目标字符序列转换为索引列表
output_seq = [[char2int[char] for char in seq] for seq in output_seq]
print(output_seq)


# 创建输入的特征矩阵(one-hot编码)
features = np.zeros((len(input_seq), len(charts)), dtype=np.float32)
for i, seq in enumerate(input_seq):
    # 对每个字符索引,设置对应位置为1
    features[i, seq] = 1

print(features)
# 转换为torch张量
input_seq = torch.tensor(features, dtype=torch.float32)

# 创建输出的标签矩阵(one-hot编码)
features = np.zeros((len(output_seq), len(charts)), dtype=np.float32)
for i, seq in enumerate(output_seq):
    features[i, seq] = 1

print(features)
# 转换为torch张量
output_seq = torch.tensor(features, dtype=torch.float32)


# 定义神经网络模型
class Model(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super().__init__()
        # 第一层全连接线性变换
        self.fc1 = nn.Linear(input_size, hidden_size)
        # 第二层全连接线性变换
        self.fc2 = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        # 输入经过第一层+ReLU激活
        x = nn.functional.relu(self.fc1(x))
        # 输出层
        x = self.fc2(x)
        return x

# 实例化模型:输入大小为所有字符的个数(one-hot长度)
# 隐藏层大小为32
# 输出大小也是所有字符的个数(预测下一字符的分布)
model = Model(len(charts), 32, len(charts))

# 交叉熵损失
cri = nn.CrossEntropyLoss()
# Adam优化器
optim = torch.optim.Adam(model.parameters(), lr=0.001)

# 训练模型(迭代1000次)
for epoch in range(1000):
    # 前向传播:输入模型,得到输出
    output = model(input_seq)
    # 计算损失(注意:这里的输出是未经过softmax,满足CrossEntropyLoss输入要求)
    loss = cri(output, output_seq)

    # 梯度清零
    optim.zero_grad()
    # 反向传播
    loss.backward()
    # 参数更新
    optim.step()

    # 每个epoch输出当前损失值
    print(epoch, loss.item())

# 测试预测:给定一个新字符序列
input_text = 'hey h'
# 将字符转换为对应索引
input_text = [char2int[char] for char in input_text]

# 创建一个全为0的特征向量(大小等于所有字符数)
features = np.zeros((len(charts)), dtype=np.float32)
# 将序列中的每个字符位置置为1(one-hot)
for seq in input_text:
    features[seq] = 1.0

# 转换为Tensor
input_text = torch.tensor(features, dtype=torch.float32)

# 用模型预测
out = model(input_text)
# 获取预测的概率最大的字符的索引
re = int2char[torch.argmax(out).item()]
print(re)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值