신경망의 구조

신경망은 앞서 언급했던 퍼셉트론(여러 개의 입력을 계산하여 하나의 결과값을 출력하는 객체)과 공통점이 많습니다. 이번에는 신경망과 퍼셉트론의 차이점을 주로 설명하여 신경망에 대해서 설명하겠습니다.

퍼셉트론의 구조

 

신경망은 여러개의 퍼셉트론을 연결하여 입력층, 은닉층 그리고 출력층을 제작한 것입니다. 

입력층은 우리가 분석하고자 하는 데이터를 입력할 때 사용되는 층입니다. 그리고 신경망이 데이터를 분석할 때 하나 이상의 은닉층에서는 매 번 가중치를 곱하고 결과값을 다음 은닉층에 전달하는 과정이 일어납니다. 이러한 일련의 과정을 거쳐 출력층에서 우리가 원하는 결과값이 출력되는 것입니다.

우리의 몸으로 비유를 하자면 눈으로 사물을 인식하는 것이 입력층이고 시각신호가 뇌에서 처리되는 것이 은닉층 그리고 은닉층을 통해서 우리는 어떤 사물인지 인지하는 결과가 출력층인 것입니다.

 

신경망의 기본 구조


활성화 함수

활성화 함수란 입력신호의 총합을 어떤 출력신호로 변화시킬지 정하는 함수입니다.

활성화 함수

퍼셉트론에서는 데이터의 총합이 임계값을 넘으면 1 그렇지 않으면 0을 출력하는 단순한 구조였지만 신경망에서는 인공뉴런들이 데이터의 총합을 독특한 방식으로 출력합니다. 

1. 시그모이드 함수

시그모이드 함수

# coding: utf-8
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()


# coding: utf-8
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()

시그모이드 함수는 사용하는 뉴런은 각각의 데이터와 가중치의 총합을 시그모이드 함수로 계산한 결과값을 다음 층에 전달합니다. 입력값이 0보다 더 큰 경우 1에 가까운 결과값을 출력하고 0보다 작을 수록 0에 가까운 결과값을 출력하는 것이 특징입니다.

초기에는 자주  logistic classification 신경망에 사용되었지만 여러가지 단점들이 부각되고 ReLU함수의 등장으로 최근에는 사용하지 않게 되었습니다.

 

2. 계단함수

계단함수

# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
def function(x):
  return np.array(x > 0, dtype=np.int);
x=np.arange(-5,5,0.1);
y=function(x);
plt.plot(x,y);
plt.show();

계단 함수는 0을 기준으로 0보다 크면 1, 0보다 작으면 0을 출력하는 함수 입니다. 

이 함수는 입력값에 비해서 출력값이 0을 기준으로 극단적으로 출력하는 함수 이기 때문에 신호처리 분야에서 자주 사용되는 함수 입니다.

 

3. ReLU 함수

ReLU

# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
def function(x):
  return np.maximum(0,x);
x=np.arange(-5,5,0.1);
y=function(x);
plt.plot(x,y);
plt.show();

ReLU(Recrified Linear Unit, 정류된 선형 함수)는 0이하의 입력값은 모두 0으로 0이상의 출력값은 그대로 출력하는 함수입니다. 시그모이드 함수로 인해 발생하는 문제(vanishing gradient)를 해결하기 위해 사용된 함수로써 현재 가장 많이 사용되는 함수입니다.

 

** 활성화 함수의 특징 : 활성화 함수는 여러가지가 존재 할 수 있지만 반드시 비선형 함수여야 합니다. 선형함수인 경우 여러개의 층을연결하여 계속 계산하는 것은 한 번 계산하는 것과 동일하기에 의미가 없기 때문입니다.**

AdapterViewAdapter와 AdapterView란?

어댑터 뷰는 말 직역하면 적응형 뷰라는 의미가 된다. 앱들을 보면 같은 틀에 다른 내용들이 포함되어 여러개로 나열된 경우를 많이 보았을 것이다. (ex. 카카오톡 친구목록, 페이스북 게시글, Pinterest의 게시글 등) 여기서 사용되는 하나의 틀은 AdapterView로 정의하고 입력할 내용들과 방식은 Adapter로 정의하여 정보들을 원하는 방식으로 나열하여 표현 할 수 있다. 

 

사용방식

기본적으로 ListView나 GridView를 통해서 하나의 View씩 나열 할 수 있다. 또한 Custom View를 제작하여 AdapterView로 사용함으로써 자신이 원하는 틀을 제작할 수 있다. 실제 개발에서는 후자의 경우가 많이 사용될 것이므로 이에 대해서 설명하도록 하겠다.

 


 

개발방법 

(customView를 수직으로 나열하도록 개발)

  1. 먼저 res->layout에 AdapterView로 사용할 customVeiw.xml 파일을 생성한다

  2. 자신이 원하는 View구성을 위 파일에 입력한다.

  3. View들을 나열할 액티비티로 이동해서 ListView listview를 추가한다.

  4. 나열할 데이터들을 가져와 배열을 생성함

  5. ListView객체를 생성하고 미리 생성한 ListVeiw를 참조함

  6. Adapter를 생성함

    1. 데이터를 가지고 있는 ArrayList<HashMap<String,Object>> dataList를 생성함

    2. 배열 내부의 HashMap을 참조하기 위해 key값이 나열된 배열을 생성 -> String[] keys

    3. 위에서 생성한 AdapterView의 내부 View아이디를 참조하기 위한 id 배열생성 -> String[] id

      1. **중요** 나중에 keys, id 배열들의 값이 각각 일대일 대응되어 데이터가 저장되므로 순서가 중요함

    4. Adapter를 만들어 준다

      1. SimpleAdapter ad = new SimpleAdapter( this,  dataList, R.layout.customView, keys,id);

        (keys와 ids 내부의 배열들이 인덱스 0 부터 일대일 대응이 되고 keys 배열 순서에 따라 dataList의 하나의 해쉬맵에서 value가 참조되어 ids에  일대일 대응 되어 삽입이 된다.)
    5. Adapter를 세팅해준다.

      1. listview.setAdapter(ad);

        

 

 

Chapter 1 ~ 3은 파이썬의 초기설정, 퍼셉트론 이론 그리고 신경망이론에 대해서 설명하고 있다.

이에 대해서는 기본적으로 알고 있다고 생각하고 여기에는 신경망을 실질적으로 이해하고 코드로 구현하는 방법에 대해서 설명하고자 한다.

 

1. 신경망의 정의

 

책에서 설명하는 신경망은 사실상 퍼셉트론의 확장이라고 할 수 있다. 퍼셉트론에서 활성화 함수(인공뉴런 의 입력값을 출력값으로 바꿀때 쓰이는 함수)로 시그모이드 함수나 ReLU함수 같은 비계단형 함수를 사용하면 그것이 신경망의 물리적 구조라고 할 수 있기 때문이다. 

 

2. 신경망의 학습과정

 

신경망의 학습과정은 추상적으로 표현할 경우 다음과 같다.

1. 모델(예측함수) -> 2. 결과값 비교 -> 3. 매개변수 업데이트 계산 -> 1. 모델(예측함수) .....

 

이런 말은 상당히 많이 들어봤을 거라고 생각한다. 그래서 하나하나 문장의 의미를 프로그래밍 코드로 표현할 수 있도록 수학적으로 표현해 볼 예정이다.

 

1. 모델(예측함수)

 여기서 말하는 모델은 말그대로 신경망 자체를 의미한다. 신경망은 입력층 - 은닉층 - 출력층으로 구성되어 있고 각 층 사이에는 가중치값들로 노드들이 서로 연결되어있다. 

 그리고 예측은 입력층부터 출력층까지 가중치 값을 통해서 계산하여 결과값을 나타내는 것을 의미한다.

 

이를 세부적으로 풀어서 말해보자

 

1) 입력층

입력층은 말그대로 데이터를 입력하는 뉴런들이 있는 첫 번째 층이다. 예를 들어 우리가 24x24 사이즈의 사진 데이터를 입력하여 사진에 고양이가 있는지 없는지 판단해본다고 하자. 그럼 입력해야하는 데이터는 24x24 = 576가지가 된다. 그러므로 입력층에는 576개의 뉴런들이 존재하게된다.

 

2) 출력층

은닉층을 설명하기 전 출력층에 대해서 설명해보도록 하자. 출력층 또한 말 그대로 전 단계의 층에서 받은 데이터를 처리해서 출력하는 것을 의미한다. 우리가 원하는 출력은 고양이가 있는지/없는지 즉 두 가지 종류를 가지고 있다. 이를 좀더 수식으로 표현하면 Result = 1 ( 고양이가 존재함 ) or 0 (고양이가 존재하지 않음)으로 표현할 수 있다. 따라서 마지막 출력층은 두 가지 데이터를 출력 할 수있으므로 출력층의 뉴런은 1개만 있어도 된다.

 

3) 은닉층

은닉층은 입력층과 출력층 사이에 존재하면서 데이터를 처리하도록 한다. 만약 은닉층이 없을 경우 입력층에서 바로 출력층으로 이어지게 되며 위와 같은 예시에서는 576개의 입력층 뉴런이 1개의 출력층 뉴런에 바로 이어지게 되며 이에 사용되는 매개변수는 576개가 된다. 이 때 매개변수가 매우 적으므로 범용적으로 데이터의 출력값을 정확히 하기에는 어려움이 있다. 왜냐하면 매개변수가 적을 경우 데이터를 판별하는 기준이 적다는 의미가 되고 기준이 적다는건 컴퓨터가 제대로 데이터를 판단하는데 부족한 능력을 가질 수 밖에 없기 때문이다.

 

 

+ Recent posts