계단 함수, 시그모이드 함수, ReLU 함수(ft.파이썬)

2018. 10. 15. 17:49ML, OpenCV

계단 함수는 계단 모양!

계단함수에 대한 이미지 검색결과

 

시그모이드(Sigmoid)는 S모양!

Sigmoid function에 대한 이미지 검색결과

 

ReLU는 아래와 같이 0보다 큰 값만 나타낸 모양

ReLU function에 대한 이미지 검색결과

 

이제 계단 함수부터 파이썬으로..

 

1
2
3
4
5
6
7
8
9
10
11
>>> def step_function(x):
    if x > 0:
        return 1
    else:
        return 0
 
    
>>> step_function(3)
1
>>> step_function(-0.5)
0
cs

 

요런 식으로 함수를 만들어주고

x가 0보다 큰 값이 들어오면 1을 반환해주고

그렇지 않으면 0을 반환해주도록 합니다.

0보다 큰 3을 넣었더니 1이 나오고

-0.5를 넣었더니 0이 나오는 것을 확인할 수 있었습니다.,

하지만 입력값을 계속 하나씩 줄 수는 없으니 배열을 사용해봅시다.

 

1
2
3
4
5
6
7
8
9
>>> import numpy as np
>>> x = np.array([-0.1,1.0,2.0])
>>> step_function(x)
Traceback (most recent call last):
  File "<pyshell#12>", line 1in <module>
    step_function(x)
  File "<pyshell#5>", line 2in step_function
    if x > 0:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
cs

그러면 오류가 발생합니다.

 

x에 -0.1,1.0,2.0 이라는 배열을 넣어줬는데 오류가 발생했네요.

오류를 해결하기 위해서 bool 형을 활용해 보겠습니다.

bool은 true 혹은 false로 반환됩니다.

 

1
2
3
4
5
6
7
>>> import numpy as np
>>> x = np.array([-0.1,1.0,2.0])
>>> x
array([-0.1,  1. ,  2. ])
>>> y = x > 0
>>> y
array([False,  True,  True])
cs

하지만 계단 함수엔는 bool형이 아닌 int형을 사용해서 0과 1로 나타내야 합니다.

그래서 배열 y의 원소를 bool에서 int로 바꿔줍니다.

 

1
2
3
>>> y = y.astype(np.int)
>>> y
array([011])
cs

 

이 방법을 사용해서 계단 함수를 만들어주면

다음과 같습니다.

1
2
3
4
5
6
7
>>> def step_function(x):
    return np.array(x>0,dtype=np.int)
 
>>> x = np.array([-0.1,1.0,2.0])
>>> y = step_function(x)
>>> y
array([011])
cs

단 두줄로 함수를 정의할 수 있네요.

 

이제 시그모이드 함수를 구현해봅시다.

1
2
3
4
5
6
>>> def sigmoid(x):
    return 1/(1+np.exp(-x))
 
>>> x = np.array([-1.0,1.0,2.0])
>>> sigmoid(x)
array([0.268941420.731058580.88079708])

cs

 

시그모이드는 이미 numpy에 있는 exp를 활용하면 간단하게 구현할 수 있습니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
= np.arange(-5.0,5.0,0.1)
sigmoid(x)
       
array([0.006692850.007391540.008162570.0090133 , 0.0099518 ,
       0.010986940.012128430.013386920.014774030.0163025 ,
       0.017986210.019840310.021881270.024127020.02659699,
       0.029312230.032295460.035571190.039165720.04310725,
       0.047425870.052153560.057324180.062973360.06913842,
       0.075858180.0831727 , 0.091122960.099750490.10909682,
       0.119202920.130108470.141851060.154465270.16798161,
       0.182425520.197816110.214165020.231475220.24973989,
       0.268941420.2890505 , 0.310025520.331812230.35434369,
       0.377540670.401312340.425557480.450166  , 0.47502081,
       0.5       , 0.524979190.549834  , 0.574442520.59868766,
       0.622459330.645656310.668187770.689974480.7109495 ,
       0.731058580.750260110.768524780.785834980.80218389,
       0.817574480.832018390.845534730.858148940.86989153,
       0.880797080.890903180.900249510.908877040.9168273 ,
       0.924141820.930861580.937026640.942675820.94784644,
       0.952574130.956892750.960834280.964428810.96770454,
       0.970687770.973403010.975872980.978118730.98015969,
       0.982013790.9836975 , 0.985225970.986613080.98787157,
       0.989013060.9900482 , 0.9909867 , 0.991837430.99260846])
 
cs

np.arange를 사용해서 -5.0부터 5.0까지 0.1 간격으로 나타낸 값들을 시그모이드 함수에 넣었더니

위와 같은 값을 얻을 수 있었습니다.

0에 가까운 값에서 1에 가까운 값으로 커지는 것을 알 수 있습니다. (시그모이드는 0과 1 사이의 값을 가진다)

 

마지막으로 ReLU

더 간단합니다.

파이썬에서 제공하는 np.maximum을 사용하면 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> def relu(x):
       return np.maximum(0,x)
 
       
>>> x = np.arange(-5.0,5.0,0.1)
       
>>> relu(x)
       
array([0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,
       0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,
       0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. ,
       0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0. , 0.1,
       0.20.30.40.50.60.70.80.91. , 1.11.21.31.4,
       1.51.61.71.81.92. , 2.12.22.32.42.52.62.7,
       2.82.93. , 3.13.23.33.43.53.63.73.83.94. ,
       4.14.24.34.44.54.64.74.84.9])
cs

시그모이드 때와 같이

np.arrange를 사용해서 -5.0부터 5.0까지 0.1 간격으로 나타낸 값들을 시그모이드 함수에 넣었더니

0.1부터 값이 늘어나고 0보다 작은 값들은 모두 0으로 나타내 줍니다.