[ 배운 내용 ]
1. 실습
- 캘리포니아 주택, 와인 데이터 실습
2. Connection
- Locally Connected - Concatenate
- Locally Connected - Add
Connection
딥러닝의 내부에서 어떤 동작이 이루어지는지는 사실 우리가 정확하게 알 수 없다. 이 때문에 딥러닝은 Black Box 구조를 갖고 있다고도 한다. 이를 설명하기 위해 노력하는 Explainable AI라는 학문도 있다고 한다.
하지만 딥러닝의 Artificial Neural Network구조에서 연결을 어떻게 하느냐에 따라서는 우리가 해석을 시도해 볼 여지가 있다
iris 데이터를 예시로 살펴보자
이전에 해본 모델링은 인풋, 아웃풋, 히든레이어의 모든 노드들이 서로 연결된 Fully Connected Multi Layer Perceptron 구조로 되어 있었다.
위의 그림 같은 경우는 4개의 인풋 feature들을 모두 연결해서 4개의 새로운 feature를 만들어냈다.
하지만 만약에 sepal, petal이라는 부위에 대한 정보 없이 length, width의 정보만 갖고 있어도 분류가 잘 되지 않을까? 라고 생각을 해보게 된다면 어떨까? 이렇게 된다면 기존 머신러닝에서 하던 feature engineering 시에는 sepal과 petal의 length와 width 관련 feature들을 사용해서 새로운 feature를 만들어냈을 것이다.
딥러닝에서도 비슷하게 모델링이 가능하다. length와 width끼리만 각각 묶어서 새로 feature를 만들어주는 것이다.
아래 그림을 보면 Sepal과 Petal의 Length 관련 feature와 Width 관련 feature들만 사용해서 각각 2개의 feature들을 새로 만들어주고, 이 feature들을 합쳐서 아웃풋 레이어에 연결해주었다.
새로 만들어지는 feature가 정확히 무엇을 의미하는 feature인지는 모르지만 어쨌든 length, width와 관련된 새로운 feature가 생겼다고 치는 것이다.
이러한 모델링이 실제로 우리가 의도한대로 feature를 만든건지는 모르지만 일단 우리의 의도를 믿고 모델링 해보는 것이다. 성능 역시 모델을 돌려봐야 알 것이다.
이렇게 하는 이유는 모델링할 때, 일단 사람의 의도를 반영해서 노드의 연결을 제어하여 추상적으로라도 해석을 시도해 보는 것이다.
지금까지 설명한 바와 같이 인풋(노드)을 따로 분리해서 국소적으로 각각을 연결한 히든 레이어의 노드들을 새로운 feature로 사용하는 방식을 Locally Connected 라고 한다.
위의 그림의 경우는 국소적으로 연결된 length, width로부터 생성된 각각의 새로운 high-level feature들의 각 노드값을 그대로 살린 채로 합쳐서(concat) 다시 fully connected로 연결해주는 방식인데, 모델링 시에 Concatenate() 라는 함수로 구현이 가능하다.
Concatenate와는 약간 다른 방식으로 Add() 라는 함수도 사용이 가능하다.
아래 그림을 보면 length, width를 각각 locally connected하게 연결해서 4개의 high-level feature들을 만들었다.
이 때, length, width 각각의 high-level feature들 간에 같은 자리에 위치한 노드들은 유사한 특징을 가지고 있다고 보고 feature들의 값을 element-wise하게 더해주는 방식이 Add이다.
이제 다음의 두 가지 방식으로 Locally connected하게 연결하여 모델링을 직접 해보자.
- Concatenate()
- Add()
Locally Connected - Concatenate()
- iris 데이터 불러오기
from sklearn.datasets import load_iris
iris = load_iris()
x = iris.data
y = iris.target
x = pd.DataFrame(x, columns=iris.feature_names)
x.head() # feature를 갖고오기 용이하도록 데이터프레임으로 변환
아래와 같이 train, test set을 분리해주었다 (코드는 생략)
train_x.shape, train_y.shape, test_x.shape, test_y.shape
# ((135, 4), (135,), (15, 4), (15,))
[ length, width별로 x데이터 따로 분리 ]
length와 width가 따로 사용되기 때문에 train과 test 데이터를 length, width로 분리해준다.
이후 target 데이터의 one-hot encoding도 수행해준다. (코드는 생략)
# 칼럼 이름 확인
print(x.columns)
# Index(['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)',
# 'petal width (cm)'],
# dtype='object')
train_x_l = train_x.loc[:, ['sepal length (cm)', 'petal length (cm)'] ] # length끼리
train_x_w = train_x.loc[:, ['sepal width (cm)', 'petal width (cm)'] ] # width끼리
test_x_l = test_x.loc[:, ['sepal length (cm)', 'petal length (cm)'] ]
test_x_w = test_x.loc[:, ['sepal width (cm)', 'petal width (cm)'] ]
train_x_l.shape, train_x_w.shape
((135, 2), (135, 2))
[ 모델링 - Concatenate layer ]
Locally connectec 방식의 모델링을 할 때에는 Functional 방식으로 모델링 해야 한다.
Sequential 방식의 경우에는 만들어주는 레이어들을 모두 순차적으로 이어주기 때문이다.
- tensorflow.keras.layers에서 Input, Dense 말고도, Concatenate를 임포트 해준다.
- tensorflow.keras.utils의 plot_model을 사용하면 모델의 구조를 시각화해서 확인해볼 수 있다.
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
- length와 width 인풋 레이어와 각각의 히든 레이어 계층들을 따로 연결해준다.
- Concatenate()를 사용해서 각각의 히든 레이어 계층들을 묶어주는데, 리스트 형태로 넣어주어야 한다.
- 모델의 시작과 끝 레이어를 지정할 때에서 시작 인풋 레이어가 length, width로 두개라서 리스트로 묶어준다.
# 1. 세션 클리어
clear_session()
# 2. 레이어 사슬처럼 엮기 : input 2개
il_l = Input( shape=(2,) )
hl_l = Dense(2, activation=relu)(il_l)
il_w = Input( shape=(2,) )
hl_w = Dense(2, activation=relu)(il_w)
cl = Concatenate()([hl_l, hl_w]) # 리스트 형태로 넣어준다.
ol = Dense(3, activation=softmax)(cl)
# 3. 모델 시작과 끝 지정
model = Model([il_l, il_w], ol) # 인풋 레이어를 리스트로
# 4. 모델 컴파일
model.compile(loss=categorical_crossentropy, metrics=['accuracy'],
optimizer=Adam())
model.summary()
input 계층이 각각 들어갔다가 히든 레이어들이 마지막에 concat 되는 것을 볼 수 있다.
[ 모델 시각화 ]
plot_model()을 사용해서 모델을 시각화 해볼 수 있다.
plot_model(model, show_shapes=True)
이후 학습 과정 코드는 생략함
Locally Connected - Add()
다른 코드들은 Conocatenate와 동일하니 모델링 코드만 확인해보자
이번에는 length, width가 아니라 sepal, petal 별로 인풋을 나눠주었다.
- Concatenate와 똑같이 tensorflow.keras.layers에서 Add()를 임포트해준다.
from tensorflow.keras.backend import clear_session
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Input, Dense, Add, Concatenate
- Add() 계층에서는 element-wise로 노드값들을 더해주기 때문에, 각 인풋들의 shape는 동일해야 한다.
# 1. 세션 클리어
clear_session()
# 2. 레이어 연결
il_sepal = Input(shape=(2,), name='Input_sepal')
hl_sepal = Dense(4, activation='swish', name='Hidden_sepal')(il_sepal)
il_petal = Input(shape=(2,), name='Input_petal')
hl_petal = Dense(4, activation='swish', name='Hidden_petal')(il_petal)
al = Add(name='Add_layer')([hl_sepal, hl_petal]) # element-wise로 더해주기 때문에 레이어 간 노드 수의 짝이 맞아야 한다.
ol = Dense(3, activation='softmax', name='Output_layer')(al)
# 3. 모델의 시작과 끝 지정
model = Model([il_sepal, il_petal], ol)
# 4. 컴파일
model.compile(loss=keras.losses.categorical_crossentropy, metrics=['accuracy'],
optimizer=keras.optimizers.Adam())
# 모델링 정보 확인
model.summary()
- 모델 시각화
from tensorflow.keras.utils import plot_model
plot_model(model, show_shapes=True)
만약에 이렇게 나만의 가설을 설정해서 high-level feature가 생성되는 과정을 추측해보고 모델링 해보았을 때, 성능이 잘 나오지 않았다면 이렇게 모델 구조를 짠 본인의 의도가 좋지 않았다고 볼 수 있기 때문에 다른 방식으로 모델링을 시도해볼 필요가 있다.
'KT AIVLE School' 카테고리의 다른 글
(10주차 - 22.09.20~21) 시각지능딥러닝2 - Object Detection (YOLO) (0) | 2022.09.22 |
---|---|
(10주차 - 22.09.19) 시각지능딥러닝1 - BatchNormalization, Dropout, Conputer Vision (CNN) (0) | 2022.09.20 |
(9주차 - 22.09.15) 딥러닝3 - 이미지(비정형)데이터 분류 (ANN 방식) (0) | 2022.09.16 |
(9주차 - 22.09.14) 딥러닝2 - 히든레이어 (0) | 2022.09.15 |
(9주차 - 22.09.13) 딥러닝1 - Tensorflow + Keras (선형회귀, 로지스틱회귀, 멀티클래스분류) (0) | 2022.09.13 |