@markdown
# MNIST ReLU, Xavier 초기화, Dropout 적용하여 정확도 높이기
<br/>
## ReLU 함수 사용
____
- 기존의 Sigmoid 보단 ReLU를 사용하여 인식률을 높인다.
- shape=[512, 512]와 ReLU로 5-Layer를 설계해 Deep하고 Wide한 Neural Network을 구성한다.
<pre><code class="python" style="font-size:15px">import tensorflow as tf
import random
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
learning_rate = 0.001
training_epochs = 15
batch_size = 100
X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])
# ReLU 사용한 NN 구성
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=learning_rate).minimize(cost)
sess = tf.Session()
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)
feed_dict = {X: batch_xs, Y: batch_ys}
c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
avg_cost += c / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print("---------------------------------------------------------------------")
print('Learning Finished!')
correct_prediction = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print('Accuracy:', sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels}))
for epoch in range(5):
r = random.randint(0, mnist.test.num_examples - 1)
# print("Test Random Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
print("\nTest Image -> ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
plt.imshow(mnist.test.images[r:r + 1].reshape(28, 28), cmap='Greys', interpolation='nearest')
plt.show()
print("Prediction: ", sess.run(tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1]}))
</code></pre>
<pre><code class="python" style="font-size:15px">실행결과
지난번 Sigmoid+NN으로 구성했던 결과보다 5%나 정확도가 증가한 것을 확인할 수 있다.
하지만 초기 cost가 높은 값으로 학습이 시작된다.
Epoch: 0001 cost = 168.560498304
...
Epoch: 0015 cost = 0.686247512
---------------------------------------------------------------------
Learning Finished!
Accuracy: 0.942
</code></pre>
<br/>
## Xavier 초기화 방법
____
- 변수를 xavier initialization 방법을 사용하여 초기값을 초기화해 정확도를 올릴 수 있다.
- 초기값이 적절하게 초기화되어 첫 Cost부터 낮은 값을 얻을 수 있어 효율적이다.
- tf.Variable과 tf.get_variable의 차이는 변수를 생성하냐, 기존의 변수를 공유하냐의 차이이다.
<pre><code class="python" style="font-size:15px"># weights & bias for nn layers
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
</code></pre>
<pre><code class="python" style="font-size:15px">실행결과
ReLU로 구성한 Network보다 3% 가량 정확도가 올라간 것을 확인할 수 있다.
또한, 초기 Cost값이 상당히 낮은 값에서 점차 줄어드는 것을 확인할 수 있다.
Epoch: 0001 cost = 0.327931981
...
Epoch: 0015 cost = 0.007789033
---------------------------------------------------------------------
Learning Finished!
Accuracy: 0.9755
</code></pre>
<br/>
## Dropout 사용
____
- Network가 깊어지면 Overfitting 현상이 나타날 수 있어, Dropout을 사용한다.
- Dropout은 Network이 Overfitting 되지 않도록 Network(뉴런 연결)을 랜덤으로 끊는 방식으로 overfitting을 방지한다.
- Dropout을 사용해 학습 시킬 경우, 0.5~0.7로 keep_prob 값을 설정하여 Network를 얼마나 유지(50%~70%)할지 설정해준다.
<pre><code class="python" style="font-size:15px">import tensorflow as tf
import random
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
learning_rate = 0.001
training_epochs = 15
batch_size = 100
X = tf.placeholder(tf.float32, [None, 784])
Y = tf.placeholder(tf.float32, [None, 10])
# Network의 학습, 테스팅에 얼마나 유지, 학습에 사용할지 설정값을 placeholder 변수로 초기화한다.
# Train과 Testing 두 곳에서 각각 다른 값을 사용해야하기 때문에
keep_prob = tf.placeholder(tf.float32)
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=learning_rate).minimize(cost)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
# train my model
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)
# keep_prob : Network의 70%를 유지해 학습
feed_dict = {X: batch_xs, Y: batch_ys, keep_prob: 0.7}
c, _ = sess.run([cost, optimizer], feed_dict=feed_dict)
avg_cost += c / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print("---------------------------------------------------------------------")
print('Learning Finished!')
correct_prediction = tf.equal(tf.argmax(hypothesis, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# keep_prob : 100%의 Network을 사용해 학습된 모델로 예측하겠다.
print('Accuracy:', sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels, keep_prob: 1}))
for epoch in range(5):
r = random.randint(0, mnist.test.num_examples - 1)
# print("Test Random Label: ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
print("\nTest Image -> ", sess.run(tf.argmax(mnist.test.labels[r:r + 1], 1)))
plt.imshow(mnist.test.images[r:r + 1].reshape(28, 28), cmap='Greys', interpolation='nearest')
plt.show()
print("Prediction: ", sess.run(tf.argmax(hypothesis, 1), feed_dict={X: mnist.test.images[r:r + 1], keep_prob: 1}))
</code></pre>
<pre><code class="python" style="font-size:15px">실행결과
98%까지 정확도가 올라간 것을 확인할 수 있다.
Epoch: 0001 cost = 0.474214064
...
Epoch: 0015 cost = 0.045329618
---------------------------------------------------------------------
Learning Finished!
Accuracy: 0.9806
</code></pre>
## Adam Optimizer 사용
____
- TensorFlow에는 다양한 Optimizer가 있지만 그 중에서 Adam Optimizer가 가장 성능이 좋다.
- 이전에는 GradientDescentOptimizer를 주로 사용했지만, 위의 예제에서 모두 Adam Optimizer를 Cost를 최소화했다.
<pre><code class="python" style="font-size:15px">cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=hypothesis, labels=Y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
</code></pre>
> 소스코드 - 모두를 위한 머신러닝 김석훈 교수님 강의 참고 : ([https://hunkim.github.io/ml/](https://hunkim.github.io/ml/))
'Deep Learning' 카테고리의 다른 글
비지도 학습 - 오토인코더(Autoencoder) (0) | 2018.05.27 |
---|---|
TensorFlow - RNN 기초 (0) | 2017.08.25 |
TensorFlow - MNIST 데이터 셋 활용한 손 글씨 인식 모델 구현 (0) | 2017.08.07 |
TensorFlow - Neural Network XOR 문제 (4) | 2017.08.03 |
TensorFlow - Learning Rate, Data Preprocessing, Overfitting (0) | 2017.08.01 |