###################ReLU 함수


#########KEYWORD##########

#saturated : 함수의 출력값에 한계가 있는 것. 시그모이드 함수나 계단 함수는 출력값이 무조건 0에서 1이기 때문에 saturate 하다고 하고
#            ReLU 함수는 x값이 커질 때 출력값도 커지기 때문에 그렇지 않다고 한다.

#ReLU
#PReLU
#ELU


##########################




#ReLU 함수에서 Re는 Rectified로 정류된 이라는 뜻.
#이는 전기회로쪽 용어로 특정 값 이하에선 회로가 반응하지 않다가 해당 값 이상에선 값이 커질수록 크게 반응하는 것을 의미.
#ReLU 함수 그래프를 보면 ReLU함수가 왜 ReLU 함수로 불리는지 알 수 있다. ReLU 함수의 그래프를 그리기 전 ReLU 함수의 함수식을 살펴보자.

#          |-------- x (x > 0)
#          |
#  h(x) =  -
#          |
#          |-------- 0 (x <= 0)

#ReLU함수는 0보다 작은 입력 값에 대해선 0으로 반응하지 않다가
#0이 넘는 값이 입력되면 출력값이 점점 커지는 형태.

#그래프
import numpy as np
import matplotlib.pylab 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.ylim(-1,5)
plt.show()

#ReLU는 최근 몇 년 간 가장 인기 있는 activation 함수이다. 이 함수는 f(x)=max(0,x)의 꼴로 표현할 수 있는데, 이는 x > 0 이면 기울기가 1인 직선이고
#x<0 이면 출력값은 항상 0이다. 시그모이드나 tanh 함수와 비교했을 때 시그모이드의 수렴속도가 매우 빠른 것으로 나타났는데. 이는 함수가
#saturated하지 않고 선형적이기 때문에 나타난다. 시그모이드와 tanh는 exp()에 의해 미분을 계산하는데 비용이 들지만,
#ReLU는 별다른 비용이 들지 않는다.(미분도 0 혹은 1)
#ReLU의 큰 단점은 네트워크를 학습할 때 뉴런들이 죽는 경우가 발생한다. x < 0일때 기울기가 0이기 때문에 만약 입력값이 0보다 작다면 뉴런이 죽어버릴수 있으며
#더 이상 값이 업데이트 되지 않게 된다.


#이 ReLU 함수 또한 0 이하의 입력값에서 아예 반응하지 않는 점이 문제가 될 때가 있다.
#이를 보완한 Parametric ReLU 함수라는 것을 사용하기도 한다.
#PReLU 함수의 함수식과 그래프는 아래와 같다.

#        |---- x ( x > 0 )
#        |
# h(x)= --
#        |
#        |---- ay (x <= 0,0 < a )

#PRelu의 장점
#ReLU 함수의 장점을 그대로 가지고 있다.
#ReLU 함수의 입력값이 0보다 작을 때의 약점(4번)을 보완했다.

#단점
#exp() 함수를 계산해야하므로 시그모이드 함수의 3번 약점과 비슷한 문제가 있다.

#dying ReLU. 즉, ReLU x < 0 인 경우 항상 함수 값이 0이지만 PReLU는 작은 기울기를 부여하여 죽지 않게한다.
#이것은 f(x)=max(ax,x)로 표현하며 이 때 a는 매우 작은 값이다.
#몇몇 경우에 이 함수를 이용하여 성능 향상을 이루었다는 보고가 있지만 모든 경우에 해당하지 않으므로 직접 경험해보고 판단해야한다.


# ELU함수.
# 1) PReLU 함수와 장점 단점이 같다.

#        |------ x if x>0
#        |
# f(x) = -
#        |
#        |------ 알파(e^x-1) if x <= 0

#ReLU 함수들과의 비교 그림과 공식을 보면 알겠지만 ELU는 ReLU의 임계값을 -1로 낮춘 함수를 exp()로 이용하여 근사한 것.
#ELU의 특징은 ReLU의 장점을 모두 포함하고 역시 dying ReLU 문제를 해결하였으며 출력값이 거의 zero-centered에 가깝다. 하지만
#ReLU, PReLU와 달리 exp()를 계산해야하는 비용이 든다.

#정리하자면 공부하는 과정에선 시그모이드와 ReLU함수를 사용해서 공부하고 실제 신경망을 설계할 땐
#ReLU와 PReLU 함수를 활성 함수로 사용하는 것이 좋을 것.


