로지스틱 회귀(Logistic Regression)

시그모이드 함수(sigmoid function)

  • 퍼셉트론 모델에서 뉴런이 발화하는지($1$) 발화하지 않는지($0$)는 계단함수를 가지고 판별하여 이진 분류(binary classification)를 할 수 있다
  • 일상적인 문제에서는 이진분류로만 해결할 수 없는 일들이 많다. 예를 들어 $0$과 $1$이 아닌 어중간한 것들을 판별해야하는 일들이 많다
  •  이런 경우에는 $0$과 $1$ 사이의 값에 대응시켜야 하는데, 이런 경우 확률로 대응시킬 수 있어 몇 %의 확률로 예측이 가능하다고 할 수 있다
  • 확률을 출력하기 위해서서는 $0$과 $1$ 사이의 실수에 대응시켜줄 수 있는 함수가 필요한데 이런 성질을 만족하는 함수 중의 하나가 식 (4.1)이며 시그모이드 함수(sigmoid function) 또는 로지스틱 함수(logistic function)이라고 한다

\begin{eqnarray} \sigma(x) = \frac{1}{1+e^{-x}}\tag{4.1}\end{eqnarray}


  • 계단함수와 시그모이드 함수의 비교


시그모이드 함수와 확률 밀도 함수, 누적 분포 함수와의 관계

  • 확률 밀도 함수(PDF; Probability Density Function) : 확률 변수의 분포를 나타내는 함수로 확률 변수 $X$가 $a$ 이상 $b$ 이하가 될 확률을 식 (4.2)와 같이 표현할 때 $f(x)$를 확률밀도함수라고 한다

\begin{eqnarray}\textrm{Pr}(a\leqslant X \leqslant b) = \int_a^b f(x) dx\tag{4.2}\end{eqnarray}

  • $f(x)$는 확률이기 때문에 다음 두 조건 식 (4.3)과 식 (4.4)를 만족해야 한다
    1. 모든 실수 $x$에 대하여\begin{eqnarray}f(x) \geqslant 0\tag{4.3}\end{eqnarray}
    2. 실수 범위를 가지는 확률 변수 $X$에 대하여\begin{eqnarray}\textrm{Pr}(-\infty \leqslant X \leqslant \infty) = \int_{-\infty}^{\infty}f(x)dx=1\tag{4.4}\end{eqnarray}
  • 누적 분포 함수(CDF; Cumulative Distribution Function) : 어떤 확률 분포에서 확률 변수가 특정값보다 작거나 같은 확률로 실수 범위를 가지는 확률 변수 $X$의 누적 분포 함수를 $F(x)=P(X\leqslant x)$이라고 할 때, 식 (4.5)와 같이 표현된다

\begin{eqnarray}F(x)= \int_{-\infty}^x f(t)dt\tag{4.5}\end{eqnarray}

  • 식 (4.2)와 식 (4.5)로부터 확률 밀도 함수와 누적 분포 함수 사이에는 식 (4.6)과 같은 관계가 있는 것을 알 수 있다

\begin{eqnarray} \frac{d}{dx}F(x) = F'(x) = f(x)\tag{4.5}\end{eqnarray}


정규분포의 확률 밀도 함수와 누적 분포 함수

  • 확률을 표현하는 함수로는 확률 밀도 함수와 누적 분포 함수가 있는데, 누적 분포 함수는 값이 $0$부터 $1$까지의 범위에 있으므로 함수값이 확률을 나타내는 함수로 적절
  • 그러나 특정 값만 취하는 함수를 사용한다면 확률 변수 $x$의 분포에 편향이 생길 수 있기 때문에 확률 변수의 분포가 가장 일반적인 정규분포를 따르는 함수를 생각해보자
  • 평균이 $\mu$이고 표준편차가 $\sigma$인 정규분포의 확률 밀도 함수는 식 (4.6)와 같으며, 그림과 같이 정규분포의 누적 분포 함수의 값도 $0$에서 $1$ 사이에 있다

\begin{eqnarray} f(x) = \frac{1}{\sqrt{2\pi\sigma}}e^{-\frac{(x-\mu)^2}{2\sigma^2}}\tag{4.6}\end{eqnarray}

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-10, 11, 100000)

fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)

def pdf(x, mu=0, sigma=1):
    return (np.exp(-(x-mu)**2/2/(sigma**2))) / (np.sqrt(2*math.pi)*sigma)

for sigma in range(1, 4):
    ax1.plot(x, pdf(x, sigma=sigma), label=f'$\sigma$={sigma}')

ax1.legend()
ax1.grid(linestyle=':')
ax1.set_title("PDF of Normal Distribution")
ax1.set_xticks([0])

ax2 = fig.add_subplot(1, 2, 2)

from scipy.special import erf

def cdf(x, mu=0, sigma=1):
    return (1 + erf((x - mu) / np.sqrt(2) / sigma)) / 2

for sigma in range(1, 4):
    ax2.plot(x,cdf(x, sigma=sigma),label=f'$\sigma$={sigma}')

ax2.legend(loc=5)
ax2.grid(linestyle=':')
ax2.set_title('CDF of Normal Distribution')
ax2.set_xticks([0])
ax2.set_yticks([0, 1])
plt.show()


  • 로지스틱 회귀는 활성화 함수로 시그모이드 함수를 사용하는데, 시그모이드 함수 대신 정규분포의 누적 분포 함수를 사용하는 모델을 프로빗 회귀(probit regression)이라고 한다
    • 정규분포의 확률 누적 함수가 확률을 출력하는 함수로 시그모이드 함수보다 더 적절하지만 신경망 모델에서는 거의 사용되지 않음


정규분포의 확률 누적 분포 함수가 사용되지 않는 이유

  • 표준정규분포의 누적 분포 함수 $p(x)$를 이용해 뉴런을 모델화하는 것을 생각해보면 가설 모델은 식 (4.7)과 같이 표현할 수 있다

\begin{align} H(\mathbb{x}) & = \textrm{Pr}(\mathbb{wx} + b) \\ & = \int_{-\infty}^{\mathbb{wx}+b}\frac{1}{\sqrt{2\pi}}e^{-\frac{(\mathbb{w}t+b)^2}{2}}dt\tag{4.7}\end{align}

  • 학습을 위해서는 실제의 값과 뉴런 모델의 출력값의 차가 최소가 되도록 웨이트와 바이어스를 조절해야하는데, 식 (4.7)를 사용하는 경우에는 이를 계산하는 것이 쉬운 일이 아니다
  • 오차가 최소가 되도록 매개변수의 값을 업데이트하는 것이 쉬워야하기 때문에 다소 오차는 있지만 누적 분포 함수와 모양의 거의 흡사하면서도 계산은 매우 쉬운 시그모이드 함수를 사용하는 것이 편리하다. 아래 그림은 $\sigma=1$과 $\sigma=2$일 때의 누적 분포 함수와 시그모이드 함수의 그래프를 비교한 것이다
    • 모든 일에서 이론도 매우 중요하지만 '현실적으로 계산이 가능한가?'라는 생각을 가지고 공학적으로 접근한 것도 중요하다

import numpy as np
import matplotlib.pyplot as plt
from scipy.special import erf

x = np.linspace(-10, 11, 100000)

def sigmoid(x):
    return 1 / (1+np.exp(-x))

def cdf(x, mu=0, sigma=1):
    return (1 + erf((x - mu) / np.sqrt(2) / sigma)) / 2

plt.plot(x, sigmoid(x), label='sigmoid function')
plt.plot(x, cdf(x, sigma=1), label='CDF where $\sigma$=1')
plt.plot(x, cdf(x, sigma=2), label='CDF where $\sigma$=2')
plt.grid(linestyle=":")
plt.xticks([0])
plt.yticks([0, 1])
plt.legend()
plt.show()


로지스틱 회귀 모델화

  • 로지스틱 회귀는 단순 퍼셉트론과는 달리 $0$과 $1$ 사이의 값을 갖는 확률적인 분류 모델이기 때문에 단순 신경망 모델과는 다른 모델링 방법을 사용해야 한다
  • 어떤 입력 $x$에 대하여 뉴런이 발화할지 여부를 나타내는 확률변수를 $C$라고 하면 $C$는 뉴런이 발화할 경우 $C=1$이 되고 발화하지 않을 경우 $C=0$이 되는 확률변수이기 때문에 단순 신경망 모델식을 고려해보면 뉴런이 발화할 확률은 식 (4.8)과 같다

\begin{eqnarray} \textrm{Pr}(C=1|x)=\sigma(\mathbb{wx}+b)\tag{4.8}\end{eqnarray}

  • 뉴런이 발화하는 않을 확률은 식 (4.9)와 같다
    • 뉴런이 발화하거나 발화하지 않은 확률은 둘 중의 하나이기 때문에 $1$이다

\begin{eqnarray} \textrm{Pr}(C=0|x) = 1 - \textrm{Pr}(C=1|x)\tag{4.9}\end{eqnarray}

  • $C$는 $1$(발화)이거나 $0$(발화하지 않음)의 두 가지 값만 갖기 때문에 가설 모델을 $H(\mathbb{x})=\sigma(\mathbb{wx}+b)$라고 하면, $y\in\{0,1\}$일 때 식 (4.8)과 식 (4.9)는 식 (4.10)으로 표현할 수 있다

\begin{eqnarray} \textrm{Pr}(C=y|x)=(H(\mathbb{x}))^y(1-H(\mathbb{x}))^{1-y} \tag{4.10}\end{eqnarray}

    • $y=0$인 경우, 

\begin{align}\textrm{Pr}(C=0|x) &=(H(\mathbb{x}))^0(1-H(\mathbb{x}))^{1-0}\\&=1\cdot(1-H(\mathbb{x}))^1\\&=1-H(\mathbb{x})\\&=1-\sigma(\mathbb{wx}+b)\\&=1-\textrm{Pr}(C=1|x)\end{align}

    • $y=1$인 경우,

\begin{align}\textrm{Pr}(C=1|x)&=(H(\mathbb{x}))^1(1-H(\mathbb{x}))^{1-1}\\ &=y\cdot(1-H(\mathbb{x}))^0\\ &=y\cdot 1\\ &=H(\mathbb{x})\\ &=\sigma(\mathbb{wx}+b)\\ &=\textrm{Pr}(C=1|x)\end{align}

  • $N$개의 입력 데이터 $\mathbb{x}_n(n=1, 2,\ldots,N)$과 이 입력 데이터와 쌍을 이루는 출력 데이터 $\mathbb{y}_n$이 주어졌을 때 신경망의 매개변수인 $\mathbb{w}$와 바이어스 $b$의 가장 좋은 값을 찾기 위하여 가능도 또는 우도 함수(likelihood function)는 표준정규분포의 누적 분포 함수 대신에 시그모이드 함수를 사용한 가설식 (4.11)를 사용해 식 (4.12)과 같이 나타낼 수 있다

 \begin{eqnarray} H(\mathbb{x})=\sigma(\mathbb{wx}+b) \tag{4.11}\end{eqnarray}

    • 각각의 $\mathbb{x}_n$에 대하여 신경망 모델의 출력값이 $\mathbb{y}_n$이 될 확률 $\textrm{Pr}(C=\mathbb{y}_n|\mathbb{x}_n)$이 높아야 좋은 모델이다

\begin{align} L(\mathbb{w},b) &= \prod_{n=1}^{N}\textrm{Pr}(C=\mathbb{y}_n|\mathbb{x}_n)\\ &= \prod_{n=1}^{N} (H_n(\mathbb{x}))^{\mathbb{y}_n}(1-H_n(\mathbb{x}))^{1-\mathbb{y}_n}\tag{4.12}\end{align}

  • 식 (4.12)의 가능도 함수 또는 우도 함수의 값이 최대가 되도록 매개변수를 업데이트하면 신경망 모델이 학습을 잘한 것이라고 볼 수 있다
    • 함수의 최대나 최소가 되는 상태를 구하는 문제를 최적화 문제(optimization problem)라고 한다
    • 함수의 최대화는 부호를 바꾸면 최소화가 되기 때문에 일반적으로 함수를 최적화한다고 하는 것은 함수를 최소로 만드는 매개변수를 구하는 것을 의미한다


함수 최적화와 미분 관계

  • 함수 최적화 문제는 함수를 최대나 최소로 만드는 매개변수를 구하는 것이기 때문에 함수의 최대와 최소는 미분(differentiation)과 관계가 있기 때문에 우리는 식 (4.12)를 매개변수들로 편미분(partial differentiation)하는 문제를 생각해야 한다
  • 식 (4.12)는 함수가 곱의 형태로 되어 있어 편미분을 계산하는 것이 쉽지 않기 때문에 편미분 계산이 쉽도록 식 (4.11)에 로그를 취해 덧셈 형태로 변환하고 최소가 되는 최적화 문제가 되도록 음수의 형태로 변환하면 식 (4.13)이 된다

\begin{align} E(\mathbb{w}, b) &= -\log L(\mathbb{w}, b)\\ &= -\log \prod_{n=1}^{N} (H_n(\mathbb{x}))^{\mathbb{y}_n}(1-H_n(\mathbb{x}))^{1-\mathbb{y}_n}\\&= -\sum_{n=1}^N\Big(\mathbb{y}_n\log H_n(\mathbb{x})+(1-\mathbb{y}_n)\log (1-H_n(\mathbb{x})\Big)\tag{4.13}\end{align}

  • 식 (4.13)과 같은 형태의 함수를 교차 엔트로피 오차 함수(cross-entropy error fuction 또는 crosss-entropy cost function)이라고 하며, 이 함수를 최소화하는 것이 식 (4.12) 가능도 또는 우도 함수를 최대화하는 것이기 때문에 식 (4.12)는 최적의 상태에서 오차가 어느 정도 있는지를 알 수 있는 식이라고 할 수 있기 때문에 식 (4.13)를 오차 함수(cost function) 또는 손실 함수(loss function)이라고 한다


경사하강법

  • 식 (4.13) 오차 함수에서 매개변수는 $\mathbb{w}$와 $b$이기  때문에 $\mathbb{w}$와 $b$로 편미분해서 $0$이 되는 값이 오차 함수가 최소가 되기 때문에 이 식을 직접 해석적으로 식을 풀어 해를 구하는 것은 쉬운 문제가 아니다
  • 해석적으로 식을 푸는 방법보다는 단순 신경망 모델에서 처럼 오차를 계산하여 줄여나가는 방법으로 매개변수를 갱신하는 방법을 사용해야 하는데 매개변수를 업데이트하며 오차를 최소하는 방법 중 대표적인 것이 경사하강법(GDA; Gradient Descent Algorithm)이다
  • 가중치 $\mathbb{w}$와 바이어스 $b$는 식 (3.9)와 식 (3.10)과 같은 방법으로 업데이트된다

\begin{align}\mathbb{w}^{k+1} &=\mathbb{w}^k + \Delta\mathbb{w}^k \tag{3.9} \end{align}

\begin{align} b^{k+1} &= b^k + \Delta b^k\tag{3.10}\end{align}

  • 경사하강법에서 가중치와 바이어스는 식 (4.14)와 식 (4.15)와 같은 방법으로 계산
    • $\alpha(>0)$는 학습률(learning rate)이라는 하이퍼파라미터(hyperparameter)로 알고리즘 내부 설정값인데 이는 가설 모델의 매개변수가 업데이트 또는 최소로 수렴하는 정도를 조절하는 매개변수
    • 보통 $0.1$이나 $0.01$과 같은 적당히 작은 값을 사용

\begin{align} \mathbb{w}^{k+1} &= \mathbb{w}^k - \alpha \frac{\partial E(\mathbb{w},b)}{\partial \mathbb{w}} \tag{4.14}\end{align}

\begin{align} b^{k+1} &= b^k-\alpha \frac{\partial E(\mathbb{w}, b)}{\partial b} \tag{4.15}\end{align}

  • 가중치 $\mathbb{w}$에 대한 기울기를 편미분을 통해 구하기 위해 $n$번째 오차 함수 $E_n$을 식 (4.16)로 정의한다

\begin{eqnarray} E_n = -\big( \mathbb{y}_n \log H_n(\mathbb{x}) + (1-\mathbb{y}_n)\log (1-H_n(\mathbb{x})\big)\tag{4.16}\end{eqnarray}

  • 가중치 $\mathbb{w}$에 대한 기울기는 식 (4.17)과 같이 구할 수 있다

\begin{align} \frac{\partial E(\mathbb{w},b)}{\partial \mathbb{w}} &= \sum_{n=1}^N\frac{\partial E_n}{\partial H_n(\mathbb{x})}\frac{\partial H_n(\mathbb{x})}{\partial \mathbb{w}}\\ &= -\sum_{n=1}^N \Bigg(\frac{\mathbb{y}_n}{H_n(\mathbb{x})} - \frac{1-\mathbb{y}_n}{1-H_n(\mathbb{x})}\Bigg) \frac{\partial H_n(\mathbb{x})}{\partial \mathbb{w}}\quad(\because\,\, H(\mathbb{x})=\sigma(\mathbb{wx}+b)\,\,(4.11))\\ &= -\sum_{n=1}^N \Bigg(\frac{\mathbb{y}_n}{H_n(\mathbb{x})} - \frac{1-\mathbb{y}_n}{1-H_n(\mathbb{x})}\Bigg)  H_n(\mathbb{x})(1-H_n(\mathbb{x}))\mathbb{x}_n\quad(\because \,\, (4.18))\\ &= -\sum_{n=1}^N\Big( \mathbb{y}_n(1-H_n(\mathbb{x}))-H_n(\mathbb{x})(1-\mathbb{y}_n)  \Big)\mathbb{x}_n \\ &= -\sum_{n=1}^N\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\mathbb{x}_n\tag{4.17}\end{align}

\begin{align}\frac{d}{dx}\sigma(x) &= \frac{d}{dx}(1+e^{-x})^{-1}\\ &= (-1)(1+e^{-1})^{-1-1}\frac{d}{dx}(1+e^{-x})\\ &= \frac{-1}{(1+e^{-x})^{2}}\bigg(\frac{d}{dx}1+\frac{d}{dx}e^{-x}\bigg) \\ &= \frac{-1}{(1+e^{-x})^{2}}\bigg(0+e^{-x}\frac{d}{dx}(-x)\bigg) \\&=\frac{-1}{(1+e^{-x})^{2}}e^{-x}(-1) \\ &= \frac{e^{-x}}{(1+e^{-2})^2} \\ &=  \frac{1+ e^{-x} -1}{(1+e^{-2})^2}\\ &=\frac{1+e^{-x}}{(1+e^{-x})^2}-\frac{1}{(1+e^{-x})^2}\\&= \frac{1}{1+e^{-x}} -\frac{1}{(1+e^{-x})^2}\\ &= \frac{1}{1+e^{-x}}\bigg(1-\frac{1}{1+e^{-x}}\bigg)\\ &= \sigma(x)(1-\sigma(x)) \tag{4.18}\end{align}

  • 바이어스 $b$에 대한 기울기는 식 (4.19)과 같이 구할 수 있다

\begin{align} \frac{\partial E(\mathbb{w},b)}{\partial b} &= \sum_{n=1}^N\frac{\partial E_n}{\partial H_n(\mathbb{x})}\frac{\partial H_n(\mathbb{x})}{\partial b}\\ &= -\sum_{n=1}^N \Bigg(\frac{\mathbb{y}_n}{H_n(\mathbb{x})} - \frac{1-\mathbb{y}_n}{1-H_n(\mathbb{x})}\Bigg) \frac{\partial H_n(\mathbb{x})}{\partial b}\quad(\because\,\, H(\mathbb{x})=\sigma(\mathbb{wx}+b)\,\,(4.11))\\ &= -\sum_{n=1}^N \Bigg(\frac{\mathbb{y}_n}{H_n(\mathbb{x})} - \frac{1-\mathbb{y}_n}{1-H_n(\mathbb{x})}\Bigg)  H_n(\mathbb{x})(1-H_n(\mathbb{x}))\quad(\because \,\, (4.18))\\ &= -\sum_{n=1}^N\Big( \mathbb{y}_n(1-H_n(\mathbb{x}))-H_n(\mathbb{x})(1-\mathbb{y}_n)  \Big) \\ &= -\sum_{n=1}^N\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\tag{4.19}\end{align}


  • 경사하강법을 통해 우리가 구하고자 하는 가중치 식 (4.14)와 바이어스 식 (4.15)는 각각 식 (4.20) 및 식 (4.21)과 같이 구할 수 있다

\begin{align} \mathbb{w}^{k+1} &= \mathbb{w}^k - \alpha \frac{\partial E(\mathbb{w},b)}{\partial \mathbb{w}} \\&= \mathbb{w}^k + \alpha\sum_{n=1}^N\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\mathbb{x}_n\tag{4.20}\end{align}

\begin{align} b^{k+1} &= b^k-\alpha \frac{\partial E(\mathbb{w}, b)}{\partial b} \\ &= b^k+\alpha\sum_{n=1}^N\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\tag{4.21}\end{align}


확률적 경사하강법과 미니배치 경사하강법

  • 식 (4.20)와 식 (4.21)의 경사하강법을 통해 로지스틱 회귀 문제를 해결할 수 있지만 실제 구현에 있어서는 한번 학습을 할 때마다 학습 데이터의 개수만큼 $N$번의 합을 구해야만 하는 문제가 발생하는데, $N$이 작으면 큰 문제가 없지만 $N$이 큰 경우에는 구현상에 문제가 발생
    • 메모리에 적재할 때 용량의 문제로 메모리에 다 올려놓지 못하는 경우가 발생하는 문제
    • 계산 시간이 증가하는 문제
  • 이 문제를 해결하기 위한 대책으로 나오는 것이 확률적 경사하강법(SGD; Stochastic Gradient Descent Algorithm)
    • 경사하강법 : 모든 입력데이터의 합을 구한 후 매개변수 업데이트

\begin{align} \mathbb{w}^{k+1} &=  \mathbb{w}^k + \alpha\sum_{n=1}^N\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\mathbb{x}_n\\ b^{k+1} &= b^k+\alpha\sum_{n=1}^N\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\end{align}

    • 확률적 경사하강법 : $N$개의 데이터 중에서 무작위로 1개를 선택해 계산 후 매개변수 업데이트

\begin{align} \mathbb{w}^{k+1} &= \mathbb{w}^k + \alpha\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\mathbb{x}_n\tag{4.22}\\ b^{k+1} &= b^k+\alpha\big(\mathbb{y}_n-H_n(\mathbb{x})\big)\tag{4.23}\end{align}

      • 식 (4.22)와 식 (4.23)을 $N$개의 데이터에 대해 계산
      • 장점 : 경사하강법 1번의 계산량으로 확률적 경사하강법을 $N$번 계산할 수 있기 때문에 효율적으로 최적의 해를 찾을 수 있음
      • 단점 : 경사가 $0$으로 수렴하는 일이 거의 없기 때문에 최소해를 찾기가 힘들 뿐만 아니라 $N$개의 데이터 전체에 대하여 반복해서 학습을 해야함
        • 에포크(epoch) : $N$개의 데이터 전체에 대한 반복 학습 횟수
        • 각 에포크마다 데이터를 무작위로 섞어서(shuffle) 학습을 하기 때문에 학습을 할 때 편향되지 않은 최적의 해를 찾기 쉬워짐
for epoch in range(epochs):
    shuffle(data)       # 에포크마다 데이터를 섞는다
    for datum in data:  # 데이터를 1개씩 사용해 매개변수를 업데이트한다
        parameters_gradient = evaluate_gradient(cost_function, parameters, datum)
        parameters -= learning_rate * parameters_gradient 


    • 미니배치 경사하강법(Minibatch Gradient Descent Algorithm) : 경사하강법과 확률적 경사하강법의 중간에 위치한 방법으로 $N$개의 데이터를 $M(\leqq N)$개씩으로 나눠서(미니배치) 학습하는 방법이며, $M$는 대략 $50 \leqq M \leqq 500$정도의 값을 사용하며, 이와 대비하여 일반 경사하강법을 배치 경사하강법이라고도 한다
      • 미니배치 경사하강법을 사용하면 메모리의 부족함없이 선형대수를 사용하여 연산할 수 있기 때문에 1개씩 반복 계산하는 것보다 빠르게 연산이 가능
      • 일반적으로 '확률적 경사하강법'이라고 하면 '미니배치 경사하강법'을 말하는데, $M=1$인 경우가 정확한 확률적 경사하강법에 해당함
for epoch in range(epochs):
    shuffle(data)           # 에포크마다 데이터를 섞는다
    batches = get_batches(data, batch_size=M)
    for batch in batches:   # 각 미니배치마다 매개변수를 업데이트한다
        parameters_gradient = evaluate_gradient(cost_function, parameters, datum)
        parameters -= learning_rate * parameters_gradient 


OR 게이트 로지스틱 회귀를 TensorFlow로 구현

  • 파이썬 코드
import numpy as np
import tensorflow as tf

X = np.array([[0, 0],
              [0, 1],
              [1, 0],
              [1, 1]])

Y = np.array([[0],
              [1],
              [1],
              [1]])

W = tf.Variable(tf.zeros([2, 1]))
b = tf.Variable(tf.zeros([1]))

x = tf.placeholder(tf.float32, shape=[None, 2])
y = tf.placeholder(tf.float32, shape=[None, 1])

hypothesis = tf.nn.sigmoid(tf.matmul(x, W) + b)
cost = -tf.reduce_sum(y * tf.log(hypothesis) + (1-y)*tf.log(1-hypothesis))
train = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(cost)

correct_predict = tf.equal(tf.to_float(tf.greater(hypothesis, 0.5)), y)

with tf.Session() as sess:
    init = tf.global_variables_initializer()
    sess.run(init)

    for epoch in range(200):
        sess.run(train, feed_dict={x: X, y: Y})

    classified = correct_predict.eval(session=sess, feed_dict={x: X, y: Y}) # OR 게이트 예측값
    print(f'OR 게이트 예측 결과: \n{classified}')

    prob = hypothesis.eval(session=sess, feed_dict={x: X, y: Y})            # OR 게이트의 출력 확률
    print(f'OR 게이트 출력 확률: \n{prob})
  • 실행 결과
OR 게이트 예측 결과 :
[[ True]
 [ True]
 [ True]
 [ True]]

OR 게이트 출력 확률 :
[[0.22355038]
 [0.9142595 ]
 [0.9142595 ]
 [0.99747425]]


OR 게이트 로지스틱 회귀를 Keras로 구현

  • 파이썬 코드
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import SGD

# 가설식 모델 정의 : 입력(input_dim) 2개, 출력(units) 1개
# 발화를 결정하는 활성화 함수는 누적 분포 함수가 아닌 sigmoid를 사용
model = Sequential()
model.add(Dense(input_dim=2, units=1))
model.add(Activation('sigmoid'))

# 가설식의 오차 함수는 cross-entropy 함수를 사용
model.compile(loss='binary_crossentropy', optimizer=SGD(learning_rate=0.1))

X = np.array([[0, 0],
              [0, 1],
              [1, 0],
              [1, 1]])

Y = np.array([[0],
              [1],
              [1],
              [1]])

# 가설식 모델 학습시키기
model.fit(X, Y, epochs=200, batch_size=1)

# 학습 결과 확인하기
classes = model.predict_classes(X, batch_size=1)
prob = model.predict_proba(X, batch_size=1)

print(f'\nOR 게이트 예측 결과 :\n{Y==classes})')
print()
print(f'OR 게이트 출력값 확률:\n{prob}')
  • 실행 결과
1/4 [======>.......................] - ETA: 0s - loss: 0.2746
4/4 [==============================] - 0s 500us/step - loss: 0.1184
Epoch 197/200

1/4 [======>.......................] - ETA: 0s - loss: 0.0911
4/4 [==============================] - 0s 751us/step - loss: 0.1179
Epoch 198/200

1/4 [======>.......................] - ETA: 0s - loss: 0.0031
4/4 [==============================] - 0s 501us/step - loss: 0.1174
Epoch 199/200

1/4 [======>.......................] - ETA: 0s - loss: 0.0905
4/4 [==============================] - 0s 750us/step - loss: 0.1169
Epoch 200/200

1/4 [======>.......................] - ETA: 0s - loss: 0.2696
4/4 [==============================] - 0s 750us/step - loss: 0.1163

OR 게이트 예측 결과 :
[[ True]
 [ True]
 [ True]
 [ True]]

OR 게이트 출력값 확률:
[[0.23539683]
 [0.9141111 ]
 [0.906056  ]
 [0.99700963]]



출처 : 정석으로 배우는 딥러닝

'신경망(Neural Network) 스터디' 카테고리의 다른 글

6. 다층 퍼셉트론 모델링  (0) 2017.12.28
5. 다중 클래스 로지스틱 회귀  (0) 2017.12.27
3. 단순 신경망 모델의 확장  (0) 2017.12.22
2. 논리 회로  (0) 2017.12.22
1. 신경망의 단순 모델  (0) 2017.12.21

+ Recent posts