🤖머신러닝/직접 구현하기

머신러닝 | 퍼셉트론(Perceptron) 이론과 실습

Mawile 2021. 10. 15.
728x90

현재 머신러닝 분야에서 인공신경망의 근원이 되는 퍼셉트론(Perceptron)에 관하여 저가 개인적으로 공부한 내용을 바탕으로 포스팅을 진행하겠습니다.

 

퍼셉트론(Perceptron)은 프랑크 로젠블라트(Frank Rosenblatt)1957년에 제안한 초기 형태의 인공 신경망으로 다수의 입력으로부터 하나의 결과를 내보내는 알고리즘입니다.

 

 

퍼셉트론(Perceptron)은 위 사진처럼 여러 개의 입력값을 집어넣으면,

가중치와 편향에 의해서 새로운 결괏값으로써 변환되어 나옵니다.

 

가중치(w)입력 신호가 결과에 주는 영향력을 나타내며,

편향(b)뉴런이 얼마나 쉽게 활성화되느냐에 대한 수치입니다.

 

이 단순한 퍼셉트론의 활성화 함수는 다음과 같습니다.

\( if \sum_i^n [x_{i} \cdot w_{}] + b > 0 \blacktriangleright y = 1 \)
\( if \sum_i^n [x_{i} \cdot w_{}] + b \leq 0 \blacktriangleright y = 0 \)

 

가중치(w)편향(b)을 실제 코드로 구현할 때는 임의의 값으로 주게 될 텐데

대부분 각각 11.5가 적절합니다.

 

단층 퍼셉트론(Single-Layer Perceptron, SLP)

퍼셉트론은 크게 단층 퍼셉트론과 다층 퍼셉트론으로 나뉩니다.

 

우선 단층 퍼셉트론은 입력층(Input Layer)출력층(Output Layer)만 존재합니다.

대표적인 논리게이트로 AND, OR, NAND 논리게이트가 존재합니다.

 

단층 퍼셉트론 같은 경우는 선형 영역으로도 나눌 수 있기 때문에 다층 퍼셉트론에 비해 크게 복잡하지는 않습니다.

 

단층 퍼셉트론의 논리게이트 중 하나인 NAND 논리게이트입니다.

시각적으로도 알 수 있지만, 선형 영역으로 구역을 나눌 수 있습니다.(검은색: 1, 흰색: 0)

 

다층 퍼셉트론(MultiLayer Perceptron, MLP)

다층 퍼셉트론입력층(Input Layer)과 출력층(Output Layer) 사이에

은닉층(Hidden Layer)이라는 층이 여러 개로 존재하며,

대표적인 논리게이트로는 XOR 논리게이트가 존재합니다.

 

XOR 논리게이트는 다른 단층 퍼셉트론으로 구현할 수 있는 AND, OR, NAND 논리게이트와는 달리 비선형 영역을 가집니다.

XOR 논리게이트는 단층 퍼셉트론의 논리게이트와는 확연히 시각적으로도 다른 달걸 알 수 있습니다.

XOR 논리게이트 같은 경우는, 다음과 같은 형식으로 단층 퍼셉트론의 논리게이트를 조합하여 구현하는 것이 가능합니다.

 

그리고 XOR 논리게이트 같은 다층 퍼셉트론의 형상을 띈,

또는 은닉층이 2개 이상인 신경망을 심층 신경망(Deep Neural Network, DNN)이라고 합니다.

 

소스코드 및 실습

저는 개인적으로 c++ 이 제일 편하고 좋아서 c++로 구현했습니다만, 다른 언어도 똑같이 사용해도 이상 없이 작동합니다.

 

#include <iostream>
#include <cmath>
#include <tuple>

#define ndArray(w1, w2, theta) std::make_tuple(w1, w2, theta)

const short nerual_signals[4][2] = { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } };

const float Weight = 1;
const float bias = 1.5;

class Perceptron{
public:
	short AND(short x1, short x2){
		auto[w1, w2, theta] = ndArray(Weight, Weight, -bias);
		float y = x1 * w1 + x2 * w2 + theta;
		
		if(y <= 0) return 0;
		return 1;
	}
	
	short NAND(short x1, short x2){
		auto[w1, w2, theta] = ndArray(-Weight, -Weight, bias);
		float y = x1 * w1 + x2 * w2 + theta;
		
		if(y <= 0) return 0;
		return 1;
	}
	
	short OR(short x1, short x2){
		auto[w1, w2, theta] = ndArray(Weight, Weight, -bias / 2);
		float y = x1 * w1 + x2 * w2 + theta;
		
		if(y <= 0) return 0;
		return 1;
	}
	
	short XOR(short x1, short x2){
		short a1 = NAND(x1, x2);
		short a2 = OR(x1, x2);
		short y = AND(a1, a2);
		
		return y;
	}
};

int main(){
	Perceptron pcp;
	
	for(std::size_t i=0;i<4;++i){
		std::cout << "NAND(" << nerual_signals[i][0] << ", " << nerual_signals[i][1] << "): " << pcp.NAND(nerual_signals[i][0], nerual_signals[i][1]) << '\n';
		std::cout << "AND(" << nerual_signals[i][0] << ", " << nerual_signals[i][1] << "): " << pcp.AND(nerual_signals[i][0], nerual_signals[i][1]) << '\n';
		std::cout << "OR(" << nerual_signals[i][0] << ", " << nerual_signals[i][1] << "): " << pcp.OR(nerual_signals[i][0], nerual_signals[i][1]) << '\n';
		std::cout << "XOR(" << nerual_signals[i][0] << ", " << nerual_signals[i][1] << "): " << pcp.XOR(nerual_signals[i][0], nerual_signals[i][1]) << "\n\n";
	}
}

 

실제 위 c++코드를 실행시켜보면 아래와 같은 입출력 결과를 얻을 수 있습니다.

 

 

 

 

 

궁금한 부분 있으시면 댓글로 질문 부탁드립니다~!!!

그럼 안녕~~~~~~~~~~~~~~~~~~~~~~~!!!!!


728x90

댓글