달력

09

« 2018/09 »

  •  
  •  
  •  
  •  
  •  
  •  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  •  
  •  
  •  
  •  
  •  
  •  

[정리] 모두를 위한 딥러닝 07 - 실전 연습 및 팁  by 김성훈 


강의 웹사이트 : http://hunkim.github.io/ml/

Lec = 강의 / Lab = 실습


러닝 레이트 learning rate 가 너무 크면 아래 그림과 같이 예측값이 아래로 수렴하는게 아니고,

밖으로 나가버리는 경우가 생깁니다.

 


반대로 러닝 레이트 learning rate 가 너무 작으면 좋은 예측을 못하거나 시간이 너무 오래 걸립니다. 


그리고, 2차 함수를 3차원처럼 등고선으로 나타낼 수도 있습니다.

만약 x1, x2 두 값이 입력값인데, 차이가 너무 크다면 납작한 원이 될 수 있습니다.

이렇게 되면 데이터를 함수에 넣기 전에 먼저 적절한 처리를 해야 합니다.


이렇게 넓은 범위를 포함하고 있는 입력값이 있다면 이를 적절한 범위로 만드는 선 작업이 필요합니다.

그걸 프리 프로세싱. 노말라이제이션. 정규화 라고 부릅니다.


정규화를 위한 많은 알고리즘이 있지만 유명한 스탠다디제이션은 아래와 같습니다.

코드를 보니 파이썬으로 구현할때에는 좀 쉬워 보입니다.


다음에는 오버피팅이라는걸 살펴보겠습니다.

빨간 네모가 예측해야 하는 값이라면 이게 - 마이너스일까 + 플러스일까 쉽지 않습니다.

왼쪽 그래프로 본다면 - 마이너스가 되지만 (적절한 학습), 오른쪽 그래프로 보면 + 플러스가 됩니다.

- 마이너스가 맞는 값인데, 너무 정확하게 학습하면 + 플러스로 잘못 예측하게 됩니다.

이걸 오버피팅이라고 합니다. 

경계선을 그을때 너무 구부리지 말아야 합니다.

어떻게 이렇게 할 수 있을까요?

많은 트레이닝 셋이 필요합니다. 데이터가 많아야 합니다.

너무 큰 값, 동떨어진 값, 특정값은 줄여야 합니다.

일반화를 시켜야 합니다.


이를 파이썬으로 구현하면 아주 쉽습니다.

square 함수를 사용하면 됩니다.


그래서 트레이닝 세트가 (기반 데이터가) 많으면 일부를 따로 뺍니다.

따로 남겨둔 데이터는 트레이닝을 하지 않고 모의 테스트를 진행합니다.






Posted by 멋지다마라송

[정리] 모두를 위한 딥러닝 08 - 딥러닝 개념  by 김성훈 


강의 웹사이트 : http://hunkim.github.io/ml/

Lec = 강의 / Lab = 실습


사람의 뇌를 연구해보니 작은 뉴런들이 신호를 주고 받는걸로 밝혀졌는데,
이 뉴런 하나는 아주 단순한 신호를 전달하지만, 이게 합해지면서 바로 생각이라는게 만들어진다는 것이었습니다.

"이를 기계에도 적용해서 학습시키면 좋은 결과가 나오지 않을까" 라는 생각에서 CNN (Convolutional Neural Networks) 이 생겨났습니다.


그리고, 리니어 리그레션만으로는 XOR 를 풀 수 없습니다.


이런 문제를 Convolutional Neural Networks (CNN) 기법으로 풀 수 있습니다.


MNIST = 글자 이미지를 분석해서 어떤 글자인지 맞추는 학습인데, 지금은 거의 99% 정확도에 도달하고 있습니다.

(99% 정확도는 아마 영어만 인거 같습니다.)




Posted by 멋지다마라송

[정리] 모두를 위한 딥러닝 06 - Softmax Regression (Multinomial Logistic Regression)  by 김성훈 


강의 웹사이트 : http://hunkim.github.io/ml/

Lec = 강의 / Lab = 실습


결과값이 A, B, C 중에 하나인 경우, 지금까지 알아본 내용(리니어 리그리션)으로는 불가능합니다.

시그모이드 개념과 비슷하긴 하지만, 이 함수는 둘 중 하나로 수렴하기 때문에,

결과가 3개 넘을때에는 이중에서 하나로 수렴할 수 있는 방법이 없습니다.


A, B, C 가 나올 확률을 구해서 가장 높은거 하나만 1, 나머지는 0 으로 만들면 됩니다.

A, B, C 가 나올 확률의 합은 1 이 됩니다. 

입력 X, 결과 Y 모두 행렬을 이용하는데, 이 개념이 소프트맥스 softmax 입니다.

이를 위해 로그함수를 두번 사용하면 가능하며, 더 발전된 원핫 인코딩 One-Hot 함수를 사용하면 좋습니다.




실제 소스 코드는 아래와 같습니다.




x_data = [[1, 2, 1, 1], [2, 1, 3, 2], [3, 1, 3, 4], [4, 1, 5, 5], [1, 7, 5, 5],

                                                       [1, 2, 5, 6], [1, 6, 6, 6], [1, 7, 7, 7]]

y_data = [[0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 1, 0], [0, 1, 0], [0, 1, 0], [1, 0, 0], [1, 0, 0]]


X = tf.placeholder("float", [None, 4])

Y = tf.placeholder("float", [None, 3])

nb_classes = 3


W = tf.Variable(tf.random_normal([4, nb_classes]), name='weight')

b = tf.Variable(tf.random_normal([nb_classes]), name='bias')


# tf.nn.softmax computes softmax activations

# softmax = exp(logits) / reduce_sum(exp(logits), dim)

hypothesis = tf.nn.softmax(tf.matmul(X, W) + b)


# Cross entropy cost/loss

cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1))

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)


# Launch graph

with tf.Session() as sess:

  sess.run(tf.global_variables_initializer())


  for step in range(2001):

      sess.run(optimizer, feed_dict={X: x_data, Y: y_data})

      if step % 200 == 0:

          print(step, sess.run(cost, feed_dict={X: x_data, Y: y_data}))


-----------------------------------------------------------------------------

파일에서 불러와서 원핫 인코딩을 사용하는 샘플

# Predicting animal type based on various features

xy = np.loadtxt('data-04-zoo.csv', delimiter=',', dtype=np.float32)

x_data = xy[:, 0:-1]

y_data = xy[:, [-1]]


nb_classes = 7  # 0 ~ 6


X = tf.placeholder(tf.float32, [None, 16])

Y = tf.placeholder(tf.int32, [None, 1])  # 0 ~ 6


Y_one_hot = tf.one_hot(Y, nb_classes)  # one hot

Y_one_hot = tf.reshape(Y_one_hot, [-1, nb_classes])


W = tf.Variable(tf.random_normal([16, nb_classes]), name='weight')

b = tf.Variable(tf.random_normal([nb_classes]), name='bias')


# tf.nn.softmax computes softmax activations

# softmax = exp(logits) / reduce_sum(exp(logits), dim)

logits = tf.matmul(X, W) + b

hypothesis = tf.nn.softmax(logits)


# Cross entropy cost/loss

cost_i = tf.nn.softmax_cross_entropy_with_logits(logits=logits,

                                               labels=Y_one_hot)

cost = tf.reduce_mean(cost_i)

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)

cost = tf.reduce_mean(cost_i)

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)


prediction = tf.argmax(hypothesis, 1)

correct_prediction = tf.equal(prediction, tf.argmax(Y_one_hot, 1))

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

# Launch graph

with tf.Session() as sess:

  sess.run(tf.global_variables_initializer())


  for step in range(2000):

      sess.run(optimizer, feed_dict={X: x_data, Y: y_data})

      if step % 100 == 0:

          loss, acc = sess.run([cost, accuracy], feed_dict={

                               X: x_data, Y: y_data})

          print("Step: {:5}\tLoss: {:.3f}\tAcc: {:.2%}".format(

              step, loss, acc))


  # Let's see if we can predict

  pred = sess.run(prediction, feed_dict={X: x_data})

  # y_data: (N,1) = flatten => (N, ) matches pred.shape

  for p, y in zip(pred, y_data.flatten()):

      print("[{}] Prediction: {} True Y: {}".format(p == int(y), p, int(y)))



소스코드 다운로드 : https://github.com/hunkim/DeepLearningZeroToAll



Posted by 멋지다마라송

[정리] 모두를 위한 딥러닝 10 - ReLU & 초기값 정하기   by 김성훈 


강의 웹사이트 : http://hunkim.github.io/ml/

Lec = 강의 / Lab = 실습


시그모이드 결과값은 0<f(x)<1 이기 때문에 이를 체인룰에 따라 계속 곱하다보면 (레이어가 많으면) 

0.01 * 0.03 * 0.2 와 같은 형태가 되기 때문에 결국 한없이 0 에 가까워지게 됩니다. 

즉, 입력값 X 가 결과값 f(x), Y 에 미치는 영향이 거의 없게 됩니다.  

따라서, 학습을 깊게 여러번 하면 할수록 에러가 커지는 현상이 일어납니다. 이건 오버피팅 Over Fitting 과 다릅니다.


이를 극복하기 위한 함수가 렐루 ReLU 입니다. (위 그림에서 검정색이 시그모이드 sigmoid, 자주색이 렐루 ReLU 함수)

렐루는 0 이하는 0 으로, 그 이상값은 자기 자신의 값을 갖는 함수입니다.


이 두가지 함수를 비교하기 위해 텐서보드 tensorboard 를 이용해보겠습니다.

텐서보드로 분석할 수 있도록 로그를 남긴 다음, 텐서보드를 띄워서 웹브라우저로 확인하면 됩니다.

생각보다 메모리나 CPU 를 많이 사용하는, 좀 무거운 라이브러리입니다.

(텐서보드 이미지 추가)


정확도 비교.

1번 방법 = 시그모이드를 사용하여 레이어 3개 ~ 10개 사용하기.

# weights & bias for nn layers
with tf.name_scope("L1") as scope:
W1 = tf.Variable(tf.random_normal([784, 256]))
b1 = tf.Variable(tf.random_normal([256]))
L1 = tf.sigmoid(tf.matmul(X, W1) + b1)
w1_hist = tf.summary.histogram("weights1", W1)
b1_hist = tf.summary.histogram("biases1", b1)
layer1_hist = tf.summary.histogram("L1", L1)

with tf.name_scope("L2") as scope:
W2 = tf.Variable(tf.random_normal([256, 256]))
b2 = tf.Variable(tf.random_normal([256]))
L2 = tf.sigmoid(tf.matmul(L1, W2) + b2)
w2_hist = tf.summary.histogram("weights2", W2)
b2_hist = tf.summary.histogram("biases2", b2)
layer2_hist = tf.summary.histogram("L2", L2)

이런 형태로 레이어를 3개, 10개 만듭니다.


2번 방법 = 렐루 relu 를 사용하여 레이어 3개 ~ 10개 사용하기.

# weights & bias for nn layers
with tf.name_scope("L1") as scope:
W1 = tf.Variable(tf.random_normal([784, 256]))
b1 = tf.Variable(tf.random_normal([256]))
L1 = tf.nn.relu(tf.matmul(X, W1) + b1)
w1_hist = tf.summary.histogram("weights1", W1)
b1_hist = tf.summary.histogram("biases1", b1)
layer1_hist = tf.summary.histogram("L1", L1)

with tf.name_scope("L2") as scope:
W2 = tf.Variable(tf.random_normal([256, 256]))
b2 = tf.Variable(tf.random_normal([256]))
L2 = tf.nn.relu(tf.matmul(L1, W2) + b2)
w2_hist = tf.summary.histogram("weights2", W2)
b2_hist = tf.summary.histogram("biases2", b2)
layer2_hist = tf.summary.histogram("L2", L2)

이런 형태로 레이어를 3개, 10개 만듭니다.

두 소스에서 sigmoid / relu 이 부분만 다릅니다.


4개의 소스를 비교해보면 

 

 Sigmoid 3 Layer

 ReLU 3 Layer

 Sigmoid 10 Layer

 ReLU 10 Layer

 정확도

 94.21 %

 95.87 %

 94.31 %

 93.00 %


엠니스트 MNIST 는 위 4가지 중에서 렐루 3 레이어로 만들때 가장 좋은 결과가 나왔습니다.

즉, 너무 많은 레이어는 결과가 더 나빠지기도 합니다.


그리고, 초기값 잘 설정하는게 중요합니다.

(정리중)

RBM : Restricted Boatman (Boltzman) Machine

자비어 : xavier

MSRA



Posted by 멋지다마라송

[정리] 모두를 위한 딥러닝 09 - XOR 풀기  by 김성훈 


강의 웹사이트 : http://hunkim.github.io/ml/

Lec = 강의 / Lab = 실습


XOR 게이트는 입력값 두개를 받아서, 두개가 다르면 (1,0) 또는 (0,1) 이런 형태이면 1 참값을 리턴하는 함수입니다.


XOR 게이트는 한개의 선형 리니어 함수로는 풀 수 없고, 여러개를 이용하면 풀 수 있습니다.


이렇게 3개로 연결해서 만들면 됩니다.


여기에서는 w1, b1 값이 주어졌는데, 이 값 말고도 다른 값도 찾을 수 있습니다.

이 슬라이드에서 5, -8 / -7, 3 / -11, 6 이런 값들이 이미 주어졌지만, 이 값들은 학습을 통해 찾아야 합니다.


이를 위해 백 프로파게이션 기법을 이용합니다.

출력으로 나온 에러 loss 를 다시 뒤에서부터 계산하는 방법입니다. (계산할때에는 편미분을 사용합니다.)


아래 슬라이드에서 보면 빨간색 가장 위에 글자. 편미분 : w 가 f 에 미치는 영향. 이걸 먼저 보겠습니다. 

최종적으로 입력값이 가장 마지막에 있는 f 에 미치는 영향.이 필요한건데, 아래와 같이 구할 수 있습니다.

w 가 f 에 미치는 영향 = g 가 f 에 미치는 영향 * x 가 f 에 미치는 영향 = 편미분 f/g * 편미분 g/x  = 1 * w


이렇게 편미분을 뒤에서부터 계산하면 아주 쉽게 이 값들을 구할 수 있습니다.

편미분들의 곱으로 전체를 나타내는 방법이 바로 백 프로파게이션 이며, 이를 체인룰 이라고도 합니다.

특히 가장 마지막에 있는 함수 f 를 Activation Function 이라고 부릅니다.

자, 그런데 이 함수가 시그모이드 형태를 띄고 있다면 문제가 있습니다.

1 또는 0 에 수렴하기 때문에 무조건 1 보다 작게 됩니다.

그러니 f 결과값, 즉 액티베이션 함수의 결과값을 곱하면 (이런 로직이 생긴다) 0 보다 한없이 작아지게 됩니다.

다음번에 이걸 풀어보겠습니다.


참고로, 이렇게 그려지는 그래프를 텐서보드로 확인하는 방법입니다. (소스 09-4)

D:\marasong\Workspace\DeepLearningZeroToAll-master>tensorboard --logdir=./logs/xor_logs_r0_01

실행한 다음 웹 브라우저로 확인해 볼 수 있습니다.

Posted by 멋지다마라송


티스토리 툴바