728x90
반응형

 지난 포스트에서 데이터 셋에 대해 간략히 설명해보았다. 이번 포스트부터 본격적으로 텐서플로우를 사용해서, 내가 찾아내고 싶은 알고리즘을 찾아내 보자.

 

 

학습 목표

  • 분석가가 알고 있는 패턴으로 데이터를 생성하고, 그 패턴을 찾아내는 모델을 만들어보자.
  • Input이 1개, Output이 1개인 연속형 데이터에서 패턴을 찾아보자.

 

 

 

1. 데이터 셋 생성

  • 패턴: $f(x) = x + 10$
# Module 설정
import pandas as pd
import numpy as np
from tensorflow import keras
from tensorflow.keras.layers import Dense
def f(x):
    return x + 10
    
# Data set 생성
np.random.seed(1234)   # 동일한 난수가 나오도록 Seed를 고정한다.
X_train = np.random.randint(0, 100, (100, 1))
X_test = np.random.randint(100, 200, (20, 1))

# Label 생성
y_train = f(X_train)
y_test = f(X_test)

 

데이터 셋 생성 코드의 함수 설명

  1. np.random.seed(int):  난수(랜덤 한 데이터) 생성 시, 그 값은 생성할 때마다 바뀌게 된다. 데이터 셋이 바뀌게 되면, 일관된 결과를 얻기가 힘들어, 제대로 된 비교가 힘들어지므로, 난수를 생성하는 방식을 고정시킨다. 이를 시드 결정(Set seed)이라 하며, 숫자는 아무 숫자나 넣어도 상관없다.
  2. np.random.randint(시작 int, 끝 int, shape): 시작 숫자(포함)부터 끝 숫자(미포함)까지 shape의 형태대로 array를 생성한다.

 

데이터 셋 생성 코드 설명

  1. Train set은 0~100까지의 숫자를 랜덤으로 (100, 1)의 형태로 추출하였다.
  2. Test set은 100~200까지의 숫자로 랜덤으로 (20, 1)의 형태로 추출했다. 여기서 값은 Train set과 절대 겹쳐선 안된다.
  3. Label 데이터인 y_train과 y_test는 위에서 설정된 함수 f(x)에 의해 결정되었다.

 

  • train 데이터 생김새(가시성을 위해 10개까지만 출력)
# train Dataset을 10개까지만 가져와보자
>>> X_train[:10]

array([[47],
       [83],
       [38],
       [53],
       [76],
       [24],
       [15],
       [49],
       [23],
       [26]])
       
>>> X_train.shape
(100, 1)
  • 생성된 데이터 셋의 형태는 "(데이터 셋 수, 변수의 수)"라고 인지해도 좋다.
  • 여기서 "변수의 수"는 "데이터 하나의 벡터 크기"라고 생각하는 것이 더 적합하다.
  • 기본적으로 Tensorflow에 Input 되고 Output 되는 데이터의 형태는 이렇다고 생각하자.

 

 

 

 

2. 모델 생성하기

  • tensorflow를 사용해 모델을 생성하는 경우, tensorflow가 아닌 keras를 사용하게 된다.
  • 위에서 tensorflow의 기능을 가져올 때, 아래와 같은 코드로 가져왔다.
  • from tensorflow import keras
  • 이는, tensorflow라는 프레임워크에서 keras라는 모듈을 가지고 온다는 의미이다.
  • keras는 추후 설명하게 될지도 모르지만, 모델 생성 및 학습에 있어 직관적으로 코드를 짤 수 있게 해 주므로, 쉽게 tensorflow를 사용할 수 있게 해 준다.
  • 물론, keras와 tensorflow는 태생적으로 서로 다른 프레임워크이므로, 이 둘이 따로 에러를 일으켜, 에러 해결을 어렵게 한다는 단점이 있긴 하지만, 그걸 감안하고 쓸만한 가치가 있다.
model = keras.Sequential()
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='linear'))
  • keras를 사용해서 모델을 만드는 방법은 크게 2가지가 있다.
  • 하나는 위 같이 add를 이용해서 layer를 하나씩 추가해 가는 방법이 있고
model = keras.Sequential([
    Dense(16, activation='relu'),
    Dense(1, activation='linear')
])
  • 이렇게 keras.Sequential([]) 안에 층(layer)을 직접 넣는 방법이 있다.
  • 처음 방법처럼 add를 사용하는 방법은 API 사용 방법이고, 아래와 같이 층을 Sequential([])에 직접 넣는 방식은 Layer 인스턴스를 생성자에게 넘겨주는 방법이라 하는데, 전자인 API를 사용하는 방법을 개인적으로 추천한다.
  • 그 이유는 다중-아웃풋 모델, 비순환 유향 그래프, 레이어 공유 모델 같이 복잡한 모델 정의 시, 매우 유리하기 때문으로, 이는 나중에 다루겠으나, 이 것이 Tensorflow의 장점이다.

 

모델 생성 코드 함수 설명

  1. keras.Sequential(): 순차 모델이라 하며, 레이어를 선형으로 연결해 구성한다. 일반적으로 사용하는 모델로 하나의 텐서가 입력되고 출력되는 단일 입력, 단일 출력에 사용된다. 다중 입력, 다중 출력을 하는 경우나, 레이어를 공유하는 등의 경우엔 사용하지 않는다.
  2. model.add(layer): layer를 model에 층으로 쌓는다. 즉, 위 모델은 2개의 층을 가진 모델이다.
  3. Dense(노드 수, 활성화 함수): 완전 연결 계층으로, 전, 후 층을 완전히 연결해주는 Layer다. 가장 일반적으로 사용되는 Layer다.

 

모델 생성 코드 설명

  1. 해당 모델은 Input 되는 tensor도 1개 Output 되는 tensor도 1개이므로, Sequential()로 모델을 구성했다.
  2. 은닉층에는 일반적으로 ReLU 활성화 함수가 사용된다고 하니, ReLU를 넣었다.
  3. 출력층에는 출력 결과가 입력 값과 같은 노드 1개이므로, 노드 1개로 출력층을 만들었다. 
  4. 일반적으로 Node의 수를 $2^n$으로 해야 한다고 하지만, 크게 상관없다는 말이 있으므로, 굳이 신경 쓰지 않아도 된다. 처음엔 자기가 넣고 싶은 값을 넣다가, 성능이 안 나온다 싶으면 바꿔보는 수준이니 크게 신경 쓰지 말자.
  5. 사용된 활성화 함수(activation)는 일반적으로 은닉층에 ReLU를 넣고, 연속형 데이터이므로 출력층에 Linear를 넣어보았다.

 

 

 

 

3. 모델 컴파일하기

  • 컴파일은 모델을 학습시키기 전에 어떤 방식으로 학습을 시킬지를 설정하는 과정이다.
opt = keras.optimizers.Adam(learning_rate=0.01)
model.compile(optimizer=opt, loss = 'mse')

 

코드 설명

  1. keras.optimizers.Adam(): 최적화에 사용할 함수를 위처럼 외부에서 만들어서 넣는 경우, 학습률, 모멘텀 같은 인자들을 입맛에 맞게 바꿀 수 있다.
  2. model.complie(): 학습 방식을 설정한다.

 

compile은 기본적으로 3가지 인자를 입력으로 받는다.

  1. optimizer: 최적화하는 방법으로, 경사 하강법(GD)을 어떤 방법을 통해 사용할지를 결정한다. 일반적으로 Adam이 많이 사용된다.
  2. loss: 손실 함수를 설정한다. 일반적으로 연속형 데이터라면 제곱 오차 시리즈를, 분류 데이터라면 교차 엔트로피 오차 시리즈를 사용한다.
  3. metric: 기준이 되는 것으로, 분류를 할 때 주로 사용한다.
  • 손실 함수와 최적화에 관심이 있다면 다음 포스트(손실 함수, 최적화)를 참고하길 바란다.

 

 

 

 자, 지금까지 학습을 위한 모델 세팅을 완료하였다. 다음 포스트에서는 위 코드들을 깔끔하게 정리하고, 실제 학습을 해보겠다.

728x90
반응형

+ Recent posts