ํด๋น ์ฝ๋์์๋ keras ๋ฐ Tensorflow์์ ์ ๊ณตํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด, ์ฌ์ฉ์์๊ฒ ์๋นํ ํธ๋ฆฌํ๊ฒ ์ ๊ณต๋๋ฏ๋ก, ์์์ ์ธ ๋ถ๋ถ์ ๊ฑฐ์ ์์ต๋๋ค.
๋ํ ์ฝ๋์ ๊ธธ์ด๊ฐ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ฐ ํ์ผ์ importํ๋ ๊ฒ์ ์ ์ธํ๊ณค 10์ค ์ ๋ ์ ๋๋ค.
์ง์ ์์์ ์์ ์์ฑํ๋ค๋ฉด ์๋นํ ๊ธธ์ด์ ธ์ผํ ๋ถ๋ถ๋ค์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ๋งค์ฐ๋งค์ฐ ํธํ๊ฒ ์ฌ์ฉํ ์ ์๊ฒ ๋์์ต๋๋ค.
์ดํ ์ง์ ์์์ ํตํด ์ดํดํ๊ณ , ์ํํ๋ ๊ณผ์ ์ ๋ํด์๋ ๋ค๋ค ๋ณผ ์์ ์ ๋๋ค.
๊ตฌ๊ธ ์ฝ๋ฉ์ ํด๋น ์์ค์ฝ๋๋ฅผ ๋ถ์ฌ ๋ฃ๊ฑฐ๋,
ํด๋น ํ์ผ์ ๋ค์ด๋ฐ์ ์
๋ก๋ ํ์ฌ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๋ณธ๊ฒฉ์ ์ผ๋ก ํ์ ์์ ํ์๊ฐ ์ด์ง ์ฃฝ์์ง ์์ธกํ๋ ๋ชจ๋ธ์ ๋ง๋ค์ด ๋ณด๋๋ก ํ์.
1) ํ์ผ ์ ํ์ ํตํด ์์ ๋ฐ์ดํฐ๋ฅผ ๋ด ์ปดํจํฐ์์ ๋ถ๋ฌ์จ๋ค.
์์ ๋ฐ์ดํฐ๋ CSVํ์ผ ํํ๋ก ๋์ด์๋ค. (github์ ํฌํจ)
from google.colab import files uploaded = files.upload() my_data = 'ThoraricSurgery.csv
2) ๋ฅ๋ฌ๋์ ๊ตฌ๋ํ๋๋ฐ, ํ์ํ ์ผ๋ผ์ค ํจ์ ๋ฐ numpy๋ฅผ ๋ถ๋ฌ์จ๋ค.
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense import pandas as pd import numpy as np import tensorflow as tf
3) ์คํํ ๋๋ง๋ค ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋๋๋ก ํ๊ธฐ ์ํด์ ์๋๋ฅผ ๊ณ ์ ํด์ค๋ค.
np.random.seed(3) tf.random.set_seed(3)
4) ํ์ ๊ธฐ๋ก์ ๋ถ๋ฌ์จ๋ค.
df = pd.read_csv(my_data, header=None) Data_set = df.to_numpy()
ํ์ ๊ธฐ๋ก์ csv ํ์ผ์ ์ดํด๋ณด์.
ํ์ ๊ฐ์๊ฐ ์ด 470๊ฐ ์ฆ, 470๋ช
์ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ๋ค.
์ด์ ๊ฐ์๊ฐ ์ด 18๊ฐ๋ก (1~17)์ ์ข
์์ ์ ํ์ ๋ํ๋ด๋ฉฐ, ๋ง์ง๋ง(18)์ ์์กด์ฌ๋ถ๋ฅผ 1or0์ผ๋ก ๋ํ๋ธ๋ค.
5) ํ์์ ๊ธฐ๋ก๊ณผ ์์ ๊ฒฐ๊ณผ๋ฅผ X์ Y๋ก ๊ตฌ๋ถํ์ฌ ์ ์ฅํ๋ค.
์ฆ, ์
๋ ฅ๋ฐ์ดํฐ(X)์ ๊ฒฐ๊ณผ-์ ๋ต๋ฐ์ดํฐ(Y)๋ก ๊ตฌ๋ถํ๋ค.
X = Data_set[: ,0 :17]
Y = Data_set[: ,17]
X์ :
๋ ํ ์ ์ฒด(๋ชจ๋ ์ผ์ด์ค)๋ฅผ ์๋ฏธํ๊ณ ,
๋ค์ 0:17
์ 0์ ํฌํจํ 17 ์ด์ ๊น์ง์ ์ธ๋ฑ์ค๋ฅผ ๋งํ๋ค. (0~16 ์ด 17๊ฐ)
Y์ :
๋ํ ํ ์ ์ฒด(๋ชจ๋ ์ผ์ด์ค)๋ฅผ ์๋ฏธํ๊ณ , 17์ ์ธ๋ฑ์ค๋ 18๋ฒ์งธ๋ฅผ ์๋ฏธํ๋ค.
(-1์ ์ฐ๋ ๊ฒ๊ณผ ๊ฐ๋ค)
๊ทธ๋ฆผ์ผ๋ก ํํํ๋ค๋ฉด ์๋์ ๊ฐ์ด X(ํ๋), Y(๋
ธ๋)๊ณผ ๊ฐ์ด ๋ถ๋ฅ๋๋ค.
6) ๋ชจ๋ธ์ ์ ์ํ๋ค.
model = Sequential() model.add(Dense(30, input_dim=17, activation='relu')) model.add(Dense(1, activation='sigmoid'))
Sequential() : ๋ชจ๋ธ์ ํ์ ์์ฑํ๋ค.
์ฒซ๋ฒ์งธ add()
add()
: ๊ฐ add ํ๋๋น ์ธต
์ด ํ๋์ฉ ์ถ๊ฐ๋๋ค.Dense
: Fully Connectedํ ๋ฐฉ์์ผ๋ก ์ธต์ ๊ตฌ์ฑํ๋ค๋ ์๋ฏธ์ด๋ค. ํ์ฌ์์ ๋ค์ ๋
ธ๋๋ก์ ์ฐ๊ฒฐ์ด ์์ ํ ์ ๋ถ ์ฐ๊ฒฐ ๋์ด์๋ค๋ ๋ป์ผ๋ก ์ ๋ต์ ๊ฒฐ์ ์ง๋ weight๊ฐ ๋ชจ๋ ์ฐ๊ฒฐ๋ง๋ค ์กด์ฌํ๋ค.input_dim
: ์
๋ ฅ๋๋ feture์ ๊ฐ์๊ฐ ์ด 17๊ฐ์ด๋ฏ๋ก ์
๋ ฅ์ผ๋ก ๋ค์ด์ค๋ ๋
ธ๋์ ๊ฐ์๋ 17๊ฐ์ด๋ค. ๋ฐ๋ผ์ hidden layer์์ ๋ฐ๊ฒ ๋๋ (input_dim)๋ 17์ด๋ค. 30
: hidden layer์ ์ฌ์ฉํ ์ ๋์ ๊ฐ์๋ฅผ ์๋ฏธํ๋ค.activation
: ํ์ฑํจ์. vanishing gradient ๋ฌธ์ ๋ฅผ ๋ฐ์ํ๋ sigmoid๊ฐ ์๋ relu๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค.๋๋ฒ์งธ add()
sigmoid
ํจ์๋ฅผ ์ฌ์ฉํ๋ค.์ธต์ ํ๋ ๋ ์ถ๊ฐํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ดํ ์ ์๋ค. input_dim์ ์ ์ํ์ฌ ๋ณด์.
model = Sequential() model.add(Dense(30, input_dim=17, activation='relu')) model.add(Dense(40, input_dim=30, activation='relu')) model.add(Dense(1, activation='sigmoid'))
7) ๋ชจ๋ธ์ ํ์ตํ๋ค. (๋ฅ๋ฌ๋)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy', tf.ke ras.metrics.Recall()]) model.fit(X, Y, epochs=100, batch_size=10)
loss
: ๋น์ฉํจ์๋ฅผ ์ด๋ค ๊ฑธ๋ก ์ฌ์ฉํ ๊ฒ์ธ๊ฐ?optimizer
: ์ต์ ํ ๋ฐฉ๋ฒ(weight์ update ๋ฐฉ๋ฒ)์ ์ด๋ค ๊ฑธ๋ก ์ฌ์ฉํ ๊ฒ์ธ๊ฐ?metrics
: ๋ชจ๋ธ์ ํ๊ฐํ ๋, ํ๊ฐํ๋ ์งํ๋ก ์ด๋ค ๊ฑธ ๋ณด๊ณ ์ถ์๊ฐ? (์ ํ๋, ์ฌํ์จ, F1์ค์ฝ์ด ๋ฑ..)Fit() : ๋ชจ๋ธ์ ํ์ต์ํจ๋ค.
X
: ํ์ต๋ฐ์ดํฐ
Y
: ์ ๋ต๋ฐ์ดํฐ
(ํ์ต๋ฐ์ดํฐ์ ์ ๋ต์ ๋ชจ๋ธ์๊ฒ ํจ๊ป ์ ๊ณตํ๋ฏ๋ก ์ง๋ํ์ต
์ด๋ค)
epochs
: ๋ชจ๋ ์ํ์ ํตํด ํ์ตํ ๋, ์ด๋ฅผ 1 epoch
์ด๋ผ๊ณ ํ๋ค. ์ด๋ ๋ช๋ฒ ํ์ตํ ๊ฒ์ธ๊ฐ?
batch_size
: ๊ฐ์ค์น๋ฅผ update
ํ๋ ๋ฐฉ๋ฒ์๋ SGD
, BatchGD
๋๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
์ด๋, SGD
๋ผ๋ฉด 1epoch
๋น 470๊ฐ์ ๋ชจ๋ ์ํ๋ง๋ค ๊ฐ์ค์น๊ฐ update
๋๊ฒ ๋๋ค.
BatchGD
๋ผ๋ฉด 1epoch
๋น 470๊ฐ์ ์ํ์ ๋ชจ๋ ๋ฐ์ํ 1๋ฒ์ update
๋ง ์ํํ๊ฒ ๋๋ค.
batch_size
๋ฅผ ์ฌ์ฉ์๊ฐ ์ง์ ์ง์ ํ๋ ์ด๋ฌํ ๋ฐฉ๋ฒ์ด ๋ฐ๋ก mini batch
๋ฐฉ๋ฒ์ด๋ค.์ด๋ค์ ์ค๊ฐ์ง์ ์ ์ฐพ์, ํํํ ๋ฐฉ๋ฒ์ด ๋ฐ๋ก mini_batch
์ด๋ค. ์ด๋ฌํ batch_size
๋ฅผ ์ง์ ํจ์ผ๋ก์จ mini_batch
๋ฅผ ์ํํ ์ ์๋ค.
์์ ์์๋ batch_size
๊ฐ 10์ด๋ฏ๋ก ์ด 470๊ฐ์ ์ํ์ด ์์ ๋, 1 epoch
๋ง๋ค 47๋ฒ์ update
๊ฐ ์ํ๋๊ฒ ๋๋ค.
์ค์ฐจ๊ฐ ๊ฝค๋ ํฌ๊ฒ ๋์๋ค. ์ด๋ฅผ ์ค์ด๊ธฐ ์ํด์ ์ธต์ ๋ ์๊ฑฐ๋, batch_size๋ฅผ ๋ค๋ฅด๊ฒ ์กฐ์ ํ๊ฑฐ๋, optimizer๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋, optimizer์ ๋ด๋ถ lr๋ฅผ ์กฐ์ ํ๋ ๋ฑ ์ฌ๋ฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ณ๊ฒฝํด๋ณด๊ณ ์๋ํด๋ณด๋ฉด ๋๋ค. ์ด๋ฌํ ์ต์ ์ ๊ฐ์ ์ฐพ๋ ๊ฒ์ด ๋ฅ๋ฌ๋์ด๋ค.
๋น์ฉํจ์๋ ์ฌ์ค ๊ฑฐ์ ๊ณ ์ ์ ์ด๋ค.
ํ๊ท์ ๋ถ๋ฅ์ ๋ฐ๋ผ ์ฌ์ฉ๋๋ ๋น์ฉํจ์๊ฐ ๋ค๋ฅด๊ธฐ์, ๋ณ๊ฒฝํ ์ผ์ด ์ ์๋ค.
์ด๋ฒ ๋ฌธ์ ์์๋ (์์กด/์ฌ๋ง)์ ์ด์ง ๋ถ๋ฅ ๋ฌธ์ ์ด๋ฏ๋ก logistic(sigmoid)์ ํํํ๋ ์ค์ฐจ ํจ์์ธ binary_crossentropy๋ฅผ ์ฌ์ฉํ๋ค.
์ด๋ฌํ ์ฌ์ฉ์ ๋ํด์๋ logistic regression์ ์ฐธ๊ณ ํ๋ฉด ์ฝ๊ฒ ์ดํด๋ ๊ฒ์ด๋ค.
์ต์ ํ๋ ๊ฒฐ๊ตญ, ๊ฒฝ์ฌ ํ๊ฐ๋ฒ์ ํตํ weight๊ฐ์ update๋ฅผ ๋ปํ๋ค.
๋๋ถ๋ถ์ ๋ชจ๋ธ์ ์ต์ ํ๋ ๊ฑฐ์ ๊ณ ์ ์ ์ผ๋ก adam์ ์ฌ์ฉํ๋ค. ์ด๊ฒ ๊ฐ์ฅ ์๋๋ ๋ฌด๋ํ๊ณ ๊ฒฐ๊ณผ๋ ์ข๋ค๊ณ ํ๋ค.
์ด์ธ์๋ ์ฌ๋ฌ ์ต์ ํ ํจ์๋ค์ด ์๋ค. ํ๋ฒ ์ฌ์ฉํด ๋ณด๋ ๊ฒ๋ ์ข์ ๊ฒ ๊ฐ๋ค.
์ต์ ํ ํจ์์ ์ด๋ฆ๋ง ๋ค๊ณ ์์ ๊ทธ๋๋ก default ๊ฐ์ ์ต์ ํ ํจ์๋ฅผ ์ฌ์ฉํ ์๋ ์์ง๋ง, ์ง์ ์ต์ ํ ํจ์์์์ ๋ด๋ถ์ ํ๋(?)๋ํ ๊ฐ๋ฅํ๋ค.
(ํ์๊ฐ ํด๋ณธ ๋ฐ๋ก๋ ๋ช๋ช ์ข
๋ฅ์ ํ์ต์ ์ง์ ์ต์ ํ ํจ์๋ฅผ ์ ์ํด์ ๋ด๋ถ ํ๋? ๋ํ ์์ผ์ฃผ์ด์ผ ์ ๋๋ก๋ ํ์ต์ด ์ด๋ฃจ์ด์ง๋ ๊ฒฝ์ฐ๋ ์ข
์ข
์์๋ค.)
# ๊ธฐ์กด์ ๋ฐฉ๋ฒ model.compile(loss='mean_squared_error', optimizer='sgd') # ์ง์ ์ต์ ํ ํจ์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ์ฌ์ฉ sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True) model.compile(loss='mean_squared_error', optimizer=sgd)
SGD
๋ผ๊ณ ํด์, ๋ง์ฝ sample ๋ฐ์ดํฐ 100๊ฐ๊ฐ ์์ ๋, ๋ง๋ฅ sample์ ์์๋๋ก 1, 2, 3,, 100 ๋ฒ์งธ sample์ ์์๋๋ก ์ฐจ๋ก ์ฐจ๋ก ๊ฐ์ค์น๋ฅผ update
์ํค๋ ๊ฒ์ ์๋๋ค.
58, 92, 3, 64, 18, 23 ,... ์ด๋ฐ ์์ ๋ฌด์์ ์์๋ก ์ํ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ update
๋ฅผ ์ํํ๊ฒ ๋๋ค.
๊ทธ๋ ๊ธฐ์ Stochastic Gradient Descent์ด๋ค.