- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章解决pytorch rnn 变长输入序列的问题由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
输入数据是长度不固定的序列数据,主要讲解两个部分 。
1、Data.DataLoader的collate_fn用法,以及按batch进行padding数据 。
2、pack_padded_sequence和pad_packed_sequence来处理变长序列 。
Dataloader的collate_fn参数,定义数据处理和合并成batch的方式.
由于pack_padded_sequence用到的tensor必须按照长度从大到小排过序的,所以在Collate_fn中,需要完成两件事,一是把当前batch的样本按照当前batch最大长度进行padding,二是将padding后的数据从大到小进行排序.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
def
pad_tensor(vec, pad):
"""
args:
vec - tensor to pad
pad - the size to pad to
return:
a new tensor padded to 'pad'
"""
return
torch.cat([vec, torch.zeros(pad
-
len
(vec), dtype
=
torch.
float
)], dim
=
0
).data.numpy()
class
Collate:
"""
a variant of callate_fn that pads according to the longest sequence in
a batch of sequences
"""
def
__init__(
self
):
pass
def
_collate(
self
, batch):
"""
args:
batch - list of (tensor, label)
reutrn:
xs - a tensor of all examples in 'batch' before padding like:
'''
[tensor([1,2,3,4]),
tensor([1,2]),
tensor([1,2,3,4,5])]
'''
ys - a LongTensor of all labels in batch like:
'''
[1,0,1]
'''
"""
xs
=
[torch.FloatTensor(v[
0
])
for
v
in
batch]
ys
=
torch.LongTensor([v[
1
]
for
v
in
batch])
# 获得每个样本的序列长度
seq_lengths
=
torch.LongTensor([v
for
v
in
map
(
len
, xs)])
max_len
=
max
([
len
(v)
for
v
in
xs])
# 每个样本都padding到当前batch的最大长度
xs
=
torch.FloatTensor([pad_tensor(v, max_len)
for
v
in
xs])
# 把xs和ys按照序列长度从大到小排序
seq_lengths, perm_idx
=
seq_lengths.sort(
0
, descending
=
True
)
xs
=
xs[perm_idx]
ys
=
ys[perm_idx]
return
xs, seq_lengths, ys
def
__call__(
self
, batch):
return
self
._collate(batch)
|
定义完collate类以后,在DataLoader中直接使用 。
1
|
train_data
=
Data.DataLoader(dataset
=
train_dataset, batch_size
=
32
, num_workers
=
0
, collate_fn
=
Collate())
|
pack_padded_sequence将一个填充过的变长序列压紧。输入参数包括 。
input(Variable)- 被填充过后的变长序列组成的batch data 。
lengths (list[int]) - 变长序列的原始序列长度 。
batch_first (bool,optional) - 如果是True,input的形状应该是(batch_size,seq_len,input_size) 。
返回值:一个PackedSequence对象,可以直接作为rnn,lstm,gru的传入数据.
用法:
1
2
3
|
from
torch.nn.utils.rnn
import
pack_padded_sequence, pad_packed_sequence
# x是填充过后的batch数据,seq_lengths是每个样本的序列长度
packed_input
=
pack_padded_sequence(x, seq_lengths, batch_first
=
True
)
|
定义了一个单向的LSTM模型,因为处理的是变长序列,forward函数传入的值是一个PackedSequence对象,返回值也是一个PackedSequence对象 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class
Model(nn.Module):
def
__init__(
self
, in_size, hid_size, n_layer, drop
=
0.1
, bi
=
False
):
super
(Model,
self
).__init__()
self
.lstm
=
nn.LSTM(input_size
=
in_size,
hidden_size
=
hid_size,
num_layers
=
n_layer,
batch_first
=
True
,
dropout
=
drop,
bidirectional
=
bi)
# 分类类别数目为2
self
.fc
=
nn.Linear(in_features
=
hid_size, out_features
=
2
)
def
forward(
self
, x):
'''
:param x: 变长序列时,x是一个PackedSequence对象
:return: PackedSequence对象
'''
# lstm_out: tensor of shape (batch, seq_len, num_directions * hidden_size)
lstm_out, _
=
self
.lstm(x)
return
lstm_out
model
=
Model()
lstm_out
=
model(packed_input)
|
这个操作和pack_padded_sequence()是相反的,把压紧的序列再填充回来。因为前面提到的LSTM模型传入和返回的都是PackedSequence对象,所以我们如果想要把返回的PackedSequence对象转换回Tensor,就需要用到pad_packed_sequence函数.
参数说明:
sequence (PackedSequence) – 将要被填充的 batch 。
batch_first (bool, optional) – 如果为True,返回的数据的形状为(batch_size,seq_len,input_size) 。
返回值: 一个tuple,包含被填充后的序列,和batch中序列的长度列表.
用法:
1
2
|
# 此处lstm_out是一个PackedSequence对象
output, _
=
pad_packed_sequence(lstm_out)
|
返回的output是一个形状为(batch_size,seq_len,input_size)的tensor.
1、pytorch在自定义dataset时,可以在DataLoader的collate_fn参数中定义对数据的变换,操作以及合成batch的方式.
2、处理变长rnn问题时,通过pack_padded_sequence()将填充的batch数据转换成PackedSequence对象,直接传入rnn模型中。通过pad_packed_sequence()来将rnn模型输出的PackedSequence对象转换回相应的Tensor.
补充:pytorch实现不定长输入的RNN / LSTM / GRU 。
As we all know,RNN循环神经网络(及其改进模型LSTM、GRU)可以处理序列的顺序信息,如人类自然语言。但是在实际场景中,我们常常向模型输入一个批次(batch)的数据,这个批次中的每个序列往往不是等长的.
pytorch提供的模型(nn.RNN,nn.LSTM,nn.GRU)是支持可变长序列的处理的,但条件是传入的数据必须按序列长度排序。本文针对以下两种场景提出解决方法.
1、每个样本只有一个序列:(seq,label),其中seq是一个长度不定的序列。则使用pytorch训练时,我们将按列把一个批次的数据输入网络,seq这一列的形状就是(batch_size, seq_len),经过编码层(如word2vec)之后的形状是(batch_size, seq_len, emb_size).
2、情况1的拓展:每个样本有两个(或多个)序列,如(seq1, seq2, label)。这种样本形式在问答系统、推荐系统多见.
定义ImprovedRnn类。与nn.RNN,nn.LSTM,nn.GRU相比,除了此两点【①forward函数多一个参数lengths表示每个seq的长度】【②初始化函数(__init__)第一个参数module必须指定三者之一】外,使用方法完全相同.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
torch
from
torch
import
nn
class
ImprovedRnn(nn.Module):
def
__init__(
self
, module,
*
args,
*
*
kwargs):
assert
module
in
(nn.RNN, nn.LSTM, nn.GRU)
super
().__init__()
self
.module
=
module(
*
args,
*
*
kwargs)
def
forward(
self
,
input
, lengths):
# input shape(batch_size, seq_len, input_size)
if
not
hasattr
(
self
,
'_flattened'
):
self
.module.flatten_parameters()
setattr
(
self
,
'_flattened'
,
True
)
max_len
=
input
.shape[
1
]
# enforce_sorted=False则自动按lengths排序,并且返回值package.unsorted_indices可用于恢复原顺序
package
=
nn.utils.rnn.pack_padded_sequence(
input
, lengths.cpu(), batch_first
=
self
.module.batch_first, enforce_sorted
=
False
)
result, hidden
=
self
.module(package)
# total_length参数一般不需要,因为lengths列表中一般含最大值。但分布式训练时是将一个batch切分了,故一定要有!
result, lens
=
nn.utils.rnn.pad_packed_sequence(result, batch_first
=
self
.module.batch_first, total_length
=
max_len)
return
result[package.unsorted_indices], hidden
# output shape(batch_size, seq_len, rnn_hidden_size)
|
使用示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class
TestNet(nn.Module):
def
__init__(
self
, word_emb, gru_in, gru_out):
super
().__init__()
self
.encode
=
nn.Embedding.from_pretrained(torch.Tensor(word_emb))
self
.rnn
=
ImprovedRnn(nn.RNN, input_size
=
gru_in, hidden_size
=
gru_out,
batch_first
=
True
, bidirectional
=
True
)
def
forward(
self
, seq1, seq1_lengths, seq2, seq2_lengths):
seq1_emb
=
self
.encode(seq1)
seq2_emb
=
self
.encode(seq2)
rnn1, hn
=
self
.rnn(seq1_emb, seq1_lengths)
rnn2, hn
=
self
.rnn(seq2_emb, seq2_lengths)
"""
此处略去rnn1和rnn2的后续计算,当前网络最后计算结果记为prediction
"""
return
prediction
|
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.
原文链接:https://blog.csdn.net/u011550545/article/details/89529977 。
最后此篇关于解决pytorch rnn 变长输入序列的问题的文章就讲到这里了,如果你想了解更多关于解决pytorch rnn 变长输入序列的问题的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我使用 tensorflow 实现了一个简单的 RNN 模型来学习时间序列数据的可能趋势并预测 future 值。然而,该模型总是在训练后产生相同的值。实际上,它得到的最佳模型是: y = b. RN
我正在关注this tutorial关于循环神经网络。 这是导入: import tensorflow as tf from tensorflow.examples.tutorials.mnist i
一段时间以来,我一直在苦思冥想,无法弄清楚我在实现这些 RNN 时做错了什么(如果有的话)。为了让你们省去前向阶段,我可以告诉你们这两个实现计算相同的输出,所以前向阶段是正确的。问题出在倒退阶段。 这
我正在用 RNN 练习。我随机创建 5 个整数。如果第一个整数是奇数,则 y 值为 1,否则 y 为 0(因此,只有第一个 x 有效)。问题是,当我运行这个模型时,它不会“学习”:val_loss 和
我正在使用 bidirectional_rnn与 GRUCell但这是一个关于 Tensorflow 中 RNN 的普遍问题。 我找不到如何初始化权重矩阵(输入到隐藏,隐藏到隐藏)。它们是随机初始化的
我正在尝试找出适应开放命名实体识别问题的最佳模型(生物学/化学,因此不存在实体字典,但必须通过上下文来识别它们)。 目前我最好的猜测是调整 Syntaxnet,这样它就不会将单词标记为 N、V、ADJ
我正在通过以下方式训练 RNN: def create_rnn_model(stateful,length): model = Sequential() model.add(Simpl
我对 PyTorch 非常陌生,而且对一般神经网络也相当陌生。 我试图构建一个可以猜测性别名字的神经网络,并且基于判断国籍的 PyTorch RNN 教程。 我的代码运行没有错误,但损失几乎没有变化,
我正在尝试训练一个模型,返回单词序列(RNN)的类。 我为我的模型提供一系列嵌入: [ batchSize, sequence_length, word_embedding ] as float[]
我正在尝试预测输入向量中每个数字的类别。有3个类(class)。如果输入值从 0 变为 1,则为 1 类。如果从 1 变为 0,则为 2 类。否则为 0 类。 在第二个纪元之后,精度停留在 0.882
我正在尝试为我的日志分析项目开发一个顺序 RNN。 输入是一个日志序列,例如 [1,2,3,4,5,6,1,5,2,7,8,2,1] 目前我正在使用 keras 库中的 to_categorical
为了加深我对 RNN 和 LSTM 的理解,我正在尝试实现一个简单的 LSTM 来估计正弦波的频率和相位。事实证明,这出奇地难以收敛。 MSE 相当高(以千为单位)唯一似乎有点工作的是,如果我生成所有
请帮助我编写以下代码,当我尝试直接在数据上拟合模型时,该代码运行良好,但在网格搜索上失败(我已注释掉直接 model.fit()我的 grid.fit() 语句末尾的部分,这给了我满意的结果。还请告诉
前提1: 关于 RNN 层中的神经元 - 我的理解是,在“每个时间步,每个神经元都接收输入向量 x (t) 和前一个时间步的输出向量 y (t –1)”[1]: 前提2: 据我了解,在 Pytorch
我想训练一个 RNN 来解决一个简单的回归问题。我有一个形状为 (35584,) 的数组 X_train,它表示几年来每小时的测量值。我还有相应的 Y_train 形状为 (35584,) 作为预期值
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 4 年前。 Improve this qu
pytorch实现变长输入的rnn分类 输入数据是长度不固定的序列数据,主要讲解两个部分 1、Data.DataLoader的collate_fn用法,以及按batch进行padding数据
基于循环神经网络(RNN)的古诗生成器,具体内容如下 之前在手机百度上看到有个“为你写诗”功能,能够随机生成古诗,当时感觉很酷炫= = 在学习了深度学习后,了解了一下原理,打算自己做个实现练练手
使用循环神经网络(RNN)实现影评情感分类 作为对循环神经网络的实践,我用循环神经网络做了个影评情感的分类,即判断影评的感情色彩是正面的,还是负面的。 选择使用RNN来做情感分类,主要是因为影评
我的目标是在 Keras/TensorFlow 中构建一个 RNN,它由循环单元层(GRU、LSTM 等)以及从网络底部到顶部的循环组成,以添加注意力机制或特殊的内存类型。我不熟悉符号循环,所以首先我
我是一名优秀的程序员,十分优秀!