보통 뉴럴네트워크라고 하면 굉장히 어려운 것 이라고 생각하는 경우가 많은 것 같음
통상 ANN이라고 불리는 인공신경망은 현재에 와서는 그 종류가 상당히 많고 복잡한 알고리즘이 많아서 처음 하는 사람들이 접근하기 어려움
하지만 초창기의 단층퍼셉트론과 역전파방식으로 학습하는 다층퍼셉트론은 고등학교 수준의 수학만 할 줄 알아도 별 어려움 없이 구현이 가능함
('구현만' 가능함 -_-;; 수식이 다 유도되어 있어서... )
신경망에 대한 자세한 내용은 DMW횽의 게시물을 보삼 (솔찍히 이거보다 잘 쓸 자신이 없음;; )
지금부터 만들건 하나의 뉴런을 만들고, 그 뉴런에다가 큼퓨터의 기본적인 연산은 AND와 OR을 각각 학습시켜 볼 거임.
인공신경망을 구성하는 '뉴런'은 조금 극단적으로 보면 이런식으로 구성되어 있뜸
출력 = 활성화함수( [입력 벡터] * [가중치 벡터]T - 임계치 )
여기서 T는 Transpose인데 행렬의 행과 열을 바꿔치기 하는 연산이고 벡터는 한줄짜리 행렬을 의미함 -0-
활성화 함수로는 보통 step함수나 signoide 함수를 사용하는데, signoide함수는 미분이 용이해서 역전파 알고리즘에서 많이 쓰임.
여기에서는 step함수를 사용하고 step함수는 다음과 같이 정의함
step(x) = 1 , x < 0
0 , otherwise
들어가는 x값이 0보다 크면 1이 되는 단위계산 함수임.
결국 뉴런의 정체라는 건 입력벡터와 가중치 벡터의 내적이 미리 정해놓은 임계값을 넘으면 활성화(1출력) 아니면 비활성화(0출력) 하는 블럭인 것임
여기에서는 임계치는 임의로 정하면 됨 (ex 0.5)
우리가 만들것은 2개의 입력을 받고 그것의 AND연산을 하여 출력할 수 있는 뉴런 이므로, 뉴런은 결국 다음과 같은 구성이 됨
Y = step( [x1, x2] * [w1, w2]T - 0.5 )
= step( x1w1 + x2w2 - 0.5 )
와.. 짱 단순함 이건 그냥 행렬의 곱셈인 거임. 따라서 우리가 이 뉴런에다가 적절한 w1과 w2값을 넣어주기만 하면, 이 뉴런은 AND함수로도 OR함수로도 동작할 수 있음 (Xor은 안댐;;; 단층 신경망은 선형분리가 불가능한 님은 분류가 불가능함..)
다만 이 한가지 문제가 있음.... 바로 w1과 w2값을 모른다는거 ;;;
이 뉴런이 내가 원하는 함수로 동작하도록 하는 w1고 w2값을 찾기 위해서는, 임의의 입력을 넣고 그 출력을 우리가 원하는 출력과 비교해서 w1,w2값을 우리가 필요한 값으로 근사해 나가는 작업이 필요함.
우리는 이것을 학습이라고 함.
학습은 아래의 명료한 공식에 의해 이루어짐 참 여기서 학습률은 한번의 학습에서 가중치가 변화하는 비율인데 적당한 값을 써 주어야 함
너무 크면 학습오차가 커지고, 너무 작으면, 학습이 오래걸리게 됨
w1 = w1 + 학습률 * x1 * 출력오차
w2 = w2 + 학습률 * x2 * 출력오차
출력오차 = 목표출력 - 현재출력값
대충 이런 방식으로, w1과 w2값을 구하고 그 값이 AND연산이 될 때 까지 계속 반복해서 학습을 하면, AND연산을 하는 뉴런이 완성댐..
C로 짜 놓은 소스 첨부함
---------------------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double step(double x); //스텝함수
int main(int argc, char *argv[])
{
double input[4][2] = {0,0,0,1,1,0,1,1};
double w[2] = {0.1, 0.9}; //가중치
double thold = 0.5; // 임계치
double x[2]; //입력값
double y = 0; // 결과값
const int xnum = 2;//입력값의 개수
int cnt =0;
double error = 0; // 에러수치
double alpa = 0.1; //학습률
int superloop = 0;
printf("로젠블렛 퍼셉트론 OR연산 학습 n");
for(superloop = 0; superloop < 4*6; superloop++)
{
for(cnt =0; cnt < xnum; cnt++)x[cnt]=input[superloop%4][cnt];
double sum =0; //선형결합
for(cnt =0; cnt < xnum; cnt++) sum += x[cnt]*w[cnt];
y = step(sum - thold); //하드리미터
//에러값 추출
error = (x[0] || x[1]) - y;
//가중치 보정
for(cnt =0; cnt < xnum; cnt++) w[cnt] = w[cnt] + alpa * x[cnt] * error;
if(superloop%4 == 0) printf("n%d 회차n",superloop/4);
printf("%f %f 결과값 : %lfn",x[0],x[1],y);
if(superloop%4 == 3) printf("가중치 : w[0] : %lf , w[1] : %lfn",w[0],w[1]);
}
[...];
return 0;
}
double step(double x)
{
if( x < 0 ) return 0;
else return 1;
}
---------------------------------------------------------------------------------------------------------------
댓글 영역
획득법
① NFT 발행
작성한 게시물을 NFT로 발행하면 일주일 동안 사용할 수 있습니다. (최초 1회)
② NFT 구매
다른 이용자의 NFT를 구매하면 한 달 동안 사용할 수 있습니다. (구매 시마다 갱신)
사용법
디시콘에서지갑연결시 바로 사용 가능합니다.