주제

1. 딥러닝이란?
2. 이미지 처리(CNN) & 텍스트 처리(RNN)
3. 교차 검증
4. 성능 평가
5. 이미지 분류 실습

 

 

1. 딥러닝(Deep Learning)이란?

  • 인공지능 > 머신 러닝 > 딥러닝
  • 사람의 신경망을 기반으로 학습과 추론을 진행하는 학문
  • 사람의 신경 구조 기본 단위 : 뉴런(neuron)
  • 딥러닝의 기본 단위 : 퍼셉트론(perceptron) → 뉴런을 모방

1.1 기본 개념

뉴런

  • 뉴런 : 사람의 신경계를 구성하는 가장 작은 구성 물질
  • 수상 돌기 : 앞 뉴런의 신호를 수신
  • 세포체 : 신호 연산
  • 축색 돌기 : 신호 이동
  • 축색 말단 : 뒤 뉴런에게 신호 전달
  • 수많은 뉴런들이 시냅스를 통해 신호를 신경계 최고 기관인 뇌로 전달하고, 뇌에서 적절한 반응을 근육으로 전달하는 과정이 반복됨

퍼십트론

  • 퍼셉트론 : 뉴런의 동작을 단순화하여 수학적으로 모델링한 것으로, 뉴런과 마찬가지로 다수의 입력을 바탕으로 하나의 결과를 출력
  • 앞선 신호로부터 정보를 얻고 정제해 후속 전파
  • 퍼셉트론은 원, 가중치는 반직선의 형태로 표시

 

1.2 딥러닝 모델의 적용

  • 머신 러닝과는 다르게 비정형 데이터(이미지, 텍스트, 오디오 등)도 사용할 수 있음
  • 퍼셉트론을 다양하게 배치하여 데이터 특성에 맞는 구조를 설계, 모델의 크기 조절 등 사람과 비슷한 인지 과정을 모방함
    • 이미지 데이터 : CNN
    • 텍스트 데이터 : RNN, Attention

 

 

2. 이미지 처리(CNN) & 텍스트 처리(RNN)

2.1 이미지 처리 : CNN

  • 사람의 이미지 처리 과정 : 
    1. 분석 단위를 설정 후 정보를 추출
    2. 주변 정보를 통합상위 개념 구성
    3. 목적하는 상위 개념에 도달할 때까지 반복
  • 작은 곡선과 직선의 의미를 통합하는 과정으로 이미지 판단
  • 기계의 이미지 처리 과정
    1. Convolutional Filter
    2. Pooling
    3. 반복
  • CNN(Convolutional Neural Network) : 문제 해결을 위한 특징(feature) 추출을 Convolution 필터를 사용한 딥러닝 모델
  • Pooling 과정과 반복의 과정으로 상위 개념의 특징을 만드는 과정이 수반됨(이미지 출처)

Convolution 필터

  • Convolution : 이미지의 한 픽셀과 주변 픽셀의 연관성을 유지시키며 필터에 학습하는 것
  • Pooling : 이미지가 너무 많아지지 않게 1개의 이미지에 1개의 출력을 만들며 기존 이미지에 padding없이 크기를 줄이는 것

2.2 텍스트 처리 : RNN

  • 사람의 텍스트 처리 과정 :
    1. 문장의 앞에서부터 한 단어씩 읽음
    2. 새로운 단어가 들어오면 이를 읽고 이해
    3. 앞서 해석해 만들어낸 기억 정보에 정보를 추가하여 기억을 업데이트
    4. 문장이 끝나는 시점까지 위 과정을 되풀이
  • 기계의 텍스트 처리 과정 :
    1. 문장의 앞에서부터 한 단어씩 입력으로 받음
    2. 새로운 단어가 들어오면 이를 처리해서 정보 추출
    3. 앞서 해석해 만들어낸 정보 덩어리에 추출한 정보까지 추가하여 정보를 업데이트
    4. 문장이 끝나는 시점까지 위 과정을 되풀이(Recurrent)
  • RNN(Recurrent Neural Network) : 텍스트와 같은 순차 데이터를 처리하기 위해 고안된 모델
  • 이웃한 텍스트 글자 간의 연관성을 표현하는 방식으로 정보 처리
  • 정보 덩어리 = hidden state
  • 새로운 정보가 들어오면 hidden state 업데이트

2.3 Attention Module

  • 데이터의 중요도에 따라 처리하는 딥러닝 모델에 적용된 기술
  • 이미지나 텍스트 데이터에서 중요한 데이터부터 처리하는 것

 

 

3. 교차 검증

  • 검증(validation) : 모델의 학습이 잘 진행되었는지(일반화 능력)을 판단하는 평가 과정
  • 검증 과정에서 일어날 수 있는 문제점 :
    • 우연히 너무 쉬운 데이터가 검증 데이터로 구성됨
    • 데이터가 너무 적음
  • 이 문제점들을 피할 수 있는 방법이 없을까? → 교차 검증!
  • 교차 검증(Cross Validation) : 전체 데이터를 여러 개의 하위 데이터로 나누고, 하위 세트들의 조합은 서로 다른 방법으로 훈련과 검증에 사용해 일반화 능력을 측정
    • 일반적인 랜덤 검증 데이터 활용 검증법보다 효과적
    • 일반화 추정 능려그 데이터 활용 최대화, 과적합 방지
  • 교차 검증의 종류(학습 데이터와 검증 데이터를 구성하는 방법에 따라 다름) :
    • K-Fold CV
    • 계층적 교차 검증(Stratified Cross Validation)
    • LOOCV(Leave-One-Out Cross Validation)

3.1 K-Fold CV

  • 전체 데이터를 총 K개의 덩어리(폴드)로 나누고, 각 폴드를 순차적으로 검증 데이터로 사용하는 방법
  • 나머지 K - 1 개의 폴드는 학습 데이터로 사용
  • K번의 학습 및 평가 과정이 반복됨
  • 의미 :
    • 모든 데이터가 학습 및 평가로 사용됨
    • 데이터 활용의 극대화
    • 과적합 방지
    • 논리적인 일반화 평가 진행

K가 5개로 나뉜 데이터 예시

 

3.2 계층적 교차 검증(Stratified Cross-Validation)

  • K-Fold CV와 비슷하지만, 각 폴드에서 클래스의 비율을 원본 데이터 셋의 클래스 비율과 유사하게 유지하여 검증
  • 클래스 별로 데이터를 분할 → 각 클래스 데이터를 K개의 폴드로 나눔 → 각 클래스에 존재하는 K개의 폴드를 하나씩 조합 → 이후 과정은 K-Fold CV와 동일
  • 의미 :
    • 위의 장점과 동일
    • 클래스 사이의 불균형이 있는 경우 편향까지 고려

계층적 교차 검증 예시

 

3.3 LOOCV(Leave-One-Out Cross Validation)

  • 한 번에 하나의 데이터 포인트만을 검증 데이터로 사용
  • 전체 데이터 수 만큼의 K를 활용
  • 의미 :
    • 매우 정확함
    • 데이터의 크기가 크다면 많은 시간이 소요 → 작은 데이터셋에 유용

선형 분류 모델의 교차 검증 실습

# K-Fold CV
from sklearn.model_selection import cross_val_score

k_fold_score = np.mean(cross_val_score(logistic_reg, X, y, cv=5))


# Stratified CV
from sklearn.model_selection import cross_val_score, StratifiedKFold

stratified_cv_score = np.mean(cross_val_score(logistic_reg, X, y, cv=StratifiedKFold(5)))


# LOOCV
from sklearn.model_selection import cross_val_score, LeaveOneOut

loocv_score = np.mean(cross_val_score(logistic_reg, X, y, cv=LeaveOneOut()))

 

 

4. 성능 평가

  • 머신 러닝 모델의 성능을 객관적으로 측정하고 비교하는 과정에서 모델의 강점과 약점을 파악하는 과정
  • 성능 평가에 사용되는 지표를 metric이라고 함
  • metric을 선택할 때는 목적에 맞고 해석이 잘되는 것을 선택해야 함
  • 지금까지 배운 metrics :
지도 학습 비지도 학습
분류 문제 회귀 문제 군집화 이상치 탐지
정확도(Accuracy)
혼동 행렬(Confusion matrix)
정밀도(Precision)
재현율(Recall)
F1 score
MSE(Mean Squared Error) SSE(Sum of Squared Error)
실루엣 계수
분류 문제의 metric을 대안으로 활용

 

 

4.1 분류 문제 성능 Metric

 

4.1.1 Confusion Matrix

  • 실제 레이블과 예측 레이블을 비교해 모델의 성능을 시각적으로 표현한 행렬
  • 4가지 요소로 구성 :
    • 진짜 양성(True Positive, TP)
    • 거짓 양성(False Negative, FN)
    • 진짜 음성(True Negative, TN)
    • 거짓 음성(False Negative, FN)

지표의 계산식
Confusion Matrix의 모습

 

 

4.1.2 ROC(Receiver Operating Characteristic) curve

  • 이진 분류 문제에서 널리 사용되는 모델 성능 측정 도구
  • 양성(positive)과 음성(negative)를 나누는 임계값의 변화에 따른 성능을 시각화한 그래프
    • x 축 : 거짓 양성률(False Positive Rate, FPR)
      • 전체 음성 중에서 실제로는 음성인데 양성이라고 잘못 찾은 비율
    • y 축 : 진짜 양성률(True Positive Rate, TPR)
      • Recall과 동일!
  • 왼쪽 위에 포인트가 존재하게 하는 임계치를 선택하는 것이 최고!
  • ROC 커브 : 
    • 머신 러닝 모델이 양성을 최대한 많이, 잘 찾아내면서 잡음에 의한 거짓 탐지를 최소화하는지를 바탕으로 적절한 임계치를 찾는 도구

ROC curve

  • 그림의 왼쪽 상단에 있는 roc curve위의 빨간점이 최상의 위치에 있게 하는(그림 속 위치) 임계치(검은색 바)를 찾는 도구

ROC curve 예시

  • 최적의 임계치(threshold) 찾기
# 최적 threshold 위치 찾기
# tpr은 크고 fpr은 작아야하므로 아래와 같은 코드로 위치를 선정
closest_leftupper_conner = np.argmin(np.abs(tpr - 1) + fpr)
optimal_threshold = thresholds[closest_leftupper_conner]
print(f'가장 좌측 상단에 위치한 포인트의 threshold 값 : {optimal_threshold}')

최적의 임계치를 표시한 ROC curve

 

 

 

4.1.3 AUC(Area Under the Curve) 점수

  • ROC 커브에서도 확인이 가능한 음성과 양성을 잘 구분했는지의 지표
  • 음성과 양성이 잘 분류된 모델이라면 ROC 커브가 왼쪽 위로 치우침
  • 그렇지 않다면 y = x 그래프에 수렴함
  • ROC 커브 아래의 면적으로 좋은 분류기인지 아닌지를 알 수 있음 → AUC 점수
  • 최대 1, 최소 0.5
  • 1에 가까울수록 좋은 분류기

 

4.2 회귀 문제 성능 Metric

 

4.2.1 (결정 계수, Coefficient of Determination)

  • 회귀 모델의 성능을 평가하는 통계적 지표
  • 모델이 데이터의 변동성을 얼마나 잘 설명하는지 나타냄

결정 계수 식

  • SSres : 모델 예측값과 실제 값 사이의 제곱합
  • SStot : 실제 값들의 평균과 실제 값 사이의 차이 제곱합
    • 실제 데이터 내의 총 변동량
    • 모델이 설명해야하는 '전체' 변동성의 양을 의미함
  • R² = 1 : 모델이 데이터의 변동성을 완벽하게 설명함 → 모든 데이터 포인트가 회귀선에 정확히 놓여있는 상태
  • R² = 0 : 변동성을 설명하지 못함 → 단순히 모델의 평균값을 예측
  • 0 < R² < 1 : 일부 변동성을 설명. R²이 클수록 설명력이 높다고 볼 수 있음
  • R²의 값이 클수록 과적합의 위험성도 있으니 주의해야함
  • R² 값 확인
from sklearn.metrics import r2_score
r2 = r2_score(y, y_pred)
print(f'R² 값 : {r2:.4f}')

회귀 문제에서의 R²값 확인

 

 

5. 이미지 분류 실습

  • 문제 설정 : 학습된 이미지 분류 모델을 활용해 이미지 분류 실습 진행
  • 입력으로 하나의 이미지를 제공하고 해당 이미지의 종류(클래스)를 예측
  • 선택 가능한 모든 클래스에 대한 정답 점수값을 예측하고 그 중 가장 큰값을 선택
  • 사용할 모델 : ResNet
    • 연구적으로도 많이 사용되며 현업에서도 기본 모델로 많이 사용하는 모델
    • 당시 사람의 이미지 인식 능력을 넘어선 최초의 이미지 인식 모델
    • 모델의 깊이인 Layer에 따라 18, 34, 50, 101, 152라는 5가지 종류가 존재
      • 깊이가 얕을수록 성능 ↓, 결과 도출 속도 ↑
      • 깊이가 깊을수록 성능 ↑, 결과 도출 속도 ↓
  • 딥러닝 모델을 학습하는 시간은 머신 러닝 모델 대비 오래 걸리기 때문에 Pytorch의 이미 학습된 모델을 활용

5.1 데이터 전처리

  • 인터넷에서 이미지 url을 가져와 변수에 할당
url = 'https://cdn.newsquest.co.kr/news/photo/202305/206197_97856_1244.jpg'

import requests
from PIL import Image
import matplotlib.pyplot as plt

# 이미지를 웹에서 불러오는 함수
def load_image_from_web(url):
    response = requests.get(url, stream=True).raw
    img = Image.open(response).convert('RGB')
    if img is None :
        raise ValueError('url로부터 데이터를 가져오지 못했습니다. 다른 url을 사용해보세요!')
    return img

# 이미지 시각화 코드
def imshow(img):
    plt.imshow(img)
    plt.axis('off')
    
image = load_image_from_web(url)
imshow(image)

실습에 사용될 이미지

  • ResNet 모델도 전처리를 진행한 뒤 추론을 진행해야 함
    • 모델이 학습할 당시의 전처리 과정이 저장된 class가 존재
    • 만약 resnet18모델을 사용한다면 ResNet18_Weights라는 이름의 클래스에 있음
    • 해당 전처리 코드를 가져와 이미지에 적용
import re
import torchvision.models as models

# 모델 선택 및 로드
def get_model_and_trans(model_name):
    if model_name not in ['resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152']:
        raise ValueError("model name을 확인해주세요.  옵션 : 'resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152'")

    weight_name = 'ResNet' + re.findall(r'\d+', model_name)[0] +'_Weights'
    weights = getattr(models, weight_name).DEFAULT

    transforms = weights.transforms()

    model = getattr(models, model_name)(weights=weights)
    model.eval()

    meta_data = weights.meta
    return model, transforms, meta_data
# 타깃 모델을 선택하고
model_name='resnet18'

# 모델과 그에 맞는 전처리 과정을 불러온다
myModel, transform, meta_data = get_model_and_trans(model_name)
  • 전처리 진행
import torch

# 이미지 전처리 진행
trans_image = transform(image)
trans_image = torch.unsqueeze(trans_image, 0)
def imshow_from_tensor(tensor):
    image = tensor.cpu().clone()  # 텐서 복제
    image = image.squeeze(0)      # 배치 차원 제거
    image = image.permute(1, 2, 0)  # 차원 재배열
    image = image.numpy()

    plt.imshow(image)
    plt.axis('off')
    plt.show()
    
# 전처리가 진행되면 원본 이미지의 형태가 많이 훼손됨
# 하지만 딥러닝 모델은 이런 형태를 더욱 잘 알아본다고!
imshow_from_tensor(trans_image)

딥러닝 모델이 잘 알아볼 수 있는 형태로 전처리된 이미지

5.2 결과 확인

# 모델에 입력하고 결과를 출력
output = myModel(trans_image)

output 출력

  • output 중 최고 값은 가지는 것이 출력 결과값이 됨
import torch.nn.functional as F

# 출력 결과로부터 출력 결과 도출하기
conf, predicted = F.softmax(output, dim=1).max(1)
total_class = meta_data["categories"]
cls = total_class[predicted.item()]

print(f'최종 결과 입력 이미지는 {conf.item()*100:.2f} % 의 확률로 {cls} 이라고 예측됩니다.')

최종 결과

  • ResNet 모델을 입력된 이미지가 1,000개의 이미지 종류 중 어떤 부류에 속하는지를 판단함(1000의 크기를 갖는 vector)
  • 이 vector값 중, 제일 큰 값을 갖는 위치의 클래스가 실제 정답이 됨
    • 어떤 위치가 어떤 클래스인지는 메타 데이터의 형태로 weights 객체에 들어있음
  • 출력값을 통해 딥러닝 모델이 얼마나 큰 정확도로 입력 이미지의 종류에 확신을 갖고 있는지 계산할 수 있음

 

 


느낀점

딥러닝은 사람의 thought process를 모방하는 학문이다보니 보건 전공인 나에게는 너무나 흥미로웠다(뉴런이 반갑기도 했고!). 특히나 뉴런의 역할을 모방한 퍼셉트론의 컨셉이 정말 신기하고, 나중에 더 깊게 공부할 기회가 생긴다면 굉장히 재밌을 것 같다. 이번주 수업은 알차고 강사님이 수업을 너무나 잘해주셔서 걱정한 게 무색할 정도로 즐겁게 배웠다. 의료 도메인에 관심이 많은데 이쪽 분야는 머신 러닝의 비중이 클 것 같아서 앞으로 관련 데이터로 많이 공부해봐야겠다.

+ Recent posts