(코드 : https://github.com/J-Hoplin/Machine-Learning-with-Python/blob/master/3%20.%20Perceptron.ipynb)
1 . Perceptron Algorithm
퍼셉트론 이라는 1957년 프랑크 로젠블라트에 의해 제안된 알고리즘이 있다. 이 퍼셉트론 알고리즘은 딥러닝(신경망)의 기원이 되는 알고리즘이다. 즉 앞으로 딥러닝을 배우는데 베이스 개념을 배운다고 생각하시면 됩니다.
퍼셉트론은 다수의 신호를 입력받은 후 하나의 신호값만 출력한다. 신호를 생각할때, 그냥 전류처럼 어떠한 흐르는 값이라 생각하면 됩니다.
퍼셉트론 신호 또한 흐름을 만들고 정보를 그 다음 순서로 전달한다. 퍼셉트론은 신호가 흐른다(1)/흐리지 않는다(0) 두가지 값을 가질 수 있습니다.
이번 포스트에서는 일반 퍼셉트론보다는 단순 퍼셉트론에 가까운것을 다루어 보겠습니다.
다음 그림을 보자. 다음 그림은 입력이 2개인 퍼셉트론에 해당된다. 우선적으로 x1,x2는 입력 신호이고, w1,w2 는 가중치, y는 출력신호를 의미한다. 그리고 x,y의 각각의 원을 '노드'(Node)' 혹은 '뉴런' 이라고 명칭한다. 입력신호(x)가 뉴런으로 보내질 때 각각 고유한 가중치(w)가 곱해진다. 수식으로는 x1w1, x2w2 로 표현할 수 있다. 만약 뉴런에서 보낸 신호의 총 합이 정해진 한계를 넘어설 때만 신호가 흐른다에 해당하는 값 1을 출력한다. 여기서 말한 정해진 한계값을 '임계값'이라고 하고 이를 theta(세타)로 표시한다.
퍼셉트론을 수식으로 다음과 같이 나타낼 수 있다.
가중치는 신호마다 결과에 주는 영향력을 조절해 준다.
이것이 헷갈리는 사람은 생명과학의 뉴런을 생각해도 된다. 인체의 뉴런에서는 역치 이상의 자극이 와야지만 다음 뉴런으로 자극이 전달되는것과 같은 원리이다.
가중치, w는 회로에서의 저항과 비슷한 역할이다. 회로에서의 저항은 저항값이 클수록 전달되는 전류값이 낮아지지만, 퍼셉트론에서의 가중치는 가중치 값이 클수록 더 강한 신호가 전달된다. 또한 가중치가 크면 클수록 그만큼 더 중요한 입력신호임을 말한다. 반대로 가중치가 작다면 그만큼 중요도가 낮은 입력신호임을 의미한다.저항과 비슷한 점은 신호가 얼마나 잘 흐르는지를 통제한다는 점에서 저항과 가중치가 같은 기능을 한다.
2 . 논리 게이트
퍼셉트론을 이용한 간단한 문제로 논리게이트를 살펴보자. 우선적으로 AND게이트 를 살펴보자. AND 게이트는 입력이 두 가지(x1,x2)이고 출력은 하나(y)이다.
위의 사진에서 왼쪽 상단과 같이 입력신호와 출력신호에 대한 대응표를 진리표라고 한다. AND게이트의 경우 두 가지 입력 신호가 모두 1(흐름)일 경우에만 결과값은 1(임계값을 넘음)이되고 만약 입력 신호 중 하나라도 0(흐르지 않음)이 있으면 결과값은 0(임계값을 넘지 못함)이 나온다.
만약 이 AND게이트를 퍼셉트론으로 나타내고 싶다면 매개변수의 각 입력값(매개변수 : (w1가중치,w2가중치,임계값)) 에 대한 가중치 w1,w2를 정해주고 임의의 임계값 Θ를 정해주어야 한다. 물론 예시에서는 가중치와 임계값 조합을 (0.5,0.5,0.7)로 놓았지만 이 외에도 무수히 많다.
해당 연산을 한번 풀이해보자면
1) 입력값 (x1,x2)의 조합은 (0,0)이라고 하고 매개변수를 (0.5,0.5,0.7)이라고 해보자. 위에서 작성해 보았던 퍼셉트론 수식을 이용해 가중치와의 대응 관계를 보면
x1w1 + x2w2 = 0 + 0 = 0, 즉 0 < 0.7이므로 임계값을 못넘는것을 볼 수 있다. 결론적으로 출력값은 0이된다.
2) 반대로 입력값은 (1,1) 매개변수를(0.5,0.5,0.7)이라고 놓는다.
x1w1 + x2w2 = 0.5 + 0.5 = 1, 즉 1 > 0.7이므로 임계값을 넘는것을 볼 수 있다. 결론적으로 출력값은 1이된다.
그 다음에는 NAND게이트를 살펴보자. NAND는 Not AND의 줄임말로 AND게이트의 출력을 뒤집은거라고 생각하면 된다. 사진으로 NAND의 진리표를 알면 이 말의 뜻을 알 수 있다.
해당 진리표를 보면 알 수 있듯이, AND게이트에서는 입력신호가 x1,x2가 각각 1, 1일때만 출력신호가 1인 반면 NAND 게이트에서는 입력값이 모두 1인 경우에만 결과값이 0이 된다. NAND게이트는 AND게이트의 출력값을 뒤집은 거라고 하였다. NAND게이트에서의 매개변수(가중치, 임계값)는 AND게이트를 구현하는 매개변수들의 부호들을 반전시켜주면 NAND게이트의 가중치 임계값 조합이 된다.
매개변수(가중치, 임계값)와 입력 신호에 대한 연산은 AND게이트의 예시에서 연산하였듯이 퍼셉트론 수식을 이용해 각자 해보자.
그 다음에는 OR게이트이다. OR게이트는 두개의 값중 하나라도 1이 있으면 출력신호는 1이된다. OR게이트에 대한 매개변수를 생각해보면 (1.5,1.5,1),(1.5,1.5,1.2) 등 있다.
우리가 이 세가지 게이트를 보면서 알아야 할것은 퍼셉트론의 구조는 AND, NAND, OR게이트에서 모두 동일하다는 것이다. 물론 다른것은 각 게이트마다의 매개변수일 뿐이다. 즉 똑같은 구조의 퍼셉트론이 매개변수값만 적절히 조정해 AND,NAND,OR게이트로 각각 변한다는 것이다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
현재 논리게이트에 대한 이해를 할 때 매개변수값을 부여한 것은 우리, 즉 인간이다. 여기서 우리는 AND,NAND,OR게이트의 진리표라는 '학습데이터'를 보고 각 입력신호의 가중치와 임계값이 담긴 매개변수를 생각하였다.
앞으로 우리는 Machine Learning을 통해 적당한 매개변수의 값을 정하는걸 컴퓨터가 자동으로 정하도록 해볼 것이다.
우리가 흔히 말하는 '학습' 이란 컴퓨터가 적당한 매개변수 값을 구하는 것이고, 인간이 이 과정에서 해야할 일은 퍼셉트론의 구조(흔히 말하는 모델)를 설계하고 컴퓨터에 학습할 데이터를 넣어주는 역할을 한다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
이제 위에서 보았던 AND,NAND,OR게이트에 대한 각각의 구현을 시도해 보자
우선 간단히 AND게이트를 구현해보자.
함수의 매개변수로는 입력 신호(x1,x2)를 주고, 매개변수를 둔 다음 퍼셉트론과 동일히 x1w1 + x2w2값이 임계값보다 작거나 같으면 0을, 크면 1을 반환하는 코드를 입력해 준다. 이 함수에서의 출력값은 출력신호(y)를 의미한다.
그럼 다음과 같이 AND게이트의 진리표에서 봤듯이 두가지의 입력신호가 모두 1이 아닌경우는 출력신호가 0을, 둘다 1일 경우에만 1을 출력하는것을 볼 수 있다.
그 외 NAND, OR게이트에 대해서도 코드를 다음과 같이 짜보았다. AND게이트와 마찬가지로 매개변수를 함수에 선언하고 인자를 받는 방식이다.
NAND게이트
OR게이트
3 . 가중치와 편향
지금까지 우리는 임계값을 정하고 x1w1 + x2w2가 임계값보다 작거나 같을때는 0을, 임계값보다 클때는 1을 반환하는 퍼셉트론 식을 사용해 왔다. 하지만 앞으로의 연산들을 위해 theta에 해당하는 임계값을 -b로 치환하고 나서 식을 재정리 해보자.
우리는 단지 임계값을 -b로 치환하고 식을 재정리 해준것 뿐이지만 결론적으로 두 식의 의미는 동일하다는 것을 알 수 있을것이다. 앞으로 우리는 임계값에 해당하였다 b를 편향(bias)라고 부를것이다. 결론적으로 출력 신호에 대한 연산 식은 W * X + b 라는 식이 완성되는것을 볼 수 있다. W * X + b식은 이번 머신러닝 뿐만 아닌 추후 텐서플로우 등 딥러닝 라이브러리를 다룰때도 사용할 것이니 잘 알아두자. 중요한 식이다.
식을 한번 해석해보면 퍼셉트론은 입력신호에 가중치를 곱한 값에 편향값을 더한 후 만약 그 값이 0을 넘으면 1을, 0을 넘지 못하면 0을 출력신호로 내보낸다로 해석할 수 있다. 그렇다면 이 수식을 가지고 코드를 작성하여 보자.(이 코드는 인터프리터로 해도좋다)
다음 코드를 보자. 우선적으로 우선적으로 x라는 입력 신호를, w라는 가중치를 넘파이 배열 형식으로 정의해준다. 그 후 편향(b)값을 정의해야 하는데 여기서 우리가 주의할 점은 우리가 앞에서 임계값 theta를 치환할 때 -b로 치환을 해주었다. 해당 게이트에서의 매개변수를 쓰면 w1,w2,임계값 순서로 (0.5,0.5,0.8)이 된다. 여기서 편향은 임계값의 부호 반전된 값이므로 편항값을 선언할 때도 부호 반전을 해주어야 한다.
그 다음 W * X + b 식에서 우선순위인 W * X부터 연산하면, 넘파이 배열 두개를 곱해주어야 한다. 형상이 동일한 두개의 넘파이 배열을 곱해주면 #1에서도 했듯이 각 인덱스 번호와 일치하는 값들끼리 연산이 되어 값을 배열 형태로 반환한다. 그 후 np.sum()메소드를 이용하여 입력한 배열(W*X)에 담긴 모든 원소들의 합을 구하고 편향값 b를 더하면 연산이 완료된다.
여기서는 연산값이 -0.3, 즉 0보다 작은 값이 나오기 때문에 출력 신호값은 0이된다.
|Tip| np.sum() 메소드는 괄호 안에있는 배열의 모든 값들을 더한다음 반환한다.
그렇다면 이러한 원리를 기반으로 AND게이트를 작성해 보자. 원리는 방금 하였던 원리를 이용하면 된다.
우리가 한번 더 짚고 넘어갈것이 있다. 바로 편향(b)와 가중치(w)는 서로 기능이 다르다는것을 우리는 한번 더 인지하고 가야한다. 편향이라는 것은 뉴런이 얼마나 쉽게 활성화를 하는지 결정해 주는 매개변수이다. 여기서 활성화란 출력 신호를 1로 나오게끔 하는 과정을 말한다. 가중치에 해당하는 w는 각 입력 신호가 결과에 주는 영향력을 조절하는 매개변수이다.
이어서 NAND게이트와 OR게이트도 작성해 보자
여기서도 동일하게 모두 동일한 구조의 퍼셉트론이고 각 게이트마다 다른점은 단지 매개변수에 대한 부분밖에 없었다.
4 . 퍼셉트론의 한계
지금까지 AND,NAND,OR게이트에 대해 살펴보았다. 이 세가지 논리 게이트 외 다른 한가지 유형이 있는데 그 이름은 바로 XOR게이트이다.
XOR게이트는 흔히 배타적 논리합이라는 논리회로이다. 배타적이라는 사전적 의미는 자기자신을 거부한다는 의미이다. 이를 진리표로 해석하면 입력신호 x1,x2중 한쪽이 1일때만 출력신호 값으로 1을 출력하고 입력신호가 둘다 0 혹은 1일경우 출력신호가 0이된다.
위의 표가 바로 XOR 게이트에대한 진리표이다. 한가지 알아두어야 할것은 지금까지 AND,NAND,OR에서 사용하였던 퍼셉트론으로는 XOR게이트를 구현할 수 없다. 그 이유를 지금부터 시각적으로 볼 것이다.
지금까지 우리가 보았던 AND,NAND,OR게이트는 모두 퍼셉트론으로 구현을 하였다. 우리가 지금까지 AND,NAND,OR게이트에 대해 퍼셉트론에서의 수식을
다음과 같이 만족하였었다. 이러한 형태의 퍼셉트론은 직선으로 나뉜 두 영역을 만든다. 직선 영역으로 나뉜 기준으로 한쪽은 0을 또 다른 한쪽은 1을 출력한다. 퍼셉트론을 시각화 하면
다음과 같이 시각화 할 수 있다. 출력신호에 대해 1의 값은 사각형으로 0의 값은 삼각형으로 나타내었다. AND게이트이기 때문에 (1,1)일때만 1이 나오고 그 이외의 경우는 0이 나온다는 사실 여기를 보고있을때 쯤이면 바로바로 생각나야한다. 해당 그래프에서는 출력신호값이 0일때, 1일때 총 두가지 영역을 직선을 통해 나누어 주었다. 이와 같이 직선의 영역을 선형 영역이라고 정의한다.
그렇다면 XOR같은 경우는 시각적으로 어떻게 표현을 해야할까? 우선 위와 같이 사각형 삼각형을 통해 XOR 시각화를 시켜보자.
XOR을 시각화 시키면 다음과 같이 나타낼 수 있다. 하지만 해당 시각화를 보면 직선 하나로 0과 1 두 영역으로 나누는것 자체가 불가능해 보인다. 물론 XOR게이트의 1과 0을 아예 못나누는것은 아니다. 여기서 조건이 하나가 붙는데 바로 직선이 아닌 곡선으로 나눌때를 의미한다.
다음과 같이 곡선으로 표현하면 0과 1로 충분히 두가지 영역으로 나눌 수 있다. 이와같이 곡선의 영역을 비선형 영역이라고 정의한다. 여기서 본 선형, 비선형 영역에 대한 개념은 앞으로 많이 다룰 것이므로 잘 기억해 두자.
현재까지 우리가 AND,NAND,OR게이트에서 다뤄온 형식의 퍼셉트론은 단층 페셉트론에 해당한다. 단층 퍼셉트론은 직선 하나로 나눈 영역만 표현이 가능하다는 또 단층 퍼셉트론은 비선형 영역을 분리할 수 없다는 한계가 있다. 그렇다면 XOR게이트는 대체 어떻게 표현 해야하는 것일까? XOR 게이트는 단층 퍼셉트론을 이용해 층을 쌓은 다층 퍼셉트론으로 표현할 수 있다.
XOR게이트를 만드는데 다양한 방법이 있지만 이번 포스트에서는 앞에서 다룬 AND,NAND,OR게이트를 조합하는 형식으로 다루어 볼 것이다.
조합의 시각화를 위해 AND,NAND,OR게이트를 다음과 같이 기호로 두었다고 가정하자.
다음과 같이 세가지 게이트를 조합하면 XOR 연산자를 구현할 수 있다. 우선 설계도를 분석해 보자. x1, x2각각의 신호는 하나는 OR게이트로 하나는 NAND게이트로 들어가게 된다.
결론적으로 위에서 봤듯이 입력신호 x1,x2가 OR게이트로 들어갔을때 출력신호는 (0,0) -> 0 (1,0) -> 1, (0,1) -> 0, (1,1) ->1 이 된다. 또 입력신호 x1,x2가 NAND게이트로 들어갔을때 출력신호는 (0,0) -> 1 (1,0) -> 1, (0,1) -> 1, (1,1) -> 0 이 된다.
출력신호 OR게이트에대한 출력신호를 s1으로 놓고, NAND게이트에 대한 출력신호를 s2로 놓자. 이 출력신호 s1, s2는 최종적으로 AND게이트의 입력신호로서의 역할을 하게되고 s1, s2를 이용해 AND게이트의 논리로 진리표를 작성하면 위에서 보았던 XOR게이트와 동일한 값을 보이는것을 볼 수 있다.
위에서 AND,NAND,OR게이트를 구현해 봤듯이 XOR게이트도 코드로 구현해 보자.
(필자의 경우는 주피터 노트북 상에서 진행하였다. 동일 커널에 위의 예시로 작성했던 AND,NAND,OR게이트 함수가 선언된 상태로 있기 때문에 위의 함수를 불러서 사용했다. 만약 주피터 노트북 상에서 함수가 있는데 실행이 안될경우 해당 커널을 재실행하고 코드를 짜보자.)
다음과 같이 코드를 작성해 주었다. 우선적으로 XOR이라는 함수는 입력신호에 해당하는 x1,x2라는 인자값을 받게 되고 해당 인자값들에 대해 NAND의 출력값은 s1로, OR의 출력값은 s2 변수에 저장해 주었다. 그 다음 AND함수에 OR,NAND의 출력 신호 값들이 저장된 s1,s2를 인자로 넣어준 후 해당 결과값을 반환하는 구조로 코드를 작성해 주었다.
밑에 결과값을 보면 XOR게이트 진리표에서 보았듯이 (0,0)과 (1,1)은 0값을 , (1,0)과 (0,1)은 1값을 반환하는것을 볼 수 있다.
XOR게이트는 다음과 같이 다층 퍼셉트론 네트워크 구조로 되어있다. 이번 포스트에서 구현한 다층 퍼셉트론은 0층 -> 1층, 1층 -> 2층 총 2층 퍼셉트론 혹은 3층 퍼셉트론(명칭은 자신이 편한대로 부르자)을 구현해 보았다. 결론적으로 퍼셉트론은 층을 깊게 쌓으면 쌓을수록 단지 2층 퍼셉트론 상에서 sigmoid 함수를 활성화 함수로 이용한 다음 컴퓨터를 구현할 수 있는 등 더 다양한 것들을 표현할 수 있다는 것이다. 앞으로는 퍼셉트론 개념이 매우 중요하니 이번 포스팅 내용은 깊게 잘 새겨두자.
'Machine Learning &DeepLearning > Machine Learning Base Theory' 카테고리의 다른 글
Machine Learning with Python #3 - 1 (0) | 2019.01.22 |
---|---|
Machine Learning with Python #1 (0) | 2019.01.13 |