[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 |