TigerCow.Door


안녕하세요. 문범우입니다.

이번 포스팅에서는 우리가 Deep Neural Network 에 대해 이론으로 배웠던 내용들을 실제로 텐서플로우로 구현해보도록 하겠습니다.


우리가 아래 포스팅에서 softmax classifier를 이용하여 mnist 데이터를 예측해보는 모델을 만들어봤었는데, 이때 정확도가 약 83%도 나왔습니다. 이를 DNN으로 구현해보면서 정확도를 최대 98%까지 끌어올려보도록 하겠습니다.


텐서플로우(Tensor Flow) #10_ MNIST DATA



1. MNIST Data 다루기


우리가 MNIST Data에 대해서는 위에서 언급했던 아래 포스팅에서 다루어 보았습니다.

보다 자세한 내용은 해당 글을 참고하시면 되겠습니다.


텐서플로우(Tensor Flow) #10_ MNIST DATA


이때 작성했던 코드를 기본으로 이번 포스팅을 시작할 것이며 그 코드는 아래와 같습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
import random
from tensorflow.examples.tutorials.mnist import input_data
 
# read data
mnist = input_data.read_data_sets("/~/deep_learning_zeroToAll/", one_hot=True)
 
nb_classes = 10
 
= tf.placeholder(tf.float32,[None,784])
= tf.placeholder(tf.float32,[None,nb_classes])
 
= tf.Variable(tf.random_normal([784,nb_classes]))
= tf.Variable(tf.random_normal([nb_classes]))
 
hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)
 
cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis = 1))
optimizer = tf.train.GradientDescentOptimizer(learning_rate = 0.1).minimize(cost)
 
is_correct = tf.equal(tf.arg_max(hypothesis,1), tf.arg_max(Y, 1))
accuracy = tf.reduce_mean(tf.cast(is_correct,tf.float32))
 
training_epochs = 15
batch_size = 100
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(mnist.train.num_examples / batch_size)
 
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            c, _= sess.run([cost,optimizer], feed_dict={X: batch_xs, Y: batch_ys})
            avg_cost += c / total_batch
 
        print('Epoch:''%04d' % (epoch + 1), 'cost = ''{:.9f}'.format(avg_cost))
    print("Learning finished")
    print("Accuracy: ", accuracy.eval(session=sess, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
 
    # Get one and predict using matplotlib
    r = random.randint(0, mnist.test.num_examples - 1)
    print("Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
    print("Prediction: ", sess.run(
        tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1]}))
 
    plt.imshow(
        mnist.test.images[r:r + 1].reshape(2828),
        cmap='Greys',
        interpolation='nearest')
    plt.show()
 
 
cs


( mnist dataset 경로를 알맞게 설정하세요. )

해당코드로 코드를 돌려보면 아래와 같은 결과가 나옵니다.



위의 결과 처럼, 약 84%의 결과를 보이고 있습니다.

이제 하나씩 우리가 배웠던 내용을 추가해보면서 정확도를 올려보도록 하겠습니다.



2. Deep, Wide and ReLU

딥러닝(DeepLearning) #4_ ReLU::Rectified Linear Unit


먼저 우리가 적용해볼 것은 모델을 보다 deep하고, wide하게 layer를 만들면서 sigmoid 함수 대신에 ReLU 함수를 적용시키는 것 입니다.


또한 optimizer 함수를 AdamOptimizer 함수로 바꾸었는데, 이에 대해서는 크게 생각하지 않고, 더 좋은 것이기 때문에 사용한다는 점만 알아두도록 하겠습니다.


따라서 코드를 아래와 같이 수정하였습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import tensorflow as tf
import matplotlib.pyplot as plt
import random
from tensorflow.examples.tutorials.mnist import input_data
 
tf.set_random_seed(777)
# read data
mnist = input_data.read_data_sets("/~/deep_learning_zeroToAll/", one_hot=True)
 
nb_classes = 10
 
= tf.placeholder(tf.float32,[None,784])
= tf.placeholder(tf.float32,[None,nb_classes])
 
# W = tf.Variable(tf.random_normal([784,nb_classes]))
# b = tf.Variable(tf.random_normal([nb_classes]))
 
W1 = tf.Variable(tf.random_normal([784,256]))
b1 = tf.Variable(tf.random_normal([256]))
L1 = tf.nn.relu(tf.matmul(X, W1) + b1)
 
W2 = tf.Variable(tf.random_normal([256,256]))
b2 = tf.Variable(tf.random_normal([256]))
L2 = tf.nn.relu(tf.matmul(L1, W2) + b2)
 
W3 = tf.Variable(tf.random_normal([256,10]))
b3 = tf.Variable(tf.random_normal([10]))
hypothesis = tf.matmul(L2, W3) + b3
 
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)
 
is_correct = tf.equal(tf.arg_max(hypothesis,1), tf.arg_max(Y, 1))
accuracy = tf.reduce_mean(tf.cast(is_correct,tf.float32))
 
training_epochs = 15
batch_size = 100
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(mnist.train.num_examples / batch_size)
 
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            c, _= sess.run([cost,optimizer], feed_dict={X: batch_xs, Y: batch_ys})
            avg_cost += c / total_batch
 
        print('Epoch:''%04d' % (epoch + 1), 'cost = ''{:.9f}'.format(avg_cost))
    print("Learning finished")
    print("Accuracy: ", accuracy.eval(session=sess, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
 
    # Get one and predict using matplotlib
    r = random.randint(0, mnist.test.num_examples - 1)
    print("Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
    print("Prediction: ", sess.run(
        tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1]}))
 
    plt.imshow(
        mnist.test.images[r:r + 1].reshape(2828),
        cmap='Greys',
        interpolation='nearest')
    plt.show()
 
 
cs


이렇게, 3개의 ReLU함수를 적용한 layer로 학습을 진행하니 아래 결과와 같이 약 94%의 정확도를 가지게 되었습니다.




3. Xavier initialize

딥러닝(DeepLearning) #5_ Restricted Belief Machine & Xavier initialize


이번에는 초기값을 건드려 보겠습니다.

Xavier initialize를 이용하여 아래와 같이 코드를 수정하였습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import tensorflow as tf
import matplotlib.pyplot as plt
import random
from tensorflow.examples.tutorials.mnist import input_data
 
tf.set_random_seed(777)
# read data
mnist = input_data.read_data_sets("/~/deep_learning_zeroToAll/", one_hot=True)
 
nb_classes = 10
 
= tf.placeholder(tf.float32,[None,784])
= tf.placeholder(tf.float32,[None,nb_classes])
 
# W = tf.Variable(tf.random_normal([784,nb_classes]))
# b = tf.Variable(tf.random_normal([nb_classes]))
 
W1 = tf.get_variable("W1",shape=[784,256], initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.Variable(tf.random_normal([256]))
L1 = tf.nn.relu(tf.matmul(X, W1) + b1)
 
W2 = tf.get_variable("W2",shape=[256,256], initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.Variable(tf.random_normal([256]))
L2 = tf.nn.relu(tf.matmul(L1, W2) + b2)
 
W3 = tf.get_variable("W3",shape=[256,10], initializer=tf.contrib.layers.xavier_initializer())
b3 = tf.Variable(tf.random_normal([10]))
hypothesis = tf.matmul(L2, W3) + b3
 
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)
 
is_correct = tf.equal(tf.arg_max(hypothesis,1), tf.arg_max(Y, 1))
accuracy = tf.reduce_mean(tf.cast(is_correct,tf.float32))
 
training_epochs = 15
batch_size = 100
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(mnist.train.num_examples / batch_size)
 
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            c, _= sess.run([cost,optimizer], feed_dict={X: batch_xs, Y: batch_ys})
            avg_cost += c / total_batch
 
        print('Epoch:''%04d' % (epoch + 1), 'cost = ''{:.9f}'.format(avg_cost))
    print("Learning finished")
    print("Accuracy: ", accuracy.eval(session=sess, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
 
    # Get one and predict using matplotlib
    r = random.randint(0, mnist.test.num_examples - 1)
    print("Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
    print("Prediction: ", sess.run(
        tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1]}))
 
    plt.imshow(
        mnist.test.images[r:r + 1].reshape(2828),
        cmap='Greys',
        interpolation='nearest')
    plt.show()
 
 
cs


각 레이어의 초기값을 랜덤하게 지정하지 않고, xavier initialize를 이용하여 결과를 확인해보니 아래와 같습니다.



위와 같이 약 97%의 정확도를 보여주고 있습니다.



4. Drop out

딥러닝(DeepLearning) #6_ Dropout and Ensemble


그럼 이번에는 우리의 모델을 더 깊고, 더 넓게 만들어 보겠습니다.

현재까지는 3개의 layer를 가진 모델이었는데 아래코드와 같이, 5단으로 넓히면서 더 wide하게 모델을 만들어봅니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import tensorflow as tf
import matplotlib.pyplot as plt
import random
from tensorflow.examples.tutorials.mnist import input_data
 
tf.set_random_seed(777)
# read data
mnist = input_data.read_data_sets("/~/deep_learning_zeroToAll/", one_hot=True)
 
nb_classes = 10
 
= tf.placeholder(tf.float32,[None,784])
= tf.placeholder(tf.float32,[None,nb_classes])
 
# W = tf.Variable(tf.random_normal([784,nb_classes]))
# b = tf.Variable(tf.random_normal([nb_classes]))
 
W1 = tf.get_variable("W1",shape=[784,512], initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.Variable(tf.random_normal([512]))
L1 = tf.nn.relu(tf.matmul(X, W1) + b1)
 
W2 = tf.get_variable("W2",shape=[512,512], initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.Variable(tf.random_normal([512]))
L2 = tf.nn.relu(tf.matmul(L1, W2) + b2)
 
W3 = tf.get_variable("W3",shape=[512,512], initializer=tf.contrib.layers.xavier_initializer())
b3 = tf.Variable(tf.random_normal([512]))
L3 = tf.nn.relu(tf.matmul(L2, W3) + b3)
 
W4 = tf.get_variable("W4",shape=[512,512], initializer=tf.contrib.layers.xavier_initializer())
b4 = tf.Variable(tf.random_normal([512]))
L4 = tf.nn.relu(tf.matmul(L3, W4) + b4)
 
W5 = tf.get_variable("W5",shape=[512,10], initializer=tf.contrib.layers.xavier_initializer())
b5 = tf.Variable(tf.random_normal([10]))
hypothesis = tf.matmul(L4, W5) + b5
 
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)
 
is_correct = tf.equal(tf.arg_max(hypothesis,1), tf.arg_max(Y, 1))
accuracy = tf.reduce_mean(tf.cast(is_correct,tf.float32))
 
training_epochs = 15
batch_size = 100
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(mnist.train.num_examples / batch_size)
 
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            c, _= sess.run([cost,optimizer], feed_dict={X: batch_xs, Y: batch_ys})
            avg_cost += c / total_batch
 
        print('Epoch:''%04d' % (epoch + 1), 'cost = ''{:.9f}'.format(avg_cost))
    print("Learning finished")
    print("Accuracy: ", accuracy.eval(session=sess, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
 
    # Get one and predict using matplotlib
    r = random.randint(0, mnist.test.num_examples - 1)
    print("Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
    print("Prediction: ", sess.run(
        tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1]}))
 
    plt.imshow(
        mnist.test.images[r:r + 1].reshape(2828),
        cmap='Greys',
        interpolation='nearest')
    plt.show()
 
 
cs


위와 같이, 다른 것들은 모두 그대로 두고 layer를 5개로 확장하면서 보다 wide 하게 만들었습니다.

결과는 어떨까요?



미세하지만, 오히려 이전보다 정확도가 떨어졌습니다.

보다 더 깊고, 넓게 모델을 만들었는데, 왜그럴까요?

바로 우리가 배웠던 overfitting 때문입니다.

이를 해결하기 위해서 우리는 dropout 이라는 것을 배웠고, 바로 코드에 적용시켜보도록 하겠습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import tensorflow as tf
import matplotlib.pyplot as plt
import random
from tensorflow.examples.tutorials.mnist import input_data
 
tf.set_random_seed(777)
# read data
mnist = input_data.read_data_sets("/~/deep_learning_zeroToAll/", one_hot=True)
 
nb_classes = 10
keep_prob = tf.placeholder(tf.float32)
 
= tf.placeholder(tf.float32,[None,784])
= tf.placeholder(tf.float32,[None,nb_classes])
 
# W = tf.Variable(tf.random_normal([784,nb_classes]))
# b = tf.Variable(tf.random_normal([nb_classes]))
 
W1 = tf.get_variable("W1",shape=[784,512], initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.Variable(tf.random_normal([512]))
L1 = tf.nn.relu(tf.matmul(X, W1) + b1)
L1 = tf.nn.dropout(L1, keep_prob=keep_prob)
 
W2 = tf.get_variable("W2",shape=[512,512], initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.Variable(tf.random_normal([512]))
L2 = tf.nn.relu(tf.matmul(L1, W2) + b2)
L2 = tf.nn.dropout(L2, keep_prob=keep_prob)
 
W3 = tf.get_variable("W3",shape=[512,512], initializer=tf.contrib.layers.xavier_initializer())
b3 = tf.Variable(tf.random_normal([512]))
L3 = tf.nn.relu(tf.matmul(L2, W3) + b3)
L3 = tf.nn.dropout(L3, keep_prob=keep_prob)
 
W4 = tf.get_variable("W4",shape=[512,512], initializer=tf.contrib.layers.xavier_initializer())
b4 = tf.Variable(tf.random_normal([512]))
L4 = tf.nn.relu(tf.matmul(L3, W4) + b4)
L4 = tf.nn.dropout(L4, keep_prob=keep_prob)
 
W5 = tf.get_variable("W5",shape=[512,10], initializer=tf.contrib.layers.xavier_initializer())
b5 = tf.Variable(tf.random_normal([10]))
hypothesis = tf.matmul(L4, W5) + b5
 
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate = 0.001).minimize(cost)
 
is_correct = tf.equal(tf.arg_max(hypothesis,1), tf.arg_max(Y, 1))
accuracy = tf.reduce_mean(tf.cast(is_correct,tf.float32))
 
training_epochs = 15
batch_size = 100
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for epoch in range(training_epochs):
        avg_cost = 0
        total_batch = int(mnist.train.num_examples / batch_size)
 
        for i in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            c, _= sess.run([cost,optimizer], feed_dict={X: batch_xs, Y: batch_ys, keep_prob: 0.7})
            avg_cost += c / total_batch
 
        print('Epoch:''%04d' % (epoch + 1), 'cost = ''{:.9f}'.format(avg_cost))
    print("Learning finished")
    print("Accuracy: ", accuracy.eval(session=sess, feed_dict={X: mnist.test.images, Y: mnist.test.labels, keep_prob: 1}))
 
    # Get one and predict using matplotlib
    r = random.randint(0, mnist.test.num_examples - 1)
    print("Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
    print("Prediction: ", sess.run(
        tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1], keep_prob: 1}))
 
    plt.imshow(
        mnist.test.images[r:r + 1].reshape(2828),
        cmap='Greys',
        interpolation='nearest')
    plt.show()
 
 
cs


위와 같이 keep_prob 라는 변수를 새로 만들어서, 각 레이어마다 dropout 함수를 적용시키고 이때 keep_prob 값을 변수값으로 넣었습니다.

이후 훈련할때 keep_prob 값을 feed_dict에서 0.7로 주었으며 실제로 예측할때는 1값을 주었습니다.


이를 통해 나오는 결과는 아래와 같습니다.



위의 결과를 확인하면 정확도가 98%를 넘기는 것을 확인할 수 있습니다.


이렇게 우리가 그동안 배웠던 개념들을 실제로 텐서플로우에서 구현해보고, 그것들이 얼마나 정확도를 높여주는지 확인해보았습니다.

블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번 포스팅에서는 dropout과 model ensemble에 대해서 살펴보도록 하겠습니다.



1. Dropout


우리가 dropout을 하는 이유는 바로 아래와 같은 overfitting 때문입니다.



우리가 과거에 알아봤던 것처럼, 훈련 data에 있어서는 100%의 accuracy를 내지만, 실제로 test data에 있어서는 높은 예측율을 내지 못하게 되는 현상이죠.



위와 같이, 파란색 그래프, training 에서는 에러율이 점점 낮아지지만, 실제로 빨간색 그래프처럼 test data를 통해 확인해보니 어느 시점부터 에러율이 더 증가하게 됩니다.


이러한 overfitting은 우리가 더 깊게 만들수록 일어날 확률이 커집니다.

왜냐하면 더 깊어질수록 더 많은 변수가 생기기 때문입니다.


그럼 이를 해결하기 위해서는 무슨 방법이 있을까요?


첫번째로는, 더 많은 데이터를 훈련시키는 것입니다.

또는 feature를 줄여주는 방법도 있을 것입니다.

그리고 우리가 예전에 간단히 알아봤던, Regularization 이라는 방법이 있습니다.



우리가 예전에 알아봤던 것처럼, 위의 식과 같이 처리함으로써 Regularization을 하는 L2regularization도 있습니다.


그리고 Neural Network에서는 또다른, dropout이라는 방법이 있습니다.

dropout이란 쉽게 말해서, 위 그림에서 왼쪽 그림과 같은 모델에서 몇개의 연결을 끊어서, 즉 몇개의 노드를 죽이고 남은 노드들을 통해서만 훈련을 하는 것입니다.

이때 죽이는, 쉬게하는 노드들을 랜덤하게 선택합니다.




쉽게 말해 각 노드들을 어떤 전문가라고 생각해본다면 랜덤하게 몇명은 쉬게하고 나머지만 일하게 합니다. 

그리고 마지막에는 모든 전문가들을 총 동원해서 예측을 하게 합니다.


이러한 아이디어가 dropout 입니다.


실제로 텐서플로우에서 구현하기에도 어렵지 않게 가능합니다.

우리가 원래 만들었던 layer를 dropout함수에 넣어서, 몇 퍼센트의 노드가 일하게 할 것인지 함께 적어줍니다.

위의 코드를 보면 Train에서는 0.7, 즉 70%의 노드들이 랜덤하게 훈련되게 하였습니다.

그리고 실수하면 안되는 점이 Evaluation 과정에서는 dropout_rate를 1로 함으로써 100%의 노드들을 참가시키도록 해야 합니다.



2. Ensemble



우리가 추후, 학습시킬 수 있는 장비가 많을때 사용할 수 있는 또 하나의 방법도 있습니다.

Ensemble이라고 하는 것인데, 위와 같이 여러개의 독립적인 모델을 만듭니다. 이때 훈련 데이터셋은 별도로 해도 되고, 모두 같은 훈련 데이터셋을 이용해도 상관 없습니다.

이때 각 모델의 초기값이 서로 다르기때문에 결과도 약간씩 다를 것입니다.

그리고 이후에 독립적인 모델들을 모두 합쳐서 한번에 예측을 하게 합니다.

즉, 이것은 전문가 한명에게 어떤 질문을 하는 것이 아니고 서로 독립적인 전문가 다수를 모아두고 질문을 하는 것과 같습니다.


실제로 Ensembel을 이용하면 2%~5%까지도 예측율이 올라간다고 합니다.


블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc


안녕하세요. 문범우입니다.

이번에는 지난 포스팅에 이어서 딥러닝을 잘하는 방법 중 weight의 초기값을 설정하는 방법에 대해서 알아보도록 하겠습니다.



1. RBM(Restricted Belief Machine)


우리가 지난 포스팅에서 위의 그림과 같은 Vanishing gradient 문제에 대해서 알아보았습니다.

그리고 이 문제에 대해서는 Hilton 교수님께서는 4가지 이유를 꼬집었습니다.


위의 4가지 항목중 제일 아래에 있는 것은 우리가 지난 포스팅에서 sigmoid함수 대신, ReLU함수를 사용함으로써 해결할 수 있었습니다.

하지만 하이라이트 된 것과 같이 또 다른 문제도 있었습니다.


이전의 테스트에서도 아래와 같이, 같은 ReLU함수를 사용했음해도 불구하고 cost가 초반에 다르게 변화하는 것을 볼 수 있습니다.


이러한 현상이 발생하는 이유는 우리가 테스트를 할때, 초기값을 랜덤하게 지정해서 발생한 현상입니다.


그럼, 이런 초기값에 대해서 좀 더 자세히 살펴보도록 하겠습니다.

단적으로 초기값을 0으로 설정해보면 어떨까요?

그럼, 위와 같은 그림에서 W를 0으로 둔것이고, 이것이 chain rule에서 사용됩니다. 그럼 x = df/dg * W 이므로 x = 0이 되고, 그 앞에 있는 것들도 모두 0이되면서 gradient가 사라져 버립니다.


따라서, 절대로 초기값으로 0을 주면 안된다는 것을 알 수 있습니다.

그럼 초기값을 어떻게 주어져야 할까요?


이에 대해 2006년 Hilton교수님께서 논문을 쓰시면서 RBM(Restricted Boatman Machine)을 사용함으로써 해결하게 됩니다.

그리고 이러한 RBM을 사용한 네트워크를 DBN(Deep Belief Networks)라고 합니다.


어떻게 동작되는 것 일까요?


먼저, 입력을 재생산 해냅니다.


위의 그림과 같이, 입력값을 weight와 곱해서 b값을 얻어냅니다. 또한 b 유닛아래에 있는 것들에 대해서도 같은 방법을 통해서 값을 얻습니다. 이러한 과정을 Forward 라고 합니다.



그리고, Backward 방법으로, 우리가 얻은 값들과 weight를 통해 위의 그림에서의 b 값을 얻습니다.

그럼 우리가 처음에 입력한 값을 x라고 한다면, x와 b의 값의 차이가 존재할텐데 이 차이가 최소가 될 때까지 weight를 조절합니다.


이렇게 해서 weight를 구하는 것을 RBM이라고 합니다.

그리고 위와 같은 방법을 encoder/decoder라고도 합니다.


실제로 이것을 네트워크 상에서 적용시키기 위해서는 아래와 같은 과정을 가집니다.

여러개의 레이어가 있을때, 입력값 측의 레이어부터 시작하여 layer 1과 layer 2를 encoder/decoder를 수행하고, 이후에 layer2 와 layer3에 대해 수행하며 끝까지 나아가는 방법입니다.


이제 이러한 과정을 통해 각 weight를 구할 수 있고, 그것을 학습시킨다, training한다는 표현보다는 fine tunning 이라는 표현을 사용합니다.

학습하는 것보다 훨씬 더 빨리 진행되는 작업이기 때문이죠.

이러한 fine tunning이 끝나게 되면 이후 우리가 학습시키고자 하는 데이터들에 대해서 label을 붙여서 실제로 training을 진행합니다.



2. Xavier initalize




그런데 실제로 이것을 구현하는데 있어서는 복잡한 과정이 있을 수 있습니다.

하지만 좋은 소식은, 2010년에 발표된 논문에서 우리가 굳이 RBM을 쓰지 않아도, 좋은 초기값을 얻을 수 있다는 Xavier initialize라는 알고리즘이 나왔습니다.


이는 입력의 노드의 개수에 비례해서 초기값을 세팅하면 된다는 식의 알고리즘 입니다.


이를 식으로 간단히 살펴보면, 우리가 좋은 값, 좋은 weight를 얻기 위해서 입력값의 개수 fan_in 과 출력 값의 개수 fan_out을 이용하여 초기값을 주는 것입니다. 이러한 식을 통해 어쩌면 RBM보다 더 좋은 결과를 가질 수 있다고 합니다.


블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc

티스토리 툴바