입력을 처리하기 위한 인코더(Encoder)와 출력을 위한 디코더(Decoder)가 연결되는 구조
GNMT
인코더는 차례로 입력된 문장들의 모든 단어를 압축하여 컨텍스트 벡터를 생성
컨텍스트 벡터는 차례로 입력된 문장의 모든 단어의 정보를 압축한 벡터이며 잠재 벡터(Latent Vector) 라고도 한다.
디코더는 입력된 컨텍스트 벡터를 이용하여 출력 시퀀스를 생성하고 출력
실습 - Seq2Seq를 이용한 영-한 번역기
# 모델 구축
# 입력값 토큰화, 임베딩
# 훈련을 정의하고 학습
# 평가
# 예측하기 위한 데이터를 토큰화, 임베딩후 predict
# 라벨 출력
from tensorflow.keras import Model, layers
# 입력 단어는 4글자 영단어, 전체문자수는 171개(SEP 포함)
enc_input = layers.Input(shape=(4, 171))
_, state_h, state_c = layers.LSTM(128, return_state=True)(enc_input)
dec_input = layers.Input(shape=(3, 171)) # 한글 단어 2자와 start 토큰 1개
lstm_out = layers.LSTM(128, return_sequences=True)(dec_input, initial_state=[state_h, state_c])
dec_output = layers.Dense(171, activation='softmax')(lstm_out)
model = Model(inputs=[enc_input, dec_input], outputs=dec_output)
model.summary()
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam') # metrics가 없으면 훈련시 loss만 출력됨
# 문자배열 생성
import pandas as pd
import numpy as np
# <START>, <END>, <PAD>
arr1 = [c for c in 'SEPabcdefghijklmnopqrstuvwxyz']
arr2 = pd.read_csv('./data/korean.csv', header=None)
# print(arr2[0].values.tolist())
num_to_char = arr1 + arr2[0].values.tolist()
print(len(num_to_char))
char_to_num = {char:i for i, char in enumerate(num_to_char)}
# print(char_to_num)
171
# 학습용 단어셋 불러오기
raw = pd.read_csv('./data/translate.csv', header=None)
eng_kor = raw.values.tolist()
print(len(eng_kor)) # 학습할 전체 단어 수 110개
110
# 단어를 숫자 배열로 변환
temp_eng = 'love'
temp_eng_n = [char_to_num[c] for c in temp_eng]
print(temp_eng_n)
np.eye(171)[temp_eng_n].shape
[14, 17, 24, 7]
(4, 171)
# 단어를 원-핫 인코딩된 배열로 변환
def encode(eng_kor):
enc_in = []
dec_in = []
rnn_out = [] # decoder output
for seq in eng_kor:
eng = [char_to_num[c] for c in seq[0]]
enc_in.append(np.eye(171)[eng])
kor = [char_to_num[c] for c in ('S'+seq[1])]
dec_in.append(np.eye(171)[kor])
target = [char_to_num[c] for c in (seq[1] + 'E')]
rnn_out.append(target)
enc_in = np.array(enc_in)
dec_in = np.array(dec_in)
rnn_out = np.array(rnn_out)
rnn_out = np.expand_dims(rnn_out, axis=2)
return enc_in, dec_in, rnn_out
for i in range(len(choose)):
eng = choose[i][0]
word = np.argmax(pred[i], axis=-1)
kor = ''
for j in range(2):
kor = kor + num_to_char[word[j]]
print(eng, kor)