티스토리 뷰
RNN-Hi Hello¶
RNN에게 hi hello라는 단어를 훈련시켜 보겠다.
한 문자를 주면 그 다음 문자를 예측하도록 할 수 있도록 학습 시켜보겠다.
간단해 보이지만 어떤 h를 훈련시켰을 때는 i가 나와야 하고 같은 h 이지만 어떤 h는 e가 나온다는 사실이다.
그래서 일반적인 forward net으로는 쉽지 않다. 이전의 문자를 알아야 값을 잘 출력 하도록 해주는 RNN이 효과적이다.
rnn 자체가 어려운건 아닌데 rnn에 넣을 문자들을 가공하는 것이 복잡하게 느껴질 수 있다.
텍스트를 유니크한 문자만 구하고, 각 문자들에 숫자를 매긴다.
이렇게 문자를 숫자와 대응시키고 나면 원핫인코딩을 이용해 표현할 수 있다.
입력의 디멘션은 5이다.
sequence 길이는 6이다.
출력(hidden)의 디멘션도 5이다.
문자열은 하나밖에 없으므로 배치는 1이다.
RNN을 구성해보자.¶
1. Data creation¶
In [1]:
import tensorflow as tf
import numpy as np
tf.set_random_seed(777)
In [2]:
idx2char = ['h', 'i', 'e', 'l', 'o']
# Teach hello: hihell -> ihello
x_data = [[0, 1, 0, 2, 3, 3]] # hihell
x_one_hot = [[[1, 0, 0, 0, 0], # h 0
[0, 1, 0, 0, 0], # i 1
[1, 0, 0, 0, 0], # h 0
[0, 0, 1, 0, 0], # e 2
[0, 0, 0, 1, 0], # l 3
[0, 0, 0, 0, 1]]]# l 3
y_data = [[1, 0, 2, 3, 3, 4]] # ihello
num_classes = 5
input_dim = 5 # one-hot size
hidden_size = 5 # output from the LSTM. 5 to directly predict one-hot
batch_size = 1 # one sentence
sequence_length = 6 # |ihello| == 6
learning_rate = 0.1
2. Feed to RNN¶
In [3]:
X = tf.placeholder(
tf.float32, [None, sequence_length, input_dim]) # X one-hot
Y = tf.placeholder(tf.int32, [None, sequence_length])# Y label
cell = tf.contrib.rnn.BasicLSTMCell(num_units=hidden_size, state_is_tuple=True)
initial_state = cell.zero_state(batch_size, tf.float32)
outputs, _states = tf.nn.dynamic_rnn(
cell, X, initial_state=initial_state, dtype=tf.float32)
3. Cost:sequence_loss¶
[In]
# [batch_size, sequence_length]
y_data = tf.constant([[1, 1, 1]])
# [batch_size, sequence_length, emb_dim]
prediction = tf.constant([[[0.2, 0.7], [0.6, 0.2], [0.2, 0.9]]], dtype=tf.float32)
# [batch_size * sequence_lenghth]
weights = tf.constant([[1, 1, 1]], dtype=tf.float32)
sequence_loss = tf.contrib.seq2seq.sequence_loss(logits=prediction, targets=y_data, weights=weights)
sess.run(tf.global_variables_initializer())
print("Loss: ", sequence_loss.eval())
[Out]
Loss: 0.596759
[In]
# [batch_size, sequence_length]
y_data = tf.constant([[1, 1, 1]])
# [batch_size, sequence_length, emb_dim]
prediction1 = tf.constant([[[0.3, 0.7], [0.3, 0.7], [0.3, 0.7]]], dtype=tf.float32)
prediction2 = tf.constant([[[0.1, 0.9], [0.1, 0.9], [0.1, 0.9]]], dtype=tf.float32)
# [batch_size * sequence_lenghth]
weights = tf.constant([[1, 1, 1]], dtype=tf.float32)
sequence_loss1 = tf.contrib.seq2seq.sequence_loss(logits=prediction1, targets=y_data, weights=weights)
sequence_loss2 = tf.contrib.seq2seq.sequence_loss(logits=prediction2, targets=y_data, weights=weights)
sess.run(tf.global_variables_initializer())
print("Loss: ", sequence_loss.eval(),
"Loss: ", sequence_loss.eval())
[Out]
Loss1: 0.513015
Loss2: 0.371101
In [4]:
# FC layer
X_for_fc = tf.reshape(outputs, [-1, hidden_size])
# fc_w = tf.get_variable("fc_w", [hidden_size, num_classes])
# fc_b = tf.get_variable("fc_b", [num_classes])
# outputs = tf.matmul(X_for_fc, fc_w) + fc_b
outputs = tf.contrib.layers.fully_connected(
inputs=X_for_fc, num_outputs=num_classes, activation_fn=None)
# reshape out for sequence_loss
outputs = tf.reshape(outputs, [batch_size, sequence_length, num_classes])
weights = tf.ones([batch_size, sequence_length])
sequence_loss = tf.contrib.seq2seq.sequence_loss(
logits=outputs, targets=Y, weights=weights)
loss = tf.reduce_mean(sequence_loss)
train = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(loss)
4. Training¶
In [5]:
prediction = tf.argmax(outputs, axis=2)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(50):
l, _ = sess.run([loss, train], feed_dict={X: x_one_hot, Y: y_data})
result = sess.run(prediction, feed_dict={X: x_one_hot})
print(i, "loss:", l, "prediction: ", result, "true Y: ", y_data)
# print char using dic
result_str = [idx2char[c] for c in np.squeeze(result)]
print("\tPrediction str: ", ''.join(result_str))
처음에 [[3 3 3 3 3 3]]=lllll 였다가 마지막에는 [[1 0 2 3 3 4]]=ihello가 나왔다.
'beginner > 파이썬 딥러닝 기초' 카테고리의 다른 글
Stacked RNN + Softmax Layer (0) | 2019.05.18 |
---|---|
Long Sequence RNN (0) | 2019.05.16 |
RNN in TensorFlow (0) | 2019.05.14 |
NN의 꽃 RNN 이야기 (0) | 2019.05.13 |
Class, tf.layers, Ensemble (MNIST 99.5%) (0) | 2019.05.13 |