Disqus for deduction-theory

퍼셉트론 강의


퍼셉트론

퍼셉트론(perceptron)은 인공신경망의 한 종류로서, 1957년에 코넬 항공 연구소(Cornell Aeronautical Lab)의 프랑크 로젠블라트(Frank Rosenblatt)에 의해 고안되었다.


신경망을 얇게 잘라 확대한 사진을 보면 특정한 규칙이 보인다고 한다. 그것을 보고 연구자가 만들어낸 모델이 퍼셉트론이다. 실제 동물과 인간이 가진 신경망의 정확한 구조와 정보처리 과정은 아직 전부 밝혀지지 않았다. 그런 의미에서 퍼셉트론도 현상을 이해하려고 만든 하나의 모델이다.


머신러닝에서는 퍼셉트론을 제한된 선형분류기 모델로 사용한다. 딥러닝에서는 활성화 함수(Activation function)을 다양하게 조합하여 사용하거나 퍼셉트론의 입력과 출력 구조를 다양하게 조립하여 제한된 선형 분류보다 복잡한 정보처리를 한다. 쉽게 말해서 같은 퍼셉트론이 있을 때 머신러닝에서 퍼셉트론을 사용하는 방식과 딥러닝에서 퍼셉트론을 사용하는 방식이 달라진다.

기본적으로 퍼셉트론이 동작하는 방식은 다음과 같다.
각 노드의 가중치와 입력치를 곱한 것을 모두 합한 값이 활성화 함수에 의해 판단되는데, 그 값이 임계치(보통 0)보다 크면 뉴런이 활성화되고 결과값으로 1을 출력한다. 뉴런이 활성화되지 않으면 결과값으로 -1을 출력한다.

수학식으로는 아래와 같이 표현된다.
1. 각 노드의 가중치와 입력치를 곱한 것을 모두 합한 값이 활성화 함수에 의해 판단된다.  



2. 그 값이 임계치(보통 0)보다 크면 뉴런이 활성화되고 결과값으로 1을 출력한다. 뉴런이 활성화되지 않으면 결과값으로 -1을 출력한다.



"모든 입력이 1이라는 가중치를 가지고 한계랎이 입력 수의 절반일 경우 입력의 절반 이상이 발화하면 퍼셉트론이 발화한다. 다른 말로 하면 퍼셉트론은 다수가 이기는 작은 국회와 같다. 하지만 보통 모든 의원의 투표권이 같은 효력을 지니지 않기 때문에 완전히 민주적인 것은 아니다. 신경망은 소수의 가까운 친구들이 페이스북 친구 1000명 이상보다 중요한 사회관계망과 더 비슷하다.
그래서 당신에게 가장 많은 영향을 미치는 친구가 가장 신뢰하는 친구다. 친구가 추천한 영화가 좋았다면 당신은 다음번에도 그 친구의 추천을 따를 것이다. 반면에 당신이 좋아하지 않는 영화에 대하여 입이 마르도록 칭찬한다면 그 친구의 의견을 무시해 버릴 것이다."
마스터 알고리즘(The Master Algorithm, 2015) by Pedro Domingos, 본문 173쪽 중

퍼셉트론을 수식으로만 접하면 무미건조하고 개념이 와닿지가 않는다. 그것을 다양한 관점으로 보면 좀 더 많은 것을 볼 수 있다. 아래 도식은 내 입장에서 퍼셉트론을 인간이 인관관계를 평가하는 모델로 비교해보면 이해가 쉽다고 생각해서 만든 것이다.


수식에서 weight을 통로관점이라고 이름 붙였다. activation function은 판정기준(구분잣대)이라고 이름 붙였다.

위 도식을 보면 느낄 수 있듯이 자연 상태(initial state)의 퍼셉트론이 하는 것은 "무작위 의견", 즉 쉬운 말로 헛짓거리다. 그러면 어떻게 하면 "무작위 의견"을 내어 놓는 퍼셉트론이 인간의 입장에서 유의미한 행위를 하도록 개선할 수 있을까?

나는 개를 키우고 있다. 개는 주인과 유대감을 가지고 주인이 시키는 일을 해보려고 한다. 그런데 대부분의 경우 개는 무작위 행동을 한다. 개를 잘 가르치려면 개가 하는 무작위 행동 중에 주인이 원하는 행동을 했을 때 먹이를 주고 칭찬을 해서 보상을 해야 한다. 개가 주인이 원하지 않는 행동을 했을 때는 무시하거나 "안돼."하고 말하는 식으로 제재하는 의사표현을 해야 한다. 그렇게 적절한 타이밍을 잡아서 계속 특정 행동에 보상을 하면 그것이 바로 훈련이 된다.

내가 주인이고 애완견(Show Dog)에게 곡예를 가르친다고 상상해 보자.
  1. 일단 무엇이 좋은 기술이고 무엇이 아무 의미 없는 헛짓거리인지 주인 입장에서 정의를 해야 제대로된 곡예를 가르칠 수 있다. 곡예 행위를 정의한다.
  2. 애완견이 어떤 행위를 했을 때 그것이 주인이 목표로 한 곡예 기술과 얼마나 가까운지 판단할 수 있는 "판정 기준"을 만들어야 한다.
  3. 애완견이 주인이 원하는 방향으로 행동하도록 교정하는 일관된 명령 체계가 있어야 한다.

"헥헥!"

위의 문장을 다양한 관점으로 분석해보면 더 자세한 것을 알아낼 수 있다.
  1. 무엇이 곡예인지 인식하고 정하는 것은 주인이고 애완견은 자신이 무슨 짓을 하는지 사실 모른다.
  2. 곡예의 정의가 바뀌면 그동안 애완견이 연습한 기술은 적어도 주인 입장에서는 의미가 없어진다.
  3. 애완견은 자신이 한 행동이 옳은지 그른지 판단하지 않는다. 주인의 즉각적인 교정을 받고 행동을 고치거나 "파블로프의 개 실험"처럼 주인의 보상을 기대하고 거기에 맞는 행동을 한다.
  4. 그럼에도 애완견이 자신이 하는 행동과 주인의 교정 행위 간의 관계를 상상하여 주인의 명령에 따르는 확률을 높이는 것이 정보를 창조하는 활동이다.

최근 머신러닝과 딥러닝이 해결하려고 하는 과제들도 위의 분석과 관련이 있다. 딥러닝 프로그램은 행위의 실체와 아웃풋이 의미하는 바를 모르지만 연구자(주인)의 교정을 받아서 연구자가 목적하는 방향으로 정보처리의 확률을 높인다. 그리고 컴퓨터 하드웨어의 발달로 대량 정보처리가 가능해지자 이 정보처리 부분에서는 인간보다 수행능력이 더 나아지게 된 것이다.


퍼셉트론 손실 함수 Loss function, Cost function

퍼셉트론은 독립 변수 x로부터 종속 변수 y를 예측하는 예측 모형이므로 예측 오차 즉 손실(loss)을 최소화하는 가중치를 계산해야 한다. 위에 든 예시로 설명하면 “2. 애완견이 어떤 행위를 했을 때 그것이 목표로 한 기술과 얼마나 가까운지 판단할 수 있는 판정 기준을 만들어야 한다.” 와 관계있는 과정이다.

손실 함수(loss function) 는 목표로 한  y  값과 퍼셉트론이 예측한  y^  값의 차이를 나타내는 함수이다.



시그마는 반복하는 과정에서 나온 값을 전부 더한다는 의미이다.
max는 인자로 받은 값 중 큰 값을 골라낸다는 의미이다.

애완견을 가르치는 활동과 퍼셉트론을 가르치는 활동에서 보이는 두드러진 차이는 수학적인 정량 체계이다.
애완견을 가르칠 때 점프 높이를 정밀한 단위로 정량해서 특정 상황에 정해진 단위만큼 행동하게 한다면 더욱 프로페셔널한 곡예견을 양성할 수 있을 것이다. 그래서 사람이 눈대중으로 하는 활동을 머신러닝은 확률 정량 수치로 처리한다고 할 수 있겠다.


가중치 계산

위에 든 예시로 설명하면 “3. 애완견이 주인이 원하는 방향으로 행동하도록 교정하는 일관된 명령 체계가 있어야 한다.” 와 관계있는 과정이다. 아래는 현재까지 개발된 퍼셉트론 학습 방법이다.

전역 가중치 검색: 경우의 수를 일일이 계산하는 방법이다. 너무 경우의 수가 많아 불가능에 가깝다.

미분 계산: 가중치를 미분하여 값을 일일이 구하는 방법이다. 경우의 수 계산에 비해서 빠르고 수학적으로 명확하지만 백프로퍼게이션에 비해서 컴퓨터 자원 소모가 많고 느리다.


현재 상태에서 오류값이 줄어들거나 늘어나는 기울기, 경향을 알아내려고 오류값의 변화량(dE) / 가중치의 변화량(dw)을 계산한다.
i는 학습 샘플의 개수, x는 입력, y는 출력이다.

경사하강법 gradient descent: 미분을 응용하여 오류값을 줄이는 경향을 따라서 값을 조정하는 방법이다. 가중치와 오류(손실)값을 2차원 그래프로 그리면 기울기가 나올 것이라고 상상할 수 있는데 이 기울기를 목표에 근접하는 방향 즉, 가중치 축에 달라붙는 모양으로 가도록 값을 조정하는 것을 생각하면 이해가 편할 것이다. 가중치가 2개보다 많으면 평면 그래프로 표현하기 어렵기 때문에 상상만 할 수있다.



eta는 learning rate이다. learning rate는 1보다 작고 0보다 큰 수로 연구자가 임의로 정한다. 이렇게 하는 이유는 learning rate를 너무 높이면 경사하강을 하다가 목표 경사를 지나치는 경우가 생기고 learning rate를 너무 줄이면 학습이 더디게 되기 때문이다.

백프로퍼게이션: 다층퍼셉트론에서 gradient descent 방식으로 학습을 할 때 오류값을 출력 레이어에서 입력 레이어 방향으로 전파시키는 방식이다. 업계에서 가장 폭넓게 사용하고 있다. 백프로퍼게이션 공식은 퍼셉트론의 구조에 따라 다양한데 아래는 단순한 형태의 예이다.

weight = old weight - learning rate * (current output - desired output) * g(current output) * old input
여기서 g는 gradient descent on activation function을 의미한다.


백프로퍼게이션을 사용하면 연구자가 원하는 값을 출력하는데 방해가 되는 가중치 통로를 아웃풋에서 인풋 방향으로 역순으로 추적해서 고쳐 나가게 된다. 그렇게 해서 최종적으로 아웃풋이 연구자가 원하는 값에 확률적으로 부합하도록 하는 것이 백프로퍼게이션의 목적이다. 이 방법이 도입된 이후에 퍼셉트론의 성과가 비약적으로 커졌다.

유전 알고리즘: 쉽게 말하자면 경우의 수 계산을 띄엄띄엄하면서 상대적으로 잘된 경우만 선택하여 빠르게 하는 것이다. 백프로퍼게이션보다는 느리지만 미분보다 자원 소모가 적어서 백프로퍼게이션을 사용하기 어려운 상황일 때 사용한다.


파이썬으로 네이티브 퍼셉트론을 구현한 예



class Neuron:
   def __init__(self, w1, w2, b):
       self.w1 = w1  # weight 1 가중치 1
       self.w2 = w2  # weight 2 가중치 2
       self.a = 0.1  # alpha - learning rate 회차당 학습적용량 비율
       self.b = b  #  bias 고정값

   def feedForward(self, input1, input2):
       self.input1 = input1
       self.input2 = input2
       # summation of weight 각 노드의 가중치와 입력치를 곱한 것을 모두 합한다.
       sigma = self.w1 * input1 + self.w2 * input2 + self.b
       # return with activation function 활성화 함수로 판단한다.
       self.output = self.getAct(sigma)
       return self.output

   def getAct(self, x):
       if x < 0.0: return -1.0
       else return 1.0

   def getActGrad(self, x):
       if x >= 0.0: return 1.0
       else: return -1.0

   def propBackward(self, target):
       # 오류값을 줄이는 경향을 따라서 값을 조정한다.
       # weight = old weight - learning rate * (current output - desired output) * g(current output) * old input
       self.w1 = self.w1 - self.a*(self.output - target)*self.getActGrad(self.output)*self.input1
       self.w2 = self.w2 - self.a*(self.output - target)*self.getActGrad(self.output)*self.input2
       self.b = self.b - self.a*(self.output - target)*self.getActGrad(self.output)

neuron = Neuron(2.0, 2.0, 1.0)
for unused in range(1, 100):
   print 'Input 1.0 -> Output {}'.format(neuron.feedForward(1.0, 1.0))
   neuron.propBackward(4.0)




Facebook Comments

Disqus Comments

About Author

안녕하세요. 제 이름은 이기준이에요.  저는 Deduction Theory, LLC라는 소프트웨어 회사에서 CEO로 일하고 있어요.
저는 제 동생 이기환님과 함께 일을 하구요. 연구와 공부도 하고 있어요. 우리가 연구하는 주제는 논리학, 수학, 과학, 그리고 컴퓨터 정보공학이에요. 이 블로그는 우리가 연구하고 공부하는 주제를 설명하는 곳이에요.
그리고 저는 최근 오픈소스 공개 스터디 릴랏 프로젝트의 내용을 번역해 주실 자원봉사자를 모집하고 있어요. 제 생각에는 이 프로젝트가 전세계에 사는 어린이, 학생, 어른에게 도움이 될 거에요. 특히 저소득층에게요. 이 프로젝트는 무료에요. 사람들에게 도움을 주려고 기획했어요. 저는 나중에 저소득 국가에 학교와 고아원을 짓고 사람들에게 이 프로젝트 방식으로 컴퓨터 프로그래밍을 가르쳐 주고 싶어요. 그렇게 해서 나중에 그 사람들이 더 나은 직업을 가질 수 있게 돕고 싶어요.
아래에 링크한 릴랏 소개 페이지를 읽어 본 다음 이것이 도울 만한 가치가 있다고 생각되시면 저에게 말해주세요.
오픈소스 공개 스터디 프로젝트 Rellat을 소개합니다
원문 컨텐츠는 한글로 전부 제가 쓴 것이에요. 우리는 세계 모든 언어로 번역할 계획을 가지고 있어요. 감사합니다.
안녕하세요. 이기준님과 함께 Rellat 프로젝트를 진행하고 있는 이기환입니다.
제가 프로그래밍을 처음 시작한 것은 어린 시절 어도비 플래시 프로그램에서 애니메이션을 만들다가 게임을 만들고 싶어서 액션스크립트를 사용한 것입니다.
Rellat 프로젝트의 방법론은 제가 평소에 일을 하는 방법과 같습니다.
저는 사실 500줄 이상 넘어가는 코드를 보면 정신이 없고 잘 기억도 안됩니다. 지금도 간단한 코드 문법이 기억이 안나서 구글을 뒤지는 경우가 허다합니다.
대신 저는 이 코드가 어떤 사고방식을 사용해서 만들어졌는지, 어떤 관계정보를 사용했는지를 추적합니다. 이것이 연역론의 코딩 방법론, 코딩 스타일, 컴퓨팅 세계관입니다.
이 사고방식을 갖추면 더 나은 정보처리 방식이 무엇인지 비교할 수가 있습니다. 이것이 프로그래밍의 본질이고, 가장 중요한 것입니다.
나머지 프로그램의 빈공간은 구글과 스택오버플로우의 힘을 빌려서 채워넣습니다.
저는 여러분도 그렇게 하면 끊임없이 만들어지는 새로운 기술, 수만 줄의 코드 속에서 허우적거리지 않으면서 대규모의 질 높은 정보처리를 더 효과적으로 할 수 있다고 생각합니다. 

Popular Posts

Visitor Map

Flag Counter