노트/Python : 프로그래밍
[신경망] RNN을 이용한 단어 번역 알고리즘 코드
Diane_
2020. 5. 1. 16:06
단어 정의
"""
S : 인코딩 입력의 시작
E : 디코딩 출력의 끝
P : 현재 배치되는 데이터의 time step 크기보다 작은 경우 빈 시퀀스를 채우는 심볼
배치 데이터의 최대 크기 4 인경우,
word = > ['w','o','r','d']
to => ['t','o','P','P']
"""
char_arr=[c for c in "SEPabcdefghijklmnopqrstuvwxyz단어나무놀이소녀키스사랑"]
num_dic={n:i for i, n in enumerate(char_arr)}
dic_len=len(num_dic)
seq_data=[['word','단어'], ['wood','나무'],
['game','놀이'], ['girl','소녀'],
['love','사랑'], ['kiss','키스']]
단어 매칭 함수 정의
def make_batch(seq_data):#[['word', '단어']]
input_batch=[]
output_batch=[]
target_batch=[]
for seq in seq_data: #['word', '단어']
inputdata=[num_dic[n] for n in seq[0]] # word -> [25, 17, 20, 6]
#print(input)
outputdata=[num_dic[n] for n in ('S'+seq[1])]
targetdata=[num_dic[n] for n in (seq[1]+'E')]
input_batch.append(np.eye(dic_len)[inputdata])
output_batch.append(np.eye(dic_len)[outputdata])
target_batch.append(targetdata) #출력값만 원핫이 아님(sparse_사용)
return input_batch,output_batch,target_batch
input_batch,output_batch,target_batch=make_batch(seq_data)
tf.reset_default_graph()
# 모델 옵션 설정
lr = 0.01
n_hidden = 128
total_epoch = 100
n_class = n_input = dic_len
신경망 구성
# 신경망 구성 [배치사이즈, 단계, 입력크기 ]
encInput = tf.placeholder(tf.float32, [None, None, n_input ])
decInput = tf.placeholder(tf.float32, [None, None, n_input ])
targets = tf.placeholder(tf.int64, [None, None])
# 인코더 셀을 구성
enc_cell = tf.nn.rnn_cell.BasicRNNCell(n_hidden,reuse=tf.AUTO_REUSE)
enc_cell = tf.nn.rnn_cell.DropoutWrapper(enc_cell, output_keep_prob=0.5)
outputs, enc_states = tf.nn.dynamic_rnn(enc_cell, encInput, dtype=tf.float32 )
# 디코더 셀을 구성
dec_cell = tf.nn.rnn_cell.BasicRNNCell(n_hidden, reuse=tf.AUTO_REUSE)
dec_cell = tf.nn.rnn_cell.DropoutWrapper(dec_cell, output_keep_prob=0.5)
outputs, dec_states= tf.nn.dynamic_rnn(dec_cell, decInput, initial_state = enc_states, dtype=tf.float32)
모델 학습
model = tf.layers.dense(outputs, n_class, activation=None)
cost = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=model, labels=targets))
opt = tf.train.AdamOptimizer(lr).minimize(cost)
# 신경망 모델 학습
sess=tf.Session()
sess.run(tf.global_variables_initializer())
input_batch, output_batch, target_batch = make_batch(seq_data)
for epoch in range(total_epoch):
_,cv=sess.run([opt, cost], feed_dict = {encInput: input_batch,
decInput: output_batch,
targets: target_batch})
print(" epoch: ","%04d" %(epoch+1), "cost: ","{:.5f}".format(cv))
번역 결과
def translate(w):
seq_data = [w, "P"*len(w)]
#seq_data = ['love', 'PPPP']
input_batch, output_batch, target_batch = make_batch([seq_data])
# input_batch = ['w','o','r','d']
# output_batch = ['P','P','P','P']
# target_batch = [2,2,2,2]
# 결과 : [배치사이즈, 스텝, 입력 ]
# 2번째 차원인 입력차원을 argmax로 적용 -> 확률이 가장 높은 글자가 예측
prediction = tf.argmax(model,2)
#[[[0 0 0 0.9 ..... 0.1]]]
res=sess.run(prediction, feed_dict={
encInput:input_batch,
decInput:output_batch,
targets:target_batch
}) # 숫자 인덱스가 저장되어 있음
decoded = [char_arr[i] for i in res[0]]
end=decoded.index("E")
translated="".join(decoded[:end])
return translated
print("word?", translate('word'))
print("wodr?", translate('wodr'))
print("love?", translate('love'))
print("loev?", translate('loev'))
print("like?", translate('like'))
>>>
word? 단어
wodr? 나무
love? 사랑
loev? 사랑
like? 사랑