[BoostCamp AI Tech 5기] Week1. AI Math 학습정리 및 주간 회고
1. 벡터가 뭐예요?
1. 벡터(Vector)
- 벡터란 숫자를 원소로 갖는 리스트 또는 배열이다.
- 벡터는 d차원 공간에서의 한 점을 나타낸다.
- 벡터는 원점으로부터 상대적 위치를 나타낸다.
2. 노름(Norm)
- 벡터의 노름(norm)은 원점에서부터의 거리를 나타낸다.
- 보통 L1-노름과 L2-노름을 사용하는데, 노름 종류에 따라 기하학적 성질이 다르므로 상황에 따라 다르게 사용한다.
- L1-노름의 경우 L2-노름에 비해 이상치 영향을 덜 받는다. (L2에는 원소를 제곱하는 과정이 있기 때문이다.
- p가 커질수록 원의 모양이 사각형에 가까워진다. (L2노름의 원이 우리가 생각하는 원의 형태이다.)
3. 벡터 간 연산
- 두 벡터 사이의 거리는 벡터의 뺄셈으로 구할 수 있다.
- || y - x || = ||x - y||
- L2-노름과 제2 코사인 법칙으로 두 벡터 간의 각도를 계산할 수 있다.
4. 내적
- 이때 코사인을 구하는 수식에서 분자에 있는 식 대신 내적이 활용될 수 있다.
- numpy에서 내적은 np.inner 함수이다.
- 정사영된 벡터 Proj(x)는 벡터 x가 벡터 y로 투영(정사영)된 그림자를 나타낸다.
- 코사인 법칙에 의해 Proj(x) = ||x|| cos θ 가 된다.
- 이때 내적은 정사영의 길이를 벡터 y의 길이 ||y||만큼 조정한 값이다.
2. 행렬이 뭐예요?
1. 행렬의 의미 1
- 행렬(matrix)은 벡터를 원소로 가지는 2차원 배열이다.
- 행렬은 공간에서 여러 점들을 나타낸다.
2. 행렬의 연산
- 행렬끼리 같은 모양을 가지면 덧셈, 뺄셈, 성분곱(같은 인덱스 원소끼리 곱한다.)을 수행할 수 있다.
- 행렬 곱셈(matrix multiplication)은 i번째 행벡터와 j번째 열벡터 사이의 내적을 성분으로 갖는 행렬을 계산한다.
- numpy의 np.inner는 i번째 행벡터와 j번째 행벡터 사이의 내적을 한다. 즉 행렬 곱셈과 다르다!! numpy에서 행렬 곱셈은 @ 연산자를 사용한다.
3. 행렬의 의미 2
- 행렬(matrix)은 벡터공간에서 사용되는 연산자(operator)로 해석할 수 있다.
- 위 수식에서 행렬 A는 m차원의 벡터 x를 n차원의 벡터 z로 변환시킨다. (+모든 선형변환은 행렬곱으로 가능하다.)
- 행렬곱을 통해 패턴 추출, 데이터 압축도 가능하다.
4. 역행렬
- 역행렬은 위의 수식에서 벡터 z를 벡터 x로 다시 변환할 때 필요한 행렬이라 할 수 있다.
- 역행렬은 정방행렬이고, 행렬식(determinant)이 0이 아닌 경우에만 계산할 수 있다.
- numpy에서 numpy.linalg.inv 로 구할 수 있다.
- 역행렬을 계산할 수 없으면 유사역행렬 또는 무어-펜로즈 역행렬을 사용할 수 있다.
- numpy에서 numpy.linalg.pinv로 구할 수 있다.
- numpy.linalg.pinv로 연립방정식의 해와 선형회귀식을 구할 수 있다.
- 이때 선형회귀분석에서는 numpy.linalg.pinv와 sklearn의 LinearRegression 두가지를 사용할 수 있는데, numpy.linalg.pinv는 절편 y를 직접 입력해줘야 하지만 LinearRegression은 절편 y도 직접 추정해주는 차이가 있다.
3&4. 경사하강법
1. 미분
- 미분(differentiation)은 '변수의 움직임에 따른 함수값의 변화를 측정하는 도구'이다.
- sympy.diff로 미분 계산이 가능하다.
- 미분은 함수의 접선의 기울기를 구한다.
2. 경사하강법
- 이 점을 이용해 함수의 극소값을 찾을 수 있고 이를 경사하강법(grdient descent)라 한다. 접선의 기울기가 0에 가까워질 수록 극값에 가까워진다.
- 예시 코드:
!pip install sympy
Collecting sympy
Downloading sympy-1.11.1-py3-none-any.whl (6.5 MB)
---------------------------------------- 6.5/6.5 MB 9.2 MB/s eta 0:00:00
Collecting mpmath>=0.19
Downloading mpmath-1.3.0-py3-none-any.whl (536 kB)
-------------------------------------- 536.2/536.2 kB 8.5 MB/s eta 0:00:00
Installing collected packages: mpmath, sympy
Successfully installed mpmath-1.3.0 sympy-1.11.1
import sympy
def gradient(val):
"""
val 값을 미분한 함수 f에 대입하고 그 값을 반환하는 함수이다
"""
x = sympy.symbols('x', imaginary = True) #x를 대수 기호로 인식
f = x**2 + 2*x + 3 #예시를 위해 임의의 함수를 선언했다.
#미완성...
def grad_de(init, lr, eps): #init: 시작점, lr: learning rate(학습률), eps: 알고리즘 종료 조건
var = init #이렇게 입력값을 다른 임시 변수에 저장해두는 것을 습관화하자!
grad = gradient(var)
count = 0
while(abs(grad) > eps):
count += 1
print(f"count: {count}, grad: {grad}")
var = var - lr * grad
grad = gradient(var)
return grad
- 변수가 스칼라값이 아닌 벡터인 다변수 함수의 경우 변수 별로 편미분(partial differentiation)을 진행한다. 이렇게 편미분을 계산한 그레디언트(gradient) 벡터를 이용하여 경사하강법을 진행할 수 있다.
- 그레디언트 벡터 앞에 '-'부호가 붙으면 가장 빨리 감소하는 방향을 가리킨다.
- 코드: 이전 경사하강법 알고리즘의 while문의 조건문과 같이 gradient값의 절댓값을 사용하는 것이 아닌, norm을 사용한다는 점을 제외하고는 모두 동일하다. (벡터를 계산하기 때문)
def grad_de(init, lr, eps): #init: 시작점, lr: learning rate(학습률), eps: 알고리즘 종료 조건
var = init #이렇게 입력값을 다른 임시 변수에 저장해두는 것을 습관화하자!
grad = gradient(var)
count = 0
while(norm(grad) > eps):
count += 1
print(f"count: {count}, grad: {grad}")
var = var - lr * grad
grad = gradient(var)
return grad
3. 경사하강법으로 선형회귀 계수 구하기
- 역행렬로 선형회귀식을 구하는 것이 아니라 경사하강법을 이용해 선형모델을 찾고자 한다.
- 선형회귀의 목적식은
$$\left\| \mathbf{y - X\beta }\right\|_{2}$$
이고 이 목적식을 최소화하는 베타를 찾아야한다.
- 위의 수식은 목적식을 베타에 대해 편미분하는 과정이다. 목적식의 제곱을 최소화해도 된다. 마지막 식에서 n으로 나눈 이유는 데이터의 평균을 구하기 위함이고, 맨 마지막 시그마의 d는 베타의 종류 즉, 컬럼의 개수를 의미한다.
- X베타를 계수 베타에 대해 미분한 결과가 X의 전치행렬인 것을 생각하면 증명이 쉬워진다.(사실 쉽진 않다...)
- 다음과 같이 구해진다.
- 베타를 업데이트하는 방법은 다음과 같다.
- 편미분한 목적식은 위에서 정리한 수식을 대신 대입할 수 있다.
- 코드 구현:
def grad_de(X, y, lr, T): #lr: learning rate(학습률), T: 반복 횟수
for t in range(T): # 학습횟수를 지정해준다.
error = y - X @ beta
grad = - transpose(X) @ error
beta = beta - lr * grad
return beta
- 이전의 알고리즘과 다르게 종료조건을 eps로 설정하는 것이 아니라 일정 학습횟수로 변경했다.
4. 확률적 경사하강법 (SGD)
- 이때 경사하강법은 미분가능하고 볼록(convex)한 함수에 대해서만 수렴이 보장되어 있다. 즉 비선형회귀 문제에서는그렇지 않다.
- 확률적 경사하강법(stochastic gradient descent)는 전체 데이터가 아닌 일부 묶음(batch)으로 나누어 업데이트한다.
- 때문에 기존 경사하강법보다 학습이 빠르고 연산자원을 효율적으로 사용 가능하다.
- 또한 convex하지 않은 목적식도 해결할 수 있다.
- 종합적으로 GD보다 학습에 더 효율적이라고 할 수 있다.
- SGD는 미니배치를 확률적으로 선택하므로 목적식 모양이 계속 바뀐다. 그래서 GD보다는 정확도가 떨어질 수 있지만, 미니배치로 나누어 병렬적으로 처리함으로써 오늘날 GD로 발생하는 out of memory 문제를 해결할 수 있다.
5. 딥러닝 학습방법 이해하기
1. 신경망(neural network)
(1) 선형모델
- 실제 우리가 다룰 데이터는 4강에서 다룬 선형모양보다는 비선형모델에 가까울 것이다. 이번 5강에서는 비선형모델인 신경망에 대해 다룬다.
- 기존의 선형모델은 n개의 데이터(인스턴스)와 d개의 열로 이루어진 x 행렬(데이터셋)이 가중치 행렬 W와 행렬곱으로 d개에서 p개의 칼럼으로 이루어진 행렬 O가 만들어진다.
(2) 분류모델
- 위의 수식을 기반으로 분류모델도 만들 수 있는데, 선형모델과 다음의 softmax(o) 함수를 결합하여 분류문제를 해결할 수 있다.
- 실제로 추론을 할 때는 softmax 함수 대신 원-핫(one-hot) 벡터로 표현한다.
(3) 신경망
- 선형모델과 활성함수(activation function)를 합성한 함수를 신경망이라 한다.
- 활성함수는 비선형(nonlinear) 함수로 선형모델과 합성하여 신경망을 나타낸다. (선형모델을 계속해서 합성해도 결국 선형모델이 나오기 때문에 활성함수가 필요하다.)
- 대표적인 활성함수로 다음 세가지가 있다.
- 다층 퍼셉트론(MLP)은 신경망이 여러층 합성된 함수이다. 층이 깊을수록 목적함수를 0으로 근사하는데 필요한 노드(파라미터, 히든 벡터 등)가 줄어들어, 더 효율적으로 학습이 가능하다.
- 다음 사진이 MLP를 나타내고, 왼쪽에서 오른쪽으로 가는 순차적인 계산을 순전파(forward propagation)이라 한다.
- 맨 오른쪽에 최종 계산 값이 나오면 그 값과 실제 값을 비교하여 모델을 최적화 시켜야한다. 층이 여러개이고, 노드 및 파라미터가 여러 개이기 때문에 모두 업데이트를 시켜줘야한다. 이때 사용되는 것이 딥러닝 "역전파(backpropagation) 알고리즘"이다.
- 워딩 그대로 가장 마지막 층부터 초기 뉴런까지 이동하며 가중치를 업데이트 시켜주는 작업인데, 연쇄법칙(chain rule)을 이해하면 역전파의 원리가 쉬워진다. (아닐수도 있다...!) (연쇄법칙은 따로 설명하지 않을 거다,,, 그냥 분수끼리 곱할 때 분자와 분모가 서로 같아, 지워지는 것을 연쇄법칙이라 한다. 이게 설명 끝이다,,,~)
- https://wikidocs.net/37406 자세한 설명은 이 게시글을 추천한다. 필자는 역전파를 처음 배웠을 때 이 글을 7번 정도 읽고 비로소 이해했다... 계산도 눈으로만 보지말고 직접 풀어보는 것을 강력추천한다!!
- 계산한 z = x*w + b를 활성함수에 넣어서 나온 값이 히든 벡터 h 이다.(절편 b는 다음 그림에 나타나지 않지만 가독성을 위해 잠시 없앤 것 같다.)
6. 확률론 맛보기
딥러닝은 확률론 기반 기계학습 이론을 바탕으로 한다.
예를 들어, 회귀 분석에서는 손실함수 L2-노름을 예측값과 실제 값과의 차이 즉, 오차의 분산을 최소화하는 방향으로 학습하도록 한다. 또한 분류 문제에서 교차 엔트로피(cross-entropy)는 모델 예측의 불확실성을 최소화하는 방향으로 학습한다. 이렇게 분산 및 불확실성을 최소화하기 위해 측정하는 방법(확률론)을 배워야한다.
1. 확률분포
- 데이터 공간을 X x Y라 하고, 이 데이터 공간에서 데이터를 추출하는 분포를 D라 한다. 그리고 데이터는 데이터 공간에 속한 실제 데이터이자 분포 D의 확률변수로 (x, y) ~ D로 표기한다.
- 크게 이산확률변수와 연속확률변수로 나누어 볼 수 있다. (고등학생 때 배운 개념이므로 수식은 따로 올리지 않는다.)
- 이산확률변수는 확률변수가 가질 수 있는 모든 경우의 수를 고려하여 모델링한다.
- 연속확률변수는 데이터 공간에 정의된 확률변수의 밀도 위에서의 적분을 통해 모델링한다.
- 결합분포 P(x,y)는 확률분포 D를 모델링한다. 아래 그림을 볼 때, 파란 데이터 점들만 봤을 때는 연속형으로 보이지만 빨간 선들이 구간을 나누어 이산확률분포로 나타내고 있다. 이처럼 모델링 방법에 따라 확률분포가 결정되는 것을 알 수 있다.
- 결합분포 P(x,y)로 입력 x에 대한 주변확률분포 P(x)를 구할 수 있다. 이때 주변확률분포 P(x)는 y에 대한 정보는 가지고 있지 않다.
- 조건부확률분포 P(x | y)는 Y = y일 때, x에 대한 확률분포를 보여준다.
2. 조건부확률과 기계학습
음 개인적으로 이 부분부터 엄청나게 생략하신 것 같다... 또 본인만의 용어로 ex. 특징패턴 설명하시다보니 구글링해도 안 나와 이해가 어렵다.
- 조건부확률 P( y | x)는 입력변수 x에 대한 정답이 y일 확률/밀도를 의미한다.
- (1) 분류문제에서 softmax()함수는 데이터 x로부터 추출된 특징패턴과 가중치행렬 W의 행렬곱을 기반으로 조건부확률 P(y|x)을 계산한다.
- (2) 회귀문제에서 조건부기대값 E[y|x] = f(x)를 추정한다. 이때 목적식 E||y - f(x)||2 (L2-norm이다)의 f(x)를 의미한다.
- 항상 조건부기대값을 통계량으로 쓰지 않는다. 데이터가 robust한 경우는 중앙값(median)을 통계량을 사용하기도 한다.
- 기대값(expectation)은 데이터를 대표하는 통계량이고, 분산, 첨도, 공분산 등 다른 통계량을 계산할 수 있다.
- (3) 딥러닝은 다층신경망(MLP)을 사용하여 데이터 x로부터 특징패턴을 추출한다.
3. 몬테카를로 샘플링
- 확률분포를 명시적으로 알 수 없을 때 사용하는 샘플링 기법이다.
- 데이터를 이용하여 기대값을 추론한다.
- 수식을 통해 짐작할 수 있듯이, 데이터가 많아질수록 대수의 법칙(law of large number)에 의해 수렴성을 보장한다.
- 예제:
import numpy as np
def mc_int(func, low, high, sample_size = 100, repeat = 10):
int_len = np.abs(high-low)
stat = []
for _ in range(repeat):
x = np.randon.uniform(low=low, high=high, size=sample_size)
func_x = func(x)
int_val = int_len * np.mean(func_x)
stat.append(int_val)
return np.mean(stat), np.std(stat)
def f_x(x):
return np.exp(-x**2)
print(mc_int(f_x, low=-1, high=1, sample_size=10000, repeat=100))
>>>(1.4938754306231912, 0.00391398451303653)
7. 통계학 맛보기
이제 맛보는 정도가 아니라 얻어터지는 정도인,,,
1. 모수
- 통계적 모델링은 확률분포 즉, 모집단 데이터의 분포 형태를 표본을 기반으로 최대한 근사적으로 추정(inference)하는 것이 목표이다.
- 모수적 방법론: 표본이 특정 확률분포를 따른다고 먼저 가정한 후 그 분포의 모수(parameter)를 추정한다.
- 확률분포를 가정할 때에는 데이터를 먼저 관찰해야한다. ex. 데이터가 2개의 값(0 또는 1)만 가지는 경우는 베르누이 분포를 가정할 수 있다.
- 모수 추정 후 통계적 검정도 필요하다.
- 비모수 방법론: 반대로 확률분포를 가정하지 않고, 표본에 따라 모델의 구조나 모수의 개수가 바뀐다. 기계학습 대부분의 방법론은 비모수 방법론에 해당한다.
- 모수적 방법론: 표본이 특정 확률분포를 따른다고 먼저 가정한 후 그 분포의 모수(parameter)를 추정한다.
- 확률분포 가정 후 모수를 추정하는데, 정규분포를 예로 들면 모수는 평균과 분산이다. 이런 통계량(statistic)의 확률분포를 표집분포(sampling distribution)라 부르며, 데이터가 많아질수록 중심극한정리에 의해 정규분포를 따른다.
2. 최대가능도 추정법
(1) 최대가능도 추정법
- 최대가능도추정법(maximum likelihood estimation, MLE)는 모수를 추정하는 방법이다.
- 정규분포를 예로 설명하면, P(x|\theta) 에서 \theta = (평균, 분산) 이다. 이때 P(x|\theta) = L(\theta ; x) 로 관점이 바뀐다고 해석할 수 있다. 기존 확률밀도함수는 \theta가 주어졌을 때 x를 관찰하지만, 가능도함수는 x를 기반으로 \theta가 어떤 값을 갖는지 추론한다.
(2) 로그가능도(log-likelihood)
- 위 수식에서 데이터 집합 x가 독립적을 추출되었다는 전제 하에 로그를 씌워 로그가능도를 최적화할 수 있다.
- 로그가능도를 사용해야하는 이유:
- 데이터가 엄청나게 많아지면 컴퓨터의 정확도로 가능도 계산이 불가능해진다. 로그를 취하면 가능도의 곱셈을 덧셈으로 바꿀 수 있기 때문에 로그가능도가 필요하다.
- 위와 같은 맥락이지만 경사하강법으로 가능도를 최적화할 때와 비교하여 연산량이 O(n^2) 에서 O(n)으로 줄어든다.
- 경사하강법 사용 시 음의 로그가능도를 최적화하여 사용할 수 있다.
(3) 최대가능도 추정법 예제
- 1) 정규분포
- 확률변수 X로부터 독립적인 표본 {x1, x2, ..., xn}을 얻었다면 분포의 모수(모평균과 모분산)을 추정해볼 수 있다.
- 2) 카테고리 분포
- 카테고리 분포의 표본의 원소(x1, x2, ...)는 one-hot 벡터이고, 모수는 각 차원의 확률이다. 즉, 모수 pk의 합은 1이다. 이 점을 활용하여 라그랑주 승수법을 통해 문제를 풀 수 있다. (자세한 풀이는 따로 기재하지 않을 것)
- 3) 딥러닝에서의 최대가능도 추정법
- 딥러닝 모델의 가중치 (W)를 모수 \theta라 하면, 분류 문제에서 소프트맥스 벡터는 카테고리 분포의 모수 (p1, p2, ...)를 모델링한다.
- 실제 정답레이블 y = (y1, y2, ...)는 원핫벡터이기 때문에 이를 카테고리 분포의 표본 원소로 가정하여 로그가능도를 최적화할 수 있다.
- 이외에도 두 확률분포 사이의 거리(distance)를 계산하는 함수 세 가지를 소개한다.
- 총변동 거리(Total Variation Distance, TV)
- 쿨백-라이블러 발산 (KL)
- 분류문제에서 확률분포 P를 정답레이블로, 확률분포 Q를 모델 예측으로 두면 최대가능도 추정법은 쿨백-라이블러 발산을 최소화하는 것과 같다.
- 바슈타인 거리
8. 베이즈 통계학 맛보기
우선 누군가와 함께 좋은 에너지를 주고받고 성장할 수 있는 환경이 만들어진 것에 너무 감사합니다! 5개월 후에는 새로운 것을 배운다는 것에 두려움을 갖지 않고 어떠한 과목 및 학문도 잘 소화해냈으면 좋겠습니다. 그리고 실무에 참여할 수 있을 정도의 AI/프로그래밍 실력을 쌓고 싶습니다.