반응형
파이토치 rnn계열 sequence length 순환 기능 제공 여부 확인¶
- 기초부터 시작하는 NLP: SEQUENCE TO SEQUENCE 네트워크와 ATTENTION을 이용한 번역 내용을 보면 rnn 계열 모델의 순환구조에 대한 이해를 돕기 위해서 반복문을 사용하여 sequence_length 만큼 반복하여 아래 코드와 유사하게 모델을 통과시키는 것을 확인할 수 있습니다.
for batch in range(inputs.shape[0]):
for i in range(inputs[batch].shape[0]):
emb = embedding_layer(inputs[batch][i]).view(1,1,-1)
out, hidden = rnn(emb)
encoder_outputs[batch][i] = out[0,0]
- 그렇다면, 파라미터가 고정되어 있다는 가정 하에 seqence_length 만큼 순환모델을 통과시키는 결과와 아래 코드와 같이 통으로 통과 시킨 결과가 같은지 확인해 보고자 합니다.
encoder_outputs, _ = rnn(embedding_layer(inputs))
- 위 내용을 확인함으로써
torch.nn.RNN
와torch.nn.GNU
같은 pytorch 모델이 sequence_length 만큼 순환하는 코드를 개발자가 작성하지 않고도 내부적으로 처리할 수 있는 기능을 제공하는지 확인해 보고자 합니다.
In [1]:
# 관련 패키지 불러오기
import torch
import torch.nn as nn
from torch import optim
import torch.nn.functional as F
In [2]:
# 샘플데이터 생성
data = [
("I am a boy", "en"),
("저는 소년 입니다", " kr"),
("je suis un garçon", "fr")
]
In [3]:
# 데이터 토큰
sentences = []
labels = []
for i in range(len(data)):
sentence = data[i][0].split(" ")
sentences.append(sentence)
label = data[i][1]
labels.append(label)
In [18]:
print("sentences : ", sentences)
print("labels : ", labels)
sentences : [['I', 'am', 'a', 'boy'], ['저는', '소년', '입니다'], ['je', 'suis', 'un', 'garçon']] labels : ['en', ' kr', 'fr']
In [4]:
# 데이터 단어 유니크 값 확인
word_unique_list = list(set(sum(sentences, [])))
word_unique_list
Out[4]:
['a', 'I', '입니다', 'je', 'suis', 'un', 'am', 'boy', 'garçon', '소년', '저는']
In [5]:
# PAD 토큰을 포함한 단어 : 아이디 사전 만들기
word2index = {"PAD" : 0}
for num, word in zip(range(1,len(word_unique_list)+1), word_unique_list) :
word2index[word] = num
word2index
Out[5]:
{'PAD': 0, 'a': 1, 'I': 2, '입니다': 3, 'je': 4, 'suis': 5, 'un': 6, 'am': 7, 'boy': 8, 'garçon': 9, '소년': 10, '저는': 11}
In [6]:
# 최대 길이 맞춰 단어 패딩
max_length = 4
for sentence in sentences:
if len(sentence) < 4:
sentence.append('PAD')
sentences
Out[6]:
[['I', 'am', 'a', 'boy'], ['저는', '소년', '입니다', 'PAD'], ['je', 'suis', 'un', 'garçon']]
In [7]:
# 입력 데이터 텐서화
inputs = []
for sentence in sentences:
temp = []
for word in sentence:
temp.append(int(word2index[word]))
inputs.append(temp)
inputs = torch.tensor(inputs, dtype=torch.long)
inputs.shape
Out[7]:
torch.Size([3, 4])
In [8]:
# 배치 1로 고정
single_sentence = inputs[0]
In [9]:
# 관련 모델 정의 및 옵션 설정
vocab_size = len(word_unique_list)
output_size = 5
embedding_layer = nn.Embedding(13, output_size)
rnn = nn.GRU(input_size=5, hidden_size=32, num_layers=1, batch_first=True, bidirectional=False)
In [10]:
# 모델 파라미터 고정
for param in embedding_layer.parameters():
param.requires_grad = False
for param in rnn.parameters():
param.requires_grad = False
- 모델 결과 비교
In [11]:
# sequence_length 만큼 순환하는 모델 적용
encoder_outputs = torch.zeros(3, max_length, 32)
for batch in range(inputs.shape[0]):
for i in range(inputs[batch].shape[0]):
emb = embedding_layer(inputs[batch][i]).view(1,1,-1)
out, hidden = rnn(emb)
encoder_outputs[batch][i] = out[0,0]
In [12]:
# sequence_length 만큼 순환하는 모델 적용 결과 확인
encoder_outputs[0][0]
Out[12]:
tensor([ 0.0390, -0.1059, -0.2329, 0.0356, 0.0297, -0.1409, 0.1175, -0.0255, -0.1435, 0.0184, -0.0961, 0.0751, -0.0521, 0.0929, 0.0295, -0.0822, -0.1798, -0.1138, 0.1014, 0.0627, -0.1150, -0.1708, 0.1628, 0.0409, -0.1561, 0.0297, -0.0221, -0.0290, 0.0052, 0.0945, -0.0934, -0.0288])
In [14]:
# 통으로 입력하는 모델 적용
encoder_outputs, hidden = rnn(embedding_layer(inputs), )
In [15]:
# 통으로 입력하는 모델 결과
encoder_outputs[0][0]
Out[15]:
tensor([ 0.0390, -0.1059, -0.2329, 0.0356, 0.0297, -0.1409, 0.1175, -0.0255, -0.1435, 0.0184, -0.0961, 0.0751, -0.0521, 0.0929, 0.0295, -0.0822, -0.1798, -0.1138, 0.1014, 0.0627, -0.1150, -0.1708, 0.1628, 0.0409, -0.1561, 0.0297, -0.0221, -0.0290, 0.0052, 0.0945, -0.0934, -0.0288])
- [결론] 위 두 모델 적용 결과가 같은 것을 통해 파이토치 순환모델이 seqeunce_length 만큼의 순환기능을 미리 코딩해 두었음을 확인할 수 있으며, seqence_length 만큼 순환하는 코드를 직접 작성하여 통과 시키는 것도 가는한것으로 보아 원하는 만큼만 순환한 결과를 분석에 활용할 수 있음을 알 수 있었습니다.
반응형
'python' 카테고리의 다른 글
파이토치 손실함수 Cross Entropy Loss (0) | 2023.08.29 |
---|---|
while와 iter 메서드를 활용하여 파이토치 데이터 로더 5개의 데이터 까지만 확인해 보는 방법 (0) | 2023.08.28 |
matplotlib을 이용하여 컬럼수가 많을 때 컬러 그래프 만들기 (0) | 2023.08.26 |
ConversionError: Failed to convert value(s) to axis units: (0) | 2023.08.26 |
argparse 복붙용 기본 코드 (0) | 2023.08.20 |
댓글