보통 AI라고 칭하는 머신러닝 모델들은 대부분 딥러닝 모델이다. 그렇다면 딥러닝이 이전의 전통적인 머신러닝 모델들보다 뛰어난 결과를 보여주는 이유는 무엇일까? 여러가지 이유가 있겠지만 그 중 대표적인 이유 2가지에 대해 알아보자.

  1. Nonlinear Transformation
  2. Feature Representation

Nonlinear Transformation: 표현력

image 딥러닝의 기초 개념에서 많이 거론되는 것 중 하나가 XOR 문제이다. 위 그림과 같이 OR와 AND는 하나의 선으로 분류가 가능하지만 XOR은 하나의 선(Single Layer Perceptron)으로 해결할 수 없는 문제이다. Logistic, Lasso 등등 전통적인 ML 모델들은 Sigle Layer 모델이기 때문에 XOR 문제를 해결 할 수 없다.

Single Layer

코드를 통해 확인해 보면

import torch
import torch.nn as nn
import torch.optim as optim

#hyper-parameter
epochs = 10000

# X=input, y=output
X = torch.FloatTensor([[0, 0], [0, 1], [1, 0], [1, 1]])
Y = torch.FloatTensor([[0], [1], [1], [0]])

# nn layers(Perceptron)
model = nn.Sequential(
    nn.Linear(2, 1, bias=True),
    nn.Sigmoid()
)

# define cost/loss & optimizer
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=1)

# train
for step in range(epochs):
    optimizer.zero_grad()
    hypothesis = model(X)

    cost = criterion(hypothesis, Y)
    cost.backward()
    optimizer.step()

    if step%1000 == 0:
        print(step, cost.item())
0: 0.8137744665145874
1000: 0.6931471824645996
2000: 0.6931471824645996
3000: 0.6931471824645996
4000: 0.6931471824645996
5000: 0.6931471824645996
6000: 0.6931471824645996
7000: 0.6931471824645996
8000: 0.6931471824645996
9000: 0.6931471824645996

loss가 줄어들지 않는 것을 확인할 수 있다. 결과도 확인해보면

with torch.no_grad():
    hypothesis = model(X)
    predicted = (hypothesis > 0.5).float()
    accuracy = (predicted == Y).float().mean()
    print('모델의 출력값(Hypothesis): \n', hypothesis.detach().cpu().numpy())
    print('모델의 예측값(Predicted): \n', predicted.detach().cpu().numpy())
    print('실제값(Y): \n', Y.cpu().numpy())
    print('정확도(Accuracy): \n', accuracy.item())
모델의 출력값(Hypothesis): 
 [[0.5]
 [0.5]
 [0.5]
 [0.5]]
모델의 예측값(Predicted): 
 [[0.]
 [0.]
 [0.]
 [0.]]
실제값(Y): 
 [[0.]
 [1.]
 [1.]
 [0.]]
정확도(Accuracy): 
 0.5

제대로 예측하지 못하는 것을 확인할 수 있다.

DNN, Multi-Layer

image

출처: https://ang-love-chang.tistory.com/26

그렇다면 딥러닝은 XOR을 어떻게 해결한다는 것일까? 해결 방법은 위 그림과 같이 평면을 휘어주는 것이다. XOR 문제를 해결하기 위해서는 우리는 2개의 perceptorn을 한 번에 계산할 수 있어야 한다. 이를 가능하게 하려면 은닉층(hidden layer)을 만들면 된다. 은닉층을 쌓아줌으로써 좌표 평면을 왜곡시켜 하나의 직선으로 XOR의 문제를 풀 수 있게 된다.

이 또한 코드로 확인해보면

import torch
import torch.nn as nn
import torch.optim as optim

#hyper-parameter
epochs = 10000

# X=input, y=output
X = torch.FloatTensor([[0, 0], [0, 1], [1, 0], [1, 1]])
Y = torch.FloatTensor([[0], [1], [1], [0]])

# nn layers(Multi-Layer Perceptron)
model = nn.Sequential(
    nn.Linear(2, 2, bias=True),
    nn.Sigmoid(),
    nn.Linear(2, 1, bias=True),
    nn.Sigmoid()
)

# define cost/loss & optimizer
criterion = nn.BCELoss()
optimizer = optim.SGD(model.parameters(), lr=1)

# train
for step in range(epochs):
    optimizer.zero_grad()
    hypothesis = model(X)

    cost = criterion(hypothesis, Y)
    cost.backward()
    optimizer.step()

    if step%1000 == 0:
        print(f'{step}: {cost.item()}')
0: 0.7017123103141785
1000: 0.02284283936023712
2000: 0.006839723326265812
3000: 0.003976704552769661
4000: 0.002794920466840267
5000: 0.0021517882123589516
6000: 0.0017480711685493588
7000: 0.00147122866474092
8000: 0.0012697356287389994
9000: 0.001116558094508946

loss가 잘 줄어들고

with torch.no_grad():
    hypothesis = model(X)
    predicted = (hypothesis > 0.5).float()
    accuracy = (predicted == Y).float().mean()
    print('모델의 출력값(Hypothesis): \n', hypothesis.detach().cpu().numpy())
    print('모델의 예측값(Predicted): \n', predicted.detach().cpu().numpy())
    print('실제값(Y): \n', Y.cpu().numpy())
    print('정확도(Accuracy): \n', accuracy.item())
모델의 출력값(Hypothesis): 
 [[0.00104058]
 [0.9986665 ]
 [0.9986665 ]
 [0.00113763]]
모델의 예측값(Predicted): 
 [[0.]
 [1.]
 [1.]
 [0.]]
실제값(Y): 
 [[0.]
 [1.]
 [1.]
 [0.]]
정확도(Accuracy): 
 1.0

예측도 잘 하는 것을 알 수 있다.

이 처럼 여러개의 층을 가진 모델을 DNN(Deep Neural Network) 또는 딥러닝 모델이라고 한다. 깊은 층을 통해 전통적인 머신 러닝 모델들이 가진 표현력의 한계를 극복하여 데이터를 non-linearity를 학습하고 효과적으로 표현 할 수 있게 되었다.

Feature Representation: 사람의 개입

출처: 코드 스테이츠

사람의 개입여부가 또 하나의 차이점이자 딥러닝이 잘 학습하는 이유이다.

기존의 머신 러닝은 input -> feature extraction -> classification -> output의 순서로 동작하였다. 이 중 feature 추출 부분을 사람이 개입하여 특정하고, 이를 바탕으로 ML 모델이 분류하는 구조를 가져었다. 이미지에서 사물을 찾아 분류하는 Object Detection의 경우를 예로 살펴보자.

image

딥러닝 모델을 사용하기 전 많이 사용했던 HOG(Histogram of Oriented Gradient) 알고리즘이다. 간단하게 설명하면 아래와 같이 동작했다.

  1. 이미지를 나눠줌
  2. 각 셀의 gradient의 크기 값과 방향을 구함
  3. 이를 토대로 histogram을 만들고 정규화 시켜준 뒤 feature vector 생성
  4. feature vector과 label로 이루어진 쌍(example)을 선형 SVM 분류기를 통해 학습

이 중 2,3번의 feature를 추출하는 구간에 사람이 개입을 한다. 이렇게 되면 사람의 bias가 들어가게 되고 한계점이 생기게 된다.

출처: https://www.v7labs.com/blog/object-detection-guide

반면에 딥러닝은 머신러닝에서 사람이 하던 패턴 추출 작업이 생략된다. 데이터와 정답값을 주면 신경망에게 전달해주기만 하면 된다. 신경망은 적절한 구조를 통해 어린아이가 학습하는 것처럼 경험 중심으로 학습을 수행한다. 즉, 인간이 개, 고양이의 특성을 추려 사전에 정의된 알고리즘과 규칙을 적용하는 머신러닝과 달리, 딥러닝에서는 심층 신경망을 통해 스스로 개, 고양이의 특성을 훈련하여 개와 고양이를 분류할 수 있다.

References