앞서 공부했던 퍼셉트론에서 만들었던 식을 0과 1을 구간에 따라 리턴해주는 Heaviside함수를 통해 약간 수정해보았다.
이제 퍼셉트론에서 인공신경망으로 넘어가야 하는데 퍼셉트론에겐 치명적인 단점이 있다. 바로 단층 퍼셉트론의 문제점인 XOR게이트를 구현할 수 없다는 사실이다. 따라서 여러 층의 퍼셉트론을 쌓아야했었다.
또한 앞에서 Heaviside함수를 사용했는데 이 함수 대신 Sigmoid함수를 이용할 것이다. 이유는 현재 배우고 있는 것이 머신러닝에 속한 딥러닝이라는 것인데 머신러닝의 학습법은 미분을 통해 학습한다. 그런데 Heaviside함수는 0에서는 미분이 불가하고 다른 점에서는 미분계수가 모두 0이다. 정보가 없다는 뜻이다.
따라서 미분을 통해 learning을 하는 머신러닝에 전혀 도움이 되지 않는다. 따라서 모양이 제일 비슷한 함수를 찾았는데 그 함수가 바로 Sigmoid함수이다.
Activation function
- Sigmoid 함수 미분
코드 구현 - Heaviside function
# 가장 정직한 방식의 Heaviside function
# 문제점 : 실수뿐만 아니라 벡터에서도 적용해야 하기 때문
def step_function(x):
if x > 0:
return 1
else:
return 0
import numpy as np
x = np.array([-1, 1, 2])
step_function(x)
<ipython> in step_function(x)
2 # 문제점 : 실수뿐만 아니라 벡터에서도 적용해야 하기 때문
3 def step_function(x):
----> 4 if x > 0:
5 return 1
6 else:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Heaviside 함수를 구현해보았다. 하지만 오류가 발생했는데 이유는 바로 함수의 조건문에 들어가는 변수의 형태가 array형태가 아니여서 오류가 난 것이다. 위의 문제점에서 적었듯이 벡터에서도 적용해야 하기 때문에 조건문을 array형태를 받아들일 수 있게 바꿔줘야 한다.
def step_function(x):
return np.array(x > 0)
import numpy as np
x = np.array([-1, 1, 2])
step_function(x)
array([False, True, True])
이번엔 결과가 나왔지만 우리가 원하는 0, 1(int) 형태가 아닌 bool형태로 결과가 나왔다. 따라서 이 부분도 수정해주어야 하는데 함수에서 return을 할 때 true, false의 결과값을 int형태로 return해줄 수 있게 조건을 수정해주면 해결된다.
def step_function(x):
return np.array(x > 0, dtype=int)
import numpy as np
x = np.array([-1, 1, 2])
step_function(x)
array([0, 1, 1])
원하는대로 결과가 잘 나왔다. 그래프까지 그려보면
import numpy as np
import matplotlib.pylab as plt
def step_function(x):
return np.array(x > 0, dtype=int)
X = np.arange(-5.0, 5.0, 0.1)
Y = step_function(X)
plt.plot(X, Y)
plt.ylim(-0.1, 1.1)
plt.show()
원래 0 사이는 연결이 되어있지 않지만 matplotlib의 그림 그리는 방식으로 인해 선이 연결이 되어있다.
코드 구현 - Sigmoid function
이번엔 Sigmoid함수를 코드로 구현해보겠다.
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
sigmoid(x)
array([0.26894142, 0.73105858, 0.88079708])
너무 쉽게 구현이 되었다. 그래프를 그려보겠다.
import numpy as np
import matplotlib.pylab 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.ylim(-0.1, 1.1)
plt.show()
직접 그려봤던 모양과 비슷하게 그려졌다. 좀 더 세밀하게 그리고 싶다면 X값을 조정하면 된다.
코드 구현 - 두 함수의 비교 그래프
import numpy as np
import matplotlib.pylab as plt
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def step_function(x):
return np.array(x > 0, dtype=int)
X = np.arange(-5.0, 5.0, 0.1)
Y1 = step_function(X)
X = np.arange(-5.0, 5.0, 0.1)
Y2 = sigmoid(X)
plt.plot(X, Y1, 'r')
plt.plot(X, Y2, 'b')
plt.ylim(-0.1, 1.1)
plt.legend(['step', 'sigmoid'])
plt.show()
* 주의할 점 : matplotlib의 함수를 그리는 방식에서 X값을 지정할 때 가령 np.arange(-5, 5, 2) 이렇게 지정했다면 -5 이상 5 미만의 값들을 2씩 뛰는 것이라 [-5, -3, -1, 1, 3]까지만 그린다.
정리
활성화 함수는 뉴런이 다음 뉴런을 어떠한 방식으로 활성화 하는지 방식을 정해준다. 생물학적인 뉴런은 Heaviside함수의 방식으로 그 다음 뉴런을 활성화한다.
우리는 이 생물학적인 뉴런을 본뜬 인공적인 신경망(Artificicial neural network)을 만들어야 하는데 learning이 가능하게끔 하기 위해 Heaviside함수와 비슷하지만 미분이 가능한 함수인 Sigmoid함수를 찾아 활용한다.
하지만 Sigmoid함수도 깊은 신경망에서는 Vanishing gradient라는 문제가 생기기 때문에 얕은 신경망에서 Sigmoid함수를 사용하고 깊은 신경망에서는 Relu함수를 이용할 것이다.
Relu함수 맛보기
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.0, 5.5)
plt.show()
Relu함수는 numpy에서 maximum함수를 불러와 0과 x값중에 큰 수를 return하게끔 한다. 따라서 x가 음수일땐 0을, 양수일땐 x값을 return한다.
★ ★ ★ ★ ★
이 블로그는 수익창출을 목적으로 하지 않고, 제가 공부를 하기 위해 운영하고 있습니다.
따라서, 블로그 내의 모든 콘텐츠는 제 주관적인 의견과 경험을 바탕으로 작성되었으며, 모든 정보의 정확성을 보장할 수 없습니다.
만약 블로그 내의 정보에 대해 의문이 있으시거나, 정확하지 않은 정보를 발견하신다면, 언제든지 저에게 알려주시기 바랍니다.
이 블로그가 여러분의 공부에 도움이 되기를 바랍니다.
감사합니다.
★ ★ ★ ★ ★
참고한 강의 : 수원대학교 데이터과학부 한경훈 교수님의 딥러닝 1 강의
https://www.youtube.com/playlist?list=PLBiQZMT3oSxW1RS1hn2jWBgswh0nlcgQZ
'2024 Study Plan > 머신러닝&딥러닝' 카테고리의 다른 글
3 (1) | 2025.01.21 |
---|---|
2 (0) | 2025.01.21 |
1 (1) | 2025.01.17 |
[딥러닝1] 3강. 인공신경망 (7) | 2024.07.25 |
[딥러닝1] 1강. 퍼셉트론 (1) | 2024.07.18 |