从打包序列中获取每个序列的最后一项 [英] Get each sequence's last item from packed sequence

查看:86
本文介绍了从打包序列中获取每个序列的最后一项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过GRU放入打包和填充的序列,并检索每个序列的最后一项的输出.当然,我不是指 -1 项,而是实际的最后一个未填充的项.我们预先知道序列的长度,因此应该很容易为每个序列提取 length-1 项.

我尝试了以下

 导入火炬从torch.nn.utils.rnn导入pack_padded_sequence,pad_packed_sequence# 数据输入=火炬.张量([[[0.,0.,0.],[1.,0.,1.],[1.,1.,0.],[1.,0.,1.],[1.,0.,1.],[1.,1.,0.]],[[1.,1.,0.],[0.,1.,0.],[0.,0.,0.],[0.,1.,0.],[0.,0.,0.],[0.,0.,0.]],[[0.,0.,0.],[1.,0.,0.],[1.,1.,1.],[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]],[[1.,1.,0.],[0.,0.,0.],[0.,0.,0.],[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]]])长度= [6、4、3、1]p = pack_padded_sequence(输入,长度,batch_first =真)# 向前gru = torch.nn.GRU(3,12,batch_first = True)包装输出,gru_h = gru(p)#打开包装输出,input_sizes = pad_packed_sequence(packed_output,batch_first = True)last_seq_idxs = torch.LongTensor([x-1 for x in input_sizes]last_seq_items = torch.index_select(输出,1,last_seq_idxs)打印(last_seq_items.size())#torch.Size([4,4,12]) 

但是形状不是我期望的.我曾期望得到 4x12 ,即每个单独序列的x的最后一项x隐藏.

我可以遍历整个过程,并构建一个包含我所需项目的新张量,但是我希望采用一种内置方法,该方法可以利用一些智能数学.我担心手动循环和构建会导致性能很差.

解决方案

代替最后两个操作 last_seq_idxs last_seq_items ,您只需执行 last_seq_items = output [torch.arange(4),input_sizes-1] .

我不认为 index_select 做正确的事.它将根据您传递的索引选择整个批次,因此您的输出大小为[4,4,12].

I am trying to put a packed and padded sequence through a GRU, and retrieve the output of the last item of each sequence. Of course I don't mean the -1 item, but the actual last, not-padded item. We know the lengths of the sequences in advance, so it should be as easy as to extract for each sequence the length-1 item.

I tried the following

import torch
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence

# Data
input = torch.Tensor([[[0., 0., 0.],
                       [1., 0., 1.],
                       [1., 1., 0.],
                       [1., 0., 1.],
                       [1., 0., 1.],
                       [1., 1., 0.]],

                      [[1., 1., 0.],
                       [0., 1., 0.],
                       [0., 0., 0.],
                       [0., 1., 0.],
                       [0., 0., 0.],
                       [0., 0., 0.]],

                      [[0., 0., 0.],
                       [1., 0., 0.],
                       [1., 1., 1.],
                       [0., 0., 0.],
                       [0., 0., 0.],
                       [0., 0., 0.]],

                      [[1., 1., 0.],
                       [0., 0., 0.],
                       [0., 0., 0.],
                       [0., 0., 0.],
                       [0., 0., 0.],
                       [0., 0., 0.]]])

lengths = [6, 4, 3, 1]
p = pack_padded_sequence(input, lengths, batch_first=True)

# Forward
gru = torch.nn.GRU(3, 12, batch_first=True)
packed_output, gru_h = gru(p)

# Unpack
output, input_sizes = pad_packed_sequence(packed_output, batch_first=True)

last_seq_idxs = torch.LongTensor([x-1 for x in input_sizes])

last_seq_items = torch.index_select(output, 1, last_seq_idxs) 

print(last_seq_items.size())
# torch.Size([4, 4, 12])

But the shape is not what I expect. I had expected to get 4x12, i.e. last item of each individual sequence x hidden.`

I could loop through the whole thing, and build a new tensor containing the items I need, but I was hoping for a built-in approach that took advantage of some smart math. I fear that manually looping and building, will result in very poor performance.

解决方案

Instead of last two operations last_seq_idxs and last_seq_items you could just do last_seq_items=output[torch.arange(4), input_sizes-1].

I don't think index_select is doing the right thing. It will select the whole batch at the index you passed and therefore your output size is [4,4,12].

这篇关于从打包序列中获取每个序列的最后一项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆