Recurrent Neural Network

By Prof. Seungchul Lee
iSystems Design Lab
http://isystems.unist.ac.kr/
UNIST

Table of Contents

1. Recurrent Neural Networks

1.1. Limitation of Feedforward Neural Nets

  • 일반적인 뉴럴네트워크 (NN) 은 데이터의 순차적인 특징을 고려하지 않음
  • 순차적인 데이터인 $x_1, \cdots, x_T$를 뉴럴네트워크에 반영하기 위해서는 각각의 $x$에대해 독립인 hidden state인 $h_1, \cdots, h_T$를 사용해야함



  • 순차적인 데이터에 적합한 접근방식이라고는 할 수 없다.
    • e.g., sentence/paragraph/document (sequence of words), video (sequence of frames), etc.

1.2. Recurrent Neural Nets (RNN)

  • 이전 단계의 정보를 반영하는 hidden state를 구성



  • 각각의 hidden state는 다음과 같은 식으로 이루어져있음
$$ h_t = f \left( W x_t + U h_{t-1}\right) $$

$\quad \;$where $U$ is like a transition matrix and $f$ is some nonlinear function (e.g., $\tanh$).

  • 각각의 hidden state $h_t$는 메모리 역할을 하여 $t$시점까지의 정보를 기억할 수 있도록 도움

  • $t-1$시점의 hidden state $h_{t-1}$과 $t$시점의 hidden state $h_t$를 연결해주는 transition matrix $U$를 통해 과거의 정보를 전달


2. Training Neural Networks

2.1. RNN: Vanishing/Exploding Gradients Problem



  • Gradients Problem
    • 시퀀스가 길어지면 hidden state가 저장하고 있는 정보가 점점 희석됨
    • 학습과정에서 반복되는 연산으로 gradient가 사라지거나 과도하게 커짐

2.2. Capturing Long-Range Dependencies

  • 해결을 위한 기본 아이디어: 게이트(gate)를 이용하여 hidden state의 성능을 보강
    • 게이트는 정보를 "선별하여" 기억하거나 지우는 역할을 함

  • 새로운 hidden state는 3가지 종류의 게이트로 구성되어 있음

    • input (bottom), forget (left), output (top)
    • 그림에서 열린 게이트는 'o', 닫힌 게이트는 '-'로 표기
  • LSTM: Long Short-Term Memory 가 대표적인 방법론

3. Recurrent Neural Network in TensorFlow

  • RNN 구조를 이용하여 숫자를 분류하는 네트워크를 구성하는 예제

3.1. Import Library

In [1]:
# Import Library
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import matplotlib.pyplot as plt
from six.moves import cPickle

3.2. Load Example

In [2]:
X_all, Y_all = cPickle.load(open('./data_files/rotation_data_ohe.pkl', 'rb'))
  • 4가지 종류의 진동데이터
In [3]:
data = {}
data['normal'] = X_all[np.argmax(Y_all, 1) == 0], Y_all[np.argmax(Y_all, 1) == 0]
data['misalign'] = X_all[np.argmax(Y_all, 1) == 1], Y_all[np.argmax(Y_all, 1) == 1]
data['rubbing'] = X_all[np.argmax(Y_all, 1) == 2], Y_all[np.argmax(Y_all, 1) == 2]
data['unbal'] = X_all[np.argmax(Y_all, 1) == 3], Y_all[np.argmax(Y_all, 1) == 3]

plt.figure(figsize=(10, 6))
for data_type in ['misalign', 'unbal', 'normal', 'rubbing']:
    X, y = data[data_type]
    plt.plot(X[10,:], label=data_type)
plt.legend(loc = 'lower right', fontsize = 15)
plt.xlim(0,X.shape[1])
plt.show()

3.3. Define Network Size

  • Network를 구성하는데 필요한 변수 (hidden layer 수, classes 개수 등) 정의
  • Tensorflow에서 LSTM RNN은 input chunk 개수와 size만 결정해주면 됨
    • n_steps: chunk의 개수
    • n_input_sequence: 각 chunk에 들어가는 data point의 수 (chunk size)

In [4]:
total_length = 820
n_steps = 10
n_input_sequence = int(total_length//n_steps)
n_hidden = 30
n_classes = 4

3.4. Define Weights

  • 학습될 변수 (파라미터) 정의
In [5]:
weights = {
    'out' : tf.Variable(tf.random_normal([n_hidden, n_classes], stddev = 0.1))
}
biases = {
    'out' : tf.Variable(tf.random_normal([n_classes], stddev = 0.1))
}

3.5. Define Network

In [6]:
def net(x, weights, biases, n_input, n_step, batch_size):
    x = tf.transpose(x, [1, 0, 2])
    x = tf.reshape(x, [-1, n_input])
    x = tf.split(x, n_step, 0)
    
    with tf.variable_scope('rnn') as scope : 
        lstm_cell = tf.contrib.rnn.BasicLSTMCell(n_hidden, forget_bias=1.0, state_is_tuple=True)
        ch_tuple = lstm_cell.zero_state(batch_size, dtype=tf.float32)
        
        c_list = []
        h_list = []
        
        for input_ in x:
            try : 
                h, ch_tuple = lstm_cell(input_, ch_tuple)
            except ValueError : 
                scope.reuse_variables()
                h, ch_tuple = lstm_cell(input_, ch_tuple)
        
            c_list.append(ch_tuple[0])
            h_list.append(ch_tuple[1])
            
    return tf.matmul(h_list[-1], weights['out']) + biases['out']
        

3.6. Define Cost

  • Neural Net의 output과 label $y$의 차이가 최소가 되도록 구성
In [7]:
learning_rate = 0.5
x = tf.placeholder(tf.float32, [None, n_steps, n_input_sequence])
y = tf.placeholder(tf.float32, [None, n_classes])

Batch_size_place_holder = tf.placeholder(tf.int32)
pred = net(x, weights, biases, n_input_sequence, n_steps, Batch_size_place_holder)

cost = tf.reduce_mean(tf.square(pred - y))
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
  • Tensor Graph
    • 엣지(텐서)와 노드로 이루어진 데이터 플로우 그래프 구조를 먼저 생성한 후 tf.Session()을 통해 수학적연산 진행



3.7. Define Variable

  • 학습 과정에서 필요한 변수 (iteration 횟수 등) 정의
In [8]:
n_iter = 5000
flag = 500

3.8. Optimize

  • Train/valid 셋으로 나눔
In [9]:
from sklearn.cross_validation import StratifiedKFold
skf = StratifiedKFold(np.argmax(Y_all, 1), n_folds=5)
train_indices, valid_indices = next(iter(skf))
X_train_rnn, y_train_rnn = X_all[train_indices, :], Y_all[train_indices]
X_valid_rnn, y_valid_rnn = X_all[valid_indices, :], Y_all[valid_indices]
/home/isystems/venv/lib/python3.4/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
  "This module will be removed in 0.20.", DeprecationWarning)
In [10]:
# Optimize 
init = tf.global_variables_initializer()
sess = tf.Session()

sess.run(init)

# Training cycle
for epoch in range(n_iter):
    X_train_reshape = np.reshape(X_train_rnn, [-1, n_steps, n_input_sequence])
    sess.run(optimizer, feed_dict={x: X_train_reshape, y: y_train_rnn, Batch_size_place_holder: X_train_reshape.shape[0]})
    c = sess.run(cost, feed_dict={x: X_train_reshape,  y: y_train_rnn, Batch_size_place_holder: X_train_reshape.shape[0]})
    if epoch % flag == 0:
        print ("Iter : {}".format(epoch))
        print ("Cost : {}".format(c))
Iter : 0
Cost : 0.2241765707731247
Iter : 500
Cost : 0.055513884872198105
Iter : 1000
Cost : 0.04464704170823097
Iter : 1500
Cost : 0.04206078499555588
Iter : 2000
Cost : 0.039722051471471786
Iter : 2500
Cost : 0.03352866694331169
Iter : 3000
Cost : 0.025816822424530983
Iter : 3500
Cost : 0.020977970212697983
Iter : 4000
Cost : 0.01651313528418541
Iter : 4500
Cost : 0.013945138081908226

3.9. Test

In [11]:
X_valid_reshape = np.reshape(X_valid_rnn, [-1, n_steps, n_input_sequence])
predict = sess.run(pred, feed_dict={x:X_valid_reshape, Batch_size_place_holder: X_valid_reshape.shape[0]})
accuracy = np.mean(np.equal(np.argmax(predict, 1), np.argmax(y_valid_rnn, 1)))
print('Accuracy = {:.4f}'.format(accuracy))
Accuracy = 0.9630
In [12]:
%%javascript
$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')