PackedSequence 와 PaddedSequence

https://github.com/deeplearningzerotoall/PyTorch/blob/master/RNN/7-PackedSequence.ipynb

링크: PackedSequence에 대한 PyTorch 공식 문서

이 튜토리얼에서는 RNN / LSTM 계열의 모델에서 sequence batch를 잘 활용할 수 있는 PackedSequencePaddedSequence를 만드는 법을 배워보겠습니다.

PyTorch 라이브러리 안에는 다음 4가지 함수들이 주어집니다.

pad_sequence, pack_sequence, pack_padded_sequence, pad_packed_sequence

하지만 함수 이름만 봐서는 상당히 헷갈릴 수 있기 때문에 다음 그림을 참고하시면 이해하기 편하실 것 같습니다.

예제 데이터

실습을 위해 간단한 예제 데이터를 만들었습니다. 여기서 잘 기억하셔야할 점은 batch size가 5이고, sequence 중 가장 긴 길이는 13라는 것 입니다.

import torch
import numpy as np
from torch.nn.utils.rnn import pad_sequence, pack_sequence, pack_padded_sequence, pad_packed_sequence

# Random word from random word generator
data = ['hello world',
        'midnight',
        'calculation',
        'path',
        'short circuit']

# Make dictionary
char_set = ['<pad>'] + list(set(char for seq in data for char in seq)) # Get all characters and include pad token
char2idx = {char: idx for idx, char in enumerate(char_set)} # Constuct character to index dictionary
print('char_set:', char_set)
print('char_set length:', len(char_set))

>>> char_set: ['<pad>', 'm', 'i', 'd', 'l', 'n', 'r', 't', 's', 'a', 'e', ' ', 'p', 'u', 'c', 'h', 'w', 'o', 'g']
>>> char_set length: 19
# Convert character to index and make list of tensors
X = [torch.LongTensor([char2idx[char] for char in seq]) for seq in data]

# Check converted result
for sequence in X:
    print(sequence)

>>> tensor([15, 10,  4,  4, 17, 11, 16, 17,  6,  4,  3])
>>> tensor([ 1,  2,  3,  5,  2, 18, 15,  7])
>>> tensor([14,  9,  4, 14, 13,  4,  9,  7,  2, 17,  5])
>>> tensor([12,  9,  7, 15])
>>> tensor([ 8, 15, 17,  6,  7, 11, 14,  2,  6, 14, 13,  2,  7])
# Make length tensor (will be used later in 'pack_padded_sequence' function)
lengths = [len(seq) for seq in X]
print('lengths:', lengths)

>>> lengths: [11, 8, 11, 4, 13]

Sequence 데이터의 경우 어떻게 batch로 묶을까요?