> For the complete documentation index, see [llms.txt](https://ai-society-1.gitbook.io/ai-society/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-society-1.gitbook.io/ai-society/9..md).

# 9. 활성화 함수

## 활성화 함수

## 활성화 함수란?

* 간단하게 말하면 활성, 비활성을 결정하는 함수.
* 신경망에서는 노드에 들어오는 값들에 대해 다음 레이어로 바로 전달하지 않고 활성화 함수를 통과시켜 전달.
* 활성화 함수는 입력 신호의 총합을 출력 신호로 변환하는 함수로, 입력 받은 신호를 얼마나 출력할지 결정 & 네트워크에 층을 쌓아 **비선형성**을 표현할 수 있도록 해줌.
*

```
<figure><img src="/files/I1YhOfilrfu2OgubIKHL" alt=""><figcaption></figcaption></figure>
```

**<비선형성을 사용하는 이유>**

* 인공 신경망의 성능을 높이기 위해서는 은닉층을 계속해서 추가해야함
* 선형 함수를 사용하면 은닉층을 쌓을 수 없음
* 다시 말해, 선형 연산은 아무리 층을 깊게 해도 의미가 없음 ex) h(x) = ax → h(h(hx)) → h(x) = bx
* 따라서 비선형을 사용하여 복잡한 함수를 학습하고, 정확도를 향상시킴

## 활성화 함수의 종류

* 계단 함수
* 시그모이드 함수
* 하이퍼볼릭탄젠트 함수
* 렐루 함수
* 리키 렐루 함수
* ELU
* 소프트맥스 함수
* …

## 인공신경망에서의 학습 과정

<figure><img src="/files/qXzYslOnIrH9w8jXxxE1" alt=""><figcaption></figcaption></figure>

* 순전파는 입력 데이터를 신경망에 공급하고 활성화 함수를 계산하여 예측된 출력값 얻음
* 역전파에서 네트워크의 매개변수에 대한 결과값과 실제값 비교 후 오차를 통해 손실 함수의 기울기 계산, 이를 이용해 가중치와 편향 업데이트

## 계단 함수(Step function)

* 최초로 사용한 활성화 함수

$$
step(x) = \lbrace ^ {0\quad(x<0)} \_{1\quad(x > 0)}
$$

```python
import numpy as np
import matplotlib.pyplot as plt

def step(x):
    return np.array(x > 0, dtype=np.int64)

x = np.arange(-3.0, 3.0, 0.01)
y = step(x)
plt.plot(x, step(x))
plt.ylim(-0.1, 1.1)
plt.title("step")
plt.show()
```

*

```
<figure><img src="/files/zluQIvYQJbodHGGoZXhl" alt=""><figcaption></figcaption></figure>
```

* 데이터의 손실이 일어날 가능성이 있기 때문에 딥러닝에서는 사용되지 않는 활성화 함수
* 매우 간단한 분류는 가능할지도 모르지만, 딥러닝은 필요한 데이터가 매우 다양하므로, 만약 사용할 경우 매우 낮은 성능을 가질 것
* 모든 구간에서 미분값이 0 → 현대의 신경망에서는 사용하기 어려움 → 역전파 알고리즘에 적용시, 학습이 진행되지 않기 때문

## 시그모이드 함수(Sigmoid function) = Logistic

* x의 값에 따라 0\~1의 값을 출력하는 S자형 함수

$$
sigmoid(x) = {1\over 1+ e^{-x}}
$$

$$
{d\over{dx}}sigmoid(x) = {1\over {1+e^{-x}}}(1-{1\over {1+e^{-x}}}) = sigmoid(x)(1-sigmoid(x))
$$

```python
import numpy as np
import matplotlib.pyplot as plt

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

x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)

plt.plot(x, y)
plt.plot([0, 0], [1.0, 0.0], ":")
plt.title("sigmoid")
plt.show()
```

<figure><img src="/files/KdSNIjxJVaUQS6lgoovR" alt=""><figcaption></figcaption></figure>

#### 장점

* 출력값의 범위가 0\~1사이 → 확률로 보기 편함
* 매끄러운 곡성, 기울기가 급격하게 변해서 발생하는 기울기 폭주 문제 발생 안함
* 어느 분류에 속하는지 쉽게 파악 가능

#### 단점

* 시그모이드 함수의 출력값이 0 또는 1에 가까워지면, 그래프의 기울기 완만해짐
* 0과 1에 가까운 부분의 기울기 계산 ⇒ 0에 가까운 작은 값 ⇒ 학습효과 떨어짐
* 층이 많아질수록 앞단에는 기울기가 잘 전달되지 않음 ⇒ 기울기가 0이 되기 때문 ⇒ **기울기 소실 문제**(Vanishing Gradient)
* 출력값이 작아서 제대로 학습이 안될뿐만 아니라, 중심이 0이 아니라서 시간도 많이 걸림
* 출력값이 모두 양수이기 때문에 경사하강법을 진행할 때, 기울기가 모두 양수거나 음수
* 은닉층에서 사용하는 것은 지양!

#### 사용하는 곳

* 신경망, 로지스틱 회귀, 분류 문제의 가설과 비용함수 등

## 하이퍼볼릭탄젠트 함수(Hyperbolic tangent function)

* 시그모이드 함수의 한계점 보완, 크기 위치 조절
* 입력값을 -1과 1사이의 값으로 변환
* σ(x)는 sigmoid함수 식

$$
tanh(x)=2\alpha(2x)-1 = {e^{x}-e^{-x}\over{e^x-e^{-x}}}
$$

$$
{d\over{dx}}tanh(x)=1-tanh^2(x)
$$

```python
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-5.0, 5.0, 0.1)
y = np.tanh(x)

plt.plot(x, y)
plt.plot([0, 0], [1.0, -1.0], ":")
plt.axhline(y=0, color="green", linestyle="--")
plt.title("Tanh")
plt.show()
```

<figure><img src="/files/2Qjp9HjBQAOLvg7ZeRsX" alt=""><figcaption></figcaption></figure>

#### 장점

* 중앙값이 0 → 경사하강법 사용시 편향 이동 X
* 출력값 데이터의 평균이 0 → 시그모이드 보다 대부분 학습이 더 잘됨
* 시그모이드 함수보다 범위가 넓기 때문에 출력값의 변화 폭이 크고, 기울기 소실 문제가 적음
* 은닉층에서도 시그모이드 보다 효율적

#### 단점

* 여전히 기울기 소실 문제가 일어나긴함
* 은닉층에서의 사용도 여전히 조심해야함

#### 사용하는 곳

* 시그모이드와 비슷

## 렐루 함수(ReLU)

* 가장 많이 사용되는 활성화 함수 중 하나
* 시그모이드와 탄젠트 함수가 갖는 기울기 소실 문제를 해결하기 위한 함수

$$
relu(x)=max(0,x)
$$

```python
import numpy as np
import matplotlib.pyplot as plt

def relu(x):
    return np.maximum(0, x)

x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)

plt.plot(x, y)
plt.plot([0, 0], [5.0, 0.0], ":")
plt.title("Relu")
plt.show()
```

<figure><img src="/files/UJt8y5ZytoCn86yy3yuJ" alt=""><figcaption></figcaption></figure>

* 음수를 입력하면 0을 출력
* 양수를 입력하면 입력값 그대로 반환

#### 장점

* 특정 양수값에 수렴하지 않아 깊은 신경망에서 시그모이드 함수보다 훨씬 잘 작동
* 시그모이드나 탄젠트 함수처럼 다른 연산을 필요로 하지 않고 단순 임계값이므로 속도가 빠름
* 구현 매우 간단

#### 단점

* 입력값이 음수면 기울기가 0 ⇒ 가중치 업데이트가 안 될 수 있음 ⇒ 다시 회생하는 것이 어려움 ⇒ **죽은 렐루 문제**
* 출력값은 0 또는 양수, 기울기는 0또는 1인 양수 ⇒ 최적의 가중치를 찾는 지그재그 현상 발생
* 0에서 미분 불가능

#### 사용하는 곳

* 은닉층 활성화 함수 사용

## 리키 렐루(Leaky ReLU)

* 죽은 렐루 문제 보완하기 위해 등장

$$
leakyrelu(x)=max(ax, x)
$$

* a는 일반적으로 0.01값을 가짐
* 입력값이 음수일 경우에 0이 아니라 0.001과 같은 매우 작은 수를 반환하도록 함

```python
import numpy as np
import matplotlib.pyplot as plt

a = 0.1

def leaky_relu(x):
    return np.maximum(a * x, x)

x = np.arange(-5.0, 5.0, 0.1)
y = leaky_relu(x)

plt.plot(x, y)
plt.plot([0, 0], [5.0, 0.0], ":")
plt.title("Leaky Relu")
plt.show()
```

<figure><img src="/files/2EIPPlYmzzA3Plwk7noJ" alt=""><figcaption></figcaption></figure>

#### 장점

* 음수일 경우 더 이상 기울기가 0이 아니므로, **죽은 렐루 문제 해결**
* 층이 아무리 깊어져도 손실없는 정보 전달가능, 미분값이 항상 0과 1이기 때문에 연산 빠름
* Relu보다 학습이 잘됨

#### 단점

* 음수에서 **선형성**이 생김, 복잡한 분류에서 사용 X

#### 사용하는 곳

* 음수가 아주 중요한 상황에 사용

## ELU(Exponential Linear Unit)

* ReLU의 모든 장점 포함
* α는 사용자가 설정 → 일반적으로 1

$$
elu(x) = \lbrace ^{x;;;;;;;;;;;;; (x>0)} \_{\alpha(e^x-1);;;;(x≤0)}
$$

```python
import numpy as np
import matplotlib.pyplot as plt

def elu(x, alp):
    return (x > 0) * x + (x <= 0) * (alp * (np.exp(x) - 1))

x = np.arange(-5.0, 5.0, 0.1)
y = elu(x, 0.5)

plt.plot(x, y)
plt.plot([0, 0], [-1.0, 5.0], ":")
plt.title("ELU")
plt.show()
```

<figure><img src="/files/y0PuWgANSn1rLm11g3ho" alt=""><figcaption></figcaption></figure>

* 출력값의 중심이 거의 0에 가까움

#### 장점

* 죽은 렐루 문제 해결 → 음수 값이 작지만 0이 아닌 출력을 생성하도록 함
* 음수 부분이 선형적이지 않음

#### 단점

* ReLU, leaky ReLU와 달리 exp 함수를 계산해야 해서 연산 비용이 큼

## 소프트맥스 함수(Softmax function)

* 출력층의 뉴런에서 주로 사용
* 세 가지 이상으로 분류하는 다중 클래스 분류에서 출력층에 사용되는 활성화 함수
* 분류될 클래스가 n개라 할 때, n차원의 벡터를 입력받아, 각 클래스에 속할 확률을 추정

$$
softmax(x)=\sigma\_i(x)={e^{z\_{i}}\over\sum^j\_{j=1}e^{z\_{j}}}
$$

```python
import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-5.0, 5.0, 0.1)
y = np.exp(x) / np.sum(np.exp(x))

plt.plot(x, y)
plt.plot([0, 0], [0.1, 0.0], ":")
plt.title("Softmax")
plt.show()
```

*

```
<figure><img src="/files/HYr5DLNJsWFA2IqjaJ6Y" alt=""><figcaption></figcaption></figure>
```

* 출력값이 0과 1 사이
* 출력값의 총합이 1

#### 장점

* 확률의 총합이 1이므로, 어떤 분류에 속할 확률이 가장 높은지를 쉽게 인지 가능
* 크로스 엔트로피 로스함수와 함께 사용하면 역전파 계산이 심플함

#### 단점

* 은닉층에서 소프트맥스 함수가 사용되는 경우, 기울기 소실 문제 등 기울기를 제대로 찾지 못해 학습 효율성이 감소할 수 있음
* 추론할 때 사용 X → 확률의 합이 무조건 1이 되야 하므로, a와 b에 해당하지 않는 것이 들어있을 때도 a아니면 b중 하나로 인식해버림

#### 사용하는 곳

* 다중 분류에서 사용
