SOFTMAX REGRESSION이란 Logistic Classfication 의 일종으로 Multinomial, 즉 다항을 사용하여 학습하는 모델입니다.
제공되는 데이터를 비교해보면 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 | //Logistic Classification x_data = [[40, 40], [50, 50], [60, 60], [70, 70], [80, 80], [90, 90]] y_data = [[0], [0], [0], [1], [1], [1]] //Multinomial Logistic Classification ( Softmax Regression ) x_data = [[1, 2], [2, 1], [3, 1], [4, 1], [1, 7], [1, 2], [1, 6], [1, 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]] | cs |
Softmax의 y_data 데이터셋을 이해하기 위해서는 ONE HOT ENCODING에 대해서 먼저 알아야 합니다.
[ONE HOT ENCODING]
1 2 | x_data = [[1, 2], [2, 1], [3, 1], [4, 1], [1, 7], [1, 2], [1, 6], [1, 7]] y_data = [[A], [A], [A], [B], [B], [B], [C], [C]] | cs |
다음과 같은 데이터가 있습니다.
우리는 Logistic Classfication을 이용해서 각각의 x 데이터셋이 A, B, C 를 지정함( 분류 )을 학습해야 합니다.
이는 단순히 PASS / NPASS로 생각할 수 없는 문제입니다.Logistic Classitication에서는 모든 y 데이터셋이 0 또는 1로 구성되어야 하기 때문입니다.
따라서 이 모델을 이용하기 위해서는 A, B, C를 0 또는 1로 구성해야 합니다. 따라서 데이터를 다음과 구성하는 방법이 ONE HOT ENCODING 입니다.
A -> [0, 0, 1] //2번째 자리가 1
B -> [0, 1, 0] //1번째 자리가 1
C -> [1, 0, 0] //0번째 자리가 1
따라서 y_data 데이터셋은 다음과 같이 각각 A, B, C를 나타낼 수 있습니다.
1 | 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]] | cs |
이제 Hypothesis를 구성해야합니다. 기본 Logistic 에서는 Sigmoid 함수를 사용해서 이를 구성했는데 [#E5 : Logistic Classification 이란?], 이번에는 y 데이터의 형태가 달라졌으므로 Sofmax 함수를 이용해야 합니다.
A = X * W (Hypothesis) [2번째 자리의 추정값]
B = X * W (Hypothesis) [1번째 자리의 추정값]
C = X * W (Hypothesis) [0번째 자리의 추정값]
*b는 임의의 값이므로 제외
각각의 X*W (Hypothesis) 에서 임의의 크거나 작은 추정값를 가지게 됩니다 [#E4 : 다중 변수를 가지는 Multi Variables Linear Regression]. 여기서 Softmax 함수는 데이터에 따라 도출된 추정값의 합계가 1이 되도록 도와줍니다.
[Softmax 함수로 변환된 추정값 예시]
A = X * W = Softmax(추정값) = 0.7
B = X * W = Softmax(추정값) = 0.2
C = X * W = Softmax(추정값) = 0.1
이것은 곧 다음과 같이 표현됩니다.
[C추정값 = 0.1, B추정값 = 0.2, A추정값 = 0.7]
즉 Softmax 함수는 두 가지 역할을 수행합니다.
1. Sigmoid 함수처럼 추정값을 0과 1 사이로 만들어준다.
2. 변환된 값을 더한 총 합계가 1이 되도록 만들어준다.
따라서 총합이 1이므로 이는 마치 확률처럼 볼 수 있습니다. 위의 예시에서 보면 A가 될 확률은 0.7 입니다. 마찬가지로 B는 0.2, C는 0.1입니다.
즉, A가 될 확률이 제일 높으므로 이것은 A = [0, 0, 1] 과 같다고 볼 수 있습니다.
이를 종합해서 Hypothesis를 구성하면 다음과 같습니다.
1 | hypothesis = tf.nn.softmax(tf.matmul(X, W) + b) | cs |
그 다음으로, 기본 Logistic Classfication에서는 Sigmoid 함수를 이용했지만 이번에는 Softmax 함수를 이용했으므로 Cost 함수 또한 달라져야 합니다.
다음 그림과 같이 Y의 예측값 y_hat (그림에서 왼쪽)과 실제값 (그림에서 오른쪽)의 차이 ( Cost )를 구하는 과정에서 에서 Cost 함수로 CROSS - ENTROPY 함수를 이용하게 됩니다.
이 Cost 함수에 대한 설명은 여기를 참고하세요.
따라서 CROSS - ENTROPY를 이용한 Cost 함수는 다음과 같습니다.
1 | cost = tf.reduce_mean(-tf.reduce_sum(Y * tf.log(hypothesis), axis=1)) | cs |
axis는 축으로, 이는 다음에 상세히 설명하겠습니다.
SOURCE CODE
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 | x_data = [[1, 2], [2, 1], [3, 1], [4, 1], [1, 7], [1, 2], [1, 6], [1, 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, 2]) Y = tf.placeholder("float", [None, 3]) nb_classes = 3 W = tf.Variable(tf.random_normal([2, 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) # LEARNING & PRINT 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})) print('--------------') # Testing & One-hot encoding a = sess.run(hypothesis, feed_dict={X: [[1, 2]]}) print(a, sess.run(tf.argmax(a, 1))) print('--------------') b = sess.run(hypothesis, feed_dict={X: [[2, 1]]}) print(b, sess.run(tf.argmax(b, 1))) print('--------------') c = sess.run(hypothesis, feed_dict={X: [[3, 1]]}) print(c, sess.run(tf.argmax(c, 1))) print('--------------') all = sess.run(hypothesis, feed_dict={ X: [[1, 2], [2, 1], [3, 1]]}) print(all, sess.run(tf.argmax(all, 1))) | cs |
argmax 함수는 A, B, C에 대한 확률 추정치 중 1에 가장 근접한 값 (가장 큰 값)의 자릿수를 구하는 함수입니다. 이것은 axis 값입니다.
즉, 다음에서 학습 결과 추정치가 [0.7, 0.2, 0.1] 이 나왔다면 이는 곧 [1, 0, 0]을 나타내며 이는 A이고, argmax 함수는 0을 출력합니다.
학습결과
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 | 0 4.4966693 200 0.6843643 400 0.6545731 600 0.63928384 800 0.6288383 1000 0.620518 1200 0.61337596 1400 0.6070266 1600 0.60128355 1800 0.5960389 2000 0.5912201 -------------- #A가 될 확률 #B가 될 확률 #C가 될 확률 #가장 큰 값의 위치 [[0.06344459 0.37413925 0.56241614]] [2] -------------- [[1.9597406e-04 1.6238879e-01 8.3741528e-01]] [2] -------------- [[5.3981917e-06 3.8204747e-01 6.1794716e-01]] [2] -------------- [[6.3444592e-02 3.7413925e-01 5.6241614e-01] [1.9597406e-04 1.6238879e-01 8.3741528e-01] [5.3981921e-06 3.8204747e-01 6.1794716e-01]] [2 2 2] | cs |
학습 후 입력한 x 데이터는 [1,2] , [2,1], [3,1] 이고 이것에 대한 실제 Y 값은 [0, 0, 1], 즉 C입니다.
결과에서 보다시피 예측된 Y값, 즉 y_hat 또한 모두 [0, 0, 1], C값을 가리키므로 학습된 모델이 정확하다고 볼 수 있습니다.
'파이썬 > 머신러닝' 카테고리의 다른 글
[#E8] Fancy Softmax Regression이란? (0) | 2018.12.05 |
---|---|
[#E7] 텍스트 파일로부터 데이터를 읽어오는 방법 (0) | 2018.12.05 |
[#E5] Logistic Classification 이란? (0) | 2018.12.02 |
[#E4] 다중 변수를 사용하는 Multi Variables Linear Regression (0) | 2018.12.01 |
[#E3]Linear Regression 데이터를 유동적으로 지정하는 방법 (0) | 2018.11.30 |