이글은 towardsdatascience.com의 내용임. (링크)
Word Level English to Marathi Neural Machine Translation using Encoder-Decoder Model
LSTM을 사용하는 Seq2Seq 모델 구축을 위한 가이드
목차
- Introduction
- Prerequisites
- Encoder — Decoder Architecture
- Encoder LSTM
- Decoder LSTM — Training mode
- Decoder LSTM — Inference mode
- Code Walk through
- Results and Evaluation
- Future Work
- End Notes
1. Introduction
순환 신경망(Recurrent Neural Network, 또는 더 정확하게 LSTM/GRU)은 주어진 대규모의 데이터 문제와 관련된 복잡한 시퀀스(sequence)관련 문제에서 매우 효과적인것으로 알려졌다. 순환 신경망은 음성인식, 자연어처리 문제, 시계열 예측(time series forecasting)등에서 실시간 응용프로그램이 있다.
Seq2Seq(Sequence to Sequence) 모델은 기계번역, 질의응답, 챗봇, 테스특 요악 등과 같은 복잡한 언어관련 문제를 해결하기 위해 일반적으로 사용되는(하지만 제한되지 않는) 순환 신경망 구조의 특수한 분류이다.
Source https://www.analyticsvidhya.com/blog/2018/04/sequence-modelling-an-introduction-with-practical-use-cases/
이 글의 목적은 어떻게 Seq2Seq 모델이 구축되는지에 대한 자세한 설명과 어떻게 이러한 복잡한 작업을 해결할 수 있는지 직관적으로 이해할 수 있도록 한다.
이 글에서는 실행 예제로 기계 번역(English to Marahi)의 문제를 다룬다. 그러나 세부기술은 보통 어떠한 Seq2Seq 문제에도 적용된다.
기계번역을 하기 위해 신경망을 사용하기 때문에 보통 NMT(Neural Machine Translation)으로 불린다.
2. Prerequisites
이 글은 아래와 같은 사전 지식이 필요하다.
- ML(Machine Learning)과 신경망(Neural Networks)분야의 기본적인 개념.
RNN이 언어 모델 구축에 어떻게 사용되는지를 설명하는 글 (The Unreasonable Effectiveness of Recurrent Neural Networks)
LSTMs의 동작 설명 (Understanding LSTM Networks) - 고교수준의 선형대수와 확률
- Python과 Keras로 LSTM 네트워크에 대한 실무 지식
3. Encoder — Decoder Architecture
Seq2Seq 모겔 구측에 사용되는 가장 일반적인 구조는 Encoder Decoder 구조이다. 이 구조는 이 글에서 사용할 것이다. 아래 그림은 이 구조의 매우 고차원적인 표현이다.
Source
주목할 점
- 인코더와 디코도 모두 전형적인 LSTM 모델이다.(또는 때때로 GRU 모델이다.)
- 인코더는 입력 시퀀스를 읽고 내부 상태 벡터(Internal state vector)로 불리우는 것에 정보를 요약한다.(LSTM의 경우 hidden state와 cell state vecotr로 불린다.) 이글에서는 인코더의 출력은 사용하지 않고 단지 내부 상태로만 보존한다.
- 디코더는 초기 상태가 인코더 LSTM의 최종상태로 초기화된 LSTM이다. 이 초기상태를 사용하여 디코더는 출력 시퀀스 생성을 시작한다.
- 디코더는 훈련과 추론 절차동안 약간 다르게 동작한다. 훈련동안에는 더 빨리 디코더를 훈련시키는 teacher forcing을 호출하는 기술을 사용한다. 추론동안에는 각 타임 스탭에서 디코더로의 입력은 이전 타임 스텝으로부터의 출력이다.
- 직관적으로 인코더는 입력 시퀀스를 상태 벡터(state vector, 때때로 Throught vector라고도 불리운다.)로 요약하고 상태벡터가 주어지면 출력 시퀀스를 생성하기 시작하는 디코더로 전달한다.
4. Encoder LSTM
인코더 LSTM의 주요 컴포넌트를 수학적인 접근 없이 개략적으로 살펴보자.
길이가 'K'인 입력 시퀀스를 처리하는 LSTM
LSTM은 다른 것다음에 하나의 시퀀스인 데이터를 읽는다. 따라서 만약 입력이 길이 'k'인 시퀀스라면, LSTM은 입력을 'k'번 읽는다.
위 그림을 참조하면서 아래의 LSTM의 주요 3가지 컴포넌트를 보자.
- $X_i$
: i번째 단계에서 입력 시퀀스 - $h_i$ and $c_i$
: LSTM은 각 단계에서 두가지 상태(h - hidden state, c - cell state)를 유지한다. 함께 묶여진 이 두가지는 i번째 단계에서 LSTM의 내부 상태(internal state)이다. - $Y_i$
: i번째 단계에서 출력 시퀀스
중요 : 기술적으로 이들 컨포넌트($X_i, h_i, c_i, Y_i$)는 실제 부동 소수점 숫자(floating point numbers)의 벡터이다.
이 글에서의 (번역)문제에 이것 모두를 매핑해보자. 이 글의 목적을 위해 아래의 예제를 사용할 것이다.
- 입력 시퀀스(English) : “Rahul is a good boy”
- 출력 시퀀스(Marathi) : “राहुल चांगला मुलगा आहे”
이제 입력 즉, 영어 문장에 집중하자.
$X_i$ 설명 :
문장은 단어 또는 문자의 연속(sequence)으로 보여질 수 있다. 단어의 경우에 대해서 영어 문장은 5단어의 연속으로 볼 수 있다.(‘Rahul’, ‘is’, ‘a’, ‘good’, ‘boy’) 그리고 문자의 경우에서는 19 문자의 연속으로 볼 수 있다.(‘R’, ‘a’, ‘h’, ‘u’, ‘l’, ‘ ‘, ……, ‘y’)
실제 어플리케이션에서 더 일반적인 단어로 문장을 나눌 것이다. 따라서 'Word Level NMT'이다. 위 그림을 참조하면 아래와 같은 입력을 얻을 수 있다.
$X_1 = \text{'Rahul'}, X_2 = \text{'is'}, X_3 = \text{'a'}, X_4 = \text{'good'}$, $X_5 = \text{'boy'}$
LSTM은 이 문장을 단어별로 아래처럼 5번 읽는다.
Encoder LSTM
하지만 어떻게 각 $X_i$(각 단어)를 벡터로 표현할지를 결정해야한다.
(Embeded) 단어를 고정길이 벡터로 변환하는 다양한 word embedding 기술이 있다. 이 글에서는 각 단어를 고정길이 벡터로 변환하기 위해 Keras API의 built-in Embedding layer를 사용한다.
$h_i$와 $c_i$ 설명 :
다음은 각 단계에서 내부 상태($h_i$와 $c_i$)의 역할을 결정해야 한다.
간단하게 LSTM이 지금까지 읽은(학습한)것을 기억한다. 예를 들면 다음과 같다.
$h_3, c_3$ : 이 두 벡터는 네트워크가 지금까지 'Rahul is a'를 읽은 것을 기억할 것이다. 기본적으로 벡터 $h_3$과 $c_3$에 저장된 3번째 단계까지 정보의 요약이다.(따라서 3단계에서 상태라고 불린다.)
$Y_i$ 설명
$Y_i$는 각 단계에서 LSTM 모델의 (예측) 출력이다.
하지만 $Y_i$ 벡터의 타입은 무엇일까? 더 구체적으로 단어 레벨의 언어 모델의 경우에는 각 $Y_i$는 softmax 활성화를 사용하여 생성된 전체 사전(vocabulary)에 대한 실제 확률 분포이다. 따라서 각 $Y_i$는 확률 분포를 나타내는 'vocab_size' 크기의 벡터이다.
문제의 맥락에 따라 때때로 사용되거나 폐기된다.
이 글의 경우에는 전체 영어 문장을 읽지 않는 한 아무것도 출력하지 않는다. 전체 영여 문장을 읽고 출력 문장(동일한 마라티어 문장)을 생성하기 때문이다. 따라서 이 글에서는 인코더의 $Y_i$는 사용하지 않는다.
인코더 요약
입력 문장(영어 문장)을 단어별로 읽고 마지막 단계 $h_k, c_k$(문장이 k개의 단어라고 가정하면)이후 생성된 LSTM 네트워크의 내부 상태를 보존한다. 이들 벡터(상태 $h_k, c_k$)는 전체 입력을 벡터 형태로 인코딩(요약)하기 때문에 입력 문장의 인코딩으로 불린다. 전체 문장을 읽은 후 출력을 생성하기 때문에 각 단계에서 인토더의 출력($Y_i$)은 폐기된다.
게다가 $X_i, h_i, c_i, Y_i$가 어떤 벡터 타입인지 이해햐야 한다. 그것은 각각의 크기(모양)이며 나타내는 것이다.
5. Decoder LSTM — Training mode
훈련 단계와 추론 단계 모두에서 동일한 역할을 하는 인코더 LSTM과는 다르게 디코더 LSTM은 이 두 단계에서 약간 다른 역할을 수행한다.
우선 훈련 단계에서 디코더를 어떻게 설정하는지를 이해하고 이후 추론 단계에서 어떻게 이를 사용하는지를 이해해 본다.
입력 문장인 “Rahul is a good boy”에서 훈련 절차의 목표는 디코더가 “राहुल चांगला मुलगा आहे”를 출력하도록 훈련(가르치는)것이다. 단지 인코더가 입력 문장을 단어별로 훑어보는 것처럼 유사하게 디코더도 단어별로 출력 문장을 생성한다.
몇가지 기술적 이유로 아래와 같이 출력 문장에 두개의 토큰을 추가한다.
Output sequence => “START_ राहुल चांगला मुलगा आहे _END”
이제 아래 그림을 살펴보자.
디코더 LSTM - 훈련 모드
가장 중요한 점은 디코더의 초기 상태($h_0, c_0$)가 인코더의 최종상태로 설정되는 것이다. 이것은 직관적으로 디코더가 인코다가 인코딩한 정보에 기초하여 출력 시퀀스 생성을 시작하기 위해 훈련되는 것을 의미한다. 명확하게 번역된 마라티어 문장은 주어진 영어 문장에 따라야 한다.
첫번째 단계에서 디코다가 다음 토큰(실제 마라티어 문장의 첫번째 단어)생성을 시작하도록 START_ 토큰을 추가했다. 그리고 마라티어 문장의 마지막 단어 다음에 디코더가 _END 토큰 에측을 학습하게 했다. 이는 추론 절차동안 종료 조건으로써 사용된다. 기본적으로 이것은 번역된 문장의 끝을 나타내고 추론 루프를 중지한다.
각 단계에서 입력이 이전 단계로부터의 실제 출력(예측된 출력이 아닌)으로써 주어지는 곳에서 "Teacher Forcing"이라는 기술을 사용한다. 이 기술은 네트워크 훈련을 좀 더 빠르고 효과적으로 만든다.
마지막으로 손실은 각 단계로부터 예측된 출력으로부터 계산되고 오류는 네트워크의 파라미터를 갱신하기 위해 시간(time)을 통해 역전파된다. 충분하게 큰 데이터로 더 긴 주기로 네트워크를 훈련하는 것은 꽤 좋은 예측(번역)을 한다.
아래 그림과 같이 전체 훈련 절차(인코더 + 디코더)요약할 수 있다.
훈련 절차 요약
6. Decoder LSTM — Inference mode
추론을 위한 설정을 이해해 보자. 이미 언급한바와 같이 인코더 LSTM은 입력 시퀀스(영어 문장)는 동일한 역할을 수행하고 사고 벡터(thought vector) $h_k, c_k$를 생성한다.
그러나 디코더는 사고 벡터가 주어지면 전체 출력 시퀀스(마라티어 문장)를 예측해야 한다.
동일한 예제로 시각적으로 이해해보자.
Input sequence => “Rahul is a good boy”
(Expected) Output Sequence => “राहुल चांगला मुलगा आहे”
Step 1 :입력 시퀀스를 사고 벡터로 인코딩
Step 2 :루프에서 단어별로 출력 시퀀스 생성 시작
At t=1
At t=2
At t=3
At t=4
At t=5
추론 알고리즘
- 추론 동안 한번에 한 단어를 생성한다. 따라서 디코더 LSTM은 모든 처리 단계에서 단지 한 단계에서만 루프에서 호출된다.
- 디코더의 초기 상태는 인코더의 최종 상태로 설정된다.
- 디코더의 초기 입력은 항상 START_토큰이다.
- 각 단계에서 디코더의 상태를 보존하고 다음 단계의 초기상태로 설정한다.
- 각 단계에서 예측된 출력은 다음 단계의 입력으로 전달된다.
- 디코더가 END_토큰을 예측하면 루프를 정지한다.
전체 추론 절차는 아래처럼 요약할 수 있다.
7. Code Walk through
실제 코드를 구현했을 때보다 이해하기 더 좋은 것은 없다. 이론을 이해하기 위해 얼마나 많은 노력이 들었는지는 중요하지 않다.(어떠한 이론도 다루지 않는다는 것이 아니라 이론 다음에는 구현이 반드시 따라하한다는 것을 의미한다.)
Dataset:다운로드
- 이 글에서는 mar-eng.zip을 사용한다.
모델 구축 전에 몇가지 데이터 정제(cleaning)와 사전작업이 필요하다. 자세한 설명없이 일반적인 언어 처리 프로젝트의부분인 아래 단계를 이해한다고 가정하고 진행한다.
>> Code to perform Data Cleaning
lines= pd.read_table('mar.txt', names=['eng', 'mar'])
# Lowercase all characters
lines.eng=lines.eng.apply(lambda x: x.lower())
lines.mar=lines.mar.apply(lambda x: x.lower())
# Remove quotes
lines.eng=lines.eng.apply(lambda x: re.sub("'", '', x))
lines.mar=lines.mar.apply(lambda x: re.sub("'", '', x))
exclude = set(string.punctuation) # Set of all special characters
# Remove all the special characters
lines.eng=lines.eng.apply(lambda x: ''.join(ch for ch in x if ch not in exclude))
lines.mar=lines.mar.apply(lambda x: ''.join(ch for ch in x if ch not in exclude))
# Remove all numbers from text
remove_digits = str.maketrans('', '', digits)
lines.eng=lines.eng.apply(lambda x: x.translate(remove_digits))
lines.mar = lines.mar.apply(lambda x: re.sub("[२३०८१५७९४६]", "", x))
# Remove extra spaces
lines.eng=lines.eng.apply(lambda x: x.strip())
lines.mar=lines.mar.apply(lambda x: x.strip())
lines.eng=lines.eng.apply(lambda x: re.sub(" +", " ", x))
lines.mar=lines.mar.apply(lambda x: re.sub(" +", " ", x))
# Add start and end tokens to target sequences
lines.mar = lines.mar.apply(lambda x : 'START_ '+ x + ' _END')
아래에서는 영어와 마라티어 모두에 대한 사전(vocabulary)과 사전 크기(size) 그리고 최대 시퀀스 길이를 구한다. 마지막으로 주어진 토큰을 정수 인덱스로 번환하거나 그 반대의 작업을 하기 위한 언어당 2개씩 총 4개의 파이썬 사전(dictionary)를 만든다.
Code for Data Preparation
# Vocabulary of English
all_eng_words=set()
for eng in lines.eng:
for word in eng.split():
if word not in all_eng_words:
all_eng_words.add(word)
# Vocabulary of French
all_marathi_words=set()
for mar in lines.mar:
for word in mar.split():
if word not in all_marathi_words:
all_marathi_words.add(word)
# Max Length of source sequence
lenght_list=[]
for l in lines.eng:
lenght_list.append(len(l.split(' ')))
max_length_src = np.max(lenght_list)
# Max Length of target sequence
lenght_list=[]
for l in lines.mar:
lenght_list.append(len(l.split(' ')))
max_length_tar = np.max(lenght_list)
input_words = sorted(list(all_eng_words))
target_words = sorted(list(all_marathi_words))
# Calculate Vocab size for both source and target
num_encoder_tokens = len(all_eng_words)
num_decoder_tokens = len(all_marathi_words)
num_decoder_tokens += 1 # For zero padding
# Create word to token dictionary for both source and target
input_token_index = dict([(word, i+1) for i, word in enumerate(input_words)])
target_token_index = dict([(word, i+1) for i, word in enumerate(target_words)])
# Create token to word dictionary for both source and target
reverse_input_char_index = dict((i, word) for word, i in input_token_index.items())
reverse_target_char_index = dict((i, word) for word, i in target_token_index.items())
그리고 9:1로 훈련셋과 테스트셋을 나누고 아래와 같이 배치로 데이터를 로드하기 위한 파이썬 제너레이터 함수를 작성한다.
>>Code for loading Batches of Data
def generate_batch(X = X_train, y = y_train, batch_size = 128):
''' Generate a batch of data '''
while True:
for j in range(0, len(X), batch_size):
encoder_input_data = np.zeros((batch_size, max_length_src),dtype='float32')
decoder_input_data = np.zeros((batch_size, max_length_tar),dtype='float32')
decoder_target_data = np.zeros((batch_size, max_length_tar, num_decoder_tokens),dtype='float32')
for i, (input_text, target_text) in enumerate(zip(X[j:j+batch_size], y[j:j+batch_size])):
for t, word in enumerate(input_text.split()):
encoder_input_data[i, t] = input_token_index[word] # encoder input seq
for t, word in enumerate(target_text.split()):
if t < len(target_text.split())-1:
decoder_input_data[i, t] = target_token_index[word] # decoder input seq
if t > 0:
# decoder target sequence (one hot encoded)
# does not include the START_ token
# Offset by one timestep
decoder_target_data[i, t - 1, target_token_index[word]] = 1.
yield([encoder_input_data, decoder_input_data], decoder_target_data)
다음으로 아래와 같이 훈련을 위한 모델을 정의한다.
>>Code to define the Model to be trained
# Encoder
encoder_inputs = Input(shape=(None,))
enc_emb = Embedding(num_encoder_tokens, latent_dim, mask_zero = True)(encoder_inputs)
encoder_lstm = LSTM(latent_dim, return_state=True)
encoder_outputs, state_h, state_c = encoder_lstm(enc_emb)
# We discard `encoder_outputs` and only keep the states.
encoder_states = [state_h, state_c]
# Set up the decoder, using `encoder_states` as initial state.
decoder_inputs = Input(shape=(None,))
dec_emb_layer = Embedding(num_decoder_tokens, latent_dim, mask_zero = True)
dec_emb = dec_emb_layer(decoder_inputs)
# We set up our decoder to return full output sequences,
# and to return internal states as well. We don't use the
# return states in the training model, but we will use them in inference.
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(dec_emb, initial_state=encoder_states)
# Use a softmax to generate a probability distribution over the target vocabulary for each time step
decoder_dense = Dense(num_decoder_tokens, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)
# Define the model that will turn
# `encoder_input_data` & `decoder_input_data` into `decoder_target_data`
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
# Compile the model
model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['acc'])
아래는 케라스의 plot_model로 생성된 모델 구조이다.
Tringing the network
배치크기 128, 50에포크로 네트워크를 훈련한다. (P4000GPU에서 2시간 좀 넘게 걸렸다고 한다.)
Inference Setup:
>>Code for setting up inference
# Encode the input sequence to get the "thought vectors"
encoder_model = Model(encoder_inputs, encoder_states)
# Decoder setup
# Below tensors will hold the states of the previous time step
decoder_state_input_h = Input(shape=(latent_dim,))
decoder_state_input_c = Input(shape=(latent_dim,))
decoder_states_inputs = [decoder_state_input_h, decoder_state_input_c]
# Get the embeddings of the decoder sequence
dec_emb2= dec_emb_layer(decoder_inputs)
# To predict the next word in the sequence, set the initial states to the states from the previous time step
decoder_outputs2, state_h2, state_c2 = decoder_lstm(dec_emb2, initial_state=decoder_states_inputs)
decoder_states2 = [state_h2, state_c2]
# A dense softmax layer to generate prob dist. over the target vocabulary
decoder_outputs2 = decoder_dense(decoder_outputs2)
# Final decoder model
decoder_model = Model(
[decoder_inputs] + decoder_states_inputs,
[decoder_outputs2] + decoder_states2)
마지막으로 아래처럼 루프에서 위의 setup을 호출하여 출력 시퀀스를 생성한다.
>>Code to decode the output sequence in a loop
def decode_sequence(input_seq):
# Encode the input as state vectors.
states_value = encoder_model.predict(input_seq)
# Generate empty target sequence of length 1.
target_seq = np.zeros((1,1))
# Populate the first character of target sequence with the start character.
target_seq[0, 0] = target_token_index['START_']
# Sampling loop for a batch of sequences
# (to simplify, here we assume a batch of size 1).
stop_condition = False
decoded_sentence = ''
while not stop_condition:
output_tokens, h, c = decoder_model.predict([target_seq] + states_value)
# Sample a token
sampled_token_index = np.argmax(output_tokens[0, -1, :])
sampled_char = reverse_target_char_index[sampled_token_index]
decoded_sentence += ' '+sampled_char
# Exit condition: either hit max length or find stop token.
if (sampled_char == '_END' or len(decoded_sentence) > 50):
stop_condition = True
# Update the target sequence (of length 1).
target_seq = np.zeros((1,1))
target_seq[0, 0] = sampled_token_index
# Update states
states_value = [h, c]
return decoded_sentence
8. Results and Evaluation
이 글의 목적은 LSTM을 사용하여 기본적인 seq2seq 모델을 어떻게 구축하는지 직관적으로 설명하는 것으로 언어 번역 품질을 발전시키는 것이 아니다. 따라서 결과가 여러 이유로 세계적인 수준이 아니다. 가장 중요한 이유는 단지 33000쌍의 시퀀스뿐인 매우 작은 데이터셋이다. 지금은 모델이 생성한 몇가지 결과를 살펴보자.
Evaluation on train dataset:
>>Evaluation on Training Dataset
Input English sentence: it is a holiday tomorrow
Actual Marathi Translation: उद्या सुट्टी आहे
Predicted Marathi Translation: उद्या नाताळ आहे
Input English sentence: i will give you this book
Actual Marathi Translation: मी तुम्हाला हे पुस्तक देईन
Predicted Marathi Translation: मी तुला हे पुस्तक तुला दिलं
Input English sentence: this sentence has five words
Actual Marathi Translation: या वाक्यात पाच शब्द आहेत
Predicted Marathi Translation: या पाच शब्द आहेत
Input English sentence: did you clean your room
Actual Marathi Translation: तुझी खोली साफ केलीस का
Predicted Marathi Translation: तुझी खोली साफ केली का
Input English sentence: she wrapped herself in a blanket
Actual Marathi Translation: त्यांनी स्वतःला एका चादरीत गुंडाळून घेतलं
Predicted Marathi Translation: तिने एका छोट्या चादर घातली
Input English sentence: he is still alive
Actual Marathi Translation: तो अजूनही जिवंत आहे
Predicted Marathi Translation: ते अजूनही जिवंत आहेत
Input English sentence: you cant speak french can you
Actual Marathi Translation: तुला फ्रेंच बोलता येत नाही ना
Predicted Marathi Translation: तुला फ्रेंच बोलता येत नाही का नाही माहीत
Evaluation on test dataset:
>>Evaluation on Test Dataset
Input English sentence: my wife isnt beautiful yours is
Actual Marathi Translation: माझी बायको सुंदर नाहीये तुझी आहे
Predicted Marathi Translation: माझी तुझी गर्लफ्रेंड सुंदर आहे भेटलो
Input English sentence: who lives in this house
Actual Marathi Translation: या घरात कोण राहतं
Predicted Marathi Translation: या घरात कोणी असतो
Input English sentence: somethings happened to tom
Actual Marathi Translation: टॉमला काहीतरी झालंय
Predicted Marathi Translation: टॉमला काहीतरी झालं आहे
Input English sentence: the dog jumped over a chair
Actual Marathi Translation: कुत्र्याने खुर्चीवरून उडी मारली
Predicted Marathi Translation: एक कुत्र्याला दरवाजा बंद केला
Input English sentence: i can prove who the murderer is
Actual Marathi Translation: खुनी कोण आहे हे मी सिद्ध करू शकतो
Predicted Marathi Translation: मी जिंकू शकतो हे मला माहीत आहे
Input English sentence: everyone could hear what tom said
Actual Marathi Translation: टॉम जे म्हणाला ते सर्वांना ऐकू येत होतं
Predicted Marathi Translation: टॉमने काय म्हटलं म्हटलं तर खरं
Input English sentence: those are my books
Actual Marathi Translation: ती माझी पुस्तकं आहेत
Predicted Marathi Translation: ती माझी पुस्तकं आहेत
What can we conclude?
비록 결과가 아주 좋지 않지만, 그렇게 나쁘지도 않다. 확실히 임의적으로 생성된 시퀀스의 결과보다 훨씬 좋다. 몇몇 문장에서 예측된 단어가 정확하지 않지만 의미적으로 올바른 단어에 꽤 가깝다는 것을 알수 있다.
또한, 훈련셋에서의 결과가 테스트셋에서의 결과보다 약간 더 좋다는 것이다. 이는 모델이 약간 오버피팅되었을 수도 있다는 것을 나타낸다.
9. Future Work
만약 품질 개선에 흥미가 있다면, 아래의 조치를 시도해 볼 수 있다.
- 데이터를 더 모은다. 최고 품질 번역기는 수백만개의 문장 쌍으로 훈련되었다.
- Attention같은 더 복잡한 모델을 구축한다.
- Dropout과 오버피팅을 완화시키기 위한 다른 정규화 형태의 기술을 사용한다.
- 학습률, 배치크기, 드롭아웃 비율 등 하이퍼파라미터 튜닝을 수행한다. 양방향(bidirectional) 인코드 LSTM을 사용해본다. 멀티 레이어드 LSTMs를 사용해 본다.
- greedy approach 대신 beam search를 사용해 본다.
- 모델 평가에 BLEU score를 사용해 본다.
- 기타 등등