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

- Convolution : 이미지의 한 픽셀과 주변 픽셀의 연관성을 유지시키며 필터에 학습하는 것
- Pooling : 이미지가 너무 많아지지 않게 1개의 이미지에 1개의 출력을 만들며 기존 이미지에 padding없이 크기를 줄이는 것
2.2 텍스트 처리 : RNN
- 사람의 텍스트 처리 과정 :
- 문장의 앞에서부터 한 단어씩 읽음
- 새로운 단어가 들어오면 이를 읽고 이해
- 앞서 해석해 만들어낸 기억 정보에 정보를 추가하여 기억을 업데이트
- 문장이 끝나는 시점까지 위 과정을 되풀이
- 기계의 텍스트 처리 과정 :
- 문장의 앞에서부터 한 단어씩 입력으로 받음
- 새로운 단어가 들어오면 이를 처리해서 정보 추출
- 앞서 해석해 만들어낸 정보 덩어리에 추출한 정보까지 추가하여 정보를 업데이트
- 문장이 끝나는 시점까지 위 과정을 되풀이(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번의 학습 및 평가 과정이 반복됨
- 의미 :
- 모든 데이터가 학습 및 평가로 사용됨
- 데이터 활용의 극대화
- 과적합 방지
- 논리적인 일반화 평가 진행

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)


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

- 그림의 왼쪽 상단에 있는 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}')


4.1.3 AUC(Area Under the Curve) 점수
- ROC 커브에서도 확인이 가능한 음성과 양성을 잘 구분했는지의 지표
- 음성과 양성이 잘 분류된 모델이라면 ROC 커브가 왼쪽 위로 치우침
- 그렇지 않다면 y = x 그래프에 수렴함
- 즉 ROC 커브 아래의 면적으로 좋은 분류기인지 아닌지를 알 수 있음 → AUC 점수
- 최대 1, 최소 0.5
- 1에 가까울수록 좋은 분류기
4.2 회귀 문제 성능 Metric
4.2.1 R² (결정 계수, 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}')

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 중 최고 값은 가지는 것이 출력 결과값이 됨
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를 모방하는 학문이다보니 보건 전공인 나에게는 너무나 흥미로웠다(뉴런이 반갑기도 했고!). 특히나 뉴런의 역할을 모방한 퍼셉트론의 컨셉이 정말 신기하고, 나중에 더 깊게 공부할 기회가 생긴다면 굉장히 재밌을 것 같다. 이번주 수업은 알차고 강사님이 수업을 너무나 잘해주셔서 걱정한 게 무색할 정도로 즐겁게 배웠다. 의료 도메인에 관심이 많은데 이쪽 분야는 머신 러닝의 비중이 클 것 같아서 앞으로 관련 데이터로 많이 공부해봐야겠다.
'Data Science > TIL (Today I Learned)' 카테고리의 다른 글
| 프로그래머스 데이터분석 데브코스 1기 - 52일차 (1) | 2024.02.06 |
|---|---|
| 프로그래머스 데이터분석 데브코스 1기 - 51일차 (0) | 2024.02.05 |
| 프로그래머스 데이터분석 데브코스 1기 - 49일차 (1) | 2024.02.01 |
| 프로그래머스 데이터분석 데브코스 1기 - 48일차 (0) | 2024.01.31 |
| 프로그래머스 데이터분석 데브코스 1기 - 47일차 (1) | 2024.01.30 |