[AIVLE] 딥러닝 4일차 - multi input
AIVLE
2023. 3. 3. 17:18
Connection / Add 다르게 해서 모델 설계하기
약간 multi-task learning이랑 비슷해보여서 헷갈렸는데, Iris 데이터를 보면 sepal length / sepal width / petal length / petal width가 있다. length는 length 끼리 묶고, width는 width끼리 묶어서 모델에게 넣어주고 마지막에 모델을 붙여보자.
데이터 불러오기
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow import keras
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target
df = pd.DataFrame(x, columns=iris.feature_names)
train_test_split으로 데이터를 구분해주자.
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(df, y, test_size=0.2, random_state=23)
length / width 나누기 (1) - concat 사용
print(df.columns) # Index(['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'], dtype='object')
# loc을 사용하여 나눠준다.
x_train_length = x_train.loc[:, ['sepal length (cm)', 'petal length (cm)'] ]
x_train_width = x_train.loc[:, ['sepal width (cm)', 'petal width (cm)'] ]
x_test_length = x_test.loc[:, ['sepal length (cm)', 'petal length (cm)'] ]
x_test_width = x_test.loc[:, ['sepal width (cm)', 'petal width (cm)'] ]
One - hot Encoding
from tensorflow.keras.utils import to_categorical
y_train = to_categorical(y_train, 3)
y_test = to_categorical(y_test, 3)
Modeling
from tensorflow.keras.backend import clear_session
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Concatenate
from tensorflow.keras.activations import relu, softmax
from tensorflow.keras.losses import categorical_crossentropy
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.utils import plot_model
이번에는 싹다 import로 불러와서 써줄거다.
clear_session()
input_layer_length = Input(shape = (2,))
hidden_layer_length = Dense(2, activation = relu)(input_layer_length)
input_layer_width = Input(shape = (2,))
hidden_layer_width = Dense(2, activation = relu)(input_layer_width)
concat = Concatenate()([hidden_layer_length, hidden_layer_width])
output_layer = Dense(3, activation = softmax)(concat)
model = Model([input_layer_length, input_layer_width], output_layer)
model.compile(loss = categorical_crossentropy, metrics = ['accuracy'], optimizer = Adam())
모델 시각화 - plot_model()
모델을 간단한 코드로 시각화 할 수 있다.
plot_model(model, show_shapes=True)
학습
es = EarlyStopping(monitor = 'val_loss', min_delta = 0, patience = 30, verbose = 1,
restore_best_weights = True)
hist = model.fit([x_train_length, x_train_width], y_train, validation_split = 0.15,
epochs = 1000, verbose = 1, callbacks = [es])
결과 시각화는 다음과 같다.
import matplotlib.pyplot as plt
plt.plot(hist.history['loss'], 'y', label = 'train loss')
plt.plot(hist.history['val_loss'], 'r', label = 'val loss')
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(loc = 'upper left')
plt.show()
Petal / Sepal 나누기 (2) - add 사용
x_train_s = x_train.loc[:, ['sepal length (cm)', 'sepal width (cm)']]
x_train_p = x_train.loc[:, ['petal length (cm)', 'petal width (cm)' ]]
x_test_s = x_test.loc[:, ['sepal length (cm)', 'sepal width (cm)']]
x_test_p = x_test.loc[:, ['petal length (cm)', 'petal width (cm)'] ]
one hot encoding 등은 위와 똑같으므로 생략
Modeling
clear_session()
il_s = Input(shape = (2,))
hl_s_1 = Dense(4, activation = relu)(il_s)
il_p = Input(shape = (2, ))
hl_p_1 = Dense(4, activation = relu)(il_p)
add = keras.layers.Add()([hl_s_1, hl_p_1])
ol = Dense(3, activation = softmax)(add)
model = Model([il_s, il_p], ol)
model.compile(loss = categorical_crossentropy, metrics = ['accuracy'], optimizer = Adam())
plot_model(model, show_shapes = True)
의도했던 모양이면 된다.
학습 방식도 똑같고, 결과만 첨부하겠다.
유방암 데이터
알아서 csv 읽어오고, 데이터프레임 상에서 데이터를 다뤄보자.
import pandas as pd
import numpy as np
data = pd.read_csv('path')
전처리
나는 좀 원시적인.. 방법으로 데이터를 죄다 나눴는데, 더 좋은 방법이 있으면 그걸로 하는게 나을 것 같다.
x = data.drop('target', axis = 1)
y = data.loc[:, 'target']
x = x.astype(np.float32) # 오류나서 쓴거 오류 안나면 안써도됨
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, random_state = 7)
radius = x_train.iloc[:, [0, 10, 20]]
texture = x_train.iloc[:, [1, 11, 21]]
perimeter = x_train.iloc[:, [2, 12, 22]]
area = x_train.iloc[:, [3, 13, 23]]
smooth = x_train.iloc[:,[4, 14, 24]]
compact = x_train.iloc[:, [5, 15, 25]]
concav = x_train.iloc[:, [6, 16, 26]]
cpoint = x_train.iloc[:, [7, 17, 27]]
sym = x_train.iloc[:, [8, 18, 28]]
dim = x_train.iloc[:, [9, 19, 29]]
tradius = x_test.iloc[:, [0, 10, 20]]
ttexture = x_test.iloc[:, [1, 11, 21]]
tperimeter = x_test.iloc[:, [2, 12, 22]]
tarea = x_test.iloc[:, [3, 13, 23]]
tsmooth = x_test.iloc[:,[4, 14, 24]]
tcompact = x_test.iloc[:, [5, 15, 25]]
tconcav = x_test.iloc[:, [6, 16, 26]]
tcpoint = x_test.iloc[:, [7, 17, 27]]
tsym = x_test.iloc[:, [8, 18, 28]]
tdim = x_test.iloc[:, [9, 19, 29]]
inputs = [radius, texture, perimeter, area, smooth, compact, concav, cpoint, sym, dim, x_train]
y_train도 라벨링을 해준다. loc 활용했다.
y_train.loc[y_train == 'Malignant'] = 1
y_train.loc[y_train == 'Benign'] = 0
y_test.loc[y_test == 'Malignant'] = 1
y_test.loc[y_test == 'Benign'] = 0
y_train = y_train.astype(np.float32)
...이런 구조의 모델을 만들건데, 한숨만 나오긴 하지만 어쨌든 해냈다.
from tensorflow.keras.backend import clear_session
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Concatenate, Add
from tensorflow.keras.activations import relu, softmax, sigmoid
from tensorflow.keras.losses import categorical_crossentropy, binary_crossentropy
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.utils import plot_model
필요한거 불러와주고,
clear_session()
il_0 = Input(shape = (3, ))
il_1 = Input(shape = (3, ))
il_2 = Input(shape = (3, ))
il_3 = Input(shape = (3, ))
il_4 = Input(shape = (3, ))
il_5 = Input(shape = (3, ))
il_6 = Input(shape = (3, ))
il_7 = Input(shape = (3, ))
il_8 = Input(shape = (3, ))
il_9 = Input(shape = (3, ))
hl_0 = Dense(12, activation = relu)(il_0)
hl_1 = Dense(12, activation = relu)(il_1)
hl_2 = Dense(12, activation = relu)(il_2)
hl_3 = Dense(12, activation = relu)(il_3)
hl_4 = Dense(12, activation = relu)(il_4)
hl_5 = Dense(12, activation = relu)(il_5)
hl_6 = Dense(12, activation = relu)(il_6)
hl_7 = Dense(12, activation = relu)(il_7)
hl_8 = Dense(12, activation = relu)(il_8)
hl_9 = Dense(12, activation = relu)(il_9)
add = Add()([hl_0, hl_1, hl_2, hl_3, hl_4, hl_5, hl_6, hl_7, hl_8, hl_9])
#4
input_layer = Input(shape = (30, ))
con = Concatenate()([input_layer, add])
hidden = Dense(128, activation = relu)(con)
ol = Dense(1, activation = sigmoid)(hidden)
model = Model([il_0, il_1, il_2, il_3, il_4, il_5, il_6, il_7, il_8, il_9, input_layer], ol)
model.compile(loss = binary_crossentropy, metrics = ['accuracy'], optimizer = Adam())
학습
es = EarlyStopping(monitor = 'val_loss', min_delta = 0, patience = 30, verbose = 1,
restore_best_weights = True)
hist = model.fit(inputs, y_train, validation_split= 0.2, epochs = 1000, verbose = 1, callbacks = [es])
결과 보면 꽤 잘 분류한다. 하지만 1(유방암)인 것을 아니라고(0으로) 조금이라도 분류하는 모델은 좋다고 할 수 없을 것 같다.
'AIVLE' 카테고리의 다른 글
[AIVLE] 딥러닝 3일차(CIFAR) + Functional API (1) | 2023.03.02 |
---|---|
[AIVLE] 딥러닝 2일차 (0) | 2023.02.28 |
[AIVLE] 딥러닝 - keras 기초 (0) | 2023.02.27 |
[AIVLE] 머신러닝 (0) | 2023.02.24 |
[KT AIVLE 3기] 이변량분석 (0) | 2023.02.10 |