관리 메뉴

ComputerVision Jack

[골빈해커 Chapter10정리] 본문

DeepLearning/골빈해커 - Tensor Lib

[골빈해커 Chapter10정리]

JackYoon 2020. 1. 21. 16:55
반응형

 

10_번역과 챗봇 모델의 기본 RNN.ipynb
0.03MB

[개념정리]

RNN(Recurrent Neural Network)

자연어 인식의 순환 신경망.

자연어 처리나 음성 인식처럼 순서가 있는 데이터를 처리하는데 강점인 신경망

RNN 기본 개념

셀(Cell)

한 덩어리의 신경망.

 

RNN은 셀을 여러 개 중첩하여 심층 신경망을 만든다.

앞 단계 학습 결과를 다음 단계의 학습에 이용한다.

 

[코드 정리]

MNIST를 RNN으로 처리

learning_rate = 0.001

total_epoch = 30

batch_size = 128

n_input = 28

n_step = 28

n_hidden = 128

n_class = 10

#하이퍼 파라미터를 설정한다.

 

X = tf.placeholder(tf.float32, [None, n_step, n_input])

Y = tf.placeholder(tf.float32, [None, n_class])

#RNN은 순서가 있는 학습법이기 때문에 n_step을 추가한다.

 

W = tf.Variable(tf.random_normal([n_hidden, n_class]))

b = tf.Variable(tf.random_normal([n_class]))

#placeholder를 설정하고, 가중치와 편향을 분류class에 맞게 설정한다.

 

cell = tf.nn.rnn_cell.BasicRNNCell(n_hidden)

#RNN 셀 생성

tensorflow에선 BasicLSTMCell, GRUCell등 다양한 방식의 셀을 사용하는 함수를 제공한다.

 

순서대로 학습단계를 진행하면, 맨뒤는 맨앞의 정보를 잘 기억하지 못한다.

이를 보완하기 위해 LSTM(Long-Short-Term-Memmory) 신경망이 사용된다.

GRU경우 좀더 구조가 간단하다.

 

outputs, states = tf.nn.dynamic_rnn(cell, X, dtype = tf.float32)

#dynamic_rnn을 이용하여 RNN 신경망을 완성한다.

학습을 위해 전단계를 저장하고 다시 불러오는 과정을 실행한다.

 

outputs = tf.transpose(outputs, [1, 0, 2])

outputs = outputs[-1]

#가중치와 행렬 곱연산이 이루어질 수 있도록 Shape을 한번더 수정한다.

 

model = tf.matmul(outputs, W) + b

#모델을 생성한다.

 

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits = model, labels = Y))

optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)

#softmax함수를 사용하기 때문에 cost함수로 설정하고 adam최적화를 사용한다.

 

학습 시키면 결과를 알 수 있다. 손글씨 인식의 정확도가 올라간다.

[단어 자동완성]

char_arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',

            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

num_dic = {n: i for i, n in enumerate(char_arr)}

dic_len = len(num_dic)

 

seq_data = ['word', 'wood', 'deep', 'dive', 'cold', 'cool', 'load', 'love', 'kiss', 'kind']

#학습 데이터를 준비한다. 단어의 리스트에 맞는 인덱스를 data에 맞게 배분한다.

deep 경우 -> [3, 4, 4]이며, 이는 [[0, 0, 0, 1, 00000], [0, 0, 0, 0, 1, 000000], [0, 0, 0, 0, 1, 000000]]이런 식이다.

 

따라서 deep경우 d가 온다면 다음에 e가 오고 다음에 e가 오고 그 다음 p가 올수 있도록 학습시키는 것이다.

변환 함수 적용.

 

learning_rate = 0.01

n_hidden = 128

total_batch = 30

n_step = 3

n_input = n_class = dic_len

#하이퍼 파라미터를 설정한다.

 

cell1 = tf.nn.rnn_cell.BasicLSTMCell(n_hidden)

cell1 = tf.nn.rnn_cell.DropoutWrapper(cell1, output_keep_prob=0.5)

cell2 = tf.nn.rnn_cell.BasicLSTMCell(n_hidden)

#dropout을 적용한 rnn 셀을 2개 생성한다.

 

multi_cell = tf.nn.rnn_cell.MultiRNNCell([cell1, cell2])

outputs, states = tf.nn.dynamic_rnn(multi_cell, X, dtype = tf.float32)

#muti_cell을 이용하여 조합하고, dynamic_rnn함수를 이용하여 deep Rnn을 생성한다.

 

outputs = tf.transpose(outputs, [1, 0, 2])

outputs = outputs[-1]

model = tf.matmul(outputs, W) + b

#최종 출력층을 만든다.

 

학습을 시키면 알파벳에 대한 다음 단어 예측하는 모델이 완성됩니다.

흔히 이런식으로 쳇봇을 구현합니다.

[Sequence to Sequence 기계어 번역에 사용]

이런 식의 RNN 모델은 기계어 번역에도 사용됩니다.

Sequence to Sequence 모델은 입력을 위한 신경망인 인코더와 출력을 위한 신경망인 디코더로 구성한다.

디코더는 인코더가 번역한 결과물을 입력받는다.

디코더가 출력한 결과물을 번역된 결과물과 비교하면서 학습한다.

따라서 디코더에 입력이 시작됨을 알려주는 심볼이 필요하다. 출력 또한 출력이 끝났음을 알려주는 심볼이 필요하다.

 

char_arr = [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', '소녀'],['kiss', '키스'], ['love', '사랑']]\

#앞 예제처럼 원-핫 인코딩 형식으로 유틸 함수를 이용하여 만든다.

 

enc_input = tf.placeholder(tf.float32, [None, None, n_input])

dec_input = tf.placeholder(tf.float32, [None, None, n_input])

targets = tf.placeholder(tf.int64, [None, None])

#인코더와 디코더는 입력값은 shape이 같지만 출력은 차원이 하나가 더 높다.

 

with tf.variable_scope('encode'):

  enc_cell = tf.nn.rnn_cell.BasicRNNCell(n_hidden)

  enc_Cell = tf.nn.rnn_cell.DropoutWrapper(enc_cell, output_keep_prob = 0.5)

 

  outputs , enc_states = tf.nn.dynamic_rnn(enc_cell, enc_input, dtype = tf.float32)

 

with tf.variable_scope('decode'):

  dec_cell = tf.nn.rnn_cell.BasicRNNCell(n_hidden)

  dec_cell = tf.nn.rnn_cell.DropoutWrapper(dec_cell, output_keep_prob = 0.5)

 

  outputs, dec_states = tf.nn.dynamic_rnn(dec_cell, dec_input,

                                          initial_state = enc_states, dtype = tf.float32)

#인코드와 디코드에 관련된 cell을 만든다.

각 셀에 드롭아웃을 적용한다. 디코더는 인코더의 최종출력을 입력값으로 사용한다.

  initial_state = enc_states

 

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))

optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost)

#모델과 비용함수 최적화를 설정하고 학습을 시킨다.

 

print('= = = 번역 테스트 = = =')

print('word - >  ', translate('word'))

 

= = = 번역 테스트 = = =

word - > 단어

#출력결과가 잘나오는 것을 확인 할 수있다. 점점 p가 한글에 맞게 바뀌게 된다.

중간중간 출력값을 확인하면 효율도 높고, 오타가 있어도 잘 번역한다.

반응형

'DeepLearning > 골빈해커 - Tensor Lib' 카테고리의 다른 글

[골빈해커 Chapter12정리]  (0) 2020.01.28
[골빈해커 Chapter11정리]  (0) 2020.01.23
[골빈해커 Chapter9정리]  (0) 2020.01.20
[골빈해커 Chapter8 정리]  (0) 2020.01.19
[골빈해커 Chapter7정리]  (0) 2020.01.17
Comments