Pytorch实现的LSTM、RNN模型结构

一、LSTM模型

import torch
from torch import nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import matplotlib.pyplot as plttorch.manual_seed(1)# Hyper Parameters
EPOCH = 1           # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 64
TIME_STEP = 28      # rnn 时间步数 / 图片高度
INPUT_SIZE = 28     # rnn 每步输入值 / 图片每行像素
LR = 0.01           # learning rate
DOWNLOAD_MNIST = True  # 如果你已经下载好了mnist数据就写上 Fasle# Mnist 手写数字
train_data = dsets.MNIST(root='./mnist/',      # 保存或者提取位置train=True,  # this is training datatransform=transforms.ToTensor(),    # 转换 PIL.Image or numpy.ndarray 成# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间download=DOWNLOAD_MNIST,          # 没下载就下载, 下载了就不用再下了
)# plot one example
# print(train_data.train_data.size())     # (60000, 28, 28)
# print(train_data.train_labels.size())   # (60000)
# plt.imshow(train_data.train_data[0].numpy(), cmap='gray')
# plt.title('%i' % train_data.train_labels[0])
# plt.show()# 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)# 为了节约时间, 我们测试时只测试前2000个
test_data = dsets.MNIST(root='./mnist/', train=False, transform=transforms.ToTensor())
test_x = test_data.test_data.type(torch.FloatTensor)[:2000]/255.   # shape (2000, 28, 28) value in range(0,1)
test_y = test_data.test_labels.numpy()[:2000]    # covert to numpy arrayclass RNN(nn.Module):def __init__(self):super(RNN, self).__init__()self.rnn = nn.LSTM(     # LSTM 效果要比 nn.RNN() 好多了input_size=28,      # 图片每行的数据像素点hidden_size=64,     # rnn hidden unitnum_layers=1,       # 有几层 RNN layersbatch_first=True,   # input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size))self.out = nn.Linear(64, 10)    # 输出层def forward(self, x):# 输入的input为,(batch, time_step, input_size)# x shape (batch, time_step, input_size)# r_out shape (batch, time_step, output_size)# h_n shape (n_layers, batch, hidden_size)   LSTM 有两个 hidden states, h_n 是分线, h_c 是主线# h_c shape (n_layers, batch, hidden_size)r_out, (h_n, h_c) = self.rnn(x, None)   # None 表示 hidden state 会用全0的 state# 选取最后一个时间点的 r_out 输出# 这里 r_out[:, -1, :] 的值也是 h_n 的值out = self.out(r_out[:, -1, :])return outrnn = RNN()
print(rnn)optimizer = torch.optim.Adam(rnn.parameters(), lr=LR)   # optimize all cnn parameters
loss_func = nn.CrossEntropyLoss()                       # the target label is not one-hotted# training and testing
for epoch in range(EPOCH):for step, (b_x, b_y) in enumerate(train_loader):    # gives batch datab_x = b_x.view(-1, 28, 28)                      # reshape x to (batch, time_step, input_size)output = rnn(b_x)                               # rnn outputloss = loss_func(output, b_y)                   # cross entropy lossoptimizer.zero_grad()                           # clear gradients for this training steploss.backward()                                 # backpropagation, compute gradientsoptimizer.step()                                # apply gradientsif step % 50 == 0:test_output = rnn(test_x)                   # (samples, time_step, input_size)pred_y = torch.max(test_output, 1)[1].data.numpy()accuracy = float((pred_y == test_y).astype(int).sum()) / float(test_y.size)print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.2f' % accuracy)# print 10 predictions from test data
test_output = rnn(test_x[:10].view(-1, 28, 28))
pred_y = torch.max(test_output, 1)[1].data.numpy()
print(pred_y, 'prediction number')
print(test_y[:10], 'real number')

上述中,我们对于h_n, h_c全部以0为输入,此时我们也可以修改为随机参数:

import torch
from torch import nnclass RNN(nn.Module):def __init__(self):super(RNN, self).__init__()self.rnn = nn.LSTM(     # LSTM 效果要比 nn.RNN() 好多了input_size=28,      # 图片每行的数据像素点hidden_size=64,     # rnn hidden unitnum_layers=1,       # 有几层 RNN layersbatch_first=True,   # input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size))self.out = nn.Linear(64, 10)    # 输出层def forward(self, x):# 输入的input为,(batch, time_step, input_size)# x shape (batch, time_step, input_size)# r_out shape (batch, time_step, output_size)# h_n shape (n_layers, batch, hidden_size)   LSTM 有两个 hidden states, h_n 是分线, h_c 是主线# h_c shape (n_layers, batch, hidden_size)# 初始化的隐藏元和记忆元,通常它们的维度是一样的# 1个LSTM层,batch_size=x.shape[0], 隐藏层的特征维度64h_0 = torch.randn(1, x.shape[0], 64)c_0 = torch.randn(1, x.shape[0], 64)r_out, (h_n, h_c) = self.rnn(x, (h_0, c_0))   # None 表示 hidden state 会用全0的 state# 选取最后一个时间点的 r_out 输出# 这里 r_out[:, -1, :] 的值也是 h_n 的值out = self.out(r_out[:, -1, :])return outrnn = RNN()
print(rnn)

参数:

class torch.nn.LSTM(*args, **kwargs)
参数有:input_size:x的特征维度hidden_size:隐藏层的特征维度num_layers:lstm隐层的层数,默认为1bias:False则bihbih=0和bhhbhh=0. 默认为Truebatch_first:True则输入输出的数据格式为 (batch, seq, feature)dropout:除最后一层,每一层的输出都进行dropout,默认为: 0bidirectional:True则为双向lstm默认为False

LSTM的另外两个输入是 h0 和 c0,可以理解成网络的初始化参数,用随机数生成即可。

h0(num_layers * num_directions, batch, hidden_size)
c0(num_layers * num_directions, batch, hidden_size)
参数:num_layers:隐藏层数num_directions:如果是单向循环网络,则num_directions=1,双向则num_directions=2batch:输入数据的batchhidden_size:隐藏层神经元个数

注意,如果我们定义的input格式是:

input(batch, seq_len, input_size)
则H和C的格式也是要变的:
h0(batch, num_layers * num_directions,  hidden_size)
c0(batch, num_layers * num_directions,  hidden_size)

LSTM的输出是一个tuple,如下:

output,(ht, ct) = net(input)output: 最后一个状态的隐藏层的神经元输出ht:最后一个状态的隐含层的状态值ct:最后一个状态的隐含层的遗忘门值

output的默认维度是:

output(seq_len, batch, hidden_size * num_directions)
ht(num_layers * num_directions, batch, hidden_size)
ct(num_layers * num_directions, batch, hidden_size)

和input的情况类似,如果我们前面定义的input格式是:

input(batch, seq_len, input_size)
则ht和ct的格式也是要变的:
ht(batc,num_layers * num_directions, h, hidden_size)
ct(batc,num_layers * num_directions, h, hidden_size)

我们使用线性函数进行构建LSTM:

import torch
import torch.nn as nnclass LSTM_v1(nn.Module):def __init__(self, input_sz, hidden_sz):super().__init__()self.input_size = input_szself.hidden_size = hidden_sz# 遗忘门self.f_gate = nn.Linear(self.input_size+self.hidden_size, self.hidden_size)# 输入门self.i_gate = nn.Linear(self.input_size+self.hidden_size, self.hidden_size)# 细胞cellself.c_cell = nn.Linear(self.input_size+self.hidden_size, self.hidden_size)# 输出门self.o_gate = nn.Linear(self.input_size+self.hidden_size, self.hidden_size)self.init_weights()def init_weights(self):passdef forward(self, x, init_states=None):bs, seq_sz, _ = x.size()hidden_seq = []if init_states is None:h_t, c_t = (torch.zeros(bs, self.hidden_size).to(x.device),torch.zeros(bs, self.hidden_size).to(x.device))else:h_t, c_t = init_statesfor t in range(seq_sz):x_t = x[:, t, :]input_t = torch.concat([x_t, h_t], dim=-1)f_t = torch.sigmoid(self.f_gate(input_t))i_t = torch.sigmoid(self.i_gate(input_t))c_t_ = torch.tanh(self.c_cell(input_t))c_t = f_t * c_t + i_t * c_t_o_t = torch.sigmoid(self.o_gate(input_t))h_t = o_t * torch.tanh(c_t)hidden_seq.append(h_t.unsqueeze(0))hidden_seq = torch.cat(hidden_seq, dim=0)hidden_seq = hidden_seq.transpose(0, 1).contiguous()return hidden_seq, (h_t, c_t)

二、RNN

import torch
from torch import nn
import torchvision.datasets as dsets
import torchvision.transforms as transforms
import matplotlib.pyplot as plttorch.manual_seed(1)# Hyper Parameters
EPOCH = 1           # 训练整批数据多少次, 为了节约时间, 我们只训练一次
BATCH_SIZE = 64
TIME_STEP = 28      # rnn 时间步数 / 图片高度
INPUT_SIZE = 28     # rnn 每步输入值 / 图片每行像素
LR = 0.01           # learning rate
DOWNLOAD_MNIST = True  # 如果你已经下载好了mnist数据就写上 Fasle# Mnist 手写数字
train_data = dsets.MNIST(root='./mnist/',      # 保存或者提取位置train=True,  # this is training datatransform=transforms.ToTensor(),    # 转换 PIL.Image or numpy.ndarray 成# torch.FloatTensor (C x H x W), 训练的时候 normalize 成 [0.0, 1.0] 区间download=DOWNLOAD_MNIST,          # 没下载就下载, 下载了就不用再下了
)# plot one example
# print(train_data.train_data.size())     # (60000, 28, 28)
# print(train_data.train_labels.size())   # (60000)
# plt.imshow(train_data.train_data[0].numpy(), cmap='gray')
# plt.title('%i' % train_data.train_labels[0])
# plt.show()# 批训练 50samples, 1 channel, 28x28 (50, 1, 28, 28)
train_loader = torch.utils.data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)# 为了节约时间, 我们测试时只测试前2000个
test_data = dsets.MNIST(root='./mnist/', train=False, transform=transforms.ToTensor())
test_x = test_data.test_data.type(torch.FloatTensor)[:2000]/255.   # shape (2000, 28, 28) value in range(0,1)
test_y = test_data.test_labels.numpy()[:2000]    # covert to numpy arrayclass RNN(nn.Module):def __init__(self):super(RNN, self).__init__()self.rnn = nn.RNN(    input_size=28,      # 图片每行的数据像素点hidden_size=64,     # rnn hidden unitnum_layers=1,       # 有几层 RNN layersbatch_first=True,   # input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size))self.out = nn.Linear(64, 10)    # 输出层def forward(self, x):# 输入的input为,(batch, time_step, input_size)# x shape (batch, time_step, input_size)# r_out shape (batch, time_step, output_size)# h_n shape (n_layers, batch, hidden_size)   LSTM 有两个 hidden states, h_n 是分线, h_c 是主线# h_c shape (n_layers, batch, hidden_size)r_out, h = self.rnn(x, None)   # None 表示 hidden state 会用全0的 state# 选取最后一个时间点的 r_out 输出out = self.out(r_out[:, -1, :])return outrnn = RNN()
print(rnn)optimizer = torch.optim.Adam(rnn.parameters(), lr=LR)   # optimize all cnn parameters
loss_func = nn.CrossEntropyLoss()                       # the target label is not one-hotted# training and testing
for epoch in range(EPOCH):for step, (b_x, b_y) in enumerate(train_loader):    # gives batch datab_x = b_x.view(-1, 28, 28)                      # reshape x to (batch, time_step, input_size)output = rnn(b_x)                               # rnn outputloss = loss_func(output, b_y)                   # cross entropy lossoptimizer.zero_grad()                           # clear gradients for this training steploss.backward()                                 # backpropagation, compute gradientsoptimizer.step()                                # apply gradientsif step % 50 == 0:test_output = rnn(test_x)                   # (samples, time_step, input_size)pred_y = torch.max(test_output, 1)[1].data.numpy()accuracy = float((pred_y == test_y).astype(int).sum()) / float(test_y.size)print('Epoch: ', epoch, '| train loss: %.4f' % loss.data.numpy(), '| test accuracy: %.2f' % accuracy)# print 10 predictions from test data
test_output = rnn(test_x[:10].view(-1, 28, 28))
pred_y = torch.max(test_output, 1)[1].data.numpy()
print(pred_y, 'prediction number')
print(test_y[:10], 'real number')

上述中,我们对于h全部以0为输入,此时我们也可以修改为随机参数:

import torch
from torch import nnclass RNN(nn.Module):def __init__(self):super(RNN, self).__init__()self.rnn = nn.RNN(input_size=28,      # 图片每行的数据像素点hidden_size=64,     # rnn hidden unitnum_layers=1,       # 有几层 RNN layersbatch_first=True,   # input & output 会是以 batch size 为第一维度的特征集 e.g. (batch, time_step, input_size))self.out = nn.Linear(64, 10)    # 输出层def forward(self, x):# 输入的input为,(batch, time_step, input_size)# x shape (batch, time_step, input_size)# r_out shape (batch, time_step, output_size)# h_n shape (n_layers, batch, hidden_size)   LSTM 有两个 hidden states, h_n 是分线, h_c 是主线# h_c shape (n_layers, batch, hidden_size)# 初始化的隐藏元# 1个RNN层,batch_size=x.shape[0], 隐藏层的特征维度64h_0 = torch.randn(1,x.shape[0], 64)r_out, h = self.rnn(x, h_0)   # None 表示 hidden state 会用全0的 state# 选取最后一个时间点的 r_out 输出out = self.out(r_out[:, -1, :])return outrnn = RNN()
print(rnn)

参数:

nn.RNN是PyTorch中的一个循环神经网络模型。它有几个重要的参数:input_size:输入的特征维度大小。
hidden_size:隐藏状态的维度大小。
num_layers:RNN层数。
nonlinearity:非线性激活函数,默认为’tanh’。
bias:是否使用偏置,默认为True。
batch_first:如果为True,则输入的维度为(batch_size, seq_length, input_size),否则为(seq_length, batch_size, input_size)。默认为False。
dropout:如果非零,则在输出之间应用丢弃以进行稀疏连接。
bidirectional:如果为True,则使用双向RNN,默认为False。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/112596.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BMS电池管理系统的蓝牙芯片 国产高性能 低功耗蓝牙Soc芯片PHY6222

电池管理系统是对电池进行监控与控制的系统,将采集的电池信息实时反馈给用户,同时根据采集的信息调节参数,充分发挥电池的性能。但是,前技术中,在管理多个电池时,需要人员现场调试与设置,导致其…

科学家首次为地球“全面体检”;国产光刻机或系误传;推特或将按月收费丨RTE开发者日报 Vol.52

开发者朋友们大家好: 这里是「RTE 开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE (Real Time Engagement) 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

【Linux初阶】信号入门2 | 信号阻塞、捕捉、保存

文章目录 ☀️前言☀️一、信号阻塞🌻1.信号其他相关常见概念🌻2.信号在内核中的表示 ☀️二、信号捕捉(重点)🌻1.用户态 & 内核态🌻2.如何判断进程处于用户态或内核态🌻3.OS接口的访问方法…

uniapp——生成一个签字板

在开发项目中有签名/签字的需求&#xff0c;以下实现&#xff1a; <template><view class"new_file" v-if"showAutograph"><view class"popupBox"><view class"popupTopBox">签字板</view><canvas c…

分布式id的概述与实现

文章目录 前言一、分布式id技术选型二、雪花算法三、在项目中集成雪花算法 前言 随着业务的增长&#xff0c;数据表可能要占用很大的物理存储空间&#xff0c;为了解决该问题&#xff0c;后期使用数据库分片技术。将一个数据库进行拆分&#xff0c;通过数据库中间件连接。如果…

QT-day1

实现华清远见登陆界面 #include "mywnd.h" #include <iostream> #include <QDebug> #include <QPushButton> #include <QLineEdit> #include <QLabel>MyWnd::MyWnd(QWidget *parent): QWidget(parent) {//设置固定窗口大小长400&…

大数据-玩转数据-oracel字符串分割转化为多列

一、建表 create table split_string_test(id integer primary key,test_string varchar2(500) );二、插入测试数据 insert into split_string_test values(1, 10,11,12,13,14,22); insert into split_string_test values(2, 22,23,24); insert into split_string_test valu…

Discuz论坛网站首页窄屏自定义宽度修改教程

discuz论坛管理中心默认有窄屏和宽屏的选择&#xff0c;窄屏默认是960px宽度&#xff0c;很多论坛为了页面美观&#xff0c;基本都是1200px的宽度&#xff0c;如何修改DZ论坛首页窄屏宽度大小的呢&#xff1f;今天飞飞和你们分享。 1、在网站根目录中依次打开文件 /template/de…

功能定义-变道碰撞预警

功能概述 变道碰撞预警(Lane Change Warning)功能包括两个子功能&#xff1a; ——盲区监测(Blind Spot Detection)&#xff0c;其功能表现为实时监测驾驶员视野盲区&#xff0c;并在其盲区内出现其他道路使用者时发出提示或警示信息 ——接近车辆报警(Closing Vehicle Warnin…

GitHub平台 Bookget操作

以bookget为例&#xff0c;熟悉github平台。 https://github.com/deweizhu/bookget 选择该界面中的“Wiki”&#xff0c;右侧边栏中是文章的结构大纲。 下载bookget软件。 依照说明&#xff0c;安装bookget环境。

Docker 网络学习

docker的网络模式 当你开始大规模使用Docker时&#xff0c;你会发现需要了解很多关于网络的知识。Docker作为目前最火的轻量级容器技术&#xff0c;有很多令人称道的功能&#xff0c;如Docker的镜像管理。然而&#xff0c;Docker同样有着很多不完善的地方&#xff0c;网络方面…

科技抗老新突破,香港美容仪品牌内地重磅上市

近年来&#xff0c;新消费时代“颜值经济”的火热促使美容行业市场规模增长迅速&#xff0c;越来越多的人愿意为“美”买单&#xff0c;对美的需求也随之增长&#xff0c;美容行业已经成为成长最快的新锐产业。随着经济和科技的发展&#xff0c;“快捷”也成为了当今社会的时代…