안녕하세요.

오늘은 사이킷런(scikit-learn)에서 제공해주는 보스턴 집값 데이터를 통해 신경망을 코드로 구현해보려고 합니다.

구글 코랩을 사용하였으며, 파이토치 기반으로 작성하였습니다.

 

크게 신경망을 구축하는데 있어서 필요한 요소는 다음과 같습니다.

 

1) 데이터 호출

2) 데이터 전처리

3) 신경망 모델 구현

4) 학습에 필요한 하이퍼파라미터, 손실함수 그리고 옵티마이저 세팅 및 학습 데이터셋 구성

5) 순전파와 역전파 과정을 통한 학습


 

각 과정에 맞춰 코드를 한번 살펴보겠습니다.

 

1) 데이터 호출

 

신경망에 있어 필요한 라이브러리 호출

먼저 신경망을 구성하는데 있어 필요한 라이브러리들을 호출해주었습니다.

 

이 부분은 난수 발생에 관련한 랜덤 시드를 고정시키는 부분입니다.

머신러닝에서는 랜덤성에 의하여 결과 값이 달라지기 때문에 모델에 따른 결과 값의 변화를 확인하기 위해 랜덤 시드를 고정하였습니다.

 

(다만, 현재 코드에서 DataLoader의 랜덤성을 고정시키는 방법을 찾지 못해 코드를 돌릴 때마다 다른 결과가 나올 수 있습니다.

추후, 방법을 찾게 된다면 정리하여 포스팅 하도록 하겠습니다.)

데이터를 호출하여 저장하는 코드입니다.

집값에 영향을 미치는 변수들은 총 13가지의 독립변수로 구성되어 있으며, 다음과 같습니다.

 

  • CRIM: 범죄율을 나타내는 수치
  • INDUS: 비소매상업지역 면적 비율을 나타내는 수치
  • NOX: 일산화질소 농도를 나타내는 수치
  • RM: 주택당 방 수를 나타내는 수치
  • LSTAT: 인구 중 하위 계층 비율을 나타내는 수치
  • B: 인구 중 흑인 비율을 나타내는 수치
  • PTRATIO: 학생/교사 비율을 나타내는 수치
  • ZN: 25,000 평방피트를 초과 거주지역 비율을 나타내는 수치
  • CHAS: 찰스강의 경계에 위치해 있는지 여부를 나타내는 수치
  • AGE: 1940년 이전에 건축된 주택의 비율을 나타내는 수치
  • RAD: 방사형 고속도로까지의 거리를 나타내는 수치
  • DIS: 직업센터의 거리를 나타내는 수치
  • TAX: 재산세율을 나타내는 수치

Target 데이터는 종속변수로 1978년 506개의 도시의 집값의 중앙값 입니다. (단위 1,000 달러)


2) 데이터 전처리

 

다음은 데이터를 전처리 하는 과정입니다.

 

먼저, 학습을 하기 위해 자료형은 Tensor이어야 하기 때문에 Tensor형으로 자료형을 변환해주었습니다.

 

그리고 학습을 위해서는 훈련을 위한 데이터와 훈련이 잘되었는지 검증하기 위한 검증 데이터가 필요합니다.

따라서, 주어진 입력데이터를 train_test_split 함수를 통해 데이터의 80%를 훈련용 데이터로, 20%를 검증용 데이터로 나누어 주었습니다.

 

데이터 자료형을 확인해 볼때, 13개의 독립변수(집값에 영향을 미치는 데이터)와 이에 따른 1개의 종속변수(집값)로 구성되어 있음을 알 수 있었습니다.

데이터의 shape에서도 확인할 수 있는데요.

x에 해당하는 데이터들은 13의 길이를 갖고 있고, y에 해당하는 데이터는 1의 길이를 갖고 있음을 확인할 수 있습니다.


위 코드는, 구글 코랩의 gpu를 사용하기 위한 코드입니다.

 


3) 신경망 모델 구현하기

다음은 신경망 모델을 구현한 코드입니다.

 

파이토치는 일반적으로 torch.nn.Module을 기본클래스로 지정하여 사용합니다.

따라서, 구현하고자 하는 신경망은 torch.nn.Module을 상속받는 클래스로 정의합니다.

 

이제 신경망을 어떻게 구현했는지 보겠습니다.

 

먼저, Input Layer - Hidden Layer - Output Layer로 이어지는 층을 구성하였습니다.

13개의 변수에 대하여 1개의 target 값을 예측하는 방향이므로,

Input dimension을 13으로, Hidden Layer를 거쳐 나오는 데이터의 Output dimension을 1로 설정해주었습니다.

 

또한, 각 층 사이 사이에 비선형성을 주기 위하여 ReLU를 사용하였습니다.


4) 학습에 필요한 하이퍼파라미터, 손실함수 그리고 옵티마이저 세팅 및 학습 데이터셋 구성

먼저, 신경망 모델에 필요한 하이퍼파라미터는 3가지 입니다.

 

한번 연산에 입력할 데이터 크기를 의미하는 batch_size,

학습에 있어서 한번에 얼만큼 학습할 것인지를 의미하는 learning_rate,

총 몇번 학습할 것인지를 의미하는 epochs(에포크)가 있습니다.

 

손실함수로는 MSE Loss 함수를 사용하였고, 옵티마이저로는 Adam을 사용하였습니다.

 

* model = Model().to(device) 는 모델을 학습에 gpu를 사용하기 위해, 모델을 gpu 상으로 올려주는 코드입니다.

 

학습에 필요한 데이터 셋을 구성한 코드입니다.

 

먼저, 각 train데이터와 test데이터를 TensorDataset 함수를 통해 묶어주었습니다.

이를 바탕으로, DataLoader를 활용하여 batch_size로 데이터를 나누어 저장해주었습니다.


5) 순전파와 역전파 과정을 통한 학습
 
 
 

마지막으로 학습을 시키는 과정입니다. 

세팅한 epoch(에포크) 수 만큼 학습이 진행되며, 한번의 epoch 안에서는 DataLoader를 통해 나누어 놓은 모든 데이터에 대한 학습을 진행합니다.

 

먼저, batch_size별로 구성된 x 데이터를 꺼내와 구현해놓은 신경망을 통해 순전파를 진행합니다.

 

그리고 역전파를 진행하기전, optimizer.zero_grad()를 통해 모델 매개변수 변화도를 조정합니다.

기본적으로 변화도는 계속해서 더해지기 때문에 변화도의 중복 계산을 막기 위하여 변화도를 0로 다시 세팅합니다.

 

순전파를 진행한 예측 값에 대하여, y 값과 손실함수를 통해 통해 손실을 구합니다.

이를 바탕으로, loss.backward() 함수를 통해 역전파를 진행하고 옵티마이저를 통해 매개변수 값을 조정합니다.

 


<학습된 모델의 손실도 및 정확도 확인 및 손실도 그래프 출력하기>

 

학습된 모델을 바탕으로, 테스트 데이터 셋을 이용하여 손실과 정확도를 구하는 부분입니다.

학습하는 부분과 다른 점은 with torch.no_grad() 입니다.

 

테스트 데이터 셋을 기반으로 손실과 정확도를 구할 때는 학습을 하는 것이 아니기에 더 이상 gradient를 계산할 필요가 없습니다.

따라서, 필요없는 연산을 수행하지 않게 하고 이를 바탕으로 연산 속도를 올려주기 위해 다음 코드를 활용합니다.

 

최종적으로 정확도는 약 74%가 나왔습니다.

마지막으로, 학습과정에서 각 epoch별 loss에 대해서 그래프를 그려보았습니다.

초반부에 loss가 확 떨어져, 전체적으로 감소하는 추이를 볼 수 있었습니다.

 

다만 정확도가 74% 정도로 나온 것은 조금 아쉬웠는데요.

 

데이터에 최적화된 신경망과 손실함수, 옵티마이저, 스케쥴러 등을 활용한다면 더 높은 정확도를 가진 모델을 구현할 수 있을 것 같습니다.

다만, 해당 포스팅은 정확도 보다는 신경망 자체를 코드로 보여드리는 것에 초점을 맞추었기에 이번 포스팅은 여기서 마무리 하도록 하겠습니다.

 

글에 대한 피드백은 언제나 감사드립니다. 

읽어주셔서 감사합니다.

 

'인공지능 > 구현' 카테고리의 다른 글

[케라스] VGG16 모델 구현  (0) 2022.09.21
[파이토치] CNN  (0) 2022.08.06

+ Recent posts