[tensorflow-basic] 활성화 함수
선형 모형은 활성화 함수(activation)을 통해 다양한 형태의 예측을 할 수 있습니다.
예제 데이터
파이썬 시각화 라이브러리인 seaborn에 내장된 예제 데이터로 모형을 학습시켜보겠습니다.
import seaborn as sns
seaborn 내장 데이터 중에 titanic 데이터를 사용합니다.
titanic = sns.load_dataset("titanic")
titanic.head()
| survived | pclass | sex | age | sibsp | parch | fare | embarked | class | who | adult_male | deck | embark_town | alive | alone | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 3 | male | 22.0 | 1 | 0 | 7.2500 | S | Third | man | True | NaN | Southampton | no | False |
| 1 | 1 | 1 | female | 38.0 | 1 | 0 | 71.2833 | C | First | woman | False | C | Cherbourg | yes | False |
| 2 | 1 | 3 | female | 26.0 | 0 | 0 | 7.9250 | S | Third | woman | False | NaN | Southampton | yes | True |
| 3 | 1 | 1 | female | 35.0 | 1 | 0 | 53.1000 | S | First | woman | False | C | Southampton | yes | False |
| 4 | 0 | 3 | male | 35.0 | 0 | 0 | 8.0500 | S | Third | man | True | NaN | Southampton | no | True |
titanic 데이터는 타이타닉 호 승객 중 생존자(survived=1)와 사망자(survived=0)에 관한 데이터 입니다.
여기서 survived 변수는 가질 수 있는 값이 0과 1, 두 가지밖에 없습니다. 이런 변수를 이분형(binary) 변수라고 합니다.
선형 모형은 마이너스 무한대에서 플러스 무한대까지 뻗어가는 직선 형태의 출력을 하기 때문에 이분형 변수를 예측하는데 맞지 않습니다. 이때 시그모이드 함수를 활성화 함수로 사용할 수 있습니다.
시그모이드 함수
시그모이드 함수는 다음과 같은 형태의 함수입니다.
시그모이드 함수를 활성화 함수로 사용한다는 것은 선형 모형의 출력을 다시 시그모이드에 입력으로 넣어준다는 것입니다. 그러면 아래처럼 0에서 1까지의 범위로 찌그러지게 됩니다(squashed).
import numpy as np
x = np.linspace(-5.0, 5.0, 100)
y = tf.math.sigmoid(x).numpy()
plt.plot(x, y)
[<matplotlib.lines.Line2D at 0x26530abea48>]
시그모이드 함수의 출력은 y가 1이 될 확률로 해석합니다. 즉, 타이타닉 데이터에서 0.8이 출력되었다면 생존(survived=1)할 확률이 80%라고 해석하는 것입니다.
텐서플로를 이용해 모형 만들기
텐서플로를 이용해서 pclass와 fare를 이용해서 survived를 예측하는 모형을 만들어보겠습니다.
먼저 텐서플로를 임포트합니다.
import tensorflow as tf
텐서플로에서 keras는 다양한 모형을 쉽게 만들 수 있는 방법을 제공합니다. 먼저 Sequential을 이용해 빈 모형을 만듭니다.
model = tf.keras.models.Sequential()
다음으로 레이어를 만듭니다. pclass와 sibsp, parch 3가지 변수를 입력하여 survived 1가지 변수를 예측하므로 Dense의 첫 번째 인자는 1이라고 써줍니다.
입력하는 변수가 3개이므로 input_shape에는 (3, )이라고 해줍니다.
그리고 출력이 0에서 1사이의 범위어야 하므로 활성화 함수(activation)로 시그모이드(sigmoid)를 추가해줍니다. 여기에 대해서는 아래에서 자세히 설명하겠습니다.
layer = tf.keras.layers.Dense(1, input_shape=(3,), activation='sigmoid')
모형에 레이어를 추가합니다.
model.add(layer)
위와 같이 단계를 나누어 하는 대신, 다음과 같이 한 번에 할 수도 있습니다.
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(1, input_shape=(3,), activation='sigmoid')
])
모형 학습
이분형 변수의 경우에는 loss를 binary_crossentropy로 사용합니다.
model.compile(optimizer='adam', loss='binary_crossentropy')
이제 학습을 시켜보겠습니다.
x = titanic[['pclass', 'sibsp', 'parch']].values
y = titanic['survived'].values
history = model.fit(x, y, epochs=30, verbose=0)
학습 과정에서 loss의 감소를 시각화하면 아래 그래프와 같습니다.
import matplotlib.pyplot as plt
plt.plot(history.history['loss'])
[<matplotlib.lines.Line2D at 0x2652bc53288>]
예측
이번에는 실제 데이터로 예측을 해보도록 하겠습니다. 0번 승객은 pclass가 3, sibsp가 1, 그리고 parch가 0입니다.
t = titanic.loc[[0], ['pclass', 'sibsp', 'parch']]
t
| pclass | sibsp | parch | |
|---|---|---|---|
| 0 | 3 | 1 | 0 |
이 승객의 데이터를 모형에 입력하면 약 0.62가 나옵니다. (이 결과는 조금씩 다르게 나올 수 있습니다.) 따라서 이 승객이 생존할 확률은 62%였다라고 해석할 수 있습니다.
model.predict(t.values)
array([[0.62366164]], dtype=float32)