자기 조직화 지도(Self-Organizing Map, SOM)은 비선형 차원 축소 및 데이터 군집화에 사용되는 비지도 학습 알고리즘입니다. 이 강좌에서는 SOM의 기본 개념, 작동 원리, 그리고 파이토치를 사용한 구현 방법에 대해 설명하겠습니다.
자기 조직화 지도(SOM)란?
자기 조직화 지도는 원래 Teuvo Kohonen에 의해 개발된 신경망입니다. SOM은 고차원 데이터를 저차원 공간(일반적으로 2D 격자)으로 매핑하는 데 사용됩니다. 이 과정에서 데이터가 유사한 특성을 가진 이웃 노드들로 구성된 지도 형태로 조직됩니다.
SOM의 주요 특징
- 비지도 학습: 레이블이 없는 데이터를 처리할 수 있습니다.
- 차원 축소: 데이터의 중요한 특성을 유지하면서 고차원 데이터를 저차원으로 축소합니다.
- 군집화: 비슷한 데이터 포인트가 같은 지역에 그룹화됩니다.
SOM의 작동 원리
SOM은 입력 벡터와 노드 벡터 간의 거리를 계산하여 학습을 진행합니다. 다음은 SOM의 일반적인 학습 단계입니다:
1. 초기화
모든 노드는 랜덤하게 초기화됩니다. 각 노드는 입력 데이터와 동일한 차원의 가중치 벡터를 가집니다.
2. 입력 데이터 선택
훈련 샘플을 랜덤하게 선택합니다. 각 샘플은 SOM의 입력이 됩니다.
3. 가장 가까운 노드 찾기
선택된 입력 데이터와 가장 유사한 노드를 찾습니다. 이 노드를 베스트 매칭 유닛(BMU)라고 합니다.
4. 가중치 업데이트
BMU와 그의 이웃 노드들의 가중치를 업데이트하여 입력 데이터에 더 가까워지도록 조정합니다. 이 과정은 다음과 같습니다:
w_{i}(t+1) = w_{i}(t) + α(t) * h_{i,j}(t) * (x(t) - w_{i}(t))
여기서:
w_{i}
: 노드의 가중치 벡터α(t)
: 학습률h_{i,j}(t)
: BMU에 대한 노드i
의 이웃 함수x(t)
: 입력 벡터
5. 반복
2-4단계를 충분한 수의 에포크(epoch) 동안 반복하여 가중치를 점진적으로 업데이트합니다.
파이토치를 이용한 SOM 구현
이제 파이토치를 사용하여 SOM을 구현해 보겠습니다. 여기에서는 기본적인 SOM을 구축하고 시각화하는 과정을 보여드립니다.
필요한 라이브러리 설치
먼저 필요한 라이브러리를 설치합니다.
!pip install torch numpy matplotlib
모델 클래스 정의
다음으로, SOM 클래스를 정의합니다. 이 클래스는 가중치 초기화, BMU 찾기, 가중치 업데이트 기능을 포함합니다.
import numpy as np
import torch
class SelfOrganizingMap:
def __init__(self, m, n, input_dim, learning_rate=0.5, sigma=None):
self.m = m # grid rows
self.n = n # grid columns
self.input_dim = input_dim
self.learning_rate = learning_rate
self.sigma = sigma if sigma else max(m, n) / 2
# Initialize weight vectors
self.weights = torch.rand(m, n, input_dim)
def find_bmu(self, x):
distances = torch.sqrt(torch.sum((self.weights - x) ** 2, dim=2))
bmu_index = torch.argmin(distances)
return bmu_index // self.n, bmu_index % self.n # return row, column
def update_weights(self, x, bmu, iteration):
learning_rate = self.learning_rate * np.exp(-iteration / 100)
sigma = self.sigma * np.exp(-iteration / 100)
for i in range(self.m):
for j in range(self.n):
h = self.neighbourhood(bmu, (i, j), sigma)
self.weights[i, j] += learning_rate * h * (x - self.weights[i, j])
def neighbourhood(self, bmu, point, sigma):
distance = np.sqrt((bmu[0] - point[0]) ** 2 + (bmu[1] - point[1]) ** 2)
return np.exp(-distance ** 2 / (2 * sigma ** 2))
def train(self, data, num_iterations):
for i in range(num_iterations):
for x in data:
bmu = self.find_bmu(x)
self.update_weights(x, bmu, i)
데이터 준비 및 모델 훈련
적절한 데이터를 준비하고 SOM 모델을 훈련시키겠습니다. 여기서는 랜덤하게 생성한 데이터를 사용할 것입니다.
# Generate random data
data = torch.rand(200, 3) # 200 samples, 3 dimensions
# Create and train SOM
som = SelfOrganizingMap(10, 10, 3)
som.train(data, 100)
결과 시각화
훈련된 SOM의 가중치를 시각화하여 데이터의 분포를 확인해보겠습니다.
import matplotlib.pyplot as plt
def plot_som(som):
plt.figure(figsize=(8, 8))
for i in range(som.m):
for j in range(som.n):
plt.scatter(som.weights[i, j, 0].item(), som.weights[i, j, 1].item(), c='blue')
plt.title('Self Organizing Map')
plt.xlabel('Dimension 1')
plt.ylabel('Dimension 2')
plt.show()
plot_som(som)
결론
이 강좌에서는 자기 조직화 지도(SOM)의 기본 원리와 파이토치를 통해 SOM을 구현하는 방법을 살펴보았습니다. SOM은 효과적인 비지도 학습 기법으로, 데이터의 패턴을 파악하고 군집화를 수행하는 데 유용합니다. 앞으로는 보다 복잡한 데이터셋에서 SOM의 활용을 실험해보거나, 최적화 기법을 적용하여 학습 성능을 향상시킬 수 있습니다.
이 글이 딥러닝의 세계를 탐험하는 데 도움이 되었기를 바랍니다! 질문이나 피드백이 있다면 댓글로 남겨주세요.