로지스틱 회귀를 써야만 하는 때
0/1,예/아니오 등 두개의 답 중 하나만 내놔야하는 경우에 로지스틱회귀(Logistic Regression)을 사용할 수 있다.
로지스틱 회귀에서 사용하는 함수를 활성화함수(activation function)이라고 하는데, 이 활성화 함수에는 시그모이드(Sigmoid), 렐루(ReLu) 등의 함수가 대표적이다.
그 중에서 시그모이드 함수는 $y = {1 \over 1+e^{-(ax+b)}}$이고, 로지스틱 회귀 문제는 이 함수에서의 $a, b$값을 구하는 것이다. 여기서 $a$는 함수의 경사도, $b$는 함수의 좌우 이동 정도를 나타내게 된다.
이번 포스팅의 주인공 시그모이드 함수
위의 sigmoid function은 0보다 큰 지점에서 1에 가까워져야하고, 0보다 작은 지점에서 0에 가까워져야한다.
여기서 $a$값이 커지는 경우는 오차가 무한으로 커지지는 않겠지만, $a$값이 0으로 작아지면 오차가 무한히 커질 것이다. 0.5에 걸친 직선형태가 될테니깐...
다만 $b$값은 커지던 작아지던 일정 범위에서 벗어나면 오차가 무한히 증가할 것이다.
$a, b$에 대한 각각의 오차 정도는 이렇게 될 것이다. x는 지정한 $a,b$의 값, y축은 오차의 크기
시그모이드 함수의 $a,b$는 경사하강법을 통해서 구한다.
왜 제곱평균으로 구하지 않는 지는 잘 모르겠다. 아마 경사하강법을 도입할 때 시그모이드 함수의 a값이 커질때 오차가 작아지니까, 계속해서 a가 커지는 방향으로만 가는 것을 우려해서 이렇게 오차함수를 새로 정의하는 것 같다. 딥러닝에 관한 수학적 공부를 더 해야 파악할 수 있을 듯?
로그함수를 이용해서 시그모이드 함수의 오차를 다음과 같이 쓴다.
h는 시그모이드 함수값이다. 그리고 logh는 오차값이다. y_data는 실제값(0 or 1)이다.
$-{y_{data}log(h) + (1-y_{data}log(1-h))}$
책에선 하지 않지만 난 이 오차함수의 편미분 결과를 도출해낼 것이다.만약 당신이 문과생이라면 그저 묵념...
우선 시그모이드 함수의 미분은
$sig'(x) = ({1 \over 1+e^{(-x)}})' = sig(a)(1-sig(a))$
이므로, chain rule에 의해 시그모이드 함수에 대한(오차함수가 아니다) $a, b$의 편미분은
$sig(ax+b)(1-sig(ax+b))x$
$sig(ax+b)(1-sig(ax+b))$
이렇게 되고, 이것을 기반으로
$-{y_{data}log(h) + (1-y_{data}log(1-h))} = -{y_{data}log(sig(ax+b)) + (1-y_{data}log(1-sig(ax+b)))}$
을 편미분하면...
아 하기 싫다
$y{sig'(ax+b) \over sig(ax+b)} - (1-y){sig'(ax+b) \over 1-sig(ax+b)}$이렇게 되고,
시그모이드 함수의 $a, b$의 편미분 결과를 대입하면 각각 이렇게 나올 것이다.
$x(sig(ax+b) - y)$
$(sig(ax+b) - y)$
내가 해봤다. 날 믿어라.
사용되는 라이브러리 함수들
matplotlib.pyplot.xlim(_args, *_kwargs)
는 주로 이렇게 사용한다.
left, right = xlim() # return the current xlim
xlim((left, right)) # set the xlim to left, right
xlim(left, right) # set the xlim to left, right
ylim도 똑같이 사용한다.
이건 함수가 아니라 Euler’s constant다
numpy.arange([start, ]stop, [step, ]dtype=None, *, like=None)
구간을 일정한 간격으로 나눠준 list를 반환한다.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#공부시간 X와 성적 Y의 리스트를 만듭니다.
data = [[2, 0], [4, 0], [6, 0], [8, 1], [10, 1], [12, 1], [14, 1]]
x_data = [i[0] for i in data]
y_data = [i[1] for i in data]
#그래프로 나타내 봅니다.
plt.scatter(x_data, y_data)
plt.xlim(0, 15)
plt.ylim(-.1, 1.1)
# 기울기 a와 절편 b의 값을 초기화 합니다.
a = 0
b = 0
#학습률을 정합니다.
lr = 0.05
#시그모이드 함수를 정의합니다.
def sigmoid(x):
return 1 / (1 + np.e ** (-x))
#경사 하강법을 실행합니다.
for i in range(2001):
for x_data, y_data in data:
a_diff = x_data*(sigmoid(a*x_data + b) - y_data)
b_diff = sigmoid(a*x_data + b) - y_data
a = a - lr * a_diff
b = b - lr * b_diff
if i % 1000 == 0: # 1000번 반복될 때마다 각 x_data값에 대한 현재의 a값, b값을 출력합니다.
print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))
# 앞서 구한 기울기와 절편을 이용해 그래프를 그려 봅니다.
plt.scatter(x_data, y_data)
plt.xlim(0, 15)
plt.ylim(-.1, 1.1)
x_range = (np.arange(0, 15, 0.1)) #그래프로 나타낼 x값의 범위를 정합니다.
plt.plot(np.arange(0, 15, 0.1), np.array([sigmoid(a*x + b) for x in x_range]))
plt.show()
세개 이상의 입력값은 소프트맥스 함수를 사용해야한다 카더라
다음시간은 퍼셉트론이다.
좀 더 수치해석적인 방법으로 경사하강법을 실시할 수 있으면 좋지 않을까....란 생각이 든다.
참고
'AI > 모두의 딥러닝' 카테고리의 다른 글
[Deep Learning : 딥러닝] 오차 역전파와 XOR 문제 (0) | 2021.06.09 |
---|---|
[Deep Learning : 딥러닝] 퍼셉트론과 XOR 문제 (0) | 2021.06.09 |
[Deep Learning : 딥러닝] 다중 선형 회귀(Multiple linear regression) (0) | 2021.05.16 |
[Deep Learning : 딥러닝] 경사하강법, 선형 회귀(Gradient descent, Linear Regression) (0) | 2021.05.15 |
딥러닝 입문 - 최소제곱법, 평균제곱오차, 딥러닝의 기본 연산(method of least squares, Mean squared error) (2) | 2021.05.08 |