지난 시간 Linear Regression에 대해서 배워 보았는데, 이는 Input과 Output Data들이 있을 때, 이를 이용해서 Data들의 분포가 선형을 띠고 있을 것이라고 가정한 상태에서 각 항의 매개변수의 값의 조정을 통해서 이 분포를 실제로 이끌어내는 것이었다.
한마디로, 이미 있는 Data들을 분석하여 내가 가지고 있는 Input Data가 어떤 Output을 만들어 낼 것인가에 대한 이야기였다.
그런데 Data의 Output이 항상 가격이나, 판매량과 같은 단일 숫자가 아닐 수도 있다. 예를 들어, 꽃은 같은 품종이라도 여러 종류가 있는데, 내가 가지고 있는 이 꽃이 어느 종류에 속할 것인지 알고 싶다고 하자. 오늘은 Logistic Regression을 통해서 이 분류(Classification)작업을 해 보도록 하자.
위와 같이 Linear Regression이 가설을 통한 결과값으로 숫자를 돌려준다면, Logistic Regression은 Input이 어떤 Class에 속할 확률을 돌려준다.
포켓몬으로 예를 들어보자!!! 모두들 알고 있다시피 아래와 같은 귀여운 이브이는 여러 진화형이 있다. (지난 시간에 보았으면 알 수 있듯이 나는 귀여운 것을 좋아한다.)
귀여운 이브이
에브이 샤미드 부스터 쥬피썬더
gif 출처 : 나무위키 - 이브이
내가 이 여러 진화형 친구들의 귀 크기, 꼬리 크기, 갈기 크기에 대한 데이터들을 가지고 있다고 해 보자. 그럼 누군지 알 수 없는 진화형이 주어졌을 때 이를 이용해서 이 포켓몬이 어떤 진화형일지에 대한 확률을 알 수 있는 것이다!!
에브이일 확률 : 0.1
샤미드일 확률 : 0.15
부스터일 확률 : 0.7
쥬피썬더일 확률 : 0.05
이렇게 말이다. 물론 전체 확률의 총 합은 1이어야 하고, 이 포켓몬은 부스터일 것이라는 것도 알 수가 있는 것이다!!!
우리가 AI에게 주는 것과, AI가 인간에게 돌려주는 것은 Linear Regression과 동일하다. 다만!! Hypothesis와 Cost Function에서 차이가 발생하게 된다. 그래서 이를 위주로 설명을 해 본다.
자 Logistic Regression의 Hypothesis는 이렇게 생겼다. 처음 봐서는 이게 뭐냐... 싶었을 터인데, 이는 Sigmoid라고 한단다. 역시 보는 것이 제일 빠르기에 그래프를 보자!!
이렇게 생긴 친구이다!!! 잘 보면 0과 1 사이의 값을 가지면서 x=0 주위로 일종의 부드러운 계단을 형성하는 것을 알 수가 있다. 여기에서 우리가 건드려야 하는 값은 z에 해당하는데, 이 계단이 얼마나 가파를지, 완만할지를 결정하는 것이다.
계속 말하지만 가운데 그림고 같이 적절한 계단을 찾는 것이 중요하고, 만약 Input의 종류가 많다면. 즉, x가 많아진다면 Hypothesis는 더 복잡한 모양을 가지게 될 것이다.
이번에는 Cost Function이다. 이것도 처음 봐서는 무슨 식인지 감을 잡을 수가 없는데, Class가 하나인 경우로 천천히 풀어나가 보자!
다시 한 번 귀여운 이브이께서 등장을 해 주셨다. 우리가 어떤 포켓몬의 귀 크기, 꼬리 크기, 갈기 크기로 이브이인지 아닌지를 판명을 해 보고자 한다. 결과인 확률이 1이라면이브이일 것이고, 0이면 이브이가 아닌 것이다.
이브이가 맞고, 결과도 1에 가까운 경우 : y = 1, H(x) ~ 1이 되어 대입해 보면 Cost는 -(작은 값)이 되어 작아진다.
이브이가 맞는데, 결과는 0에 가까운 경우 : y = 1, H(x) ~ 0이 되어 대입해 보면 Cost는 엄청나게 커진다!!
Cost는 클 수록 좋다고 했는데, 잘못 판단했을 경우에 Cost가 엄청나게 증가해 버리고 만다. Logistic Regression은 종류를 구별해 내야 해서 그런지 일부러 저렇게 작성되었다고 한다. 그런데 여기서 끝이 아니다!!! 앞서 이브이 예시에서는 모든 확률의 합이 1이 되었다.
확률에서는 모든 확률의 합이 1이 되어야 하는데, 우연히 1로 맞을 수도 있지만 항상 그런 것은 아니기에 우리가 그 설정을 해 주어야 한다.
그 과정의 위의 SoftMax이다. 행렬 연산의 모든 것들을 더해 보면 1이 되는 것을 알 수가 있다.
이쯤에서 정리를 해 보았다. Linear / Logistic Regression의 차이가 무엇인지 다시 한 번 짚고 넘어간다.
그럼 이제 신나는 코딩..... (종양 크기에 따른 암 발병 확률을 예측한다는 시나리오다.)
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | import numpy as np import matplotlib.pyplot as plt def get_data(): # x_data에 종양의 크기를 저장합니다. x_data = np.array([0.20, 0.55, 0.60, 0.85, 0.95]) # y_data에 암 발병 여부를 저장합니다. y_data = np.array([0.0, 1.0, 0.0, 1.0, 1.0]) return x_data, y_data def predict(theta0, theta1, x): # x에는 종양 크기가 저장되어 있습니다. # y에 추정 암 발병 확률을 계산하여 저장합니다. # x가 numpy array인 경우에는 y도 numpy array로 저장합니다. y = 1.0 / (1.0 + np.exp(-(theta0 + theta1 * x))) return y def get_cost(x_data, y_data, theta0, theta1): # x_data에 종양 크기가 저장되어 있습니다. # y_data에 암 발병 여부가 저장되어 있습니다. (0.0 or 1.0) # y_pred에 종양 크기로부터 추정한 암 발병 확률을 저장합니다. (0.0 ~ 1.0) y_pred = predict(theta0, theta1, x_data) cost = 0 # 종양 data 수 만큼 반복합니다. for i in range(len(x_data)): # y_data(암 발병 여부)와 y_pred(종양 크기로부터 추정한 암 발병 확률)가 유사하면 낮은 값이 되도록 cost를 모든 종양 data에 대해 계산하여 더합니다. cost += y_data[i] * np.log(y_pred[i]) + (1 - y_data[i]) * np.log(1 - y_pred[i]) # 종양 data 수로 나눠줘서 평균을 계산합니다. cost /= -len(x_data) return cost def draw_graph(x_data, y_data, theta0, theta1): # matplotlib 상태를 초기화합니다. plt.clf() plt.cla() plt.close() # 0.0부터 1.0까지 100개의 숫자를 만들어서 numpy array x에 저장합니다. x = np.linspace(0.0, 1.0, 100) # x 종양 크기로 추정한 암 발병 확률을 y에 저장합니다. y = predict(theta0, theta1, x) # cost를 cost에 저장합니다. cost = get_cost(x_data, y_data, theta0, theta1) # 그래프를 2개 생성합니다. axes[0]에 첫 번째 그래프를 그리고 axes[1]에 두 번째 그래프를 그립니다. fig, axes = plt.subplots(1, 2) # 첫 번째 그래프를 그립니다. ax = axes[0] # 종양 크기 x_data, 암 발병 여부 y_data의 그래프를 빨간 동그라미 점으로 그립니다. ax.plot(x_data, y_data, 'ro') # h(x)의 그래프를 그립니다. ax.plot(x, y) # 각종 부가정보를 표시합니다. ax.set( xlabel='Tumor Size in cm', ylabel='Cancer', title='Cancer\nTheta0: {}\n Theta1: {}'.format(theta0, theta1), xlim=(0, 1.0), ylim=(-0.1, 1.1) ) # 모눈모양으로 격자를 그립니다. ax.grid(True) # 두 번째 그래프를 그립니다. ax = axes[1] # -20.0부터 10.0까지 200개의 숫자를 만들어서 numpy array theta0_list에 저장합니다. theta0_list = np.linspace(-20.0, 10.0, 200) # theta0_len에 theta0_list의 길이를 저장합니다. theta0_len = len(theta0_list) # 0.0부터 40.0까지 200개의 숫자를 만들어서 numpy array theta1_list에 저장합니다. theta1_list = np.linspace(0.0, 40.0, 200) # theta1_len에 theta1_list의 길이를 저장합니다. theta1_len = len(theta1_list) # theta0와 theta1을 하나하나 바꿔가며 cost를 계산해서 costs에 저장합니다. costs = np.empty([theta1_len, theta0_len]) # theta0는 -20.0부터 10.0까지, theta1은 0.0부터 40.0까지 하나하나 바꿔가며 모든 조합의 cost를 계산해서 costs에 저장합니다. # 매우 큰 cost값을 다루기 위해 costs에 cost를 저장할 때 base 10의 log를 취한 cost를 costs에 저장합니다. for i in range(theta1_len): for j in range(theta0_len): costs[i, j] = np.log10( get_cost(x_data, y_data, theta0_list[j], theta1_list[i])) # cost의 contour map을 그립니다. cs = ax.contour(theta0_list, theta1_list, costs) # contour map에 label을 표시합니다. ax.clabel(cs) # 현재의 theta0, theta1의 값을 빨간색 x로 표시해 줍니다. ax.plot(theta0, theta1, 'rx') # 각종 부가정보를 표시합니다. ax.set( xlabel='theta0', ylabel='theta1', title='log10(cost) Contour Map\nCost: {}'.format(cost), ) # 모눈모양으로 격자를 그립니다. ax.grid(True) # 그래프를 실제 화면에 그립니다. plt.show() # x_data에 종양의 크기를 저장합니다. # y_data에 암 발병 여부를 저장합니다. x_data, y_data = get_data() # theta0와 theta1을 지정합니다. # 코드 시작 theta0 = -5.0 theta1 = 12.0 # 코드 끝 # x_data(종양의 크기), y_data(암 발병 여부), theta0, theta1, draw_graph를 이용하여 그래프를 그립니다. draw_graph(x_data, y_data, theta0, theta1) # 종양 크기를 바탕으로 암 발병 확률을 predict로 추정한 결과를 y_pred에 저장합니다. y_pred = predict(theta0, theta1, x_data) # x_data를 이용하여 종양의 크기를 print로 출력합니다. print('x_data', x_data) # y_data를 이용하여 암 발병 여부를 print로 출력합니다. print('y_data', y_data) # 종양 크기를 바탕으로 암 발병 확률을 predict로 추정한 결과를 print로 출력합니다. print('y_pred', y_pred) # 0.65cm의 크기의 종양을 가지고 암 발병 확률을 predict로 추정하여 결과를 print로 출력합니다. print(predict(theta0, theta1, 0.65)) | cs |
Gradient Descent를 사용한 버전
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 | import numpy as np import matplotlib.pyplot as plt def get_data(): # x_data에 종양의 크기를 저장합니다. x_data = np.array([0.20, 0.55, 0.60, 0.85, 0.95]) # y_data에 암 발병 여부를 저장합니다. y_data = np.array([0.0, 1.0, 0.0, 1.0, 1.0]) return x_data, y_data def predict(theta0, theta1, x): # x에는 종양 크기가 저장되어 있습니다. # y에 추정 암 발병 확률을 계산하여 저장합니다. # x가 numpy array인 경우에는 y도 numpy array로 저장합니다. y = 1.0 / (1.0 + np.exp(-(theta0 + theta1 * x))) return y def get_cost(x_data, y_data, theta0, theta1): # x_data에 종양 크기가 저장되어 있습니다. # y_data에 암 발병 여부가 저장되어 있습니다. (0.0 or 1.0) # y_pred에 종양 크기로부터 추정한 암 발병 확률을 저장합니다. (0.0 ~ 1.0) y_pred = predict(theta0, theta1, x_data) cost = 0 # 종양 data 수 만큼 반복합니다. for i in range(len(x_data)): # y_data(암 발병 여부)와 y_pred(종양 크기로부터 추정한 암 발병 확률)가 유사하면 낮은 값이 되도록 cost를 모든 종양 data에 대해 계산하여 더합니다. cost += y_data[i] * np.log(y_pred[i]) + (1 - y_data[i]) * np.log(1 - y_pred[i]) # 종양 data 수로 나눠줘서 평균을 계산합니다. cost /= -len(x_data) return cost def draw_graph(x_data, y_data, theta0, theta1): # matplotlib 상태를 초기화합니다. plt.clf() plt.cla() plt.close() # 0.0부터 1.0까지 100개의 숫자를 만들어서 numpy array x에 저장합니다. x = np.linspace(0.0, 1.0, 100) # x 종양 크기로 추정한 암 발병 확률을 y에 저장합니다. y = predict(theta0, theta1, x) # cost를 cost에 저장합니다. cost = get_cost(x_data, y_data, theta0, theta1) # 그래프를 2개 생성합니다. axes[0]에 첫 번째 그래프를 그리고 axes[1]에 두 번째 그래프를 그립니다. fig, axes = plt.subplots(1, 2) # 첫 번째 그래프를 그립니다. ax = axes[0] # 종양 크기 x_data, 암 발병 여부 y_data의 그래프를 빨간 동그라미 점으로 그립니다. ax.plot(x_data, y_data, 'ro') # h(x)의 그래프를 그립니다. ax.plot(x, y) # 각종 부가정보를 표시합니다. ax.set( xlabel='Tumor Size in cm', ylabel='Cancer', title='Cancer\nTheta0: {}\n Theta1: {}'.format(theta0, theta1), xlim=(0, 1.0), ylim=(-0.1, 1.1) ) # 모눈모양으로 격자를 그립니다. ax.grid(True) # 두 번째 그래프를 그립니다. ax = axes[1] # -20.0부터 10.0까지 200개의 숫자를 만들어서 numpy array theta0_list에 저장합니다. theta0_list = np.linspace(-20.0, 10.0, 200) # theta0_len에 theta0_list의 길이를 저장합니다. theta0_len = len(theta0_list) # 0.0부터 40.0까지 200개의 숫자를 만들어서 numpy array theta1_list에 저장합니다. theta1_list = np.linspace(0.0, 40.0, 200) # theta1_len에 theta1_list의 길이를 저장합니다. theta1_len = len(theta1_list) # theta0와 theta1을 하나하나 바꿔가며 cost를 계산해서 costs에 저장합니다. costs = np.empty([theta1_len, theta0_len]) # theta0는 -20.0부터 10.0까지, theta1은 0.0부터 40.0까지 하나하나 바꿔가며 모든 조합의 cost를 계산해서 costs에 저장합니다. # 매우 큰 cost값을 다루기 위해 costs에 cost를 저장할 때 base 10의 log를 취한 cost를 costs에 저장합니다. for i in range(theta1_len): for j in range(theta0_len): costs[i, j] = np.log10( get_cost(x_data, y_data, theta0_list[j], theta1_list[i])) # cost의 contour map을 그립니다. cs = ax.contour(theta0_list, theta1_list, costs) # contour map에 label을 표시합니다. ax.clabel(cs) # 현재의 theta0, theta1의 값을 빨간색 x로 표시해 줍니다. ax.plot(theta0, theta1, 'rx') # 각종 부가정보를 표시합니다. ax.set( xlabel='theta0', ylabel='theta1', title='log10(cost) Contour Map\nCost: {}'.format(cost), ) # 모눈모양으로 격자를 그립니다. ax.grid(True) # 그래프를 실제 화면에 그립니다. plt.show() def train_step(x_data, y_data, theta0, theta1, learning_rate): epsilon = 0.001 # 현재의 cost값을 계산하여 cost에 저장합니다. cost = get_cost(x_data, y_data, theta0, theta1) # theta0이 약간 증가한 경우 증가한 theta0에 대한 cost의 변화량을 d_theta0에 저장합니다. d_theta0 = (get_cost(x_data, y_data, theta0 + epsilon, theta1) - cost) / epsilon # theta1이 약간 증가한 경우 증가한 theta1에 대한 cost의 변화량을 d_theta1에 저장합니다. d_theta1 = (get_cost(x_data, y_data, theta0, theta1 + epsilon) - cost) / epsilon # cost가 감소하는 방향으로 d_theta0 * learning_rate만큼 theta0에 변화를 줘서 new_theta0에 저장합니다. new_theta0 = theta0 - d_theta0 * learning_rate # cost가 감소하는 방향으로 d_theta1 * learning_rate만큼 theta1에 변화를 줘서 new_theta1에 저장합니다. new_theta1 = theta1 - d_theta1 * learning_rate return new_theta0, new_theta1 # x_data에 종양의 크기를 저장합니다. # y_data에 암 발병 여부를 저장합니다. x_data, y_data = get_data() # theta0와 theta1을 지정합니다. theta0 = -3.0 theta1 = 10.0 learning_rate = 3.0 for i in range(1000): if i % 100 == 0: draw_graph(x_data, y_data, theta0, theta1) theta0, theta1 = train_step(x_data, y_data, theta0, theta1, learning_rate) draw_graph(x_data, y_data, theta0, theta1) # 종양 크기를 바탕으로 암 발병 확률을 predict로 추정한 결과를 y_pred에 저장합니다. y_pred = predict(theta0, theta1, x_data) # x_data를 이용하여 종양의 크기를 print로 출력합니다. print('x_data', x_data) # y_data를 이용하여 암 발병 여부를 print로 출력합니다. print('y_data', y_data) # 종양 크기를 바탕으로 암 발병 확률을 predict로 추정한 결과를 print로 출력합니다. print('y_pred', y_pred) # 0.65cm의 크기의 종양을 가지고 암 발병 확률을 predict로 추정하여 결과를 print로 출력합니다. print(predict(theta0, theta1, 0.65)) | cs |
tensorflow로 간단하게 작성해 보면
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 52 53 54 55 56 57 58 59 60 61 62 63 64 | import numpy as np import tensorflow as tf def get_data(): # x_data에 종양의 크기를 저장합니다. x_data = np.array([0.20, 0.55, 0.60, 0.85, 0.95]) # y_data에 암 발병 여부를 저장합니다. y_data = np.array([0.0, 1.0, 0.0, 1.0, 1.0]) return x_data, y_data x_input = tf.placeholder(tf.float32) y_input = tf.placeholder(tf.float32) theta0_var = tf.Variable(-3.0) theta1_var = tf.Variable(10.0) logit = theta0_var + theta1_var * x_input y_output = tf.nn.sigmoid(logit) cross_entropy = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_input, logits=logit) cost_output = tf.reduce_mean(cross_entropy) learning_rate = 0.9 train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost_output) x_data, y_data = get_data() theta0 = 0 theta1 = 0 cost = 0 sess = tf.Session() sess.run(tf.global_variables_initializer()) for i in range(1000): if i % 100 == 0: theta0, theta1, cost = sess.run( [theta0_var, theta1_var, cost_output], feed_dict={x_input: x_data, y_input: y_data}) print('train_step: {}, theta0: {}, theta1: {}, cost:{}'.format(i,theta0, theta1, cost)) sess.run(train_step, feed_dict={x_input: x_data, y_input: y_data}) theta0, theta1 = sess.run([theta0_var, theta1_var]) cost = sess.run(cost_output, feed_dict={x_input: x_data, y_input: y_data}) # 추정된 암 발병 확률을 sess.run에 x_data를 x_input에 feed_dict로 넘기면서 y_output을 통해서 얻어옵니다. y_pred = sess.run(y_output, feed_dict={x_input: x_data}) print('') print('theta0', theta0) print('theta1', theta1) print('cost', cost) # x_data를 이용하여 종양의 크기를 print로 출력합니다. print('x_data', x_data) # y_data를 이용하여 암 발병 여부를 print로 출력합니다. print('y_data', y_data) # 종양 크기를 바탕으로 추정한 암 발병 확률을 print로 출력합니다. print('y_pred', y_pred) # 0.65cm의 크기의 종양을 가지고 암 발병 확률을 predict로 추정하여 결과를 print로 출력합니다. print(sess.run(y_output, feed_dict={x_input: 0.65})) sess.close() | cs |
예제로 제공하는 dataset으로 iris라는 꽃의 꽃잎 크기, 꽃받침(기억이 잘 안나지만) 크기에 따른 분류를 사용해 보았다.
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import numpy as np import pandas as pd import matplotlib.pyplot as plt import tensorflow as tf def get_data(): iris = pd.read_csv('./iris.data', header=None) x_data = np.array(iris.iloc[:, 0:4].values, dtype=np.float32) species = pd.get_dummies(iris.iloc[:, 4]) names = ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'] y_data = np.array(species.loc[:, names].values, dtype=np.float32) return x_data, y_data x_input = tf.placeholder(tf.float32, [None, 4]) y_input = tf.placeholder(tf.float32, [None, 3]) theta0_var = tf.Variable(tf.zeros([3])) thetan_var = tf.Variable(tf.zeros([4, 3])) logit = theta0_var + tf.matmul(x_input, thetan_var) y_output = tf.nn.softmax(logit) cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(labels=y_input, logits=logit) cost_output = tf.reduce_mean(cross_entropy) learning_rate = 0.1 train_step = tf.train.AdamOptimizer(learning_rate).minimize(cost_output) x_data, y_data = get_data() theta0 = 0 thetan = 0 cost = 0 sess = tf.Session() sess.run(tf.global_variables_initializer()) for i in range(5000): # 500번에 한 번씩 현재 상황을 출력합니다. if i % 500 == 0: # 현재의 theta0, thetan를 얻어오고, cost를 x_data 꽃 길이 정보, y_data 꽃의 종류를 사용하여 계산합니다. theta0, thetan, cost = sess.run( [theta0_var, thetan_var, cost_output], feed_dict={x_input: x_data, y_input: y_data}) print('train_step: {}, cost: {}'.format(i, cost)) # Gradient Descent를 사용하여 cost가 약간 작아지도록 theta0, thetan을 변경합니다. sess.run(train_step, feed_dict={x_input: x_data, y_input: y_data}) theta0, thetan, cost, y_pred = sess.run( [theta0_var, thetan_var, cost_output, y_output], feed_dict={x_input: x_data, y_input: y_data}) print('') print('theta0', theta0) for theta_index in range(len(thetan)): print('theta{}'.format(theta_index + 1), thetan[theta_index]) print('cost', cost) # data상의 꽃의 분류를 출력합니다. y_data_class = np.argmax(y_data, axis=1) print('y_data_class', y_data_class) # data로 추정된 꽃의 분류를 출력합니다. y_pred_class = np.argmax(y_pred, axis=1) print('y_pred_class', y_pred_class) # data상의 꽃의 분류와 추정된 꽃의 분류를 비교한 결과를 출력합니다. y_right_class = y_data_class == y_pred_class print('y_right_class', y_right_class) # data를 기반으로 꽃을 얼마나 정확하게 분류하는지 0.0~1.0 사이의 값으로 출력합니다. accuracy = np.mean(y_right_class) print('accuracy', accuracy) y_wrong_class = y_data_class != y_pred_class # data상의 꽃의 길이 정보중에서 꽃의 종류가 잘못 분류된 것만 출력합니다. print('x_data', x_data[y_wrong_class]) # data상의 꽃의 종류중에서 꽃의 종류가 잘못 분류된 것만 출력합니다. print('y_data', y_data[y_wrong_class]) # 추정된 꽃의 분류중에서 꽃의 종류가 잘못 분류된 것만 출력합니다. print('y_pred', y_pred[y_wrong_class]) plt.clf() plt.cla() plt.close() # 그래프를 1개 생성합니다. fig, ax = plt.subplots() # x축으로 사용할 column number를 설정합니다. 0~3 까지 x_axis = 0 # y축으로 사용할 column number를 설정합니다. 0~3 까지 y_axis = 2 # x_axis, y_axis의 column을 사용하여 그래프상의 위치를 선정하고 꽃의 종류에 따라 다른 색으로 표시합니다. ax.scatter( x_data[:, x_axis], x_data[:, y_axis], c=y_data_class, cmap=plt.cm.gist_rainbow) # 잘못 분류된 꽃의 정보를 그래프에 표시합니다. ax.plot(x_data[y_wrong_class][:, x_axis], x_data[y_wrong_class][:, y_axis], 'kx') # 그래프를 실제 화면에 그립니다. plt.show() sess.close() | cs |
☆☆Gradient Descent를 하면서 주의해야 할 점들이 있다!☆☆
위 사진은 매개변수들의 시작 지점에 따라서 어떻게 최적화가 되어 가는지를 보여주는 그림인데, 왼쪽과 아래쪽의 두 가지 결과가 나올 수가 있다. 왼쪽이 더 깊어 보이는데 그렇다면 Cost가 더 작은 왼쪽이 우리가 원하는 결과이다. 하지만, 이것을 모르고 오른쪽 결과만 보고 와~ 신나한다면 큰 실수를 할 수 있다는 것이다! 여러 매개변수로 시험을 해 보아야겠다.
그 밖에 더 빠른 연산을 위한 기법들
모든 데이터들에 대해서 Cost를 구한다면 상당히 무거운 계산들을 계속 수행하는 것이 된다. 그래서 데이터의 일부만 사용해서 Cost를 구할 수도 있다. 그리고 최적화를 진행하면서 몇 번 진행하다 보면 매개변수들이 일정한 방향성을 가지고 움직이게 되는 것을 볼 수가 있는데 이와 같은 경향들을 종합해서 tensorflow에서도 사용하였듯이 Adam-Optimize기법을 사용하였다.
고래왕
출처 : 나무위키 - 고래왕
이브이는 몸집이 작지만 고래왕의 꼬리 크기, 몸무게 등의 Data를 사용한다면 300-400가까이 되는 값들로 계속 계산을 해 주어야 한다. 그러면 당연히 계산이 부담이 될 것이다. Feature Scaling은 이에 대한 대안이다. 고래왕의 몸무게 Data가 300, 350, 400 이렇게 있다면, 0.3, 0.35, 0.4 이렇게 scale을 줄여서 계산을 해 주고 나중에 값을 볼 때만 다시 1000을 곱해서 보는 것이다.
포스틀를 남기는 것이 상당히 시간도 걸리고, 귀찮지만 언젠가는 도움이 될 것이라고 생각하면서 ㅠㅁㅠ Alina 분들께도 감사함을 느낀다. 출처인 AI PM강의를 보면 더욱 잘 설명해 주신다.
'공부 > AI' 카테고리의 다른 글
Neural Network 공부했다. - Multi Layer Neural Network && Autoencoder (0) | 2018.12.24 |
---|---|
Neural Network 공부했다.- Single Layer Neural Network (0) | 2018.12.22 |
Machine Learning Methodology & analysis 공부했다 (0) | 2018.12.19 |
Recommender System 공부했다. (0) | 2018.12.16 |
Linear Regression 공부했다 (0) | 2018.12.14 |