목록으로
Chapter 8: AI/ML 응용
진행률: 8 / 8
예상 시간: 25분난이도: 중급
AI/ML 응용
학습 목표
- 신경망에서의 행렬 연산 이해
- 역전파 알고리즘의 수학적 기초
- 최적화와 텐서 연산
신경망과 행렬 연산
순전파 (Forward Pass)
z = Wx + b
a = σ(z)
W: 가중치 행렬, x: 입력, b: 편향, σ: 활성화 함수
배치 처리
X: (배치크기 × 특징수)
병렬 처리로 효율성 극대화
GPU 최적화
행렬 곱셈의 병렬화
CUDA/cuBLAS 활용
역전파와 경사하강법
체인 룰
∂L/∂W = ∂L/∂z · ∂z/∂W = δ · x^T
SGD
W = W - η∇W
Adam
적응적 학습률
RMSprop
기울기 제곱 평균
주요 ML 알고리즘의 선형대수
PCA (주성분 분석)
- • 공분산 행렬 계산
- • 고유값 분해
- • 차원 축소
SVM (서포트 벡터 머신)
- • 커널 트릭 (내적 계산)
- • 이차 계획법
- • 라그랑주 승수
선형 회귀
- • 정규방정식: (X^TX)^(-1)X^Ty
- • QR 분해 활용
- • Ridge/Lasso 정규화
Word2Vec
- • 단어 임베딩 행렬
- • 내적을 통한 유사도
- • SVD 기반 차원 축소
텐서와 딥러닝
CNN
4D 텐서: (N, C, H, W)
컨볼루션 = 행렬 곱셈
RNN/LSTM
3D 텐서: (배치, 시퀀스, 특징)
게이트 = 행렬 연산
Transformer
어텐션 = Q·K^T / √d
다중 헤드 어텐션
딥러닝 구현 예제
import numpy as np
class NeuralNetwork:
"""간단한 신경망 구현"""
def __init__(self, layers):
"""
layers: [입력층, 은닉층1, ..., 출력층]
"""
self.layers = layers
self.weights = []
self.biases = []
# 가중치 초기화 (Xavier)
for i in range(len(layers) - 1):
w = np.random.randn(layers[i], layers[i+1]) * np.sqrt(2/layers[i])
b = np.zeros((1, layers[i+1]))
self.weights.append(w)
self.biases.append(b)
def relu(self, x):
"""ReLU 활성화 함수"""
return np.maximum(0, x)
def relu_derivative(self, x):
"""ReLU 도함수"""
return (x > 0).astype(float)
def softmax(self, x):
"""Softmax 활성화 함수"""
exp_x = np.exp(x - np.max(x, axis=1, keepdims=True))
return exp_x / np.sum(exp_x, axis=1, keepdims=True)
def forward(self, X):
"""순전파"""
self.activations = [X]
self.z_values = []
for i in range(len(self.weights)):
z = self.activations[-1] @ self.weights[i] + self.biases[i]
self.z_values.append(z)
# 마지막 층은 softmax, 나머지는 ReLU
if i == len(self.weights) - 1:
a = self.softmax(z)
else:
a = self.relu(z)
self.activations.append(a)
return self.activations[-1]
def backward(self, X, y, learning_rate=0.01):
"""역전파 및 가중치 업데이트"""
m = X.shape[0]
# 출력층 그래디언트
delta = self.activations[-1] - y
# 역전파
for i in range(len(self.weights) - 1, -1, -1):
# 가중치 그래디언트
dW = (self.activations[i].T @ delta) / m
db = np.sum(delta, axis=0, keepdims=True) / m
# 가중치 업데이트
self.weights[i] -= learning_rate * dW
self.biases[i] -= learning_rate * db
# 다음 층을 위한 델타 계산
if i > 0:
delta = (delta @ self.weights[i].T) * self.relu_derivative(self.z_values[i-1])
def train(self, X, y, epochs=1000, learning_rate=0.01, batch_size=32):
"""미니배치 SGD 훈련"""
n_samples = X.shape[0]
for epoch in range(epochs):
# 데이터 셔플
indices = np.random.permutation(n_samples)
X_shuffled = X[indices]
y_shuffled = y[indices]
# 미니배치 훈련
for i in range(0, n_samples, batch_size):
X_batch = X_shuffled[i:i+batch_size]
y_batch = y_shuffled[i:i+batch_size]
# 순전파
output = self.forward(X_batch)
# 역전파
self.backward(X_batch, y_batch, learning_rate)
# 손실 계산 (크로스 엔트로피)
if epoch % 100 == 0:
output = self.forward(X)
loss = -np.mean(np.sum(y * np.log(output + 1e-8), axis=1))
print(f"Epoch {epoch}, Loss: {loss:.4f}")
# PCA 구현
def pca(X, n_components):
"""주성분 분석"""
# 1. 데이터 중심화
X_centered = X - np.mean(X, axis=0)
# 2. 공분산 행렬
cov_matrix = (X_centered.T @ X_centered) / (X.shape[0] - 1)
# 3. 고유값 분해
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)
# 4. 고유값 기준 정렬
idx = eigenvalues.argsort()[::-1]
eigenvalues = eigenvalues[idx]
eigenvectors = eigenvectors[:, idx]
# 5. 상위 n개 주성분 선택
components = eigenvectors[:, :n_components]
# 6. 변환
X_transformed = X_centered @ components
# 설명된 분산 비율
explained_variance_ratio = eigenvalues[:n_components] / np.sum(eigenvalues)
return X_transformed, components, explained_variance_ratio
# 사용 예제
if __name__ == "__main__":
# 신경망 테스트
nn = NeuralNetwork([784, 128, 64, 10]) # MNIST용
# 더미 데이터
X = np.random.randn(100, 784)
y = np.eye(10)[np.random.randint(0, 10, 100)] # one-hot
nn.train(X, y, epochs=100, learning_rate=0.01)
# PCA 테스트
X_pca, components, var_ratio = pca(X, n_components=50)
print(f"\nPCA: {var_ratio.sum():.2%} 분산 설명")