PyTorch深度学习(六)【循环神经网络-基础】

2023-09-21 16:03:07

RNN Cell

h0和x1生成h1,把h1作为输出送到下一次的RNN Cell里面。(h1=linear(h0,x1))

RNN计算过程:

输入先做线性变换,循环神经网络常用的激活函数是tanh(±1区间)。

构造RNN Cell:

代码:

import torchbatch_size = 1seq_len = 3input_size = 4hidden_size = 2# Construction of RNNCellcell = torch.nn.RNNCell(input_size=input_size, hidden_size=hidden_size)# Wrapping the sequence into:(seqLen,batchSize,InputSize)dataset = torch.randn(seq_len, batch_size, input_size)  # (3,1,4)    ;  序列数据# Initializing the hidden to zerohidden = torch.zeros(batch_size, hidden_size)  # (1,2)  ;隐层,全0for idx, input in enumerate(dataset):    print('=' * 20, idx, '=' * 20)  #分割线,20个=号    print('Input size:', input.shape)  # (batch_size, input_size)    # 按序列依次输入到cell中,seq_len=3,故循环3次    hidden = cell(input, hidden)  # 返回的hidden是下一次的输入之一,循环使用同一个cell;这一次的输入+上一次的隐层    #隐层维度是batch_size×hidden_size,就是“torch.Size([1,2])”    print('output size:', hidden.shape)  # (batch_size, hidden_size)    print(hidden)

RNN本质是一个线性层。

用RNN首先要把维度搞清楚,数据集的维度多了序列这样一个维度。

每一层都有对应输出。同样颜色的RNN Cell都是一个线性层,也就是说一共只有3个线性层。

代码:

import torchbatch_size = 1    #参数构造seq_len = 3input_size = 4hidden_size = 2num_layers = 1  # RNN层数# Construction of RNNrnn = torch.nn.RNN(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers)# Wrapping the sequence into:(seqLen,batchSize,InputSize)inputs = torch.randn(seq_len, batch_size, input_size)  # (3,1,4)# Initializing the hidden to zerohidden = torch.zeros(num_layers, batch_size, hidden_size)  # (1,1,2),隐层维数output, hidden = rnn(inputs, hidden)  # RNN内部包含了循环,故这里只需把整个序列输入即可print('Output size:', output.shape)  # (seq_len, batch_size, hidden_size)print('Output:', output)print('Hidden size:', hidden.shape)  # (num_layers, batch_size, hidden_size)print('Hidden:', hidden)

预测字符串(RNN Cell):

import torch# 1、确定参数input_size = 4hidden_size = 4batch_size = 1# 2、准备数据index2char = ['e', 'h', 'l', 'o']  #字典x_data = [1, 0, 2, 2, 3]  #用字典中的索引(数字)表示来表示helloy_data = [3, 1, 2, 3, 2]  #标签:ohlolone_hot_lookup = [[1, 0, 0, 0],  # 用来将x_data转换为one-hot向量的参照表                  [0, 1, 0, 0],                  [0, 0, 1, 0],                  [0, 0, 0, 1]]x_one_hot = [one_hot_lookup[x] for x in x_data]  #将x_data转换为one-hot向量inputs = torch.Tensor(x_one_hot).view(-1, batch_size, input_size)  #(𝒔𝒆𝒒𝑳𝒆𝒏,𝒃𝒂𝒕𝒄𝒉𝑺𝒊𝒛𝒆,𝒊𝒏𝒑𝒖𝒕𝑺𝒊𝒛𝒆)labels = torch.LongTensor(y_data).view(-1, 1)  # (seqLen*batchSize,𝟏).计算交叉熵损失时标签不需要我们进行one-hot编码,其内部会自动进行处理# 3、构建模型class Model(torch.nn.Module):    def __init__(self, input_size, hidden_size, batch_size):        super(Model, self).__init__()        self.batch_size = batch_size        self.input_size = input_size        self.hidden_size = hidden_size        self.rnncell = torch.nn.RNNCell(input_size=self.input_size, hidden_size=self.hidden_size)    def forward(self, input, hidden):        hidden = self.rnncell(input, hidden)        return hidden    def init_hidden(self):  #生成初始化隐藏层,需要batch_size。        return torch.zeros(self.batch_size, self.hidden_size)net = Model(input_size, hidden_size, batch_size)# 4、损失和优化器criterion = torch.nn.CrossEntropyLoss()optimizer = torch.optim.Adam(net.parameters(), lr=0.1)  # Adam优化器# 5、训练for epoch in range(15):    loss = 0    optimizer.zero_grad()  #梯度清零    hidden = net.init_hidden()  # 初始化隐藏层    print('Predicted string:', end='')    for input, label in zip(inputs, labels):  #每次输入一个字符,即按序列次序进行循环。(input=seq×b×inputsize)        hidden = net(input, hidden)        loss += criterion(hidden, label)  # 计算损失,不用item(),因为后面还要反向传播        _, idx = hidden.max(dim=1)  # 选取最大值的索引        print(index2char[idx.item()], end='')  # 打印预测的字符    loss.backward()   # 反向传播    optimizer.step()  # 更新参数    print(', Epoch [%d/15] loss: %.4f' % (epoch + 1, loss.item()))

预测字符串(RNN)

import torch# 1、确定参数seq_len = 5input_size = 4hidden_size = 4batch_size = 1# 2、准备数据index2char = ['e', 'h', 'l', 'o']  #字典。将来可以根据索引把字母拿出来x_data = [1, 0, 2, 2, 3]  #用字典中的索引(数字)表示来表示helloy_data = [3, 1, 2, 3, 2]  #标签:ohlolone_hot_lookup = [[1, 0, 0, 0],  # 用来将x_data转换为one-hot向量的参照表                  [0, 1, 0, 0],  # 独热向量                  [0, 0, 1, 0],                  [0, 0, 0, 1]]x_one_hot = [one_hot_lookup[x] for x in x_data]  #将x_data转换为one-hot向量inputs = torch.Tensor(x_one_hot).view(seq_len, batch_size,                                      input_size)  #(𝒔𝒆𝒒𝑳𝒆𝒏,𝒃𝒂𝒕𝒄𝒉𝑺𝒊𝒛𝒆,𝒊𝒏𝒑𝒖𝒕𝑺𝒊𝒛𝒆)labels = torch.LongTensor(y_data)# 3、构建模型class Model(torch.nn.Module):    def __init__(self, input_size, hidden_size, batch_size, num_layers=1):        super(Model, self).__init__()        self.num_layers = num_layers   # 1        self.batch_size = batch_size   # 1        self.input_size = input_size   # 4        self.hidden_size = hidden_size # 4        self.rnn = torch.nn.RNN(input_size=self.input_size, hidden_size=self.hidden_size, num_layers=num_layers)    def forward(self, input):        hidden = torch.zeros(self.num_layers, self.batch_size, self.hidden_size)        out, _ = self.rnn(input, hidden)  # out: tensor of shape (seq_len, batch, hidden_size)        return out.view(-1, self.hidden_size)  # 将输出的三维张量转换为二维张量,(𝒔𝒆𝒒𝑳𝒆𝒏×𝒃𝒂𝒕𝒄𝒉𝑺𝒊𝒛𝒆,𝒉𝒊𝒅𝒅𝒆𝒏𝑺𝒊𝒛𝒆)    def init_hidden(self):  #初始化隐藏层,需要batch_size        return torch.zeros(self.batch_size, self.hidden_size)net = Model(input_size, hidden_size, batch_size)# 4、损失和优化器criterion = torch.nn.CrossEntropyLoss()optimizer = torch.optim.Adam(net.parameters(), lr=0.05)  # Adam优化器# 5、训练步骤for epoch in range(15):    optimizer.zero_grad()    outputs = net(inputs)    loss = criterion(outputs, labels)    loss.backward()    optimizer.step()    _, idx = outputs.max(dim=1)    idx = idx.data.numpy()    print('Predicted string: ', ''.join([index2char[x] for x in idx]), end='')    print(', Epoch [%d/15] loss: %.4f' % (epoch + 1, loss.item()))

使用embedding and linear layer:

import torch# 1、确定参数num_class = 4input_size = 4hidden_size = 8embedding_size = 10num_layers = 2batch_size = 1seq_len = 5# 2、准备数据index2char = ['e', 'h', 'l', 'o']  #字典x_data = [[1, 0, 2, 2, 3]]  # (batch_size, seq_len) 用字典中的索引(数字)表示来表示helloy_data = [3, 1, 2, 3, 2]  #  (batch_size * seq_len) 标签:ohlolinputs = torch.LongTensor(x_data)  # (batch_size, seq_len)labels = torch.LongTensor(y_data)  # (batch_size * seq_len)# 3、构建模型class Model(torch.nn.Module):    def __init__(self):        super(Model, self).__init__()        self.emb = torch.nn.Embedding(num_class, embedding_size)        self.rnn = torch.nn.RNN(input_size=embedding_size, hidden_size=hidden_size, num_layers=num_layers,                                batch_first=True)        self.fc = torch.nn.Linear(hidden_size, num_class)    def forward(self, x):        hidden = torch.zeros(num_layers, x.size(0), hidden_size)  # (num_layers, batch_size, hidden_size)        x = self.emb(x)  # 返回(batch_size, seq_len, embedding_size)        x, _ = self.rnn(x, hidden)  # 返回(batch_size, seq_len, hidden_size)        x = self.fc(x)  # 返回(batch_size, seq_len, num_class)        return x.view(-1, num_class)  # (batch_size * seq_len, num_class)net = Model()# 4、损失和优化器criterion = torch.nn.CrossEntropyLoss()optimizer = torch.optim.Adam(net.parameters(), lr=0.05)  # Adam优化器# 5、训练for epoch in range(15):    optimizer.zero_grad()    outputs = net(inputs)    loss = criterion(outputs, labels)    loss.backward()    optimizer.step()    _, idx = outputs.max(dim=1)    idx = idx.data.numpy()    print('Predicted string: ', ''.join([index2char[x] for x in idx]), end='')    print(', Epoch [%d/15] loss: %.4f' % (epoch + 1, loss.item()))

番外:LSTM

更多推荐

D. Edge Split

Problem-D-Codeforces思路:思路想到了,但是不知道用什么方法写。。首先我们先看只有一个树的情况,那么如果我们所有的边是一个颜色,那么答案是1+n,如果我们将其中的一条边变色,那么产生的答案是2+n-1,答案是不变的,如果有n条边,同样的方式我们如果所有的边为一个颜色,那么产生答案是1+n,但是n条边的

C++,权限修饰符、继承与派生、派生类的构造函数、继承的二义性、基类与派生类的转换

目录一、权限修饰符二、友元三、继承与派生四、派生类的构造函数和析构函数五、继承的二义性(三角形)六、基类与派生类的转换一、权限修饰符public:共有protected:受保护private:私有使用修饰成员(成员变量、成员方法)注意只改变作用域,不改变内存分配修饰成员(成员变量、成员方法)和public:成员在任何位

在线客服系统有哪些?

对于外贸企业来说,存在着客户分布范围广,语言具有差别的情况。所以要想做好客户服务的话,拥有一款功能全面的客服系统就显得非常重要。而一款真正好用,且适用于外贸企业的客服系统应该具备哪些功能呢?小编今天就来聊一聊口碑不错的外贸客服系统要具备哪些功能?1、稳定的系统,保证沟通顺利稳定的客服系统是为了确保客服人员和客户沟通的顺

加强半圆头方颈螺栓的型式尺寸

声明本文是学习github5.com网站的报告而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们1范围本文件规定了加强半圆头方颈螺栓的型式尺寸、技术条件和标记。本文件适用于螺纹规格为M6~M20,产品等级为B级(A型)和C级(B型)的加强半圆头方颈螺栓。2规范性引用文件下列文件中的内容通过文中的规范性

Cpp/Qt-day050921Qt

目录实现使用数据库的登录注册功能头文件:registrwidget.h:widget.h:源文件:registrwidget.c:widget.h:效果图:思维导图实现使用数据库的登录注册功能头文件:registrwidget.h:#ifndefREGISTRWIDGET_H#defineREGISTRWIDGET_H

心理咨询预约微信小程序开发制作步骤

随着互联网的普及和人们对心理健康的重视,越来越多的心理咨询需求在日常生活中涌现。为了满足这一需求,开发一款心理咨询预约微信小程序势在必行。本文将介绍使用乔拓云网这个第三方制作平台来制作这款小程序的具体步骤。1.找一个合适的第三方制作平台/工具乔拓云网是一家提供全方位微信小程序制作工具的平台,具有简单易用的操作界面,丰富

.NET 8 中的 WPF File Dialog 改进

作者:DipeshKumar排版:AlanWang我们很高兴宣布从.NET8Preview7开始,对WPF中的通用文件对话框API进行了一系列新的改进。其中包括迄今为止存储库中投票最多的API建议–允许用户选择文件夹的OpenFolderDialog控件–以及文件对话框上支持新的用户场景的几个新属性,例如单独保存状态、

【AI语言大模型】文心一言功能使用介绍

一、前言文心一言是一个知识增强的大语言模型,基于飞桨深度学习平台和文心知识增强大模型,持续从海量数据和大规模知识中融合学习具备知识增强、检索增强和对话增强的技术特色。最近收到百度旗下产品【文心一言】的产品,抱着试一试的心态体验了一下,整体感觉:还行!二、模块【文心一言】有以下模块:趣味挑战、人物对话、创意写作、职场效率

Python中TensorFlow的长短期记忆神经网络(LSTM)、指数移动平均法预测股票市场和可视化...

原文链接:http://tecdat.cn/?p=23689本文探索Python中的长短期记忆(LSTM)网络,以及如何使用它们来进行股市预测(点击文末“阅读原文”获取完整代码数据)。相关视频在本文中,你将看到如何使用一个被称为长短时记忆的时间序列模型。LSTM模型很强大,特别是在保留长期记忆方面。在本文中,你将解决以

bat写的git命令大全(适合初学者)掌握命令行下的Git操作!

欢迎来到Git!无论你是一位Git初学者,这个在命令大全将帮助你在命令行下熟练运用Git,提高版本控制和团队协作的效率。从基本的仓库管理到分支操作,从提交修改到远程仓库同步,这个命令大全涵盖了Git的各种常用功能和技巧。不论你是初学者还是有经验的用户,都能从中学习到有用的命令和最佳实践,让你成为Git的高手!功能列表:

为什么tomcat要自定义线程池实现?

背景最近在研究tomcat调优的问题,开发人员做过的最多的tomcat调优想必就是线程池调优了,但是tomcat并没有使用jdk自己的线程池实现,而是自定了了线程池,自己实现了ThreadPoolExecutor类位于org.apache.tomcat.util.threads包下jdk线程池首先回顾一下jdk的线程池

热文推荐