뉴럴 네트워크에서 Manifold가 어떤 연관이 있는지 찾아보면서 이해한 부분에 대해 정리해본다.
(여러 정보들을 살펴보며 나의 이해를 기준으로 정리하였기 때문에 잘못된 내용이 들어가있을 수도 있으니 너무 믿지는 말것)
Manifold
매니폴드 가설(manifold hypothesis)은 고차원의 데이터가 사실은 더 낮은 차원의 구조인 매니폴드(manifold) 위에 있다고 주장하는 가설이다.
딥러닝 모델은 학습을 통해 주어진 데이터에 대한 잠재 매니폴드(latent manifold)를 학습하여 데이터의 본질적인 특성을 이해할 수 있게된다. (manifold learning)
매니폴드를 설명할 때 가장 많이 나오는 스위스 롤 형태의 데이터를 예로 설명하면,
3차원으로 복잡하게 표현되어있는 데이터가 아래와 같이 2차원의 데이터로 표현될 수 있다.
만약 데이터 A와 데이터 B 사이를 보간(interpolation)한다면,
3차원 상의 A와 B의 위치 사이를 보간하는 것보다는
2차원의 매니폴드 상의 A와 B 사이를 보간하는 것이 해당 데이터의 본질에서 보다 적절한 방법일 것이다.
MNIST 데이터에 대해 2와 0 사이를 보간하는 경우에 대해 얘기해보자면
- 1)과 같이 매니폴드를 기준으로 보간하면 6이 나오는 것을 볼 수 있다.
이는 잠재 매니폴드 상에서 2에 대한 데이터와 0 데이터 사이에 6에 대한 데이터가 존재한다고 볼 수 있다.
(물론 매니폴드의 형태가 다르면 이렇게 나오지 않을 수 있다) - 하지만 2)와 같이 픽셀 값의 평균을 사용하여 보간(linear interpolation)을 하면 명확하지 않은 형태의 수가 나와 적절하게 보간되지 않았다고 볼 수 있을 것이다.
Neural network 학습의 기하학적 의미
Neural network에서 각 layer에서 linear transformation과 non-linear transformation를 순차적으로 거치게 된다.
이 과정을 한 스텝 씩 살펴보기 위해 아래 영상을 참고하자.
https://www.youtube.com/watch?v=CfAL_cL3SGQ&t=264s
살펴본 것 처럼 Neural network는 non-linear transformation를 통해서, 선형으로는 분리가 되지 않는 데이터도 분리가 가능해지게 된다.
(출처: https://srome.github.io/Visualizing-the-Learning-of-a-Neural-Network-Geometrically)
실제로 아래와 같은 데이터에 대해 2진 분류하는 모델을 만들어 학습을 진행하였을 때
from sklearn.datasets import make_circles
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
X, y = make_circles(n_samples=1000, factor=0.5, noise=0.1, random_state=42)
y = tf.keras.utils.to_categorical(y)
def plot_data(X, y):
plt.scatter(X[:, 0], X[:, 1], c=np.argmax(y, axis=1), cmap=plt.cm.Spectral)
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()
plot_data(X, y)
학습이 진행됨에 따라 다음과 같이 출력 이전의 데이터가 점점 명확하게 경계가 생기는 형태로 변해가는 것을 확인할 수 있었다.
(항상 아래와 같은 데이터 형태가 나오는 것은 아니다)
from tensorflow.keras import layers
from tensorflow.keras import models
# define model
def get_model():
inputs = layers.Input(shape=(2,))
X = layers.Dense(16, activation="relu", name="hidden_1")(inputs)
X = layers.Dense(2, activation="relu", name="hidden_2")(X)
outputs = layers.Dense(2, activation="softmax", name="output")(X)
return models.Model(inputs, outputs)
model = get_model()
model.compile(optimizer="adam",
loss="categorical_crossentropy",
metrics=["accuracy"])
# train
def get_data_before_output(X):
X = model.layers[1](X)
X = model.layers[2](X)
return X
for epoch in range(50):
model.fit(X, y, epochs=1)
if epoch % 3 == 0:
plot_data(get_data_before_output(X), y)
plt.show()
이러한 딥러닝 모델의 학습의 과정은 모델이 학습을 통해 잠재 매니폴드를 학습해가는 과정으로 볼 수 있다.
- 추가) 나선 형태의 데이터를 분류 모델로 학습한 예제
import numpy as np
import matplotlib.pyplot as plt
from keras.utils import to_categorical
def create_spiral_data(points, classes):
X = np.zeros((points * classes, 2)) # 데이터 포인트를 담을 배열
y = np.zeros(points * classes, dtype='uint8') # 레이블을 담을 배열
for class_number in range(classes):
ix = range(points * class_number, points * (class_number + 1))
r = np.linspace(0.0, 1, points) # 반경
t = np.linspace(class_number * 4, (class_number + 1) * 4, points) + np.random.randn(points) * 0.2 # theta
X[ix] = np.c_[r * np.sin(t), r * np.cos(t)]
y[ix] = class_number
return X, y
# 데이터 생성
X, y = create_spiral_data(500, 3)
y = to_categorical(y)
def plot_data(X, y):
plt.scatter(X[:, 0], X[:, 1], c=np.argmax(y, axis=1), cmap=plt.cm.Spectral)
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()
plot_data(X, y)
plt.show()
from tensorflow.keras import layers, models
# define model
def get_model():
inputs = layers.Input(shape=(2,))
X = layers.Dense(32, activation="relu", name="hidden_1")(inputs)
X = layers.Dense(3, activation="relu", name="hidden_2")(X)
outputs = layers.Dense(3, activation="softmax", name="output")(X)
return models.Model(inputs, outputs)
model = get_model()
model.compile(optimizer="adam",
loss="categorical_crossentropy",
metrics=["accuracy"])
model.summary()
# train
def get_data_before_output(X):
X = model.layers[1](X)
X = model.layers[2](X)
return X
for epoch in range(100):
model.fit(X, y, epochs=1)
if epoch % 3 == 0:
plot_data(get_data_before_output(X), y)
plt.show()
참고
'Machine Learning > Deep Learning' 카테고리의 다른 글
CNN에서 layer가 깊어질 수록 channel size를 키우는 이유 (0) | 2024.05.31 |
---|---|
Dropout vs Inverted Dropout (0) | 2024.05.21 |
Non zero-centered activation function과 학습 비효율 (1) | 2024.05.01 |
ReLU의 활성 함수으로써의 사용과 미분 가능성 (0) | 2024.04.23 |
Perceptron (0) | 2024.03.03 |
댓글