close_btn
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print Files

슬라이드1.JPG슬라이드2.JPG슬라이드12.JPG

2주차에 이어 출력층에서 사용하는 활성화함수 가운데 Softmax 함수를 살펴보겠습니다.


슬라이드13.JPG

Softmax 함수는 모든 입력신호로부터 영향을 받는다는 특징이 있습니다. 이렇게 설계된 이유는 '확률적 해석'을 가능하게 하는 것이 Softmax 함수의 목적이기 때문입니다.


슬라이드14.JPG

주의점 가운데 오버플로에 대해 추가적으로 언급하자면, 오버플로가 발생하게 되면 무한대 값이 리턴되어 연산을 진행할 수 없게 됩니다. 따라서 지수함수의 값이 무한대로 발산하지 않도록 분모 분자에 C값을 곱합니다. (아래 계산1 참고)

즉, 분모 분자에 C 값을 곱함으로써 총량에는 변화가 없지만, C*값을 더해줌으로써 지수함수를 컨트롤 해주는 것입니다.

수식1.PNG

슬라이드15.JPG

앞서 언급한 것과 같이 Softmax는 확률적으로 해석할 수 있는 데 의미가 있습니다. 즉, Yk=(관심있는 출력 값)/(전체) 인 것입니다.


슬라이드16.JPG슬라이드17.JPG

일반적으로 사용되는 손실함수는 MSE, 교차 엔트로피 오차 등이 있습니다. 손실함수는 Minimize 하는 것이 좋습니다.


슬라이드18.JPG

미니배치 학습은 Sampling과 동일한 개념입니다. 데이터가 매우 커지면 모든 값에 대해 손실함수 등을 구하는 것은 엄청난 연산과 시간을 필요로 하므로 일부를 Sample(Mini Batch)로 뽑아 학습 시키겠다는 것입니다. 


슬라이드19.JPG슬라이드20.JPG슬라이드21.JPG

우측 위의 4가지 사진을 보면 각 방법론마다 최적의 값(중앙)을 찾아가는 경로가 보일 것입니다. SGD의 경우 가장 효율적이지 못한 움직임을 보여주며, Momentum보다는 하단의 AdaGrad와 Adam이 더 효율적인 움직임을 보이는 것을 알 수 있습니다. 

실제로 SGD는 빅데이터를 다룰 때는 효과적이지 못하기때문에 자주 사용되지는 않는다고 합니다. 그럼에도 SGD를 이번 세미나에서 학습한 이유는 가장 기초적인 방법이자, 작은 데이터에선 쉽게 사용할 수 있기 때문입니다.


슬라이드24.JPGSGD는 Stochastic Gradient Descent의 약자입니다. SGD는 Gradient의 반대방향으로 파라미터를 업데이트하는 것입니다. (왜냐하면 Gradient는 증가하는 방향을 가리키기 때문) 따라서 W에 대한 손실함수가 Minimize되는 방향인 중심으로 향하게 됩니다.



슬라이드25.JPG슬라이드26.JPG슬라이드27.JPG

앞서 언급한 것과 같이 손실함수는 Minimize 해야 하는 값입니다. 하지만, 가중치가 특히 큰 값은 학습을 거듭할 수록 해당 가중치에 오버피팅이 될 가능성이 높아집니다. 따라서 가중치에 더해지는 손실함수를 의도적으로 크게 키워(Minimize와 반대) 가중치를 감소시킴으로써 오버피팅을 방지시키는 방법론입니다.


슬라이드28.JPG


이제 텐서플로우를 이용해 위의 개념들을 적용해보겠습니다. 

손으로 쓴 숫자 이미지를 0~9 사이의 숫자로 인식하는 예제인 MNIST 데이터를 활용해보았습니다.

(아래의 내용은 http://bcho.tistory.com/1154 블로그를 참고하였습니다.)

mnist1.PNG


MNIST 데이터셋은 총 60000개의 데이터가 있습니다. 학습을 위한 데이터인 mnist.train, 테스트 셋인 mnist.test가 있고 모델을 확인하기 위한 mnist.validation 으로 구분이 됩니다. 각 데이터셋은 글자 이미지인 image와 그 이미지가 어떤 숫자인지 나타낸 라벨 데이터 label로 구성되어 있습니다.

데이터 셋.PNG


*이미지 데이터


이미지 데이터는 아래 그림과 같이 28x28로 구성되어 있습니다.

mnist4.PNG

이를 2차원 행렬에서 784개(28*28)의 열을 가진 1차원 행렬로 변환되어 저장이 되어 있습니다.

mnist.train.image는 이러한 이미지가 55000개 저장되어 있습니다.

mnist2.PNG


*소프트맥스

소프트맥스로 분류를 할 때, 모델에서 사용하는 가설은 다음과 같습니다.

Y = Softmax(W*x + b) (W는 Weight, b는 Bias를 의미)

Y값은 최종적으로 0~9까지의 숫자를 판단하는 결과가 나와야하므로 크기가 10인 행렬이 됩니다.

그리고, 이미지 하나는 784개의 숫자로 되어 있기 때문에 10개의 값을 각각 784개의 숫자에 적용하면 W는 784x10 행렬이 됩니다. b는 10개의 값에 각각 더하는 값이므로 크기가 10인 행렬이 됩니다.

mnist3.PNG


이를 파이썬 코드로 구현하면 아래와 같습니다.

여기서는 매개변수 갱신 방법론으로 일반적 Gradient Descent를 이용했고, 손실함수로 교차엔트로피를 사용했습니다.



import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data


# MNIST 데이터

mnist = input_data.read_data_sets("./samples/MNIST_data/", one_hot=True)


# Set up model

x = tf.placeholder(tf.float32, [None, 784])  # Input data가 들어갈 공간 정의 *None : 해당 값이 어떤 차원이든 될 수 있음을 의미

W = tf.Variable(tf.zeros([784, 10])) # 가중치 매개변수 설정. 784개의 이미지 벡터.

b = tf.Variable(tf.zeros([10])) # bias 설정

y = tf.nn.softmax(tf.matmul(x, W) + b) # softmax 함수 정의. matmul(x,W)는 x와 W를 곱하는 것.


y_ = tf.placeholder(tf.float32, [None, 10]) # 정답이 들어갈 공간 정의


cross_entropy = -tf.reduce_sum(y_*tf.log(y)) # 손실함수인 교차엔트로피 정의. 

# tf.log(y) : y의 각 원소에 대한 로그값

# tf.reduce_sum : 합



train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) 

# 경사하강법 이용하여 손실함수인 교차엔트로피 최소화


# Session

init = tf.global_variables_initializer() # 변수 초기화


sess = tf.Session() # 그래프를 돌릴 수 있는 객체를 만듦

sess.run(init) #


# Learning

for i in range(1000): # 1000번 학습 시작

  batch_xs, batch_ys = mnist.train.next_batch(100) # 100개를 임의 추출

  sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})


# Validation

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)) 

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 


# Result should be approximately 91%.

print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))

mnist5.PNG



TensorBoard를 활용한 분석


코드는 아래와 같습니다.


import tensorflow as tf

from tensorflow.examples.tutorials.mnist import input_data


# Dataset loading

mnist = input_data.read_data_sets("./samples/MNIST_data/", one_hot=True)


# Set up model


x = tf.placeholder(tf.float32, [None, 784])

W = tf.Variable(tf.zeros([784, 10]))

b = tf.Variable(tf.zeros([10]))

y = tf.nn.softmax(tf.matmul(x, W) + b)


y_ = tf.placeholder(tf.float32, [None, 10])


w_hist = tf.summary.histogram("W", W)

b_hist = tf.summary.histogram("b", b)


cross_entropy = -tf.reduce_sum(y_*tf.log(y))

cross_entropy_scalar = tf.summary.scalar("cross_entropy", cross_entropy)

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)


# Session

init = tf.global_variables_initializer()


sess = tf.Session()

sess.run(init)


correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

accuracy_scalar = tf.summary.scalar("accuracy", accuracy)


merged = tf.summary.merge([w_hist, b_hist, cross_entropy_scalar, accuracy_scalar])

writer = tf.summary.FileWriter("./logs", sess.graph)


# Learning

for i in range(1000):

  batch_xs, batch_ys = mnist.train.next_batch(100)

  summary,_ = sess.run([merged, train_step], feed_dict={x: batch_xs, y_: batch_ys})

  writer.add_summary(summary, i)

# Validation


# Result should be approximately 91%.

print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))



주피터를 사용해 위의 코드를 수행하면 주피터 작업 디렉터리에 logs라는 폴더가 생기게 됩니다.

그리고 anaconda prompt 창에 아래와 같이 입력하면 TensorBoard를 이용할 수 있는 주소를 얻을 수 있습니다.


tensorboard --logdir=./주피터작업디렉터리/logs

tensorboard.PNG


아래는 Tensorboard에서 제공하는 분석자료입니다.


tensorboard2.PNG

x축은 train 횟수 입니다. train 횟수가 높아질수록(우측으로 갈수록) 분류 정확도가 높아짐을 알 수 있습니다.



tensorboard3.PNG

train 횟수가 높아질수록 손실함수가 작아지는 것을 볼 수 있습니다.


tensorboard4.PNG 

위의 그래프는 train 횟수에 따른 Weight의 분포입니다.



tensorboard5.PNG

이 그래프는 train 횟수에 따른 bias의 분포입니다.


나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5