신경망 (Neural Networks)


우리 인간의 뇌는 무수히 많은 뉴런(neuron) 이라는 신경 세포로 구성되어 있고, 뉴런들은 시냅스를 통해 전기적, 화학적 신호를 서로 주고 받으면서 정보를 저장하는 기능을 수행 한다고 합니다. 뉴런들이 서로 복잡하고 얽혀 주고 받는 신호를 통해 우리 인간은 생각을 하고 감정을 느끼기도 하며 무엇인가를 배우기도 합니다.


머신러닝 기법 중 하나인 신경망, 혹은 인공 신경망은 이러한 뇌의 신경망을 본 떠 만든 알고리즘 중 하나 입니다. 신경망의 경우 요즘 많은 관심을 받고 있는 딥러닝의 기초가되는 알고리즘이기도 합니다.



Perceptron


인공 신경망을 구성하는 가장 기초적인 단위는 퍼셉트론(Perceptron) 입니다. 퍼셉트론은 위의 그림과 같이 1개 이상의 input 값과 bias 값 그리고 활성 함수(activation function) 와 1개의 output 값으로 구성되어 있습니다. 퍼셉트론의 input 들은 각각 weight 값들과 곱해져 활성 함수로 전달 되게 되며, 활성함수의 결과 값으로 output 값을 가지게 됩니다. 


활성화 함수의 종류는 매우 다양합니다. 구성하고자 하는 네트워크의 목적에 따라 Logistic 함수, trigonometric, Softmax ReLU, Sigmoid, Step 함수 등 다양한 함수들을 사용 할 수 있습니다. 활성화 함수를 거쳐 구해진 Output 은 이미 labeling 이 되어진 데이터와 비교하여, 비교된 결과에 따라 weight 값을 업데이트 시켜 주어야 합니다. 


이러한 과정을 무수히 반복하다 보면 Output 과 실제 값과의 차이는 점점 작아질 것이고 어느 정도 정해진 횟수 혹은 error 율에 이르게 되면 이 과정을 종료하면 됩니다. 인공 신경망에서의 학습 이라는 개념은 이러한 weight 값 업데이트 과정이라고 보시면 됩니다. 


인공 신경망을 만들기 위해서는 퍼셉트론으로 이뤄진 레이어를 한층, 한층 추가해 주면 됩니다. 인공 신경망은 기본적으로 입력을 받는 입력 계층 (Input layer) 와 출력 값을 보여주는 출력 계층 (Output layer) 를 가집니다. 그리고 입력 계층과 출력 계층 사이의 모든 계층들은 은닉 계층 (Hidden layer) 로 불립니다. 해당 계층으로 입력되는 값과 출력 되는 값이 직접적으로 보여지지 않기 때문에 은닉 계층이라 칭하고 있습니다.




SciKit-Learn


이번 글의 예제를 직접 돌려보기 위해서는 0.18 버전 이상의 SciKit-Learn 을 설치하여야 합니다. pip 이나 conda 통해서 쉽게 설치할 수 있으며, 관련 내용은 구글을 통해서 쉽게 검색하실 수 있을 것 같습니다. 개인적으로 머신러닝이나 딥러닝을 공부 할때는 conda 를 이용해서 virtual env 를 셋업하시는 것이 정신 건강에 이롭다고 생각 합니다.  Anaconda 다운로드 및 사용법에 대해서는 아래의 링크를 참조하시면 될 것 같습니다.


Anaconda 다운로드 https://www.continuum.io/downloads


How to install Machine Learning Package Using Anaconda



Data


실습을 위한 데이터는 UCI Repository 에서 제공하는 Wine 데이터 를 사용하도록 하겠습니다. 다운로드

이 데이터는 와인이 가지고 있는 13가지 화학 성분에 대한 정보를 가지고 있습니다. 데이터 상의 와인은 모두 이탈리아 한 지역에서 생산된 와인이며, 3종류의 각기 다른 품종으로 구분 됩니다. 


그럼, 인공 신경망을 이용해서 다운로드 받은 데이터를 학습해서, 데이터 상의 화학 성분만을 가지고 어떤 품종인지 예측하는 모델을 만들어보도록 하겠습니다. 



위와 같이 pandas 를 사용하여 데이터를 읽어 드립니다. 앞에서 부터 5개의 데이터의 결과가 아래와 같이 나오면 데이터를 잘 읽어 들인 것 입니다. 인공 신경망을 통해 우리가 알고 싶은 결과는 첫 번째 행인 Cultivator 입니다. Alchol ~ Proline 까지의 데이터가 입력으로 들어 왔을 때, Cultivator(품종) 이 1 인지, 2인지 아니면 3인지 예측하는 모델을 만드는 것 입니다.


  Cultivator  Alchol  Malic_Acid   Ash  Alcalinity_of_Ash  Magnesium  ... (이하 생략)

0           1   14.23        1.71  2.43               15.6        127   

1           1   13.20        1.78  2.14               11.2        100   

2           1   13.16        2.36  2.67               18.6        101   

3           1   14.37        1.95  2.50               16.8        113   

4           1   13.24        2.59  2.87               21.0        118 



데이터에 대한 정보를 좀 더 확인해 보겠습니다. 아래와 같이 wine 데이터의 shape 을 출력해 보면, 178 개의 데이터와 14개의 속성 값을 가지는 것을 확인할 수 있습니다.



(178, 14)



그럼 이제 입력 값과 출력 값을 정의 해 보도록 하겠습니다. 입력 값은 Cultivator 를 제외한 13개의 속성 값들의 집합 입니다. 즉, 위의 178 개의 데이터 중 Cultivator 행을 뺀 나머지 부분이라고 보시면 됩니다. 출력 값은 Cultivator 행만 있는 178 개의 데이터 입니다. 



입력 값 X 와 출력 값 Y 를 정하고 나면 178개의 데이터를 학습 데이터와 검증 데이터로 구분해 줍니다. 학습 데이터는 학습을 위해서만 사용되며, 검증 데이터는 학습된 결과가 제대로 학습 되었는지 확인하기 위해 사용 됩니다.



Data Processing


인공 신경망의 경우 데이터 값들을 정규화 해주지 않을 시, 아무리 학습을 해도 원하는 값을 얻기 어려울 수 있습니다. 신경망 특성 상 스케일링 (scaling) 에 매우 민감하게 반응 합니다. 따라서 학습 데이터와 검증 데이터 모두 데이터에 알맞게 정규화 해 주어야 합니다. 정규화 하는 방법은 여러가지가 있지만 이번 예제에는 sckit learn 에서 제공하는 API 를 이용해 보도록 하겠습니다.



 

위와 같이 학습 데이터를 기준으로 데이터의 전 처리까지 완료 하고 나면 학습을 진행할 수 있습니다.



Training the model


scikit-learn 은 학습을 위한 다양한 API 들을 제공하고 있습니다. 인공 신경망의 자세한 이론적 지식이 없더라도 API 호출 만으로도 학습 모델을 손쉽게 구성할 수 있습니다. 물론, 그렇다고 하더라도 이론적 지식이 없어도 된다는 이야기는 아닙니다. 아무리 많은 기능을 라이브러리가 제공한다고 하더라도 언제 어떻게 쓸 줄 모른다면 소용이 없겠죠.




학습을 위해 1개의 입력 계층과 3개의 은닉 계층, 그리고 1개의 출력 계층으로 이뤄진 인공 신경망을 구성해 보도록 하겠습니다. 각각의 은긱 계층은 30개의 퍼셉트론으로 이뤄지도록 정의 하였고, 정의된 신경망에 학습 데이터의 인풋 X (x_train) 과 출력 Y (y_train) 을 파라미터로 넘겨주면 학습 모델 구성이 완료 됩니다.


MLPClassifier(activation='relu', alpha=0.0001, batch_size='auto', beta_1=0.9,
       beta_2=0.999, early_stopping=False, epsilon=1e-08,
       hidden_layer_sizes=(30, 30, 30), learning_rate='constant',
       learning_rate_init=0.001, max_iter=200, momentum=0.9,
       nesterovs_momentum=True, power_t=0.5, random_state=None,
       shuffle=True, solver='adam', tol=0.0001, validation_fraction=0.1,
       verbose=False, warm_start=False)


지금은 단순히 모델의 계층만을 구성하였지만 실제로 모델을 객체를 생성할 때 정의 할 수 있는 파라미터들은 위와 같이 매우 많습니다. 파라미터들을 직접 정의해서 바꿔보시거나 계층 수를 늘리거나 줄이거나 혹은 퍼셉트론의 수를 변경해 보시면서 다양한 방식으로 학습을 구성해 보시면 좋을 것 같습니다.



Prediction and Evalutaion



드디어 대망의 마지막 단계 입니다. 학습이 완료된 모델이 얼마나 정확하게 예측하는지 평가해 보도록 하겠습니다.



테스트를 위해 분리해둔 x_train 데이터를 predict 함수의 파라미터로 단순히 넘겨주는 것 만으로 값을 예측해 볼 수 있습니다. 그리고 예측 결과 값인 preditctions 와 x_train 의 실제 값인 y_train 의 결과를 비교해서 얼마나 맞췄는지 평가함으로써 우리가 구축한 모델의 성능을 평가해 볼 수 있습니다.


평가와 관련된 confusion_matrix 와 classification_report 의 결과 값을 한번 보도록 합시다.


               precision    recall  f1-score   support

          0       1.00      0.94      0.97        53
          1       0.97      1.00      0.98        90

avg / total       0.98      0.98      0.98       143


리포트를 보면 위와 같이 약 98%의 정확도를 보이는 모델임을 알 수 있습니다. 이정도면 꽤 훌륭한 모델이라고 할 수 있습니다!
기본적으로 인공 신경망이 어떤 식으로 구성 되어 있는지 그리고 어떤 식으로 동작하는지에 대해서 알아 보았습니다. scikit learn 외에도 tensorflow, PyTorch, Keras 등 다양한 인공 신경망과 딥 러닝을 위한 라이브러리 / 프레임워크 들이 존재 합니다. 하나씩 사용해보고 상황에 자신의 스타일에 가장 잘 맞는 것을 선택하여 공부해 보면 좋을 것 같습니다. :-)



본 글은 아래의 원문을 일부 수정 및 번역 하였습니다.
원문 : www.kdnuggets.com/2016/10/beginners-guide-neural-networks-python-scikit-learn.html/