[머신러닝] AI, 머신 러닝, 딥러닝, 지도 학습 등
해당 내용은 강의를 들으면서 정리한 내용이다. 짜임새 있는 글이라기보다는 복습 겸 쓰는 글이어서 두서가 없을 수 있다는 점에 대해 양해를 구한다. 강의를 듣고 싶은 사람을 위해서 밑에 링크를 남긴다. 개인적으로는 선형대수에 대해 기본적인 것을 익히고 학습을 한다면 훨씬 이해가 잘될 것이라 생각한다.
https://www.youtube.com/watch?v=vcCaSBJpsHk&list=PLS8gIc2q83OjStGjdTF2LZtc0vefCAbnX
인공지능(AI) : 인간의 학습 능력, 추론 능력 등을 인공적으로 컴퓨터 상에 구현한 것
머신러닝(ML) : 인공지능의 하위 카테고리에 속하며, 정확히는 인공지능을 구현 또는 성능 향상을 위한 단계이다. 머신러닝은 지도 방식에 따라서 지도 머신러닝과 비지도 머신러닝으로 구분할 수 있다. 둘의 차이점은 지도 머신러닝의 경우 개발자가 직접 가이드 역할을 하면서 어떠한 결정을 내릴 지 관여를 한다면, 비지도 머신러닝은 가이드 없이 데이터를 입력받고 이를 스스로 패턴을 식별하게 된다.
딥러닝(Deep Learning) : 머신러닝의 하위 카테고리에 속한다. 학습 과정 중 인공 신경망을 이용하여 데이터들에 대한 일반적인 규칙을 구축하는 방식을 뜻한다.
이번 글에서는 지도 방식에 대해서 알아보기로 한다. 지도 방식에는 회귀(Regression)와 분류(Classification)로 나누어지게 된다. 회귀 방식은 입력값과 그에 대응하는 결과값이 연속적인 수치(참, 거짓처럼 딱딱 나누어지지 않는 형태)로 제공된다. 이를 통해 인공지능이 입력값과 결과값 사이의 관계를 유추하고, 차후 사용자가 입력값을 넣었을 때, 예상되는 출력값을 제공하게 된다. 반면 분류 방식은 입력값과 그에 대응하는 결과값이 이산적(참, 거짓처럼 딱딱 나누어지는 형태)으로 제공된다. 인공지능은 둘 사이의 관계를 학습하고, 차후 사용자의 입력이 들어왔을 때 출력으로 분류된 결과값을 제공하게 된다.
회귀 방식과 분류 방식의 예로써 Linear Regression Analysis와 Logistic Regression Analysis를 다루었다. 두 방식은 서로 연관성이 깊다.
Linear Regression Analysis의 기본적인 아이디어는 모든 (입력, 출력)에 대해서 오차의 제곱합이 가장 작은 y=Wx+b의 (W, b)를 구하는 것이다. 이때 W는 입력 당 n개의 파라미터가 주어지는 경우 nx1 행렬이고, b는 모든 원소가 b인 nx1 행렬을 구하는 것이다. 과거에 주어진 값들이 모두 y=Wx+b 근처에 분포하고 있었으니 미래에 들어오는 값 역시 그 주위에 있을 것이라는 이 방식에서 가정하고 있는 것이다.
각설하고 바로 코드로 보자. 자세한 설명은 코드의 주석으로 대체하겠다. 이 강의의 좋은 점 중 하나는 numpy를 이용한 파이썬 코드 위주로 수업이 이루어지는 것이다. 이 글에서 사용되는 코드들은 해당 사이트에서 가져온 것임을 미리 언급한다. 더 많은 코드를 보고싶은 사람들을 위해 글 제일 아래에 링크를 남겨 두겠다.
import numpy as np
#학습 데이터
x_data = np.array([1, 2, 3, 4, 5]).reshape(5,1) #입력
t_data = np.array([2, 3, 4, 5, 6]).reshape(5,1) #출력
print("x_data.shape = ", x_data.shape, ", t_data.shape = ", t_data.shape)
#y=Wx + b
W = np.random.rand(1,1) //W : 1x1 행렬
b = np.random.rand(1) //b
print("W = ", W, ", W.shape = ", W.shape, ", b = ", b, ", b.shape = ", b.shape)
#(W, b) 쌍에 대하여 학습 데이터에 대한 오차의 제곱합을 반환, 밑에 나오는 error_val(x, t)와 같음
def loss_func(x, t):
y = np.dot(x,W) + b
return ( np.sum( (t - y)**2 ) ) / ( len(x) )
#수치 미분(f 함수에 대해 x에서의 미분값을 반환)
def numerical_derivative(f, x):
delta_x = 1e-4 # 0.0001
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
idx = it.multi_index
tmp_val = x[idx]
x[idx] = float(tmp_val) + delta_x
fx1 = f(x) # f(x+delta_x)
x[idx] = tmp_val - delta_x
fx2 = f(x) # f(x-delta_x)
grad[idx] = (fx1 - fx2) / (2*delta_x)
x[idx] = tmp_val
it.iternext()
return grad
#loss_func(x, t)와 동일
def error_val(x, t):
y = np.dot(x,W) + b
return ( np.sum( (t - y)**2 ) ) / ( len(x) )
# 학습을 마친 후, 임의의 데이터에 대해 미래 값 예측 함수
# 입력변수 x : numpy type
def predict(x):
y = np.dot(x,W) + b
return y
learning_rate = 1e-2 # 발산하는 경우, 1e-3 ~ 1e-6 등으로 바꾸어서 실행
f = lambda x : loss_func(x_data,t_data)
print("Initial error value = ", error_val(x_data, t_data), "Initial W = ", W, "\n", ", b = ", b )
#지도 학습
for step in range(8001):
W -= learning_rate * numerical_derivative(f, W) #기울기가 음수라면 양의 방향으로, 양수라면 음의 방향으로 조정
b -= learning_rate * numerical_derivative(f, b) #기울기가 음수라면 양의 방향으로, 양수라면 음의 방향으로 조정
if (step % 400 == 0):
print("step = ", step, "error value = ", error_val(x_data, t_data), "W = ", W, ", b = ",b ) #코드를 실행하면 점점 error_value가 작아지다가 어느 시점에 진동하는 것을 볼 수 있다
predict(43)
Logistic Regression Analysis는 지도 학습 중 분류 방식에 해당된다. 앞서 살펴보았던 Linear Regression Analysis과 유사한 면이 있으나 살짝은 더 복잡하다. 분류를 위해서 앞서 우리는 y=Wx+b를 구하였다. 문제는 우리가 구하고 싶은 것은 예상되는 값이 아닌 분류라는 것이다. 연속된 수치를 디지털화 해줄 함수가 바로 시그모이드(Sigmoid) 함수이다.
함수의 형태는 x=0을 기준선으로 값이 1 또는 0에 가까워지는 형태를 취하고 있다. 우리는 x에 y=Wx+b를 대입한 sigmoid(y) 값을 이용할 것이다.
기준이되는 에러 함수가 필요하다. 우리가 위에서 구한 sigmoid(y)를 분류 1이 나올 확률로 볼 것이다. 그렇다면 그 반대일 확률은 1-sigmoid(y)를 구할 것이다. 이를 이용하여 (W, b)에 대한 cross - entropy를 구할 것인데 자세한 내용은 아래의 표를 참고해 주시기를 바란다. 쉽게 이야기하면 에러 함수처럼 옳고 그른 정도를 측정하기 위한 납득할 수 있는 기준을 만드는 것이다.
바로 코드로 보자. 코드는 다음과 같다.
import numpy as np
x_data = np.array([2, 4, 6, 8, 10, 12, 14, 16, 18, 20]).reshape(10,1)
t_data = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1]).reshape(10,1)
print("x_data.shape = ", x_data.shape, ", t_data.shape = ", t_data.shape)
x_data.shape = (10, 1) , t_data.shape = (10, 1)
# W, b
W = np.random.rand(1,1)
b = np.random.rand(1)
print("W = ", W, ", W.shape = ", W.shape, ", b = ", b, ", b.shape = ", b.shape)
W = [[0.88267191]] , W.shape = (1, 1) , b = [0.40204683] , b.shape = (1,)
# 최종출력은 y = sigmoid(Wx+b) 이며, 손실함수는 cross-entropy 로 나타냄
# sigmoid
def sigmoid(x):
return 1 / (1+np.exp(-x))
# 지표가 되는 함수
def loss_func(x, t):
delta = 1e-7 # log 무한대 발산 방지
z = np.dot(x,W) + b # 여기는 Linear Regression과 동일
y = sigmoid(z)
# cross-entropy
return -np.sum( t*np.log(y + delta) + (1-t)*np.log((1 - y)+delta ) )
# 미분 함수
def numerical_derivative(f, x):
delta_x = 1e-4 # 0.0001
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])
while not it.finished:
idx = it.multi_index
tmp_val = x[idx]
x[idx] = float(tmp_val) + delta_x
fx1 = f(x) # f(x+delta_x)
x[idx] = tmp_val - delta_x
fx2 = f(x) # f(x-delta_x)
grad[idx] = (fx1 - fx2) / (2*delta_x)
x[idx] = tmp_val
it.iternext()
return grad
# 손실함수 값 계산 함수
# 입력변수 x, t : numpy type
#loss_func과 동일
def error_val(x, t):
delta = 1e-7 # log 무한대 발산 방지
z = np.dot(x,W) + b
y = sigmoid(z)
# cross-entropy
return -np.sum( t*np.log(y + delta) + (1-t)*np.log((1 - y)+delta ) )
# 학습을 마친 후, 임의의 데이터에 대해 미래 값 예측 함수
# 입력변수 x : numpy type
def predict(x):
z = np.dot(x,W) + b
y = sigmoid(z)
if y >= 0.5:
result = 1 # True
else:
result = 0 # False
return y, result
learning_rate = 1e-2 # 발산하는 경우, 1e-3 ~ 1e-6 등으로 바꾸어서 실행
f = lambda x : loss_func(x_data,t_data) # f(x) = loss_func(x_data, t_data)
print("Initial error value = ", error_val(x_data, t_data), "Initial W = ", W, "\n", ", b = ", b )
for step in range(10001):
W -= learning_rate * numerical_derivative(f, W)
b -= learning_rate * numerical_derivative(f, b)
if (step % 400 == 0):
print("step = ", step, "error value = ", error_val(x_data, t_data), "W = ", W, ", b = ",b )
(real_val, logical_val) = predict(3)
print(real_val, logical_val)
(real_val, logical_val) = predict(17)
print(real_val, logical_val)
이 것으로 글을 마친다.
https://github.com/neowizard2018/neowizard
GitHub - neowizard2018/neowizard
Contribute to neowizard2018/neowizard development by creating an account on GitHub.
github.com