기계 학습의 목표
PLA를 알아보기 전에 우리는 기계학습의 최종적인 목표를 알아야 합니다. 우리는 진정한 target function(목표 함수) f가 무엇인지 모르는 문제를 가지고 있습니다. 여기서 함수란 내가 설계한 인공지능이 내가 생각하는 대로 움직이기 위한 수식을 함수라고 말할 수 있겠습니다. 그리고 목표 함수란 우리가 도출해낼 수 있는 최상의 함수를 말합니다. 그래서 기계학습을 통해 대략적인 가설 함수 g(완벽한 함수)에 근접하는 대략적인 f를 찾는데에 목표가 있습니다. 즉 f ≈ g를 만족하는 것입니다. 아래에 PLA는 성능은 떨어지는 알고리즘이지만 머신러닝의 아이디어를 보여주는데 의미가 있습니다.
Perceptron Learning Algorithm (PLA)
PLA는 인공신경망의 아이디어를 보여주는 기초적인 알고리즘으로 사람의 뇌에 있는 뉴런의 유기적인 연결성을 모방합니다. 인공 신경망의 여러 돌기들(입력 신호)에서 들어온 신호를 축삭 돌기(활성화 함수)를 거쳐 말단 돌기(출력 신호)로 나오는 순서를 이해한다면 PLA의 과정을 이해했다고 보시면 됩니다.
가까이 보이는 크게 보이는 돌기들이 input, 파란색 연결선이 Activation function, 끝 돌기가 output으로 보시면 되겠습니다.
이후 개념적으로 쉽게 도식화하면 아래와 같습니다.
Activation function
여기서 활성화 함수란 여러 입력값을 총합하여 출력 값을 지정해 주는 함수를 말합니다.
이번 PLA에서는 sign에 해당하는 함수를 사용하며 -1과 1로만 출력하는 함수를 말합니다. 만약 1이라면 활성화 -1이라면 비활성화처럼 yes or no로 나누어 주는 것을 말합니다. 이외에서 sigmoid (확률), linear함수가 있습니다.
이제 코드와 예시를 보며 PLA를 더 알아봅시다.
PLA의 동작 알고리즘
먼저 2차원 평면에 있는 +와 -의 점을 분류하는 시나리오를 예시로 들겠습니다.
동작 개념은 잘못 분류된 점 중 하나를 선택하고 점이 더 이상 잘못 분류되지 않도록 weight를 측정합니다. 이러한 방법으로 선을 수정하지만 다른 점을 잘못 분류할 수 있습니다. 여기서 적절한 러닝 레이트를 설정합니다. learningRate란 자신이 틀렸을 때 얼마만큼 수정을 할지를 말합니다. 러닝 레이트가 너무 작다면 틀려도 너무 작은 변화만 있기 때문에 러닝 횟수가 너무 많아져 기능 저하를 일으킵니다. 반대로 너무 크다면 값이 너무 요동치게 되는데 이경우를 Overshooting이라고 합니다. 이경우 Nan값이 나타며 이동 범위가 너무 크다는 것을 의미합니다. 러닝 레이트를 적당히 설정한다면 아래와 같은 선의 변화가 나타납니다.
이제 코드와 함께 알아보겠습니다.
우선 PLA에 사용될 퍼셉트론 함수의 코드입니다.
def perceptron(weights,x):
"""
Parameters
----------
weight : np.array [d]
The weighs of Perceptron
X : np.array [N, d]
The input data, form of matrix
Return
----------
y : np.array [N]
The predicted output
"""
return np.sign(np.inner(weights.T,x))
위 그림을 코드로 표현한 것이라 보시면 되겠습니다.
def PLA(X, y, weights=None, max_iters=50000, learningRate=1,
verbose=False, skip=1, ):
if weights is None:
weights = np.array(np.random.random(X.shape[1]))
misclassified = True
success = False
iters = 0
indexes = range(len(X))
while misclassified and iters < max_iters:
if verbose and iters % skip==0:
fig, ax = plt.subplots(1)
plot_costs(ax, X[:, 1], X[:, 2], y)
margin = 1
plt.xlim([np.min(X[:, 1]-margin), np.max(X[:, 1])+margin])
plt.ylim([np.min(X[:, 2]-margin), np.max(X[:, 2])+margin])
plot_weight_line(ax, weights, 0, 9)
plt.title('iteration %d'%iters)
plt.show()
##↓↓↓중요
misclassified = False
for i in np.random.permutation(indexes):
if perceptron(weights, X[i]) != y[i]:
weights = weights + y[i]* X[i]*learningRate
misclassified = True
success = not misclassified
iters += 1
return weights, success, iters
## 중요 부분만 보셔도 되겠습니다. (colab환경에서 실행된 코드의 일부입니다.)
우선 모든 부분이 나누어지지만 에러를 생각하여 50000번 이상은 반복이 되지 않도록 설정했습니다.
인덱스를 랜덤 추출하여 그 점이 선에 의하여 잘 나뉘어 있는지 확인합니다. 만약 잘 나뉘어 있지 않다면
weight를 업데이트해줍니다. 사실
weights = weights + y[i]* X[i]*learningRate
이 한 줄이 PLA의 개념이라고 보시면 되겠습니다. "내 답이 틀렸는지 아닌지 보고 수정한다"라는 기본적인 기계학습의 개념을 보여줍니다. 이상 포스팅을 마치겠습니다.