티스토리 뷰
모두의 딥러닝
Convolutional Neural Networks
강의-1
이번 강의는 영상 분석에서 많이 사용하는 CNN이다.
CNN 강의 중 유명한 cs231n 강의에서 모든 자료는 발췌했다고 한다.
고양이에게 어떤 영상을 보여주고, 고양이 뇌를(뉴런) 분석하니, 특정 모양에서 특정 뉴런들이 반응하는 걸 확인하였다. 그걸 보고 똑같이 학습을 시켜 보자란 취지에서 착악된게 CNN 학습법이다.
CNN이 학습하는 방법에 대해 나타낸 이미지이다. 우선 Convolution 한 후, ReLU를 한다. 이 작업을 반복하다, Pooling을 한다. 그리고 마지막으로 Fully Connected Layer를 만들어 Softmax 클래스로 분류한다. 물론, 어떻게 Layer 구조를 정하는지는 정해져 있지 않았다.
우선 Convolution에 대해 알아보자. 위의 이미지는 Convolution하는 과정을 나타낸 이미지이다.
우선 32x32x3(가로x세로x필터) 이미지를 Convolution 해보자, 필터가 3인 이유는 해당 이미지는 컬러(Red, Green, Blue)이기 때문이다.
픽셀(pixel, 화소) 1개는 흑백의 경우 1바이트를 사용하기 때문에 256단계의 gray scale을 표현할 수 있고, 컬러의 경우 RGB에 1바이트씩 할당하기 때문에 256x256x256만큼의 색상을 표현할 수 있다.
참조: http://pythonkim.tistory.com/52
여기서 주의할 점은, 우리가 사용하는 필터의 색상 값과 입력 값의 색상 값은 같아야 한다.
우리는 여기서 하나의 숫자를 구하는데, 구하는 함수는 기존에 사용하던 Wx+b 방식과 똑같다. 그리고 이후 나온 값에 ReLU를 해주면 우리가 원하는 Convolution을 구할 수 있다.
위의 이미지 처럼 Filter는 지정한 크기(Stride) 만큼 이미지를 이동하며 하나의 값을 가져온다.
참고로 위의 이미지에서 Filter의 크기는 5x5x3이므로 75개의 w(w1~w75)가 정해진다. 해당 w는 모든 이미지(stride를 통해 이동되는)에 동일하게 적용된다.
해당 이미지처럼 7x7의 이미지에서 Filter(3x3)는 한 칸씩 이동을 하게 된다. 한 칸씩 이동하는 이유는 Stride라고 하는 것을 1로 설정했기 때문이다. 그래서 나오는 이미지의 크기는 5x5가 된다.
다음은 동일한 크기의 이미지와 Filter에서 Stride를 2로 설정했을 때의 이미지이다. Stride가 2이기 때문에 Filter는 2칸 씩 이동하게 된다. 그래서 최종적으로 결과값은 3x3이 된다.
위의 이미지는 이미지가 Filter를 거친 후 가지게 되는 크기를 계산하는 식이다.
7x7이미지에서 3x3 Filter를 사용하고 Stride를 1로 설정했다. Output을 원본 이미지 크기 그대로 7x7로 하고 싶으면 어떻게 하면 될까?에 대한 해답을 알려주는 이미지이다. 원본 이미지 크기를 유지할 수 있는 방법이 존재하는데 부족한 부분을 위의 이미지와 같이 0(Pad)으로 채워 Filter를 하면 원본이미지 크기를 유지할 수 있다. 물론 Stride가 커질 수록 Pad값 또한 커져야 된다.
다음 이미지는 Filter를 통해 생성된 이미지들이 6개가 있는 모습이다. 6Filters 또는 6Channel이라고 부르는데, 각각의 Chanel은 다른 Filter를 갖는다. 여기서 다른 Filter의 의미는 다른 w와 b값을 갖는다 이다. 그래서 6 filters (5x5x3)는 Filter를 거친 이미지 6개를 가진다는 이야기 이다.
Convolution layers를 하는 과정을 보여주는 이미지이다. 처음에는 6개의 Filter를 만들고 다음으로는 10개의 Filter를 만들었다. Filter의 갯수가 많아짐에 따라 이미지의 굵기는 굵어졌지만, Pad값을 정하지 않았기 때문에, 가로x세로의 크기는 줄어들게 되는 모습이다.
변수의 개수는 몇개일까? 6Filter에 5x5x3이므로 6*5*5*3 = 450개가 변수의 개수(빨간이미지)이다.
그리고 노란 이미지의 경우는, 10*5*5*6 이므로 1500개의 변수가 세팅된다.
강의-2
이번 동영상은 Pooling과 Fully connected에 대해서 알아보자.
위의 이미지가 Pooling layer를 하는 모습을 나타낸 것이다. Pooling을 하면 Filter(굵기?)의 크기는 그대로이나, 가로x세로의 길이가 작아진다.
Pooling은 종류가 몇개가 있다고 하나, 가장 흔히 쓰이는게 Max Pooling이라고 한다. Max Pooling이란 Filter 값 중에 제일 큰 값을 가져와 Resize한다. 위의 이미지의 경우, 2x2 Filter에 stride가 2이다. 여기서 Filter(굵기)는 중요하지 않은데, 왜냐하면 Pooling은 하더라도 Filter값은 변하지 않기 때문이다.
위의 4x4이미지를 2x2 Filter로 Stride를 2로 설정하면, 오른쪽과 같은 2x2이미지로 Resize된다.
Fully Connected Layer란 우리가 이전에 사용했던 Softmax 라고 생각하면 된다.
http://cs.stanford.edu/people/karpathy/convnetjs/demo/cifar10.html
위의 링크에서 CNN Demo를 확인할 수 있다.
강의-3
이번 강의는 CNN을 이용한 ImageNet에서 구성했던 그리고 CNN 초창기에 구성했던 형태에 대해 다룬다.
우선 CNN의 초창기 모습이다. LeCun 교수님이 처음 CNN에 대해 발표를 하셨고, 위와 같이 구성되었다.
위의 이미지를 보면 이제는 어느정도 해석이 가능할 것 같다. 96의 채널로 11x11x3 Filter로 Stride를 4로 설정해서 227x227x3 이미지를 Convolution 한다. 그러면 이미지는 55x55x96으로 구성이되고, 해당 이미지를 구성한 변수는 11*11*3*96= 35k이 된다.
2번째 Layer는 Pooling이다. 이미지의 크기는 55x55x96이고, Filter의 크기는3x3x96이고 Stride는 4이다. 그러면 Output Layer는 27x27x96이 된다. 그리고 Pooling의 경우는 w값이 필요 없기 때문에 Parameter는 없다.
위의 이미지는 AlexNet를 어떻게 구성했는지 보여주는 이미지이다.
위의 이미지는 GoogLeNet 구성 방법이다. 김성훈 교수님은 창의적으로 뉴런을 구성했지만, 우리도 충분히 할 수 있을 것 같다고 말한다.
위의 이미지는 ResNet이라고 2015년도에 ImageNet에서 우승을 한 구성인데, 이전의 Layer보다 훨씬 많은 Layer로 구성되어있다. 그럼 학습이 제대로 이루어질까란 의문을 가질 수 있지만, ResNet은 조금 색다르게 Layer가 구성된다.
위의 이미지와 같이 학습을 시킬 때, Layer를 뛰어넘고, 기존 Layer와 합치는 방법으로 구성이 된다.
위의 이미지는 ResNet이 계산되는 방법이다. 왜 학습이 잘되는지에 대해서는 누구도 알 수 없지만, 위의 이미지처럼 학습이 이루어진다.
그리고 자랑스러운 우리나라 김윤 박사님이 만든 CNN으로 구성된 문자 분류이다. 문자의 경우 나중에 배우는 RNN으로 학습을 많이 시키는데, CNN으로 학습 모델을 구성했고, 많은 사람들이 사용하는 모델 중 하나라고 말씀하셨다.
위의 이미지는 딥러닝으로 유명한 알파고에 대한 이미지와 학술지 Nature에 나온 알파고를 구성한 모델에 대한 설명이다. 알파고 또한 CNN으로 학습되었고,
“19x19x48 이미지를 Input으로 넣고 초기 필터값은 5x5x48 채널은 192개, stride 1, pad 2로 설정하였다. 2번째 Convolution은 3x3x192 채널은 192, stride 1, pad 1로 설정하였다….”
생각보다, 학술지를 이해하는데 어렵지 않았다. 학술지 또는 논문을 보며, 딥러닝에 대해 연구해보자는 생각이 들었다.
Lab-1
이제는 CNN을 한번 구성하여, MNIST를 99% 정확도가 되게 만들어보자.
위의 그림과 같이 CNN은 Convolution과 Sampling 그리고 Fully connected로 구성되어있다. 위의 이미지는 Convolution 2번 Sampling 2번 그리고 Fully connected로 구성된 이미지이다.
위의 이미지는 Padding 값 설정에 따른 처리 방법을 이미지로 나타낸 것 이다.
우선 설정은 VALID와 SAME두가지의 방법이 있다. Valid인 경우, Padding없이 그대로 필터를 거치게 됨으로 1,2,2,1과 같은 결과 이미지가 나오게 된다.
Same의 경우, 이미지와 크기를 똑같은 결과가 나오게 하는 설정으로 부족한 부분만큼 0으로 Padding을 채운다. 그래서 결과는 Input이미지와 동일한, 1,3,3,1이 나오게 된다.
Max Pooling에 대한 이미지이다. Image를 2,2 크기로 stride를 1로해서 padding을 same설정으로 처리한다는 내용이다.
Lab-2
import tensorflow as tf
import random
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
training_batch = 100
X = tf.placeholder(tf.float32,
shape=[None, 784])
X_image = tf.reshape(X, [-1,
28, 28, 1])
Y = tf.placeholder(tf.float32, shape=[None, 10])
W1 = tf.Variable(tf.random_normal([3, 3,
1, 32],
stddev=0.01))
L1 = tf.nn.conv2d(X_image, W1, strides=[1,
1, 1, 1], padding='SAME')
L1 = tf.nn.relu(L1)
L1 = tf.nn.max_pool(L1, ksize=[1, 2,
2, 1],
strides=[1, 2, 2,
1], padding='SAME')
W2 = tf.Variable(tf.random_normal([3, 3,
32, 64],
stddev=0.01))
L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1,
1], padding='SAME')
L2 = tf.nn.relu(L2)
L2 = tf.nn.max_pool(L2, ksize=[1, 2,
2, 1],
strides=[1, 2, 2,
1], padding='SAME')
L2_flat = tf.reshape(L2, [-1,
7 * 7 * 64])
W3 = tf.get_variable("W3", shape=[7 * 7
* 64, 10], initializer=tf.contrib.layers.xavier_initializer())
b = tf.Variable(tf.random_normal([10]))
logits = tf.matmul(L2_flat, W3) + b
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits,
labels=Y))
train = 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
/ training_batch)
for
batch in
range(total_batch):
batch_xs,
batch_ys = mnist.train.next_batch(training_batch)
c_,
_ = sess.run([cost,
train], feed_dict={X: batch_xs, Y: batch_ys})
avg_cost += c_ / total_batch
print(epoch, '%04d'
% (epoch + 1), 'cost
= ', '{:9f}'.format(avg_cost))
correct_prediction = tf.equal(tf.argmax(logits,
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}))
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(logits, 1), feed_dict={X:
mnist.test.images[r:r + 1]}))
위의 소스는 기존에 있던 CNN을 소스화 시킨 내용이다.
하나하나 해석을 하면 784개의 변수를 가진 이미지를 28x28x1로 reshape를 시킨다.
그리고 정답은 0~9까지 10개이므로 Y의 변수는 10으로 설정한다.
첫번째 Convolution에서 3,3,1,32 Filter, Stride는 1, Padding은 ‘SAME’로 통과를 시킨다.
그러면 동일한 크기의 (필터를 거친) 이미지가 생성된다.(단, 32개의 채널을 가진다.)
그리고 Relu함수를 사용한 다음, Max Pooling을 통해, 2x2 크기의 stride는 2, Padding은 ‘SAME’을 통과 시킨다.
Padding은 2이나, Stride가 2이므로, 이미지의 크기는 14x14x32가 된다.
다음 똑같은 과정(w2)을 한 번 더 거친다.
그런 다음, 일자로 정렬시키기 위해, reshape를 다시 한번 한다. W2필터를 거친 이미지는 7x7x64의 크기가 되므로, 해당 이미지를 reshape시키기 위해, 모든 것을 곱하여(7*7*64) reshape를 해준다.
다음으로 이전에 배웠던 것과 비슷한 뉴럴 네트워크가 비슷한, Fully connected를 연결해준다.
초기값과 학습방법은 이전에 배웠던 Xavier Initializer와 AdamOptimizer를 사용한다.
다음 내용은 이전과 동일하므로 생략한다.
해당 소스를 돌리면, 다음과 같은 결과값이 나온다. 확실히 거의 99% 가깝게 정확도가 올라 가는걸 확인할 수 있다.
이번에는 조금 더 Deep한 학습을 시켜보자.
import tensorflow as tf
import random
from tensorflow.examples.tutorials.mnist
import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
training_epoch = 15
training_batch = 100
learning_rate = 0.001
keep_prob = tf.placeholder(tf.float32)
X = tf.placeholder(tf.float32, [None,
784])
X_img = tf.reshape(X, [-1, 28, 28,
1])
Y = tf.placeholder(tf.float32, [None,
10])
W1 = tf.Variable(tf.random_normal([3, 3,
1, 32],
stddev=0.01))
L1 = tf.nn.conv2d(X_img, W1, strides=[1,
1, 1, 1], padding='SAME')
L1 = tf.nn.relu(L1)
L1 = tf.nn.max_pool(L1, ksize=[1, 2,
2, 1],
strides=[1, 2, 2,
1], padding='SAME')
L1 = tf.nn.dropout(L1, keep_prob=keep_prob)
W2 = tf.Variable(tf.random_normal([3, 3,
32, 64],
stddev=0.01))
L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1,
1], padding='SAME')
L2 = tf.nn.relu(L2)
L2 = tf.nn.max_pool(L2, ksize=[1, 2,
2, 1],
strides=[1, 2, 2,
1], padding='SAME')
L2 = tf.nn.dropout(L2, keep_prob=keep_prob)
W3 = tf.Variable(tf.random_normal([3, 3,
64, 128],
stddev=0.01))
L3 = tf.nn.conv2d(L2, W3, strides=[1, 1, 1,
1], padding='SAME')
L3 = tf.nn.relu(L3)
L3 = tf.nn.max_pool(L3, ksize=[1, 2,
2, 1],
strides=[1, 2, 2,
1], padding='SAME')
L3 = tf.nn.dropout(L3, keep_prob=keep_prob)
L3_flat = tf.reshape(L3, [-1,
128 * 4 * 4])
W4 = tf.get_variable('W4',
shape=[128 * 4
* 4, 625], initializer=tf.contrib.layers.xavier_initializer())
b4 = tf.Variable(tf.random_normal([625]))
L4 = tf.nn.relu(tf.matmul(L3_flat, W4) + b4)
L4 = tf.nn.dropout(L4, keep_prob=keep_prob)
W5 = tf.get_variable('W5',
shape=[625, 625], initializer=tf.contrib.layers.xavier_initializer())
b5 = tf.Variable(tf.random_normal([625]))
L5 = tf.nn.relu(tf.matmul(L4, W5) + b5)
L5 = tf.nn.dropout(L5, keep_prob=keep_prob)
W6 = tf.get_variable('W6',
shape=[625, 10], initializer=tf.contrib.layers.xavier_initializer())
b6 = tf.Variable(tf.random_normal([10]))
logits = tf.matmul(L5, W6)
+ b6
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits,
labels=Y))
train = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for epoch in range(training_epoch):
avg_cost = 0
total_batch
= int(mnist.train.num_examples
/ training_batch)
for
batch in
range(total_batch):
batch_xs,
batch_ys = mnist.train.next_batch(batch_size=training_batch)
feed_dict = {X: batch_xs, Y: batch_ys,
keep_prob: 0.7}
c_,
_ = sess.run([cost,
train], feed_dict=feed_dict)
avg_cost += c_ / total_batch
print('Epoch:',
'%04d' % (epoch + 1),
'cost =', '{:.9f}'.format(avg_cost))
correct_prediction = tf.equal(tf.argmax(logits,
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, keep_prob: 1}))
# Get one and predict
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(logits, 1), feed_dict={X:
mnist.test.images[r:r + 1], keep_prob:
1}))
위의 소스와 차이점은 overfitting을 방지하기 위해, Dropout을 사용한 부분과 그리고 조금 더 Deep하게 Convolution을 하였고, Fully connected를 했다는 점 말고는 차이점이 없다.
그러나 결과는 다음과 같다.
거의 100%에 육박할 만큼 99%의 정확도를 나타내고 있다.
Lab-3
이번 강의에서는
· Python Class를 이용하여 학습을 모델화 시키는 방법.
· Layers API를 사용하여 학습시키는 방법.
· Ensemble에 대해 배운다.
Ensemble에 대해서 간략히 설명하자면, 학습을 시키는 모델을 여러 개를 둬 학습을 시키는 방법이다. 그러면 그만큼 신뢰할 수 있는 모델이 만들어질 것이다.
import tensorflow as tf
from
tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
training_epoch = 15
training_batch
= 100
learning_rate
= 0.001
class
Model:
def __init__(self, sess, name):
self.sess = sess
self.name = name
self._build()
def _build(self):
with tf.variable_scope(self.name):
self.keep_prob =
tf.placeholder(tf.float32)
self.X =
tf.placeholder(tf.float32, [None, 784])
X_img = tf.reshape(self.X, [-1, 28, 28, 1])
self.Y =
tf.placeholder(tf.float32, [None, 10])
W1 = tf.Variable(tf.random_normal([3, 3, 1, 32], dtype=tf.float32))
L1 = tf.nn.conv2d(X_img, W1, strides=[1, 1, 1, 1], padding='SAME')
L1 = tf.nn.relu(L1)
L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
L1 = tf.nn.dropout(L1, keep_prob=self.keep_prob)
W2 =
tf.Variable(tf.random_normal([3, 3, 32, 64], dtype=tf.float32))
L2 = tf.nn.conv2d(L1, W2, strides=[1, 1, 1, 1], padding='SAME')
L2 = tf.nn.relu(L2)
L2 = tf.nn.max_pool(L2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
L2 = tf.nn.dropout(L2, keep_prob=self.keep_prob)
W3 =
tf.Variable(tf.random_normal([3, 3, 64, 128], dtype=tf.float32))
L3 = tf.nn.conv2d(L2, W3, strides=[1, 1, 1, 1], padding='SAME')
L3 = tf.nn.relu(L3)
L3 = tf.nn.max_pool(L3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
L3 = tf.nn.dropout(L3, keep_prob=self.keep_prob)
L3_flat = tf.reshape(L3, [-1, 4 * 4 * 128])
W4 = tf.get_variable('W4', shape=[128 * 4 * 4, 625],
initializer=tf.contrib.layers.xavier_initializer())
b4 = tf.Variable(tf.random_normal([625]))
L4 =
tf.nn.relu(tf.matmul(L3_flat, W4) + b4)
L4 = tf.nn.dropout(L4, keep_prob=self.keep_prob)
W5 = tf.get_variable('W5', [625, 625], initializer=tf.contrib.layers.xavier_initializer())
b5 =
tf.Variable(tf.random_normal([625]))
L5 = tf.nn.relu(tf.matmul(L4, W5) + b5)
L5 = tf.nn.dropout(L5, keep_prob=self.keep_prob)
W6 = tf.get_variable('W6', [625, 10], initializer=tf.contrib.layers.xavier_initializer())
b6 = tf.Variable(tf.random_normal([10]))
self.logits =
tf.matmul(L5, W6) + b6
self.cost =
tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
logits=self.logits, labels=self.Y))
self.optimizer =
tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(self.cost)
correct_prediction =
tf.equal(tf.argmax(self.logits, 1), tf.argmax(self.Y, 1))
self.accuracy =
tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
def predict(self, x_test, keep_prop=1.0):
return self.sess.run(self.logits, feed_dict={self.X: x_test, self.keep_prob:
keep_prop})
def get_accuracy(self, x_test, y_test, keep_prob=1.0):
return self.sess.run(self.accuracy, feed_dict={self.X: x_test, self.Y: y_test, self.keep_prob:
keep_prob})
def train(self, x_data, y_data, keep_prob=0.7):
return self.sess.run([self.cost, self.optimizer],
feed_dict={self.X: x_data, self.Y: y_data, self.keep_prob:
keep_prob})
sess = tf.Session()
m1 = Model(sess, 'm1')
sess.run(tf.global_variables_initializer())
print('Learning
Started!')
for
epoch in range(training_epoch):
avg_cost = 0
total_batch = int(mnist.train.num_examples
/ training_batch)
for batch in range(total_batch):
batch_xs, batch_ys =
mnist.train.next_batch(training_batch)
c, _ =
m1.train(batch_xs, batch_ys)
avg_cost += c / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning
Finished!')
print('Accuracy:', m1.get_accuracy(mnist.test.images, mnist.test.labels))
우선 Python Class를 이용하여 Model을 구성하여 학습을 시키는 소스이다. 기존의 내용과 다른 점은 없어 이해하는데 어려운 부분은 없을 꺼라 생각되어 생략하겠다.
다음은 Layers API를 이용하여 소스를 구성해보자.
import tensorflow as tf
from
tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
training_epoch = 15
training_batch
= 100
learning_rate
= 0.001
keep_prob
= 0.7
class
Model:
def __init__(self, sess, name):
self.sess = sess
self.name = name
self._build()
def _build(self):
with tf.variable_scope(self.name):
self.training =
tf.placeholder(tf.bool)
self.X =
tf.placeholder(tf.float32, [None, 784])
X_img = tf.reshape(self.X, [-1, 28, 28, 1])
self.Y =
tf.placeholder(tf.float32, [None, 10])
conv1 = tf.layers.conv2d(inputs=X_img, filters=32, kernel_size=[3, 3], padding='SAME',
activation=tf.nn.relu)
pool1 =
tf.layers.max_pooling2d(inputs=conv1, pool_size=2, strides=2, padding='SAME')
drop1 = tf.layers.dropout(inputs=pool1, rate=keep_prob, training=self.training)
conv2 = tf.layers.conv2d(inputs=drop1, filters=64, kernel_size=[3, 3], padding='SAME',
activation=tf.nn.relu)
pool2 =
tf.layers.max_pooling2d(inputs=conv2, pool_size=2, strides=2, padding='SAME')
drop2 = tf.layers.dropout(inputs=pool2, rate=keep_prob, training=self.training)
conv3 = tf.layers.conv2d(inputs=drop2, filters=128, kernel_size=[3, 3], padding='SAME',
activation=tf.nn.relu)
pool3 =
tf.layers.max_pooling2d(inputs=conv3, pool_size=2, strides=2, padding='SAME')
drop3 = tf.layers.dropout(inputs=pool3, rate=keep_prob, training=self.training)
flat = tf.reshape(drop3, [-1, 128 * 4 * 4])
dense4 = tf.layers.dense(inputs=flat, units=128 * 4 * 4, activation=tf.nn.relu)
drop4 = tf.layers.dropout(inputs=dense4, rate=keep_prob, training=self.training)
self.logits =
tf.layers.dense(inputs=drop4, units=10)
self.cost =
tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
logits=self.logits, labels=self.Y))
self.optimizer =
tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(self.cost)
correct_prediction =
tf.equal(tf.argmax(self.logits, 1), tf.argmax(self.Y, 1))
self.accuracy =
tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
def predict(self, x_test, trainning=False):
return self.sess.run(self.logits,
feed_dict={self.X: x_test, self.training:
trainning})
def get_accuracy(self, x_test, y_test, trainning=False):
return self.sess.run(self.accuracy, feed_dict={self.X: x_test, self.Y: y_test,
self.training: trainning})
def train(self, x_data, y_data, trainning=True):
return self.sess.run([self.cost, self.optimizer],
feed_dict={self.X: x_data, self.Y: y_data, self.training:
trainning})
sess = tf.Session()
m1 = Model(sess, 'm1')
sess.run(tf.global_variables_initializer())
print('Learning
Started!')
for
epoch in range(training_epoch):
avg_cost = 0
total_batch = int(mnist.train.num_examples
/ training_batch)
for batch in range(total_batch):
batch_xs, batch_ys =
mnist.train.next_batch(training_batch)
c, _ = m1.train(batch_xs, batch_ys)
avg_cost += c / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning
Finished!')
print('Accuracy:', m1.get_accuracy(mnist.test.images, mnist.test.labels))
위의 내용에서 알 수 있듯이. 코드 수가 줄어드는 걸 알 수 있다.
해당 Layers API에 대한 설명은 https://www.tensorflow.org/api_docs/python/tf/layers 에서 자세히 나와있다.
마지막으로 Ensemble에 대해 알아보자.
이전에 설명했듯이, 한번에 여러 개의 모델로 학습을 시켜 정확도를 높이는 방법이다.
위의 이미지와 같이 구성이 된다.
import tensorflow as tf
import
numpy as np
from
tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
training_epoch = 15
training_batch
= 100
learning_rate
= 0.001
keep_prob
= 0.7
class
Model:
def __init__(self, sess, name):
self.sess = sess
self.name = name
self._build()
def _build(self):
with tf.variable_scope(self.name):
self.training =
tf.placeholder(tf.bool)
self.X =
tf.placeholder(tf.float32, [None, 784])
X_img = tf.reshape(self.X, [-1, 28, 28, 1])
self.Y =
tf.placeholder(tf.float32, [None, 10])
conv1 = tf.layers.conv2d(inputs=X_img, filters=32, kernel_size=3, padding='SAME',
activation=tf.nn.relu)
pool1 =
tf.layers.max_pooling2d(inputs=conv1, pool_size=2, strides=2, padding='SAME')
drop1 = tf.layers.dropout(inputs=pool1, rate=keep_prob, training=self.training)
conv2 = tf.layers.conv2d(inputs=drop1, filters=64, kernel_size=3, padding='SAME',
activation=tf.nn.relu)
pool2 =
tf.layers.max_pooling2d(inputs=conv2, pool_size=2, strides=2, padding='SAME')
drop2 = tf.layers.dropout(inputs=pool2, rate=keep_prob, training=self.training)
conv3 = tf.layers.conv2d(inputs=drop2, filters=128, kernel_size=3, padding='SAME',
activation=tf.nn.relu)
pool3 =
tf.layers.max_pooling2d(inputs=conv3, pool_size=2, strides=2, padding='SAME')
drop3 = tf.layers.dropout(inputs=pool3, rate=keep_prob, training=self.training)
flat = tf.reshape(drop3, [-1, 128 * 4 * 4])
dense4 = tf.layers.dense(inputs=flat, units=128 * 4 * 4, activation=tf.nn.relu)
drop4 = tf.layers.dropout(inputs=dense4, rate=keep_prob, training=self.training)
self.logits =
tf.layers.dense(inputs=drop4, units=10)
self.cost =
tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
logits=self.logits, labels=self.Y))
self.optimizer =
tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(self.cost)
correct_prediction =
tf.equal(tf.argmax(self.logits, 1), tf.argmax(self.Y, 1))
self.accuracy =
tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
def predict(self, x_test, trainning=False):
return self.sess.run(self.logits,
feed_dict={self.X: x_test, self.training:
trainning})
def get_accuracy(self, x_test, y_test, trainning=False):
return self.sess.run(self.accuracy, feed_dict={self.X: x_test, self.Y: y_test,
self.training: trainning})
def train(self, x_data, y_data, trainning=True):
return self.sess.run([self.cost, self.optimizer],
feed_dict={self.X: x_data, self.Y: y_data, self.training:
trainning})
sess = tf.Session()
models = []
num_models = 2
for
m in range(num_models):
models.append(Model(sess, 'model' + str(m)))
sess.run(tf.global_variables_initializer())
print('Learning
Started!')
for
epoch in range(training_epoch):
avg_cost_list = np.zeros(len(models))
total_batch = int(mnist.train.num_examples
/ training_batch)
for batch in range(total_batch):
batch_xs, batch_ys =
mnist.train.next_batch(training_batch)
for idx, m in enumerate(models):
c, _ =
m.train(batch_xs, batch_ys)
avg_cost_list[idx] += c /
total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
print('Learning
Finished!')
test_size = len(mnist.test.labels)
predictions = np.zeros(test_size * 10).reshape(test_size, 10)
for
idx, m in enumerate(models):
print(idx, 'Accuracy:', m.get_accuracy(
mnist.test.images, mnist.test.labels))
p = m.predict(mnist.test.images)
predictions += p
ensemble_correct_prediction = tf.equal(tf.argmax(predictions, 1), tf.argmax(mnist.test.labels, 1))
ensemble_accuracy = tf.reduce_mean(tf.cast(ensemble_correct_prediction, tf.float32))
print('Ensemble
accuracy: ', sess.run(ensemble_accuracy))
기존의 내용과 다른 건 없고, 마지막 부분만 조금 다르다.
우선 model의 개수를 정하고, 배열에 담는다.
다음 각각의 모델을 순서대로 학습을 시킨다.
테스트(결과값) 데이터의 개수를 추출한 다음, Label의 종류가 10개이므로, 10을 곱해준다.
그리고 reshape로 각각 테스트 데이터 형태를 (테스트크기, 10) 와 같은 형태로 변경해준다.
그리고 각 값들을 학습시킨 후, 평균값을 낸다.
그리고 그 평균된 값을 기준으로, 최대값(argmax)를 뽑으면 우리가 원하는 결과값이 나온다.
위의 설명을 이미지로 나타낸 모습이다.
'''
0 Accuracy: 0.9933
1 Accuracy: 0.9946
2 Accuracy: 0.9934
3 Accuracy: 0.9935
4 Accuracy: 0.9935
5 Accuracy: 0.9949
6 Accuracy: 0.9941
Ensemble accuracy: 0.9952
'''
다음은 Ensemble을 사용한 후, 결과값이다. 기존에도 정확도가 높아, 많은 수치의 변화는 없지만 확실히 증가된 것을 확인할 수 있고, 정확도가 높은 상태에서의 수치 증가는 비록 그 값이 작더라도, 엄청난 변화인 걸 알 수 있다.
'AI > Tensorflow' 카테고리의 다른 글
[모두의딥러닝] Recurrent Neural Network (0) | 2017.09.06 |
---|---|
[모두의딥러닝] Neural Network 2: ReLU and 초기값 정하기 (2006/2007 breakthrough) (0) | 2017.09.04 |
[모두의딥러닝] Neural Network 1: XOR 문제와 학습방법, Backpropagation (1986 breakthrough) (0) | 2017.09.04 |
[모두의딥러닝] 딥러닝의 기본 개념과, 문제, 그리고 해결 (0) | 2017.09.03 |
[모두의딥러닝] ML의 실용과 몇가지 팁 (0) | 2017.08.23 |
- web
- 모두의딥러닝
- spring
- Error
- AI
- 머신러닝
- Docker
- tensorflow
- TDD
- 중앙정보처리학원
- Java
- AWS
- python
- ML
- 텐서플로우
- Configuration
- 점프투파이썬
- API
- Maven
- BigData
- mybatis
- mysql
- spark
- 파이썬
- Gradle
- executor
- memory
- javascript
- NIO
- serverless
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |