【NLP】daydayup 循环神经网络基本结构,pytorch实现

news/2024/12/22 23:10:08/

RNN 循环神经网络

循环神经网络(Recurrent Neural Network,RNN)是一种神经网络结构,专门用于处理序列数据。

RNN结构原理

在这里插入图片描述

RNN架构中,网络通过循环把信息从一个处理步骤传递到下一个,这个循环结构被称为隐藏层状态或者隐藏状态。可以捕捉并储存已经出处理的序列元素信息。

这个过程可以简化为
s t = f ( U ⋅ x t + W ⋅ s t − 1 ) s_t=f(\mathbf{U}·x_t+\mathbf{W}·s_{t-1}) st=f(Uxt+Wst1)
U是输入到隐藏的权重矩阵

W是隐藏到隐藏的权重

在这里插入图片描述

输出层 O t {O}_{t} Ot = g(V s t {s}_{t} st)

V是隐藏层到输出层的矩阵

在这里插入图片描述

import numpy as np
import torch
import torch.nn as nn# 假设输入3个时间步
x = np.random.rand(3,2) 
# 一个样本的输入,如文本中的一句话,一个样本中的3个特征,一句话有3个词,每个特征的维度是2,词向量的维度是2# 定义rnn参数
input_size = 2
hidden_size = 3
output_size = 4# 初始化权重和偏置
W_xh = np.random.rand(input_size,hidden_size) # 输入到隐藏
W_hh = np.random.rand(hidden_size,hidden_size) # 隐藏到隐藏
W_hy = np.random.rand(hidden_size,output_size) # 隐藏到输出bh = np.zeros(hidden_size) # 隐藏层偏置
by = np.zeros(output_size) # 输出层偏置# 激活函数
def tanh(x):return np.tanh(x)# 初始化隐藏状态
H_prev = np.zeros(hidden_size)x1 = x[0] # 得到第一个输入特征 文本序列中的第一个词
H1 = tanh(np.dot(x1,W_xh)+H_prev+bh)
print('隐藏1:',H1)
O1 = np.dot(H1,W_hy)+by
print('输出1:',O1)x2 = x[1]
H2 = tanh(np.dot(x2,W_xh)+np.dot(H1,W_hh)+bh)
print('隐藏2:',H2)
O2 = np.dot(H2,W_hy)+by
print('输出2:',O2)x3 = x[1]
H3 = tanh(np.dot(x3,W_xh)+np.dot(H2,W_hh)+bh)
print('隐藏3:',H3)
O3 = np.dot(H3,W_hy)+by
print('输出3:',O2)

RNNcell

PyTorch循环神经网络

import torch
import torch.nn as nnx = torch.randn(10,6,5) # 10批次大小 6词数 5向量维度
# 一次输入10句话,一句话中有6个词(特征),词向量维度是5(特征维度)class RNN(nn.Module):def __init__(self,input_size,hidden_size,batch_first=True):# input_size 输入的词向量维度,特征维度# hidden_size 隐藏状态的张量维度# batch_first 第一维度是否是batch,如果是,需要维度转换,以符合RNNcell的输入super().__init__()self.rnn_cell = nn.RNNCell(input_size,hidden_size)self.hidden_size = hidden_sizeself.batch_first = batch_firstdef __initialize_hidden(self,batch_size):# 初始化隐藏状态  第一个时间步没有隐藏的输入,需要初始化return torch.zeros((batch_size,self.hidden_size))def forward(self,x,init_hidden=None):# 得到数据的各个维度if self.batch_first:  # 维度转换 以符合cell输入bach_size,seq_size,input_size = x.size()x = x.permute(1,0,2)else:seq_size,bach_size,input_size = x.size()hiddens = [] # 储存隐藏状态if init_hidden is None: # 如果是第一个输入init_hidden = self.__initialize_hidden(bach_size)init_hidden = init_hidden.to(x.device) # 同步设备hidden_t = init_hiddenfor t in range(seq_size):hidden_t = self.rnn_cell(x[t],hidden_t)hiddens.append(hidden_t)hiddens = torch.stack(hiddens) # 堆叠所有时间步隐藏输出,合并为一个张量if self.batch_first:hiddens = hiddens.permute(1,0,2)print(hiddens)return hiddensmodel = RNN(5,8) # imput_size 词向量的维度 hidden_size 输出的维度  隐藏状态的张量维度
outputs = model(x)
print(outputs.shape) # torch.Size([10, 6, 8])

**这里并没有进行out的输出,只是获得了隐藏状态,在实际的需求中,需要增加其他的结构如线性层对隐藏状态进行操作 **

RNN

基于pytorch实现

import torch
import torch.nn as nn# 超参数设置batch_size,seq_size,input_size = 10,6,5 # 批次 句子长度 词向量维度hidden_size = 3  # 隐藏状态的张量维度# 数据
x = torch.rand(batch_size,seq_size,input_size)# 初始化隐藏状态
h_prev = torch.zeros(batch_size,hidden_size)# 创建RNNrnn = nn.RNN(input_size, hidden_size,batch_first=True) # batch_first=True是否转化out, hide= rnn(x,h_prev.unsqueeze(0))  # 返回值 第一个值为输出  第二个值是状态信息print(out.shape) # torch.Size([10, 6, 3])
print(hide.shape) # torch.Size([1, 10, 3])

biRNN双向RNN

双向RNN,使得模型能够学习到序列中某一点前后的上下文信息

在这里插入图片描述

import torch
import torch.nn as nn# 超参数设置batch_size,seq_size,input_size = 10,6,5 # 批次 句子长度 词向量维度hidden_size = 3  # 隐藏状态的张量维度# 数据
x = torch.rand(batch_size,seq_size,input_size)# 初始化隐藏状态
h_prev = torch.zeros(batch_size,hidden_size)# 创建RNNrnn = nn.RNN(input_size, hidden_size,batch_first=True,bidirectional=True) # batch_first=True是否转化out, hide= rnn(x)  # 返回值 第一个值为输出  第二个值是状态信息print(out.shape) # torch.Size([10, 6, 6])  这里直接合并了双向的隐藏状态
print(hide.shape) # torch.Size([2, 10, 3]) 输出的是正向和反向的隐藏状态

http://www.ppmy.cn/news/1530740.html

相关文章

Springboot的两种配置文件语法详细介绍、properties与yml的区别、application.properties不可以用双引号?

文章目录 一、properties语法介绍二、yaml语法介绍三、总结3.1、properties与yml的区别3.2、properties不可以用双引号? 本篇文章介绍一下springboot两种配置文件properties与yml的区别,以及两种文件的写法 一、properties语法介绍 ‌Properties‌文件…

为什么推荐使用英文版LabVIEW

在LabVIEW开发中,中文版和英文版主要在界面语言、功能习惯以及社区支持等方面存在差异。以下是两者的特点以及推荐使用英文版的原因: 中文版特点: 界面和帮助文档为中文:对于中文母语开发者来说,中文版LabVIEW的界面和…

51单片机快速入门之按键应用拓展

51单片机快速入门之按键应用拓展 LED的点动控制: 循环检测,当key 为0 时 led 亮 反之为熄灭 while(1){ if(key!1) { led0; }else { led1; } } LED的锁定控制: 当按钮按下,led取反值 while(1) { if(key!1) { led!led; } } LED的4路抢答控制: bz默认为0 !bz 取反值,循环启动…

MySQL Performance Schema 详解及运行时配置优化

引言 MySQL 的 Performance Schema 是一套性能监控与诊断工具,帮助开发者和数据库管理员收集、分析 MySQL 实例的运行状态,找出性能瓶颈并进行优化。通过 Performance Schema,我们能够监控不同的内部事件、线程、会话、语句执行等关键性能指…

note-Redis实战5 核心-构建应用程序组件1

助记提要 使用Redis列表实现自动补全列表实现自动补全的限制使用Redis有序集合实现自动补全锁的异常状态 4种使用SETNX命令实现简单的锁细粒度锁给锁加上超时限制三种信号量的实现和适用条件(基本、公平、加锁) 6章 构建应用程序组件1 构建常用组件:自动补全、分布…

气压高度加误差的两种方法(直接添加 vs 换算到气压误差),附MATLAB程序

在已知高度真实值时,如果需要计算此高度下的气压计误差,可考虑本文所述的两种方法 气压高度 气压与高度之间的关系可以用大气压的垂直变化来描述。随着高度的增加,气压通常会下降。这是因为空气的密度在高度增加时减少,导致上方空气柱对下方空气施加的压力减小。 主要关系…

LLM - 使用 XTuner 指令微调 多模态大语言模型(InternVL2) 教程

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/142528967 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 XTuner…

【C语言】const char*强制类型转换 (type cast)的告警问题

void run_upload(const char *ftp_url) {CircularQueue queue;// 初始化环形队列for (int i = 0; i < QUEUE_SIZE; i++) {queue.items[i].data = malloc(BUFFER_SIZE);if (queue.items[i].data == NULL) {fprintf(stderr, "Failed to allocate memory for queue item %…