循环网络神经模型基础快速入门

RNN介绍

对比维度 普通前馈神经网络(基础 NN) 卷积神经网络(CNN) 循环神经网络(RNN)
核心概念 最基础神经网络,由输入层、全连接隐藏层、输出层组成;层间全连接,只处理相互独立无关联的数据,无记忆、无自动特征提取能力。 以卷积运算为核心的网络,新增卷积层、池化层;依靠局部连接、权值共享自动提取空间特征,专门处理图像类网格结构数据。 具有记忆循环结构的神经网络,隐藏层会保存上一时刻状态;能记忆前文时序信息,专门处理有先后顺序的序列数据。
核心结构 全连接层堆叠,信号单向传递 卷积层 + 池化层 + 全连接层,局部连接、权值共享 隐藏层内部带循环反馈,时刻之间状态传递
数据流向 输入→隐藏→输出,单向无循环 输入→卷积→池化→全连接→输出,单向 按时序循环:当前输入 + 上一时刻隐藏状态 共同计算
核心能力 简单非线性拟合,做基础数据分类回归 自动提取图像边缘、纹理、空间特征 记忆历史信息,捕捉前后时序依赖关系
适用数据 表格数据、独立样本、一维向量 图像、视频、二维网格数据 文本、语音、时间序列、连续时序数据
关键特点 全连接、无记忆、参数量大、易过拟合 局部连接、参数少、特征自动提取、专注空间信息 有记忆、能上下文关联、可处理变长序列

专门处理有先后顺序、前后有关系的序列数据,自带记忆功能,能记住前面的信息,用来影响后面的判断。

主要用途

自然语言处理

分词、翻译、聊天机器人、情感分析、文本生成。

语音处理

语音转文字、语音识别、语音合成。

时间序列预测

股票走势、气温预测、销量预测、数据趋势预判。

连续时序数据

只要是按时间排队、前后有关联的数据,都能用 RNN。

一句话总结

普通神经网络认单独数据,CNN 认图片图像,

RNN 专门认有先后顺序、需要记前面内容的时序 / 文本数据。

自然语言处理概述

词嵌入式

把文本里的每个词,转换成低维稠密向量,作为 RNN 的输入,同时还能捕捉词和词之间的语义相似性。

三个关键作用

  1. 输入表示:把文字这种没法直接给 RNN 处理的符号,变成机器能计算的数字向量。
  2. 降低维度:不用稀疏的 one-hot 向量,而是用低维向量表示词,减少计算量。
  3. 捕捉语义 :语义相近的词,对应的向量也会很接近(比如catmat的向量,会比caton更相似)

词嵌入层的工作流程

  • 初始化词向量矩阵 :先根据词汇表的词数,构建一个词向量矩阵。比如有 100 个词,每个词用 4 维向量表示,矩阵就是100×4的大小。每个词对应矩阵里的一行向量。
  • 文本转索引:输入的句子先分词,每个词在词汇表里都有唯一的索引,把词转换成对应的索引数字。
  • 索引查表得向量 :用每个词的索引,去词向量矩阵里 "查表",找到对应的向量。比如cat的索引是 0,就取矩阵的第 0 行向量。
  • 向量输入 RNN:这些查出来的词向量,作为 RNN 的输入,让 RNN 处理序列信息。
  • num_embeddings:词汇表里一共有多少个词(词的数量)。
  • embedding_dim:每个词要转换成多少维的向量(比如 4 维、128 维)。

词嵌入(文本→向量)是 RAG 系统的 "匹配基础"。它的作用是把「用户问题」和「知识库文本」都转换成向量,让系统能通过向量相似度,快速找到和问题最相关的文档片段。

环节 词嵌入的角色 RAG 匹配的作用
文本处理 把自然语言转成机器能算的向量 让语义相似的文本有可量化的 "距离"
相似度匹配 提供向量空间中的位置信息 不用逐字比对,快速召回相关文档
大模型输入 统一问题和知识库的向量表示 保证匹配结果的语义一致性

词嵌入层使用

接下来,我们将会学习如何将词转换为词向量,其步骤如下:

  1. 先将语料进行分词,构建词与索引的映射,我们可以把这个映射叫做词表,词表中每个词都对应了一

个唯一的索引

  1. 然后使用 nn.Embedding 构建词嵌入矩阵,词索引对应的向量即为该词对应的数值化后的向量表示。

例如,我们的文本数据为:

"北京冬奥的进度条已经过半,不少外国运动员在完成自己的比赛后踏上归途

RNN网络原理

RNN 循环神经网络:带循环、有记忆 ,通过隐藏状态 h 存储历史序列信息,把前一时刻的记忆带到当前时刻,专门处理时序 / 序列数据(文本、语音、时间序列)。

每一瞬间 RNN 只干三件事:

  1. 带着上一秒的记忆 \(h_{t-1}\)
  2. 接收现在的新输入 \(x_t\)
  3. 两件东西合在一起:
    • 刷新出新记忆 \(h_t\)(留给下一秒用)
    • 给出当前的预测输出 \(y_t\)

循环往复,一直往下走。

比如读句子:我今天去公园

  • 读到「我」:脑子记一下:主角是我
  • 读到「今天」:脑子更新记忆:我 + 时间今天
  • 读到「去」:再更新:我 今天 要去
  • 读到「公园」:最后完整理解意思

RNN 的 h 就是你读句子时脑子里一直累计的上下文印象,每读一个字,就更新一次印象,同时理解当前字。

  • 记东西:把前面的信息存下来,不丢
  • 懂上下文:不是孤立看单个输入,结合前后理解
  • 串起顺序:不管句子长短,都能一步步顺着顺序处理

记性 !句子一长,最早的信息就慢慢忘了 ,记不住太远的内容,所以后来出了 LSTM、GRU,就是帮 RNN 加长记忆力的。

PyTorch RNN层的使用

RNN = torch.nn.RNN(input_size,hidden_size,num_layers)

参数意义是:

  1. input_size:输入数据的维度,一般设为词向量的维度;

  2. hidden_size:隐藏层h的维度,也是当前层神经元的输出维度;

  3. num_layers: 隐藏层h的层数,默认为1. 将RNN实例化就可以将数据送入进行处理

在 PyTorch 的 RNN 里,hn 就是 初始隐藏状态,也就是你之前理解的那个「初始记忆」。

文本生成

导入工具包

导入周杰伦数据集

构建此表

接下来, 我们对周杰伦歌词的数据进行处理构建词表,具体实现如下所示:

整体流程是:

l 获取文本数据

l 分词,并进行去重

构建词表
构建数据集对象

我们用于实现《歌词生成》的网络模型,主要包含了三个层:

  1. 词嵌入层: 用于将语料转换为词向量

  2. 循环网络层: 提取句子语义

  3. 全连接层: 输出对词典中每个词的预测概率

构建网络模型
构建训练函数

训练函数主要负责编写数据迭代、送入网络、计算损失、反向

传播、更新参数,其流程基本较为固定。

由于我们要实现文本生成,文本生成本质上,输入一串文本,预测下一个文本,也属于分类问题,所以,我们使用多

分类交叉熵损失函数。优化方法我们学习过 SGB、AdaGrad、Adam 等,在这里我们选择学习率、梯度自适应的 Adam

算法作为我们的优化方法。

训练完成之后,我们使用 torch.save 方法将模型持久化存储

模型训练

def train():

构建词典

index_to_word, word_to_index, word_count, corpus_idx = build_vocab()

数据集

lyrics = LyricsDataset(corpus_idx, 32)

初始化模型

model = TextGenerator(word_count)

损失函数

criterion = nn.CrossEntropyLoss()

优化方法

optimizer = optim.Adam(model.parameters(), lr=1e-3)

训练轮数

epoch = 10

for epoch_idx in range(epoch):

数据加载器

lyrics_dataloader = DataLoader(lyrics, shuffle=True, batch_size=1)

训练时间

start = time.time()

iter_num = 0 # 迭代次数

训练损失

total_loss = 0.0

遍历数据集

for x, y in lyrics_dataloader:

隐藏状态的初始化

hidden = model.init_hidden(bs=1)

模型计算

output, hidden = model(x, hidden)

计算损失

y:[batch,seq_len]->[seq_len,batch]->[seq_len*batch]

y = torch.transpose(y, 0, 1).contiguous().view(-1)

loss = criterion(output, y)

optimizer.zero_grad()

loss.backward()

optimizer.step()

iter_num += 1 # 迭代次数加1

total_loss += loss.item()

打印训练信息

print('epoch %3s loss: %.5f time %.2f' % (epoch_idx + 1, total_loss / iter_num, time.time() - start))

模型存储

torch.save(model.state_dict(), 'data/lyrics_model_%d.pth' % epoch)

if name == "main":

train()

构建预测函数

从磁盘加载训练好的模型,进行预测。预测函数,输入第一个指定的词,我们将该词输入网路,预测出下一个词,再

将预测的出的词再次送入网络,预测出下一个词,以此类推,知道预测出我们指定长度的内容。

复制代码
def predict(start_word, sentence_length):
# 构建词典
index_to_word, word_to_index, word_count, _ = build_vocab()
# 构建模型
model = TextGenerator(word_count)
# 加载参数
model.load_state_dict(torch.load('data/lyrics_model_10.pth'))
# 隐藏状态
hidden = model.init_hidden()
# 将起始词转换为索引
word_idx = word_to_index[start_word]
# 产生的词的索引存放位置
generate_sentence = [word_idx]
# 遍历到句子长度,获取每一个词
for _ in range(sentence_length):
# 模型预测
output, hidden = model(torch.tensor([[word_idx]]), hidden)
# 获取预测结果
word_idx = torch.argmax(output)
generate_sentence.append(word_idx)
# 根据产生的索引获取对应的词,并进行打印
for idx in generate_sentence:
print(index_to_word[idx], end='')
if __name__ == "__main__":
# 调用预测函数
predict('分手', 50)

输出结果:

分手的话像语言暴力

我已无能为力再提起 决定中断熟悉

然后在这里 不限日期

然后将过去 慢慢温习

让我爱上你 那场悲剧

是你完美演出的一场戏

总结
  1. 构建词汇表

  2. 构建数据对象

  3. 编写网络模型

  4. 编写训练函数

  5. 编写预测函数

相关推荐
DavidTaozhe1 小时前
美股api接口的WebSocket订阅如何实现自动重连
网络·websocket·网络协议
草莓熊Lotso1 小时前
【Linux网络】从 0 到 1 实现高性能 UDP 聊天室:深入拆解 Linux 网络编程与线程池架构
linux·运维·服务器·网络·数据库·c++·udp
天问一2 小时前
bat文件切换电脑ip
服务器·网络·tcp/ip
yyuuuzz2 小时前
企业出海aws运维常见问题梳理
运维·服务器·网络·数据库·aws
悟渔2 小时前
STM32N6系列MIDI 串口 GPDMA 环形接收解析模块
网络
AOwhisky2 小时前
Docker 学习笔记:网络篇
linux·运维·网络·笔记·学习·docker·容器
Bat U2 小时前
JavaEE|网络编程
运维·服务器·网络
剑锋所指,所向披靡!2 小时前
计算机网络的数据链路层
网络·计算机网络
在角落发呆2 小时前
内网电脑远程控制全攻略:从基础到进阶的实用方案
网络