no image
GAN, VAE, Flow-based model, Diffusion
옛날에 노션에 정리했던 내용인데 지우긴 아까워서 업로드함  대표적인 이미지 생성 모델들 - GAN, VAE, Flow-base model, Diffusion모두 생성 모델링을 위한 딥러닝 아키텍처에 속함생성 모델: 입력 이미지에 대한 분포 p(x)를 학습해 새로운 이미지(새로운 이미지이면서 기존 이미지에서 특성을 추출했기에 최대한 입력이미지와 유사한 이미지)를 생성하는 것을 목표로 함1. GAN (Generative Adversarial Networks)상호 적대적인 생성자(generator, G)와 판별자(Discriminator, D)라는 두 개의 신경망을 이용한 적대적 생성 모델생성자는 주어진 데이터 분포와 유사한 새로운 데이터를 생성하고, 판별자는 생성된 데이터와 실제 데이터를 구별함생성자와 구별..
2024.09.20
AI
no image
[CS231N] Lecture 4 - Introduction to Neural Networks
유한 차분은 수치적(numerical)한 방법으로 경사 계산 가능 -> 추정값이지만 동시에 작성하기 쉬움분석적 경사 : 일단 분석적 경사에 대한 표현을 얻으면, 이걸 유도하기 위해 모든 수학과 미분을 해야함 → 실수하기 쉬움동시에 우리의 구현을 수치적 경사로 확인해 수학을 제대로 했는지 확인하는 것실제에서 우리가 하고 싶은 것 = 분석적 경사를 유도해서 사용하는 것임의의 복잡한 함수에 대해 어떻게 분석적 경사를 계산하는가? = 계산 그래프(computational graph)사용! (일종의 프레임워크) Computational graphs앞의 강의들에서 배운 내용들을 아래와 같이 computational graphs 형태로 표현할 수 있음computational graphs의 장점1. input과 loc..
2024.09.03
no image
[CS231N] Lecture 3 - Loss Functions and Optimization
2강 Review & 3강 PreviewW : 이미지의 모든 픽셀에 대해, 그리고 10개의 모든 클래스에 대해 그 픽셀이 그 클래스에 얼마나 영향을 주는가-> matrix W의 행들이 그 클래스의 템플릿에 해당한다는 것행을 꺼내서 이미지로 다시 만들면 각 클래스에 대해 학습된 템플릿으로 시각화할 수 있음이떄, W가 좋은지 나쁜지를 보는 척도가 바로 오늘 다루는 손실함수 (Loss function)!  W를 사용해 10개 클래스의 점수를 얻을 수 있음위에서 3개의 이미지에 대한 학습 데이터를 보면, 이 이미지들에 대해 어떤 W 값에 대해 예측된 10개의 클래스 점수가 존재하는데, 상대적으로 어떤 점수들은 좋고 어떤 점수는 좋지 않음ex : 왼쪽 이미지는 고양이임을 사람의 관점에서는 바로 판단이 가능함. 근..
2024.07.23
no image
[PyTorch] Chapter 11
Chapter 11. 텍스트의 유사도(Text similarity)11-1. 단어의 표현 방법 단어의 표현 방법은 크게 국소 표현(Local Representation) 방법과 분산 표현(Distributed Representation) 방법으로 나뉨 국소 표현 방법 : 해당 단어 그 자체만 보고, 특정값을 맵핑하여 단어를 표현하는 방법 puppy(강아지), cute(귀여운), lovely(사랑스러운)라는 단어가 있을 때 각 단어에 1번, 2번, 3번 등과 같은 숫자를 맵핑(mapping)하여 부여함분산 표현 방법 : 그 단어를 표현하고자 주변을 참고하여 단어를 표현하는 방법 puppy(강아지)라는 단어 근처에는 주로 cute(귀여운), lovely(사랑스러운)이라는 단어가 자주 등장하므로, puppy..
2024.07.16
no image
[PyTorch] Chapter 10
Chapter 10. 언어 모델(Language Model)이란?10-1. 언어 모델(Language Model)이란?언어라는 현상을 모델링하고자 단어 시퀀스(문장)에 확률을 할당(assign)하는 모델 = 가장 자연스러운 단어 시퀀스를 찾아내는 모델통계를 이용한 방법 & 인공 신경망을 이용한 방법으로 언어 모델을 만들 수 있음최근에는 후자가 더 좋은 성능을 보이고 있음 ex) GPT, BERT단어 시퀀스에 확률을 할당하게 하기 위해 가장 보편적으로 사용되는 방법은 언어 모델이 이전 단어들이 주어졌을 때 다음 단어를 예측하도록 하는 것> 언어 모델링주어진 단어들로부터 아직 모르는 단어를 예측하는 작업= 언어 모델이 이전 단어들로부터 다음 단어를 예측하는 일 > 단어 시퀀스의 확률 할당언어 모델은 확률을 ..
2024.07.16
[PyTorch] Chapter 3
Chapter 3. 텍스트 전처리(Text preprocessing)3-1. 토큰화(Tokenization)토큰화(Tokenization)자연어 처리에서 크롤링 등으로 얻어낸 코퍼스 데이터를 사용하고자 하는 용도에 맞게 토큰화(Tokenization) & 정제(cleaning) & 정규화(normalization)하는 작업을 거친다.  토큰화 : 주어진 코퍼스에서 토큰(token)이라 불리는 단위로 나누는 작업토큰의 단위는 보통 의미있는 단위로 정의함 단어 토큰화 (word tokenization): 토큰의 기준이 단어인 경우여기서의 단어는 단어 단위 외에도 단어구, 의미를 갖는 문자열로 간주되기도 함구두점이나 특수문자를 전부 제거하면 토큰이 의미를 잃어버리는 경우가 발생하기도 함 ex) 구두점을 제외시..
2024.07.16
no image
[PyTorch] RNN & LSTM & GRU
RNN(Recurrent Neural Network)시퀀스(Sequence) 모델로, 입력과 출력을 시퀀스 단위로 처리하는 모델임피드 포워드 신경망과(Feed Forward Neural Network) 달리 은닉층의 노드에서 활성화 함수를 통해 나온 결과값을 출력층 방향으로도 보내면서, 다시 은닉층 노드의 다음 계산의 입력으로 보내는 특징 가짐피드 포워드 신경망 : 은닉층에서 활성화 함수를 지난 값이 오직 출력층 방향으로만 향하는 신경망x : 입력층의 입력 벡터y : 출력층의 출력 벡터b : 편향 (그림에서는 생략됨)t : 현재 시점cell : 은닉층에서 활성화 함수를 통해 결과를 내보내는 역할을 하는 노드. 메모리 셀 또는 RNN 셀이라고도 표현함은닉층의 메모리 셀은 각각의 시점(time step)에서..
2024.07.16
no image
[CS231N] Lecture 2 - Image Classification
한글 번역 : CS231N_17_KOR_SUB/kor/Lecture 2 Image Classification.ko.srt at master · visionNoob/CS231N_17_KOR_SUB (github.com)  CS231N_17_KOR_SUB/kor/Lecture 2 Image Classification.ko.srt at master · visionNoob/CS231N_17_KOR_SUBCS231N 2017 video subtitles translation project for Korean Computer Science students - visionNoob/CS231N_17_KOR_SUBgithub.com 1. Image Classification이미지 분류 = 컴퓨터 비전의 핵심 작업 => ..
2024.07.16

옛날에 노션에 정리했던 내용인데 지우긴 아까워서 업로드함 


 

대표적인 이미지 생성 모델들 - GAN, VAE, Flow-base model, Diffusion

  • 모두 생성 모델링을 위한 딥러닝 아키텍처에 속함
  • 생성 모델: 입력 이미지에 대한 분포 p(x)를 학습해 새로운 이미지(새로운 이미지이면서 기존 이미지에서 특성을 추출했기에 최대한 입력이미지와 유사한 이미지)를 생성하는 것을 목표로 함

1. GAN (Generative Adversarial Networks)

  • 상호 적대적인 생성자(generator, G)와 판별자(Discriminator, D)라는 두 개의 신경망을 이용한 적대적 생성 모델
  • 생성자는 주어진 데이터 분포와 유사한 새로운 데이터를 생성하고, 판별자는 생성된 데이터와 실제 데이터를 구별함
  • 생성자와 구별자는 경쟁을 통해 성능을 개선시키고, 생성자는 실제 데이터와 구별할 수 없는 데이터를 생성하게 됨
  • 장점 : 1. 다양한 데이터 학습이 가능 2. 기존의 생성 모델보다 정교한 데이터 생성 가능
  • 단점 : 1. 많은 양의 데이터가 요구됨 2. 안정적인 학습이 어려울 수 있음

 

2. VAE (Variational Autoencoder)

  • input data를 가장 잘 표현하는 feature를 추출해 latent vector z를 통해 X와 유사하지만 새로운 데이터를 생성해내는데 목표를 가짐
    • 이미지의 latent space에서 sampling해 완전히 새로운 이미지나 기존 이미지를 변형하는 방식을 사용함
    • 이때 사용되는 확률분포 z는 latent vector라고 불림
  • encoder: x를 입력받아 z와 대응되는 평균과 분산을 구하는 네트워크 = q(z|x)
  • decoder: z를 입력받아 x와 대응되는 평균과 분산을 구하는 네트워크 = p(x|z)
  • Autoencoder(AE)와 확률적 요소를 결합한 모델
    • Autoencoder: 데이터의 압축(or 차원 축소) 및 잠재 변수(latent variable) 표현을 학습하는 데 사용되는 신경망 아키텍처
      • 결정론적 모델로 입력 데이터를 고정된 잠재 변수 표현으로 매핑하고 디코딩함(VAE는 확률 분포를 사용해 잠재 변수 모델링함)
      • VAE는 데이터 생성과 잠재 변수 공간에서의 탐색에 적합한 모델인 반면, Autoencoder는 주로 데이터 압축 및 잠재 변수 표현에 중점을 둔 모델
    • 오토인코더처럼 Unsupervised Learning이기 때문에 입출력이 같기를 원하는 상황은 똑같지만, VAE는 latent vector가 평균 분산으로 이루어진 가우시안 분포를 가지게 되고, AE는 잠재 코드가 어떠한 행렬로 나오게 됨
  • 훈련 목적 함수로 ELBO(Evidence Lower Bound)를 사용하며, 이를 최대화하는 방식으로 훈련됨
    • ELBO: 잠재 변수 Z에 대한 관측 데이터 X의 로그 우도와 잠재 변수의 확률 분포와 사전 확률 분포 간의 Kullback-Leibler(KL) 발산의 합으로 구성됨
  • 인코더는 가우시안 분포를 따르는 것으로 가정하고, 이 분포에서 평균과 분산을 출력함
  • 하지만 현실적으로 Z의 분포 전체를 샘플링하는 것이 어렵기에 Reparmeterization Trick을 이용해 평균 + 분산*(가우시안 분포 랜덤 샘플링)을 해준 값을 Z(latent vector)로 가정함

 

3. Flow-based models

  • 확률 밀도 함수를 모델링하기 위한 생성 모델로, 확률 분포의 변환 표현 Flow를 사용함
    • Flow: 데이터 분포를 변환하면서 확률 분포를 추론하는 방법
  • 잠재 벡터 z의 확률 분포에 대한 일련의 역변환을 통해 데이터 x의 분포를 명시적으로 학습하며 이를 간단하게 negative log-likelihood로 해결함
  • 생성에 활용되는 inverse mapping을 학습하기 위해 invertible function을 학습함
  • 훈련이 비교적 안정적이고 수렴하기 쉽다는 특징이 있음

 

4. Diffusion

  • Diffusion(확산) : 특정한 데이터 패턴이 서서히 반복을 거쳐 와해되는 과정
  • Diffusion 모델은 학습된 데이터의 패턴을 생성해내는 역할을 하는데, 이러한 패턴 생성 과정 학습을 위해 고의적으로 패턴을 무너뜨리고(Noising)(=forward diffusion process) 이를 다시 복원하는 조건부 확률 밀도 함수를 학습함(Denoising)(=reverse diffusion process)
    • forward diffusion process : t-1 시점에서 t 시점으로 노이즈를 manual하게 점점 추가해나감 → 사전 정의된 guassian 분포에서 생성됨(우리가 연산을 알 수 있음)
    • reverse diffusion process: 수학적으로 변환하기 어려움 & 학습하는 과정 필요
    • noising과 denoising을 하나의 단일 step transformation으로 학습하는 것은 매우 어려운 과제이기에 여러 단계로 쪼개어진 Markov Chain으로 각 process를 구성함
  • VAE는 하나의 latent vector로 수행한다면, Diffusion은 sequential한 여러 개의 latent vector를 사용함

 


Flow based Generative Models 1 : Normalizing Flow - DevKiHyun’s Deep Learning

VAE(Variation Auto Encode.. : 네이버블로그 (naver.com)

 

VAE(Variation Auto Encoder)의 이론과 수식을 알아보자

참고자료 : KAIST 강남우 교수님의 딥러닝과 설계 강의 VAE란 무엇인가? Input Data를 가장 잘 ...

blog.naver.com

디퓨전 Diffusion 모델과 DDPM 원리.. : 네이버블로그 (naver.com)

 

디퓨전 Diffusion 모델과 DDPM 원리 이해하기

Reference : 고려대 산업경영공학부 DSBA 연구실 유튜브 What is Diffusion? Diffusion = 확...

blog.naver.com

 

'AI' 카테고리의 다른 글

text-to-image(txt2img)  (0) 2024.05.05

 

  • 유한 차분은 수치적(numerical)한 방법으로 경사 계산 가능 -> 추정값이지만 동시에 작성하기 쉬움
  • 분석적 경사 : 일단 분석적 경사에 대한 표현을 얻으면, 이걸 유도하기 위해 모든 수학과 미분을 해야함 → 실수하기 쉬움동시에 우리의 구현을 수치적 경사로 확인해 수학을 제대로 했는지 확인하는 것

실제에서 우리가 하고 싶은 것 = 분석적 경사를 유도해서 사용하는 것

임의의 복잡한 함수에 대해 어떻게 분석적 경사를 계산하는가? = 계산 그래프(computational graph)사용! (일종의 프레임워크)

 

Computational graphs

앞의 강의들에서 배운 내용들을 아래와 같이 computational graphs 형태로 표현할 수 있음

computational graphs의 장점

1. input과 local gradient 값을 쉽게 파악할 수 있고, 복잡한 형태의 analytic gradient(앞 강의에서 설명한 해석적 방식)를 보다 쉽게 계산해낼 수 있음

2. 일단 계산 그래프로 함수를 표현하면 역전파(backpropagation)의 테크닉 사용 가능 -> 반복적으로 체인 룰(chain rule)을 사용해 계산 그래프의 모든 변수에 대해 gradient를 얻음

 

 

 

대략적인 순서는 아래와 같음

  • 함수에 대한 computational graph 만들기
  • 각 local gradient 구해놓기
  • chain rule
  • z에 대한 최종 loss L은 이미 계산되어 있음
  • 최종 목표는 input에 대한 gradient를 구하는 것

 

Backpropagation

Chain Rule 이용해 backpropagation 가능

목표 : 함수를 가지는 것

 

문제 1

아래와 같이 하나의 Computation Node에 대해 국소적으로 볼 수 있음

이런 국소적 상황에서는 보다 쉽게 gradient 값을 각각 구할 수 있음

  • 더하기 노드 다음의 중간 변수 : q -> q = x+y, f =qz
  • x와 y에 대한 q의 경사 : 1 <- 더하기 때문
  • q와 z에 대한 f의 경사 : 각각 q와 z <- 곱하기 규칙 때문

=> 목표 : x, y, z에 대한 f의 경사를 찾는 것

 

뒤에서부터 차례로 gradient 값 구하기 가능

마지막 값의 gradient는 1임

다음 z 값에 대한 gradient 값 = q

다음 q 값에 대한 gradient 값 = z -> 따라서 z = -4 값을 가짐

 

x와 y에 대한 값(df / dq)을 계산하기 위해 앞에서 계산한 gradient 값과 현재 local gradient 간에 chain rule 적용 가능함

  • y에 관한 경사는 f와 직접적으로 연결되어 있지 않기 때문에 중간 노드인 q를 통해 연결하는 것

결과적으로 q 값에 대한 f의 gradient와 y값에 대한 q의 gradient를 곱하면 -4 * 1 = -4

x값 또한 -4 * 1 = -4 를 가짐을 backpropagation을 통해 유추할 수 있음

 

 

위의 설명을 더 보기 쉽게 그림으로 설명할 수 있음

 

x와 y값을 입력으로 받고 f라는 함수에 넣어서 z 라는 값을 얻어냄

이때 z를 x로 미분한 값과 z를 y로 미분한 값을 얻어낼 수 있는데, 이를 local gradient 값이라고 함

 

역전파를 할 때, 우리는 제일 뒤에서 시작함 & 끝에서 시작점으로 작업해나감

각 노드에 도달할 때 각 노드에서 직접적인 출력에 대한 거꾸로 오는 업스트림 경사(upstream gradient)를 갖게 됨

그래서 역전파에서 이 노드에 도달할 쯤에, 우리는 이미 z에 대한 우리의 최종 손실 L에 대한 경사를 계산한 것임

 

다음으로 찾고 싶은 것은 노드 바로 앞의 것, x와 y값에 대한 경사임 -> chain rule을 이용함

x에 대한 이 손실 함수의 경사는 (z에 대한 경사) * (이 x에 대한 z의 지역 경사) 

따라서 체인 룰에서 항상내려오는 upstream gradient를 받아 지역 경사로 곱해 입력에 대한 경사를 얻음

  • y에 대한 L의 경사도 같은 아이디어 적용함

 

 

 

즉, 각각의 노드에서 지역 경사를 얻고 역전파 중에 업스트림으로부터 오는 수치적 경사값들을 받아서 그걸 local gradient로 곱함

그리고 이 값을 연결된 노드, 즉 뒤쪽에 있는 다음 노드로 전달하는 것

 

이렇게 입력을 받고 loss값을 구하는 계산 과정을 forward pass라고 하고,

forward pass가 끝난 이후 역으로 미분해가며 기울기 값을 구해가는 과정은 backward pass라고 부름

 

몇가지 게이트 법칙은 아래와 같음

  • add gate: 비율만큼 나눠줌
  • max gate: 하나만 실제로 영향을 주는 값이다. 그쪽만 gradient 가짐
  • 하나의 노드에서 forward로 Multi로 나가면 역전파할때 gradient 더해줘야됨

 

문제 2

더 복잡한 예로는 아래와 같음

빨간색 박스가 upstream gradient인데, 이 값을 이용해 지역 경사를 계산할 수 있음

df / dx = -1/x^2 인데 여기에 순방향에 사용했던 x 값인 1.37을 대입해 계산하면 -0.53이 됨

 

 

업스트림으로부터의 경사가 -0.53이고, 지역 노드는 +1

아래쪽의 c + x에 대해서는 지역 경사가 1이므로 체인 룰을 사용하면 경사는 -0.53이 됨

 

위 과정을 반복하다보면 w0과 x0에 도달하게 되고, 모든 변수에 대한 경사를 얻을 수 있게 됨

이때 x1과 w1에 대한 경사도 같은 방식으로 적을 수 있음

 

 

주의할 점은 계산 그래프를 만들 때 계산 노드를 우리가 원하는 입상(granularity)으로 정의할 수 있다는 것임

즉, 우리가 할 수 있는 만큼 완전히 간단하게 쪼갤 수 있다는 것

  • 계산 그래프를 만들 때, 계산을 얼마나 세분화할지(즉, 입상을 얼마나 세밀하게 할지) 선택할 수 있음. 아주 세밀하게 나눌 수도 있고, 여러 단계들을 묶어서 하나의 큰 단계로 만들 수도 있음

 

아래의 파란색 박스는 sigmoid 함수와 같은 형태로, 미분 결과는 (1-sigmoid(x)) * sigmoid(x) 와 같은 형태를 가짐

시그모이드 함수를 하나의 노드로 만들어 계산 그래프에 추가해 여러 과정을 skip하고 간단하게 계산 할 수 있게 됨

아래의 예시와 같이 전체 시그모이드를 하나의 노드로 취급해서 sigmoid(x)의 출력값인 0.73를 이용하면 loss = (1-0.73) * 0.73 = 0.2 의 값을 가지는 것을 볼 수 있음

즉, 이 지역 경사 값이 0.2이므로 업스트림 경사인 1을 곱하면 정확히 시그모이드 사용 이전의 더 작은 계산으로 쪼갰을 때의 경우와 동일한 값을 얻을 수 있는 것임

 

계산 그래프를 세밀하게 만들면 각 단계가 단순해지지만, 그래프 자체는 복잡해지는 trade-off 관계가 존재함

  • 반대로 여러 단계들을 묶으면 그래프는 간단해지지만, 각 노드에서 수행해야 하는 계산이 복잡해짐

-> 둘 사이의 균형을 맞추는 것이 중요함

 

경사 계산이 어렵다면 계산 그래프로 문제를 시각화하고 체인 룰을 이용해 문제를 해결할 수 있음

 

인풋이 벡터인 경우는 gradient가 아닌 Jacobian을 계산해주면 됨

  • Jacobian matrix : 각 요소의 미분을 포함하는 행렬
  • Jacobian 행렬은 야코비 행렬이라고 함. 한국에서 번역 과정에서 자코비안이나 야고비나 다양하게 불리는 것 같

또한 입력의 각 요소는 출력의 해당 요소에만 영향을 주므로 대각 행렬임

 

 

 

문제 3

4096 차원의 입력 벡터 (CNN을 볼 때 흔히 보는 사이즈)가 있고, 이 노드는 원소마다의(element-wise) 최대값을 취해 줌

-> 우리가 x의 f가 0과 항목마다 x를 비교해 최대값인 거고, 출력은 4096 차원의 벡터가 되는 것

 

이 경우의 Jacobian matrix 사이즈는 [4096 * 4096]

-> 여기서 100개의 mini batch를 가지고 있을 경우 [409600 * 409600] 사이즈를 갖게 됨

= 사이즈가 너무 거대하기에 완전히 작업하는 것이 사실상 불가능

실제에서는 대부분의 경우 이 거대한 자코비안 행렬을 계산할 필요가 없는데 그 이유를 설명하면 아래와 같음

 

각 요소별로 최댓값을 갖는 지점에서 어떤 일이 일어나는지를 생각해본다면 그것은 각각의 편미분한 값과 이어질 것임

입력의 어떤 차원이 출력의 어떤 차원에 영향을 주는지, 그래서 Jacobian 행렬은 대각선 형태의 구조를 볼 수 있음

입력의 각 요소는 오직 출력의 해당 요소에만 영향을 주기 때문에 Jacobian 행렬은 대각 행렬이 될 것임

-> 실제로 공식화할 필요 없이 채워넣어서 사용하기만 하면 됨

 

문제 4

알고 싶은 것 : q에 대한 경사

q는 L2앞의 중간 변수로, 2차원 벡터

=> 목표 : q의 각 원소가 어떻게 f의 최종 값에 영향을 주는지 알아내는 것

ex : q1에 대한 f의 경사는 f(q) 미분하면 2q1이 됨 -> qi의 각 원소에 대한 표현을 벡터 형태로 쓰면 2*q로 놓을 수 있음

 

w에 대한 경사를 얻어 각 원소별로 계산할 수 있고, 이를 벡터화된 형식으로 적을 수 있음

이때 변수에 대한 경사를 항상 체크해야 하는데, 변수와 같은 형태를 가져야 함

  • 경사의 각 원소는 그 원소가 최종 출력에 얼마나 영향을 미치는 지 정량화한 것이기 때문

 

위를 벡터화된 형태로 적으면 아래와 같음

 

벡터의 gradient는 항상 원본 벡터의 사이즈와 같아야 함을 주의

 

위 과정들을 모듈화하면 아래와 같음

계산 그래프에서 노드에서 지역 경사 계산 -> 내려오는 업스트림 경사를 그것들과 연결

이 과정을 forward와 backward의 API로 생각할 수 있음

forward에서 이 노드의 출력을 계산하는 함수를 구현하고, backward에서 경사를 계산함 

 

아래는 특정 게이트에 대한 구현임

  • forward : x와 y를 입력으로 받아 z값 반환함
  • backward : dz를 입력으로 받음 (업스트림 경사) & 아래로 내려가는 x와 y에 대한 경사인 dx, dy 출력

 

아래는 모든 것이 scalar인 경우

순방향으로 보면 -> forward의 모든 값을 저장하고 있어야 함. 많은 경우 backward가 이걸 사용하기 때문

forward에서 x, y를 저장하고, backward에서 체인 룰을 사용해서 업스트림 경사의 값을 취하고 다른 가지의 값을 곱함

그래서 dx에 대해 저장했던 self.y의 값을 dz로 곱함 (dy에 대해서도 같음)

 

많은 딥러닝 프레임워크와 라이브러리에서 이런 모듈화를 따르고 있음 ex) Caffe

 

Neural Networks

: 신경망은 함수들의 집합(class)로 비선형의 복잡한 함수를 만들기 위해 간단한 함수들을 계층적으로 여러 개 쌓아올리는 형태임

 

이전까지는 linear score function (ex : f = Wx)를 최적화하고자 하는 함수의 예로 사용했음

이제는 이 선형 함수 대신 변형으로 2개의 layer로 된 신경망을 얻을 수 있음

 

위 식은 W1과 x를 행렬 곱셈해서 중간값을 얻고 0과 W의 최대값(max of 0 and W)을 취하는 비선형 함수를 가짐

= 이 선형 layer과 출력과의 최대값

 

이 형태는 비선형성을 가진다는 것이 중요함

비선형성이 없으면 선형 레이어를 다른 레이어 위에 쌓으면 하나의 선형 함수가 될 뿐이기 때문임

그래서 행렬 곱과 선형 레이어를 취해서 여러 개를 쌓는데, 그 사이에 비선형 함수를 넣는 것임 

그 후 score function을 얻고 score의 출력 벡터를 얻을 수 있음

 

linear score function는 가중치 행렬 W와 입력 데이터의 내적을 계산해 각 클래스에 대한 점수를 산출함

이 때 W의 각 행을 특정 클래스에 대한 템플릿으로 생각할 수 있는데, 입력 이미지가 주어졌을 때 신경망은 해당 입력이 이 템플릿과 얼마나 유사한지 계산해 "자동차" 클래스에 대한 점수를 산출함

이때 단일 템플릿만을 사용하면 다양한 스타일의 자동차를 인식하기 어렵다는 단점이 생김

  • ex: 빨간 자동차의 템플릿이 있다면 빨간 자동차는 잘 인식하지만 노란 자동차나 다른 스타일의 자동차는 인식하지 못할 수 있음

=> 현실에서는 여러 스타일과 색상의 자동차가 존재하기 때문에 단일 템플릿만으로는 충분하지 않음

-> 다층 신경망에서는 여러 layer의 가중치 행렬을 사용해 이러한 문제를 해결함

 

다층 신경망

예를 들어, 첫 번째 가중치 행렬 W1은 여전히 여러 템플릿을 포함할 수 있으며, 각 템플릿은 특정한 자동차 스타일(빨간 차, 노란 차 등)을 나타낼 수 있음

그런 다음, hidden layer h에서 이러한 템플릿들에 대한 점수들을 계산한 후, 두 번째 가중치 행렬 W2를 사용하여 이 점수들을 결합하고 조합할 수 있음

-> 다양한 스타일의 자동차를 모두 포함하는 템플릿을 학습할 수 있게 되는 것

-> 따라서, 신경망은 빨간 차뿐만 아니라, 노란 차와 다른 색상의 자동차도 잘 인식할 수 있음

 

 

 

 

 

실제 뉴런과 인공신경망

강의에서는 인공신경망이 인간의 실제 뉴런과 유사하다고 이야기하는 것을 경계하고 있음

실제로 생물학적 뉴런은 종류도 다양하고 훨씬 더 복잡한 연산을 수행하기 때문임

 

 

Activation Function

이 중 현재 가장 많이 사용하는 활성화 함수는 ReLU임

 

 

Neural Networks : Architectures

아래의 왼쪽 그림을 2-layer Neural Net 또는 1-hidden-layer Neural Net이라고 함

기본적으로 weight를 갖고 있는 것만 layer라고 하기 때문에 3-layer가 아니라 2-layer

그래서 input layer는 weight를 가지고 있지 않기 때문에 제외가 됨

  • 오른쪽의 경우도 3-layer neural network 또는 2-hidden-layer Neural Network라고 부름

모든 노드들이 연결되어 있는데, 이런 경우를 Fully-connected layer라고 부르며 줄여서 FC layer라고 함

 

 

Example : feed-forward computation of a Neural Network

layer로 구성하는 이유 = 효율적으로 계산을 할 수 있기 때문

  • 행렬 벡터 연산을 사용해 신경망을 구성하여 이 부분에서 효율적이라 함

위 그림에서 3-layer neural network를 떠올려보면 입력: [3x1] vector

첫 번째 hidden layer의 가중치  [4x3]의 크기 & 모든 노드에 대한 bias는  [4x1] vector에 있음

모든 단일 뉴런에서는 가중치 가 있으므로 행렬 벡터 곱셈 np.dot(W1,x)는 모든 layer에 있는 뉴런의 활성화를 계산함

hidden layer의 는 [4x4] 행렬을, 마지막 output layer에 대한 은 [1x4] 행렬이 됨

=> 이 3-layer 신경망의 forward pass는 activation function과 섞인 3개의 행렬 곱셈이라 볼 수 있음

  • 하나의 layer는 하나의 연산을 통해 계산해 편의성을 제공

 

 


[CS231n 4강 정리] 역전파(Back propagation), 신경망(Neural Network) (tistory.com)

 

[CS231n 4강 정리] 역전파(Back propagation), 신경망(Neural Network)

지난시간까지 w와 스코어, loss function, 그리고 gradient를 배웠습니다. 오늘은 이제 실제로 analytic gradient(앞 강의에서 설명한 해석적 방식) 를 어떻게 계산하는지에 대해서 알아봅시다. 역전파(Back Pr

oculus.tistory.com

cs231n 4강 정리 - Introduction to Neural Networks (velog.io)

 

cs231n 4강 정리 - Introduction to Neural Networks

이번 포스팅은 standford university의 cs231 lecture 4를 공부하고, 강의와 슬라이드를 바탕으로 정리한 글임을 밝힙니다.제가 직접 필기한 이미지 자료는 별도의 허락 없이 복사해서 다른 곳에 게시하는

velog.io

 

 

 

 

 

 

2강 Review & 3강 Preview

W : 이미지의 모든 픽셀에 대해, 그리고 10개의 모든 클래스에 대해 그 픽셀이 그 클래스에 얼마나 영향을 주는가

-> matrix W의 행들이 그 클래스의 템플릿에 해당한다는 것

행을 꺼내서 이미지로 다시 만들면 각 클래스에 대해 학습된 템플릿으로 시각화할 수 있음

이떄, W가 좋은지 나쁜지를 보는 척도가 바로 오늘 다루는 손실함수 (Loss function)!

 

 

W를 사용해 10개 클래스의 점수를 얻을 수 있음

위에서 3개의 이미지에 대한 학습 데이터를 보면, 이 이미지들에 대해 어떤 W 값에 대해 예측된 10개의 클래스 점수가 존재하는데, 상대적으로 어떤 점수들은 좋고 어떤 점수는 좋지 않음

  • ex : 왼쪽 이미지는 고양이임을 사람의 관점에서는 바로 판단이 가능함. 근데 W 세팅으로는 분류기가 cat class에 2.9점을 주었고, dog class에는 8.09점을 줌
    = 분류기가 이 이미지에 제대로 동작하지 않고 있음
  • 참인 클래스 점수가 제일 높길 바라기 때문

하지만, 눈을 굴려 점수를 보고 어떤 게 좋은지 나쁜지 판단하는 방법은 논리가 부족한 접근 방법임

-> 알고리즘을 통해 자동으로 어떤 W가 최선인지 결정하도록 해야 함 = 손실 함수

 

Loss Function (손실 함수)

앞의 예시를 클래스를 3개로 줄여 살펴봄

    • 3개의 예시와 3개의 클래스로 구성
    • 고양이, 개구리 : 정확하게 분류 X, 자동차 : 정확하게 분류

보통 손실 함수에 대해 이야기할 때 x와 y로 이루어진 학습 데이터셋이 주어진다고 가정함

  • 목표 : CIFAR 10의 경우 이 이미지를 10개의 카테고리로 분류 
  • x : 이미지의 픽셀 값
  • y : 알고리즘이 예측하고 싶은 값(레이블 or 타겟) -> 1~10 혹은 0~9까지의 정수(integer)
  • L_i : 손실 함수. 학습 예제에 대해 그 예측이 얼마나 나쁜지에 대한 정량적인 값을 주는 함수
  • L : 최종적인 손실. 데이터셋 N개 예제에 걸쳐 전체 데이터셋을 합친 것에 대한 손실들의 평균 
  • 예측 함수 f가 있어서 예제 x와 가중치 매트릭스 W를 받아 y에 대한 예측을 수행함

 

Multiclass SVM Loss

: 손실함수의 한 종류. 기본적이고 이미지 분류에도 성능이 좋음

  • multiclass SVM : binary SVM을 여러 클래스를 다루기 위해 일반화한 것
  • binary SVM : 단지 2개의 클래스만 존재. x는 단지 긍정과 부정으로만 분류됨

 

손실 Li : yi가 참인 카테고리만 빼고 모든 카테고리 y에 대해서 각 예제 하나하나에 대해 합을 구하는 것

-> 맞는 카테고리 점수와 모든 틀린 카테고리를 비교함

  • 맞는 카테고리 점수가 틀린 카테고리 점수보다 어떤 안전 마진 차이 보다 더 높음 -> 1
  • 참인 카테고리의 점수가 다른 거짓인 카테고리 보다 그만큼 더 큼 -> 0

=> 우리 이미지에 대해서 모든 틀린 카테고리를 더해 최종 손실을 구하고, 전체 데이터셋에 대한 손실의 평균을 취함

 

Hinge Loss

0과 어떤 값 중에 최대값을 취하는 손실 함수

  • y축 : 손실
  • s_j : 오답 카테고리의 score
  • s_y_j (x축) : 정답 카테고리의 score

참인 클래스의 점수가 증가하면, safety margin에 다다를 때까지 손실은 선형으로 줄어들고 올바르게 예를 분류하면 0이 됨

 

 

예제에 이 Loss를 적용해보면 아래와 같음

 

왼쪽의 고양이 이미지에 대해 multiclass SVM Loss 계산해볼 수 있음

  • 정답 class : cat
  • cat score = 3.2, car score = 5.1,frog score = -1.7
  • cat score = s_y_j = 3.2

 

j = car일 때 loss -> sj - syi +1 = 5.1 - 3.2 + 1 = 2.9 > 0 -> 2.9

j = frog 일 때 loss -> 0

=> 첫번째 데이터에서의 Loss 값은 2.9 + 0 = 2.9

 

이 2.9는 우리의 분류기가 이 학습 예제에서 얼마나 망쳤는지에 대한 정량적 측정 값임

 

 

이런식으로 모든 데이터에 대해 구해주면, 최종 Loss는 (2.9+0+12.9)/3=5.27

= 현재 사용된 W에 대한 정량적 평가가 됨 

-> 이 분류기가 이 데이터셋에 대해 5.3만큼 나쁘다는 것을 의미하는 일종의 정량적 측정 값 

 

즉, s_y_i >= s_j + 1이면 0이 되는 조건은 1의 마진 값을 줌으로써 정답 카테고리의 스코어를 이 정도 맞췄으면 꽤 잘맞췄네? 하는 것임

  • 마진을 크게하면 모델은 좀 더 널널하게, 작게하면 엄격하게 분류를 해야되는 것

 

Loss에 대해 할 수 있는 질문들

1) 만약 차 이미지를 바꾼다면 Loss에 무슨 일이 생기는가?

SVM Loss는 맞는 점수가 틀린 점수보다 1이상 더 큰지에 관심이 있기에 car score가 다른 score보다 이미 꽤 크다면 1의 마진이 여전히 동일하게 얻어질 것이고, Loss는 변하지 않을 것!

 

2) 가능한 최대, 최소 손실값은 무엇인가?

최소 손실은 0

모든 클래스에 대해 맞는 점수가 훨씬 크면 모든 클래스에 걸쳐 0의 손실을 만들 수 있기 때문

만약 맞는 점수가 매우 음수로 간다면, 잠재적으로 무한대의 손실을 만들 수 있음

즉, 최소 손실은 0이고 최대 손실은 무한대

 

3) 초기화시 W가 너무 작아서 모든 스코어 S가 0과 가깝고, 값이 서로 거의 비슷하다면 Loss는?

 비슷하니 그 차가 마진을 넘지 못하기에 마진값에 가까운 스코어를 얻게 됨. 이경우에서는 결국 (클래스의 수-1)

이는 유용한 디버깅 전략으로 사용됨. 학습 초기, 즉 첫 iteration에서 보는 손실이 C-1이 아니면 버그가 있다는 것 의미

 

4) SVM Loss의 경우 정답인 클래스는 제외하고 더했는데, 정답인 것도 같이 계산에 포함시키면?

Loss가 1 증가함

 

5) Loss에서 전체 합이 아닌 평균을 쓴다면?

영향없음. 

데이터셋을 선택할 때 클래스의 숫자는 이미 결정된 것이고, 전체 손실 함수를 상수로 그냥 스케일만 변화할 뿐임

 

6) 손실함수를 제곱항으로 바꾸면?

 

비선형으로 바뀜. 손실함수의 계산이 달라지므로 결과가 달라지고, squared hinge loss라고 부름

 

7) 손실이 0인 W가 존재할 때, 이 W는 유일한가?

 

 

2W도 역시 L=0임

W에 따라 문제 전체를 위 혹은 아래로 스케일링 할 수 있기 때문에 2배의 W도 고려해볼 수 있음

 

Multiclass SVM Loss 코드

def L_i_vectorized(x, y, W):
	scores = W.dot(x)
    	margins = np.maximum(0, scores - scores[y] + 1)
    	margins[y] = 0
    	loss_i = np.sum(margins)
    	return loss_i

 

하나의 클래스만 빼고 반복하면서, 즉 건너뛰고 싶은 걸 0으로 없애고 합을 계산함

 

 

Regularization

loss가 작으면 작을수록, 즉 0이 될수록 가장 좋은것은 아님

우리의 목적은 학습 데이터에 맞는 분류기에 대한 w를 찾는 것인데, 실제로는 학습 데이터에 맞추는 것이 우리의 관심사는 아님

  • 머신러닝의 전체적인 요점은 학습 데이터를 사용해 어떤 분류기를 찾고, 그걸 테스트 데이터에 적용하는 것

w가 0이라는 것은 트레이닝 데이터에 완벽한 w라는 것인데, 결과적으로 우리에겐 train set이 아닌 test 데이터에서의 성능이 중요한 것이기 때문

 

 

 

파란 점들이 데이터셋에 있다면, 이 파란 점들인 학습 데이터에 맞는 어떠한 곡선을 fit해 볼 것임

이때, 모든 학습 데이터에 대해 완벽히 분류를 하려면 매우 구불구불한 곡선을 가질 것

-> 하지만 이 성능은 중요한 것이 아님. 우리가 봐야할 것은 테스트 데이터에 대한 성능이기 때문

 

 

트렌드를 따르는 새로운 데이터가 들어오면 구불구불한 파란 선이 완전히 틀리게 되는 것임

즉, 분류기가 학습 데이터에 맞는 이 복잡한 파란 선보다는 초록 직선을 예측하는 것이 더 좋은 것

= 머신러닝에서 핵심 기본 문제

 

이 문제 해결을 위한 해결 방법으로 사용하는 것이 정규화(Regularization)

 

정규화 : 손실 함수에 정규화 항이라고 불리는 항을 더해 모델이 어느정도 단순한 W를 고르도록 유도하는 것

  • 모델은 단순해야 테스트 데이터에서 잘 동작할 것임
    • 오캄의 면도날 : "모든 경쟁하는 가설 중에서, 단순한 것이 최선이다"
      => 경쟁하는 가설들이 여럿 있을 때, 일반적으로 더 간단한 것을 선호해야 한다는 아이디어.
      그것이 미래의 관찰을 일반화할 수 있는 설명임
  • 이 직관을 머신러닝에 적용하면 표준 손실 함수는 데이터 손실(Data Loss)과 정규화 손실(Regularization Loss)이라는 두 항의 합으로 변하는 것
    • 정규화 하이퍼파라미터인 lambda는 정규화 강도로, Data Loss과 Regularization loss의 trade-off를 조절할 수 있음
    • lambda는 모델을 실제로 훈련시킬 때 튜닝해야 하는 가장 중요한 것 중 하나

 

정규화는 여러 종류가 존재하는데, 그 중 L2 정규화를 가장 많이 사용함

 

1) L2 정규화

가중치 벡터 W에 대한 유클리드 norm

때로 제곱 norm 혹은 반 제곱 norm을 사용하기도 함. 미분을 없애주기 때문임

가중치 벡터의 L2(유클리드) norm에 패널티를 주는 것이 아이디어

 

2) L1 정규화

가중치 벡터의 L1(맨해튼) norm에 패널티를 줌

matrix W의 희소성(sparsity)를 증가시킨다는 좋은 특징이 있음

 

  • L1 정규화는 가중치 벡터의 절대값 합을 최소화하려는 특성 때문에 가중치 중 일부를 0으로 만들어 희소성을 증가시킴
  • 데이터에 여러 특징이 있을 때, L1 정규화를 적용하면 비용 함수는 특정 특징들의 가중치를 0으로 만들어 모델을 단순화하려고 함
    • ex : 가중치 matrix W=[0.5,1.2,0.0,0.0,0.0,2.3] -> 6개의 특징 중에서 3개의 특징만이 중요한 역할을 하고 나머지 3개는 무시된다는 것을 의미

 

 

즉, Regularization loss를 다음과 같이 생각할 수 있음

=> 모델은 여전히 더 복잡한 모델이 될 가능성이 있으나, soft penalty인 regularization을 추가함으로써, 만약 너가 복잡한 모델을 계속 쓰고 싶으면, 이 penalty를 감수해야 할 것

 

모델의 복잡도 측정 방법 - L2 정규화

  • x : 학습 예제.4 by 1 벡터
  • 2개의 W에서 고려 중인 상황

 

 

1) linear classification (f = Wx)의 관점 - 동일

선형 분류에서는 x와 W를 내적하는데, 이 선형 분류 관점에서 W1과 W2는 동일한 스코어 1을 제공하므로 data loss도 동일함

 

2) L2 regression 관점 - W2 선호

W2가 더 norm이 작기 때문

모든 요소가 골고루 영향을 미치길 바람

만약 베이지안을 쓴다면, L2 정규화는 W에 대한 Gaussian prior를 사용한 MAP 추론에 해당함

 

2) L1 regression 관점 - W1 선호

sparse한 solution을 고름

0이 많으면 좋다고 판단함

 

-> 모델과 데이터의 특성에 따라 regularization loss를 잘 설계하는 것이 중요함

 

멀티클래스 SVM 외에 딥러닝에서 많이 쓰이는 손실 함수로는 Multinomial Logistic Regression(softmax)가 있음

 

Multinomial Logistic Regression (Softmax)

Multi-class SVM loss는 스코어 자체에 대한 해석보다는 정답 클래스와 정답이 아닌 클래스들을 비교하는 형식이었음

  • 단지 참인 점수를 원하고, 맞는 클래스의 점수가 틀린 클래스보다 커야 한다는 사실 이상으로는 점수들이 무엇을 의미하는지에 대해 얘기하지 않았음

-> Multinomial logistic regression : 스코어 자체에 추가적인 의미를 부여함

 

 

softmax 함수를 이용해 모든 점수를 얻고, 지수화해 양수로 만듦

    • 단계 : 스코어 자체를 loss로 쓰는 것이 아니라 지수화 시켜 양수로 만듦 -> 정규화 -> log 씌움

 

소프트맥스 함수로 점수들을 통과시켜 클래스별 확률 분포를 계산하고, 이를 이용해 Loss를 계산함

 

앞의 예제에 적용해보면 아래와 같음

 

 

모두 더하면 1이 되도록 정규화 -> L_i는 -log  = 소프트맥스 손실 (혹은 다항 로지스틱 회귀)

1) L_i의 최대값 & 최소값

=> 최소 손실은 0이고, 최대 손실은 무한대

  • 우리가 원하는 확률 분포 : 맞는 클래스에는 1, 틀린 클래스에는 0
  • 맞는 클래스 -> 로그 안의 것이 1이 되고 결국 로그 1은 0이 됨(-가 붙어도 0) = 우리가 완전히 다 맞으면 손실은 0
  • 그러나 모든 것을 다 맞기 위해서 우리의 점수는 꽤 극단적으로 무한대를 향해서 가야 함
  • 우리가 이 지수화와 정규화를 가지고 있기 때문에, 우리가 사실 0과 1 확률 분포를 가질 수 있는 유일한 방법은 무한대의 점수를 맞는 클래스에 주고, 마이너스의 무한대 점수를 틀린 클래스에 주는 것임
  • 하지만 컴퓨터는 무한대를 잘 쓰지 못하기에 유한한 정밀도로 0 손실을 얻기는 사실상 불가능
    (그러나 0은 이론적인 최소 손실이라고 해석해 볼 수 있음)
  • 최대 손실은 범위가 없음
  • 만약 우리가 맞는 클래스에 대해 0 확률 질량을 가짐 -> 0의 마이너스 로그를 갖게 됨
  • 로그 0은 음의 무한대고, 음수 로그 0은 양의 무한대
  • 매우 안좋지만 이걸 실제로 보진 못할 것. 이 확률이 0이되는 유일한 방법은 맞는 클래스 점수 제곱이 0이면, 이건 단지 맞는 클래스 점수가 음의 무한대일 때 가능하기 때문

결론적으로, 우리는 유한한 정확도로는 이 최소값과 최대값을 가질 수 없을 거라는 이야기임

-> 멀티클래스 SVM 문맥에서 디버깅 온전성 검사 외에 추가로 교차 검증, 혼동 행렬, 정밀도-재현율 곡선, ROC 곡선 등의 방법을 사용하여 모델의 성능을 종합적으로 평가하면 더욱 신뢰성 있는 결과를 얻을 수 있음

 

 

2) 초기화에서 w가 매우 작아서 모든 s가 0에 가깝다면 loss는 얼마인가?

- log(1/C) = log(C)

-> 소프트맥스 loss로 모델을 훈련할 때 첫번째 iteration을 확인해 봐야 함. 이게 log(C)가 아니면 무언가 문제가 있는 것이라고 판단 가능

 

softmax와 SVM 

 

 

입력에 대해 곱해지는 W 매트릭스를 갖고 있고, 그걸로 이 점수 벡터를 만들 수 있음

이 두 손실 함수간의 차이는 우리가 나중에 정량적으로 나쁨을 측정하기 위해서 어떻게 그 점수들을 해석하는 지로 결정됨

  • SVM : 우리는 맞는 클래스 점수와 틀린 클래스 점수 간의 마진을 봄
  • 소프트맥스 혹은 교차 엔트로피 손실 : 확률 분포를 계산하고 맞는 클래스의 음의 로그 확률을 봄

 

위의 3개의 점수를 가진다고 가정

  • 우리가 이전에 본 예제로 다시 돌아가면, 멀티클래스 SVM 손실에서 차 점수는 다른 틀린 클래스 보다 훨씬 점수가 높았음
    • 그 차 이미지의 점수를 약간 바꿔보는 건 멀티클래스 SVM 손실을 전혀 바꾸지 않았음
    • 왜냐면 SVM 손실이 신경 쓰는 건 틀린클래스 점수와 비교해서 마진보다 큰 맞는 점수를 얻는 것이기 때문
  • 소프트맥스 손실: 여러분이 맞는 클래스에 대해서 매우 높은 점수를 주더라도 항상 확률 질량을 1로 몰아가길 원함(틀린 클래스에 대해 아주 낮은 확률을 줌)
    • 소프트맥스는 여러분이 점점 더 많은 확률 질량을 맞는 클래스 위에 쌓길 원함
    • 맞는 클래스의 그 점수는 무한대를 향해 위로, 틀린 클래스의 점수는 아래로 음의 무한대로 밀어붙임

=> SVM은 이 데이타 포인트를 바 (bar) 위로 올려 맞는 클래스로 분류되도록 한 후엔 포기함(더이상 데이타 포인트를 상관하지 않음)

반면 소프트맥스는 계속해서 모든 데이타 포인트를 개선해서 더 나아지도록 노력함

  • 실제로는 뭘 선택하든지 별로 큰 차이가 없고, 적어도 많은 딥러닝 어플리케이션에서는 둘은 꽤 비슷하게 동작함

 

Summary

x들과 y들의 데이타 셋이 존재할 때, 우리의 선형 분류기를 사용해서 input인 x로부터 점수 s를 계산하는 어떤 점수 함수를 얻음

-> 손실 함수를 사용해 우리의 예측이 그라운드 참 타겟 (ground true target) y와 비교해서 정량적으로 얼마나 나쁜지 계산함

  • ex : 소프트맥스, SVM이나 혹은 다른 어떤 다른 손실 함수를 사용

& 손실 함수를 정규화 항으로 개선시킴

  • 정규화 항은 학습 데이타에 핏 (fit)하는 것과 간단한 모델을 선호하는 것 사이에서 트래이드오프 (trade-off)

=> 우리가 흔히 지도 학습이라고 부르는 것의 꽤 일반적인 개요! 이 모든걸 조합해서 최종 손실함수를 최소화하는 W를 찾으려고 하는 것

 

Optimization

예측 함수 f, 손실 함수, 정규화가 커지고 복잡해짐 & 신경망 사용

-> 곧장 최소값으로 데려다 주는 명확한 분석적 해답을 기대하긴 어려움

-> 실제에선 다양한 종류의 반복적 메소드를 사용함. 어떤 해답으로 시작을 해서 시간이 지남에 따라 그걸 점점 개선시킴

 

1) 랜덤 탐색(search)

가장 처음으로 생각해볼 수 있는 방법

단순히 W를 많이 받아 임의로 샘플링하고 그걸 손실함수에 넣음

가장 나쁜 방법

 

2) 경사따라가기

1차원에서의 경사 : 함수의 미분

  • 1차원 함수 f가 있다면 스칼라 x를 받아서 어떤 커브의 높이를 돌려주고, 그 후 어떤 지점에서든지 경사를(미분값을) 계산

다변수에서의 경사 : 부분 미분의 벡터. 경사는 x와 같은 모양 가짐

  • 경사의 각 항목 : 우리가 좌표에서 만약 그 방향으로 움직일 때 함수 f의 경사값이 무엇인가
  • 경사 = 부분 미분한 벡터 -> 가장 크게 증가하는 방향 가리킴
    • 반대 경사 방향 -> 가장 크게 감소하는 방향 가리짐
  • 그 풍경에서 모든 방향으로의 경사 = 경사와 그 방향을 가리키는 단위 벡터(unit vector)와의 내적

-> 경사는 현재 지점에서 우리의 함수로의 1차 선형 근사를 제공함

경사 ∇L(W)는 손실 함수 L의 각 파라미터 W_i에 대한 편미분 값으로 구성

 

딥러닝에서의 경사 : 경사를 이용해 파라미터나 벡터를 반복적으로 업데이트

 

 

가장 나이브한 경사 평가 방법 = 유한 차분(infinite difference)의 방법 이용 = numerical gradient

 

파라미터 벡터 : W

현재 손실 : 약 1.25

경사 dW의 각 항목은 W의 각 성분이 작은 무한소(infinitesimal)의 양만큼 변화할 때 그 좌표방향으로 손실이 얼마나 변할지 알려줌 

-> W의 각 성분 W_i를 아주 조금 ϵ만큼 변경했을 때, 손실 함수의 변화는 아래와 같이 근사할 수 있음 

 

 

이 유한한 차이를 계산할 수 있음

w를 가지고 있을 때 w의 첫번째 원소를 작은 값(h, 아래에선 0.0001)만큼 증가시키려고 함

그 후 손실 함수와 분류기 등을 이용해 손실을 다시 계산함

 

1) numerical gradient

첫번째 차원에서 조금 움직이면 손실은 1.2534에서 1.25322가 됨

 

 

limit definition을 사용해서 첫번째 차원의 경사에 대한 유한 차분 근사를 얻을 수 있음

두번째 차원에서 첫번째 차원을 원래 값(0.34. 0.0001을 더하기 전)으로 되돌려놓고, 두번째 방향으로 조금 움직임

 

다시 손실 계산하고 두번째 슬롯에서 경사에 대한 근사를 계산하기 위해 유한 차분 근사를 사용함

 

이 일을 계속 반복함

3번째 차원에서의 유한 차분 근사

 

 

-> 사실 끔찍한 아이디어임. 속도가 매우 느리기 때문

  • 함수 f를 계산하는 것은 실제로 엄청 느린데, 위와 같이 10개의 항목이 아닌 수천만개의 파라미터 벡터를 가지는 합성곱 신경망이라면 하나의 경사를 얻기 위해 수억개의 함수 평가를 기다려야 함
    -> 미적분을 써서 계산하는 것이 효율적! 하나의 표현식만 계산하면 되기 때문 = analytical gradient

2) analytical gradient

 

 

 

요약하면 numerical gradient는 간단하고 상식적임

하지만 실제에서는 사용하지 않고, 항상 분석적 경사(analytical gradient) 를 취해 사용함

 

 

numerical gradient는 유용한 디버깅 도구로 사용됨

  • 손실과 손실의 경사를 계산하는 코드를 썼을 때, 수치적 경사를 일종의 유닛 테스트로 사용해서 확실히 자신의 분석적 경사가 맞는지 확인함
  • 느리고 정확하지 않아서 수치적 경사 체킹을 할 땐 실제로 합리적인 시간내에 동작하도록 문제의 파라미터를 스케일 다운(scale down)해야 함

3) 경사 하강법

while True:
	weights_grad = evaluate_gradient(loss_fn, data, weights)
    weights += step_size * weights_grad

 

W를 random으로 초기화 -> 참(true)일 동안 손실과 경사 계산 -> 가중치를 경사 방향의 반대로 업데이트

경사는 함수의 가장 크게 증가하는 방향을 가리키므로, 음의 경사는 가장 크게 감소하는 방향을 가리키기 때문

하이퍼 파라미터 : 학습률(learning rate), 모델 size, 정규화 강도(regularizaton strength), ...

학습률 : 경사를 계산할 때마다 그 방향으로 얼마나 멀리 가는가

 

가운데 붉은 영역 : 손실이 가장 낮은 곳 (우리가 가고 싶은 곳)

파랑, 초록 영역 : 손실이 가장 높은 곳(피하고 싶은 곳)

-> w를 공간의 임의의 지점에서 시작하고 음의 경사 방향을 계산하는 과정을 반복하며 최소값에 도달

-> 다음 스텝이 어디인지를 결정하기 위해 경사를 이용하는데, 이 경사 정보를 어떻게 사용해야 할 지 알려주는 업데이트 룰이 존재함

ex : adam, momentum

 

확률적 경사 하강(stochastic gradient descent)

 

전체 데이터셋에 대해 손실과 경사를 계산하기 보단 매 반복마다 미니배치(mini batch)의 학습 예제를 샘플링

미니배치의 크기는 관습적으로 2의 제곱수로 설정 ex : 32, 64, 128, ...

"확률적"인 이유 : 어떤 참 값의 기댓값의 몬테카를로 추정을 사용하기 때문 

데이터의 랜덤 미니배치 샘플링 -> 미니 배치에 대한 손실과 경사 평가 -> 이 손실에 대한 추정과 이 경사의 추정에 근거해 파라미터 업데이트

 

Image Features

선형 분류기에서는 raw로 이미지 픽셀을 받아서 이 raw 픽셀을 선형 분류기에 그대도 input으로 넣음

-> 멀티 모달리티로 인해 좋은 방법은 아님

 

DNN 유행 전의 방법

이미지를 받은 후 이미지의 다양한 피쳐 표현( 이미지에 나타난 모양과 관련한 여러 종류의 정량적인 것들 )을 계산함

-> 여러 특징 표현들을 concat시켜 하나의 feature vector로 만듦 (이미지의 feature representation이 나타남)

-> raw 픽셀 자체를 넣는 것 대신 이 이미지의 피쳐 표현(feature vector)이 선형분류기로 들어감

 

 

이미지 피쳐의 동기

 

 

Linear한 결정 경제를 그릴 방법이 없는 데이터셋의 경우 적절하게 feature transform을 거침

-> 선형으로 분리가 가능하게 바뀜

 

위의 경우에서는 극 좌표계(polar coordinate)로의 트랜스폼 후 선형으로 분류할 수 있게 바뀐 것임

  • 이미지의 경우 픽셀들을 극좌표계로 바꾸는 것은 전혀 말이 안되는 일이지만 극좌표계로 변환하는 것을 일종의 특징 변환이라 생각한다면 말이 되는 것
  • 이렇게 분류기에 넣는 것이 raw 이미지를 넣는 것보다 성능이 좋을 수 있음

-> 문제에 어떤 feature transform을 적용할 것인지 결정하는 것이 중요

 

특징 변환의 예로는 다음과 같음

1. Color Histogram

이미지에서 Hue color spectrum만 뽑아서 모든 픽셀을 버킷에 나눠담은 후 모든 픽셀을 이 컬러 버킷들의 하나에 매핑

-> 얼마나 많은 픽셀이 버킷에 담겼는지 셈

= 이미지가 전체적으로 어떤 색인지 관찰 가능

  • 개구리의 예 : 초록색이 많으며 자주색이나 붉은색은 별로 없음

 

2. Histogram of Oriented Gradients(HoG)

 

이미지를 8 by 8로 픽셀을 나눔

-> 이 픽셀 지역 내에서 가장 지배적인 edge의 방향을 계산하고 edge directions를 양자화해 버킷에 넣음

-> 다양한 edge oreirentations에 대한 histogram을 계산함

=> 전체 특징 벡터는, 각각의 모든 8x8 지역들이 가진 "edge orientation에 대한 히스토그램" 이 되는 것!

  • 컬러 히스토그램 : 이미지 전체적으로 어떤 색이 있는지 나타냄
  • HOG : 이미지 내에 전반적으로 어떤 edge 정보가 있는지 나타냄 & 이미지를 여러 부분으로 지역화해서, 지역적으로 어떤 edge가 존재하는지도 알 수 있음
  • 이파리 위에 앉아있는 개구리 이미지 : 이파리들은 주로 대각선 edge를 가지고 있는데, 실제 HoG를 시각화해보면 이파리 부분에 많은 대각 edge가 있음을 볼 수 있음
  • HoG는 흔한 피쳐 표현이고, 객체 인식에 많이 사용됨

 

3. bag of words(BoW)

 

문장의 여러 단어의 발생 빈도를 세 특징 벡터로 사용하는 NLP에서의 직관을 이미지에 적용한 것

  • 시각 단어(visual words) 정의가 필요함

 

엄청 많은 이미지를 가지고, 그 이미지들은 임의대로 조각냄
-> 그 조각들을 K-means와 같은 알고리즘으로 군집화

-> 시각 단어는 빨강색, 파란색, 노랑색과 같은 다양한 색 & 다양한 종류와 다양한 방향의 oriented edges 포착해냄

-> 시각 단어 집합인 Codebook 형성

-> 어떤 이미지가 있으면, 이 이미지에서의 시각 단어들의 발생 빈도를 통해서 이미지를 인코딩 할 수 있게 됨

 

 

이미지 분류 파이프라인

5~10년 전까지만 해도 이미지를 입력받으면 BOW나 HOG와 같은 다양한 특징 표현을 계산하고, 계산한 특징들을 한데 모아 연결해서, 추출된 그 특징들을 Linear classifier의 입력으로 사용했음

  • 특징이 한번 추출되면 feature extractor는 classfier를 트레이닝하는 동안 변하지 않음
  • 트레이닝 중에는 오직 Linear classifier만 훈련이 됨

CNN이나 DNN으로 넘어가보면 위와 실제로 크게 다르지 않음

  • 유일한 차이점 : 이미 만들어 놓은 특징들을 쓰기 보다는 데이터로부터 특징들을 직접 학습하려 한다는 것
    -> raw 픽셀이 CNN에 그대로 들어가고 여러 레이어를 거쳐서 데이터를 통한 특징 표현을 직접 만들어냄
    -> Linear classifier만 훈련하는게 아니라 가중치 전체를 한꺼번에 학습하는 것

 


[cs231n] 3강 손실 함수와 최적화 (1/4, 멀티클래스 (multiclass) SVM) :: 소프트웨어공학-Software Engineering (tistory.com)

 

[cs231n] 3강 손실 함수와 최적화 (1/4, 멀티클래스 (multiclass) SVM)

3강에 오신 것을 환영합니다. 오늘은 손실 함수와 최적화에 대해서 이야기 할 겁니다. 2강을 돌아보면, 인식할 때의 챌린지들에 대해 얘기했고, 이 데이타 추진 아이디어들에 대해 연마했습니다.

softwareeng.tistory.com

[cs231n] 3강 손실 함수와 최적화 (2/4, 정규화 (regularization)와 소프트맥스 (softmax)) :: 소프트웨어공학-Software Engineering (tistory.com)

 

[cs231n] 3강 손실 함수와 최적화 (2/4, 정규화 (regularization)와 소프트맥스 (softmax))

그건 여기 써 있는 것 때문인데요. 데이타에 관해 손실만 썼는데, 우리의 학습 데이터에 맞는 분류기에 대한 W를 찾아야 한다고 얘기했죠. 하지만 실제로, 학습 데이타에 맞추는 것에는 그렇게

softwareeng.tistory.com

CS231N_17_KOR_SUB/kor/Lecture 3 Loss Functions and Optimization.ko.srt at master · visionNoob/CS231N_17_KOR_SUB (github.com)

 

CS231N_17_KOR_SUB/kor/Lecture 3 Loss Functions and Optimization.ko.srt at master · visionNoob/CS231N_17_KOR_SUB

CS231N 2017 video subtitles translation project for Korean Computer Science students - visionNoob/CS231N_17_KOR_SUB

github.com

[cs231n] 3강 손실 함수와 최적화 (4/4, 경사하강 / Gradient Descent) :: 소프트웨어공학-Software Engineering (tistory.com)

 

[cs231n] 3강 손실 함수와 최적화 (4/4, 경사하강 / Gradient Descent)

일단 우리가 경사를 어떻게 계산하는지 알게 되면, 우리는 수퍼 간단한 알고리즘에 도달하게 됩니다. 3줄 정도죠. 그러나 우리가 어떻게 이 최고로 큰 가장 복잡한 딥러닝 알고리즘을 훈련시키

softwareeng.tistory.com

 

Chapter 11. 텍스트의 유사도(Text similarity)

11-1. 단어의 표현 방법

단어의 표현 방법은 크게 국소 표현(Local Representation) 방법과 분산 표현(Distributed Representation) 방법으로 나뉨

  • 국소 표현 방법 : 해당 단어 그 자체만 보고, 특정값을 맵핑하여 단어를 표현하는 방법
    • puppy(강아지), cute(귀여운), lovely(사랑스러운)라는 단어가 있을 때 각 단어에 1번, 2번, 3번 등과 같은 숫자를 맵핑(mapping)하여 부여함
  • 분산 표현 방법 : 그 단어를 표현하고자 주변을 참고하여 단어를 표현하는 방법
    • puppy(강아지)라는 단어 근처에는 주로 cute(귀여운), lovely(사랑스러운)이라는 단어가 자주 등장하므로, puppy라는 단어는 cute, lovely한 느낌이다로 단어를 정의함

책에서 정의한 단어 표현 카테고리

 

11-2. Back of Wards (BoW)

: 단어의 등장 순서를 고려하지 않고 단어들의 출현 빈도수(frequency)를 카운트(Count)하는 텍스트 데이터의 수치화 표현 방법. 국소 표현에 속함

  • 주로 어떤 단어가 얼마나 등장했는지를 기준으로 문서가 어떤 성격의 문서인지를 판단하는 작업에 쓰임
  • 즉, 분류 문제나 여러 문서 간의 유사도를 구하는 문제에 주로 쓰임

Ex) '달리기', '체력', '근력'과 같은 단어가 자주 등장하면 해당 문서를 체육 관련 문서로 분류할 수 있을 것

 

BoW 만드는 과정

1) 각 단어에 고유한 정수 인덱스를 부여해 단어 집합을 생성함

2) 각 인덱스의 위치에 단어 토큰의 등장 횟수를 기록한 벡터를 만듦

 

doc1 = "정부가 발표하는 물가상승률과 소비자가 느끼는 물가상승률은 다르다."
vocab, bow = build_bag_of_words(doc1)
print('vocabulary :', vocab)
print('bag of words vector :', bow)
vocabulary : {'정부': 0, '가': 1, '발표': 2, '하는': 3, '물가상승률': 4, '과': 5, '소비자': 6, '느끼는': 7, '은': 8, '다르다': 9}
bag of words vector : [1, 2, 1, 1, 2, 1, 1, 1, 1, 1]

 

  • 두번째 출력 결과가 문서 1의 BoW로, 인덱스 4에 해당하는 물가상승률은 두 번 언급되었기 때문에 해당 값이 2임
  • 한국어에서 불용어에 해당되는 조사들을 제거하면 더 정제된 BoW를 만들 수 있음

 

11-3. 문서의 벡터화: 문서 단어 행렬(Document-Term Matrix, DTM)

: 서로 다른 문서들의 BoW들을 결합한 표현 방법으로, 다수의 문서에서 등장하는 각 단어들의 빈도를 행렬로 표현한 것 의미함

  • 각 문서에 대한 BoW를 하나의 행렬로 만든 것으로 생각할 수 있음
  • BoW 표현을 다수의 문서에 대해 행렬로 표현하고 부르는 용어임

Ex)

문서1 : 먹고 싶은 사과
문서2 : 먹고 싶은 바나나
문서3 : 길고 노란 바나나 바나나
문서4 : 저는 과일이 좋아요

 

띄어쓰기 단위 토큰화를 수행한다고 가정하고 DTM으로 표현하면 다음과 같음

 

문서들을 서로 비교할 수 있도록 수치화할 수 있다는 점에서 의의를 가짐

 

DTM의 한계

1) 희소 표현(Sparse representation)

희소 벡터 or 희소 행렬 : 원핫 벡터나 DTM과 같은 대부분의 값이 0인 표현

희소 벡터는 많은 양의 저장 공간과 높은 계산 복잡도를 요구함

-> 전처리를 통해 단어 집합의 크기를 줄이는 일은 BoW 표현을 사용하는 모델에서 중요할 수 있음

 

2) 단순 빈도 수 기반 접근임

 

11-4. TF-IDF(Term Frequency-Inverse Document Frequency)

: 단어의 빈도와 역 문서 빈도(문서의 빈도에 특정 식을 취함)를 사용하여 DTM 내의 각 단어들마다 중요한 정도를 가중치로 주는 방법

모든 문서에서 자주 등장하는 단어는 중요도가 낮다고 판단하며, 특정 문서에서만 자주 등장하는 단어는 중요도가 높다고 판단함

  • 우선 DTM을 만든 후, TF-IDF 가중치를 부여함
  • TF-IDF를 사용하면 기존의 DTM을 사용하는 것보다 보다 많은 정보를 고려하여 문서들을 비교할 수 있음
  • TF-IDF가 DTM보다 항상 좋은 성능을 보장하는 것은 아니지만, 많은 경우에서 DTM보다 더 좋은 성능을 얻을 수 있음
  • TF-IDF는 TF와 IDF를 곱한 값을 의미함
  • TF-IDF 값이 낮으면 중요도가 낮은 것이며, TF-IDF 값이 크면 중요도가 큰 것임 
    • the나 a와 같이 불용어의 경우에는 모든 문서에 자주 등장하기 마련이기 때문에 자연스럽게 불용어의 TF-IDF의 값은 다른 단어의 TF-IDF에 비해서 낮아지게 됨

 

문서를 d, 단어를 t, 문서의 총 개수를 n이라고 표현할 때

1) tf(d, t) : 특정 문서 d에서의 특정 단어 t의 등장 횟수

2) df(t) : 특정 단어 t가 등장한 문서의 수

3) idf(t) : df(t)에 반비례하는 수.

  • 단순하게 df의 역수를 사용하면 총 문서의 수 n이 커질 수록, IDF의 값이 기하급수적으로 커지므로 log를 사용함
  • 특정 단어가 전체 문서에서 등장하지 않을 경우에 분모가 0이 되는 상황을 방지하기 위해 1을 더해줌 

 

11-5. 코사인 유사도를 이용한 추천 시스템

코사인 유사도(Cosine Similarity)

: 두 벡터 간의 코사인 각도를 이용하여 구할 수 있는 두 벡터의 유사도를 의미

  • 두 벡터의 방향이 완전히 동일한 경우에는 1의 값을 가지며, 90°의 각을 이루면 0, 180°로 반대의 방향을 가지면 -1의 값을 가짐
  • 즉, 결국 코사인 유사도는 -1 이상 1 이하의 값을 가지며 값이 1에 가까울수록 유사도가 높다고 판단할 수 있음
  • 직관적으로 두 벡터가 가리키는 방향이 얼마나 유사한가를 의미함

 

두 벡터 A, B에 대해 코사인 유사도는 아래와 같음

  • numpy의 cos_sim으로 구할 수 있음

import numpy as np
from numpy import dot
from numpy.linalg import norm

def cos_sim(A, B):
  return dot(A, B)/(norm(A)*norm(B))

doc1 = np.array([0,1,1,1])
doc2 = np.array([1,0,1,1])
doc3 = np.array([2,0,2,2])

print('문서 1과 문서2의 유사도 :',cos_sim(doc1, doc2))
print('문서 1과 문서3의 유사도 :',cos_sim(doc1, doc3))
print('문서 2와 문서3의 유사도 :',cos_sim(doc2, doc3))
문서 1과 문서2의 유사도 : 0.67
문서 1과 문서3의 유사도 : 0.67
문서 2과 문서3의 유사도 : 1.00

 

문서3은 문서2에서 단지 모든 단어의 빈도수가 1씩 증가했을 뿐임

-> 한 문서 내의 모든 단어의 빈도수가 동일하게 증가하는 경우에는 기존의 문서와 코사인 유사도의 값이 1임

 

코사인 유사도는 유사도를 구할 때 벡터의 방향(패턴)에 초점을 두므로 코사인 유사도는 문서의 길이가 다른 상황에서 비교적 공정한 비교를 할 수 있도록 도와줌 

 

 

 

'AI > PyTorch로 시작하는 딥러닝' 카테고리의 다른 글

[PyTorch] Chapter 10  (0) 2024.07.16
[PyTorch] Chapter 3  (0) 2024.07.16
[PyTorch] RNN & LSTM & GRU  (0) 2024.07.16
[PyTorch] Functional API  (0) 2024.03.21
[PyTorch] Sequential API - tokenizer(), Sequential(), Dense()  (0) 2024.03.21

Chapter 10. 언어 모델(Language Model)이란?

10-1. 언어 모델(Language Model)이란?

언어라는 현상을 모델링하고자 단어 시퀀스(문장)에 확률을 할당(assign)하는 모델

= 가장 자연스러운 단어 시퀀스를 찾아내는 모델

  • 통계를 이용한 방법 & 인공 신경망을 이용한 방법으로 언어 모델을 만들 수 있음
  • 최근에는 후자가 더 좋은 성능을 보이고 있음 ex) GPT, BERT
  • 단어 시퀀스에 확률을 할당하게 하기 위해 가장 보편적으로 사용되는 방법은 언어 모델이 이전 단어들이 주어졌을 때 다음 단어를 예측하도록 하는 것

> 언어 모델링

주어진 단어들로부터 아직 모르는 단어를 예측하는 작업

= 언어 모델이 이전 단어들로부터 다음 단어를 예측하는 일

 

> 단어 시퀀스의 확률 할당

언어 모델은 확률을 통해 보다 적절한 문장을 판단함

  • 기계 번역 : P(나는 버스를 탔다) > P(나는 버스를 태운다)
  • 오타 교정 : 선생님이 교실로 부리나케  
    P(달려갔다) > P(잘려갔다)  
  • 음성 인식 : P(나는 메롱을 먹는다) < P(나는 메론을 먹는다)

> 단어 시퀀스의 확률

하나의 단어를 w, 단어 시퀀스를 대문자 W라고 한다면, n개의 단어가 등장하는 단어 시퀀스 W의 확률은

전체 단어 시퀀스 W의 확률은 모든 단어가 예측되고 나서야 알 수 있으므로 단어 시퀀스의 확률은 다음과 같음

 

10-2. 통계적 언어 모델(Statistical Language Model, SLM)

각 단어는 문맥이라는 관계로 인해 이전 단어의 영향을 받아 나온 단어이고, 모든 단어로부터 하나의 문장이 완성됨

-> 문장의 확률을 구하고자 조건부 확률을 사용함

 

문장의 확률을 구하기 위해 각 단어에 대한 예측 확률들 곱함

 

카운트 기반의 접근

SLM은 이전 단어로부터 다음 단어에 대한 확률을 카운트에 기반한 확률 계산으로 구함

An adorable little boy가 나왔을 때 is가 나올 확률은

 

예를 들어 기계가 학습한 코퍼스 데이터에서 An adorable little boy가 100번 등장했는데 그 다음에 is가 등장한 경우는 30번이라고 하면, 이 경우 𝑃(is|An adorable little boy)는 30%이 됨

 

카운트 기반 접근의 한계 - 희소 문제(Sparsity Problem)

> 희소 문제(sparsity problem) 

충분한 데이터를 관측하지 못하여 언어를 정확히 모델링하지 못하는 문제

 

SLM의 한계는 훈련 코퍼스에 확률을 계산하고 싶은 문장이나 단어가 없을 수 있다는 점 & 확률을 계산하고 싶은 문장이 길어질수록 갖고있는 코퍼스에서 그 문장이 존재하지 않을 가능성이 높음(카운트할 수 없을 가능성이 높음)

 

희소 문제를 완화하는 방법으로 n-gram 언어 모델이나 스무딩, 백오프와 같은 여러 일반화 기법을 사용함

하지만 근본적인 해결책은 되지 못하였고, 이러한 한계로 인해 언어 모델의 트렌드는 인공 신경망 언어 모델로 넘어가게 됨

 

10-3. N-gram 언어 모델(N-gram Language Model)

카운트에 기반한 통계적 접근을 사용하고 있으므로 SLM의 일종.

다만, 앞서 배운 언어 모델과는 달리 이전에 등장한 모든 단어를 고려하는 것이 아니라 일부 단어만 고려하는 접근 방법을 사용함

 

다음과 같이 참고하는 단어들을 줄이면 카운트할 수 있을 가능성을 높일 수 있음

 

An adorable little boy가 나왔을 때 is가 나올 확률을 그냥 boy가 나왔을 때 is가 나올 확률로 생각

-> 기준 단어의 앞 단어를 전부 포함해서 카운트하는 것이 아니라, 앞 단어 중 임의의 개수만 포함해 카운트해 근사하면 해당 단어의 시퀀스를 카운트할 확률이 높아짐

 

N-gram

임의의 개수를 정하기 위한 기준을 위해 사용하는 것이 n-gram.

  • n: n개의 연속적인 단어 나열 의미
  • 갖고 있는 코퍼스에서 n개의 단어 뭉치 단위로 끊어서 이를 하나의 토큰으로 간주함
    • n이 1일 때는 유니그램(unigram), 2일 때는 바이그램(bigram), 3일 때는 트라이그램(trigram)이라고 명명하고 n이 4 이상일 때는 gram 앞에 그대로 숫자를 붙여서 명명
    • 1-gram, 2-gram, 3-gram이라고 하기도 함 

 

  • An adorable little boy is spreading smiles에서 각 n에 대한 n-gram

 

 

n = 4라고 한 4-gram을 이용한 언어 모델을 사용한다고 하면, spreading 다음에 올 단어를 예측하는 것은 n-1에 해당되는 앞의 3개의 단어만을 고려함

 

만약 갖고있는 코퍼스에서 boy is spreading가 1000번 등장했고, boy is spreading insults가 500번 등장했으며, boy is spreading smiles가 200번 등장했을 때 boy is spreading 다음에 insults가 등장할 확률과 smiles가 등장할 확률은 아래와 같음

따라서 insults가 더 맞다고 판단할 수 있음

 

N-gram Language Model의 한계

n-gram은 앞의 단어 몇 개만 보다 보니 의도하고 싶은 대로 문장을 끝맺음하지 못하는 경우가 생김

 -> 전체 문장을 고려한 언어 모델보다 정확도가 떨어질 수밖에 없음

 

1) 희소 문제 (Sparsity Problem) 

현실적으로 코퍼스에서 카운트 할 수 있는 확률을 높일 수는 있었지만, n-gram 언어 모델도 여전히 n-gram에 대한 희소 문제가 존재함

2) n을 선택하는 것은 trade-off 문제

n을 크게 선택하면 실제 훈련 코퍼스에서 해당 n-gram을 카운트할 수 있는 확률은 적어지므로 희소 문제는 점점 심각해짐

또한 n이 커질수록 모델 사이즈가 커진다는 문제점도 존재함

-> n은 최대 5를 넘겨서는 안된다고 권장됨

 

10-4. 한국어에서의 언어 모델(Language Model for Korean Sentences)

한국어의 특징

1) 한국어는 어순이 중요하지 않음

-> 단어 순서를 뒤죽박죽으로 바꾸어놔도 의미가 전달되기에 확률에 기반한 언어 모델이 제대로 다음 단어를 예측하기 어려움

2) 교착어임

조사 존재 -> 단어 하나에도 다양한 경우가 존재함 

따라서 토큰화를 통해 접사나 조사 등을 분리하는 것은 중요한 작업이 되기도 함

3) 띄어쓰기가 제대로 지켜지지 않음

띄어쓰기를 제대로 하지 않아도 의미가 전달되고, 띄어쓰기 규칙 또한 상대적으로 까다로운 언어임 -> 띄어쓰기가 제대로 지켜지지 않는 경우가 많음

 

10-5. 펄플렉서티(Perplexity, PPL)

: 모델 내에서 자신의 성능을 수치화하여 결과를 내놓는 언어 모델의 평가 방법 

  • 두 모델의 성능을 비교하고자, 일일히 모델들에 대해서 실제 작업을 시켜보고 정확도를 비교하는 작업은 공수가 너무 많이 드는 작업이기에 사용함

PPL은 수치가 높으면 좋은 성능을 의미하는 것이 아니라, '낮을수록' 언어 모델의 성능이 좋다는 것을 의미함

 

 

분기 계수(Branching factor)

PPL은 선택할 수 있는 가능한 경우의 수를 의미하는 분기계수(branching factor)임

PPL은 이 언어 모델이 특정 시점에서 평균적으로 몇 개의 선택지를 가지고 고민하고 있는지를 의미함

 

Ex)  PPL이 10인 경우

: 해당 언어 모델은 테스트 데이터에 대해서 다음 단어를 예측하는 모든 시점(time step)마다 평균 10개의 단어를 가지고 어떤 것이 정답인지 고민하고 있다고 볼 수 있음

 

'AI > PyTorch로 시작하는 딥러닝' 카테고리의 다른 글

[PyTorch] Chapter 11  (0) 2024.07.16
[PyTorch] Chapter 3  (0) 2024.07.16
[PyTorch] RNN & LSTM & GRU  (0) 2024.07.16
[PyTorch] Functional API  (0) 2024.03.21
[PyTorch] Sequential API - tokenizer(), Sequential(), Dense()  (0) 2024.03.21

Chapter 3. 텍스트 전처리(Text preprocessing)

3-1. 토큰화(Tokenization)

토큰화(Tokenization)

자연어 처리에서 크롤링 등으로 얻어낸 코퍼스 데이터를 사용하고자 하는 용도에 맞게 토큰화(Tokenization) & 정제(cleaning) & 정규화(normalization)하는 작업을 거친다. 

 

토큰화 : 주어진 코퍼스에서 토큰(token)이라 불리는 단위로 나누는 작업

토큰의 단위는 보통 의미있는 단위로 정의함

 

단어 토큰화 (word tokenization)

: 토큰의 기준이 단어인 경우

여기서의 단어는 단어 단위 외에도 단어구, 의미를 갖는 문자열로 간주되기도 함

구두점이나 특수문자를 전부 제거하면 토큰이 의미를 잃어버리는 경우가 발생하기도 함

 

ex) 구두점을 제외시킨 토큰화 작업

입력: Time is an illusion. Lunchtime double so!

출력 : "Time", "is", "an", "illustion", "Lunchtime", "double", "so"

 

  • 토큰화의 기준 : 해당 데이터를 가지고 어떤 용도로 사용할 것인지에 따라 그 용도에 영향이 없는 기준으로 정하면 됨

 

토큰화에서 고려해야할 사항

토큰화 작업을 단순하게 코퍼스에서 구두점을 제외하고 공백 기준으로 잘라내는 작업이라고 간주할 수는 없음

 

1) 구두점이나 특수 문자를 단순 제외해서는 안된다.

마침표와 같은 경우는 문장의 경계를 알 수 있는데 도움이 되므로 단어를 뽑아낼 때 마침표를 제외하지 않을 수 있음

또한 단어 자체에 구두점을 갖고 있는 경우도 존재(ph.D, m.p.h 등)

특수 문자의 달러나 슬래시는 날짜를 의미하기도 함

 

2) 줄임말과 단어 내 띄어쓰기가 있는 경우

아포스트로피(') : 압축된 단어를 다시 펼치는 역할

New York 등의 단어는 하나의 단어이지만 중간에 띄어쓰기가 존재함 -> 사용 용도에 따라서 하나의 단어 사이에 띄어쓰기가 있는 경우에도 하나의 토큰으로 봐야하는 경우 있을 수 있음

 

Penn Treebank Tokenization 규칙

규칙 1. 하이푼으로 구성된 단어는 하나로 유지한다.
규칙 2. doesn't와 같이 아포스트로피로 '접어'가 함께하는 단어는 분리해준다.

 

Ex) "Starting a home-based restaurant may be an ideal. it doesn't have a food chain or restaurant of their own."

-> ['Starting', 'a', 'home-based', 'restaurant', 'may', 'be', 'an', 'ideal.', 'it', 'does', "n't", 'have', 'a', 'food', 'chain', 'or', 'restaurant', 'of', 'their', 'own', '.']

: 각각 규칙1과 규칙2에 따라서 home-based는 하나의 토큰으로 취급하고 있으며, dosen't의 경우 does와 n't는 분리되었음

 

문장 토큰화(Sentence Tokenization)

: 갖고있는 코퍼스 내에서 문장 단위로 구분하는 작업

보통 갖고있는 코퍼스가 정제되지 않은 상태라면, 코퍼스는 문장 단위로 구분되어 있지 않아서 이를 사용하고자 하는 용도에 맞게 문장 토큰화가 필요할 수 있음

  • NLTK : sent_tokenize
  • 한국어는 KSS 이용

 

한국어에서의 토큰화의 어려움

영어는 New York과 같은 합성어나 he's 와 같이 줄임말에 대한 예외처리만 한다면, 띄어쓰기(whitespace)를 기준으로 하는 띄어쓰기 토큰화를 수행해도 단어 토큰화가 잘 작동함

-> 거의 대부분의 경우에서 단어 단위로 띄어쓰기가 이루어지기 때문에 띄어쓰기 토큰화와 단어 토큰화가 거의 같기 때문

 

하지만 한국어는 영어와는 달리 띄어쓰기만으로는 토큰화를 하기에 부족함

-> 어절 토큰화는 한국어 NLP에서 지양되고 있기 때문. 이는 어절 토큰화와 단어 토큰화는 같지 않기 때문임. 그 근본적인 이유는 한국어가 영어와는 다른 형태를 가지는 언어인 교착어라는 점에서 기인함

  • 어절 : 띄어쓰기 단위가 되는 단위
  • 교착어 : 조사, 어미 등을 붙여서 말을 만드는 언어

 

1) 교착어의 특성

그 ->  '그가', '그에게', '그를', '그와', '그는'과 같이 다양한 조사가 '그'라는 글자 뒤에 띄어쓰기 없이 바로 붙을 수 있음

 

자연어 처리를 하다보면 같은 단어임에도 서로 다른 조사가 붙어서 다른 단어로 인식이 되면 자연어 처리가 힘들고 번거로워지는 경우가 많음

대부분의 한국어 NLP에서 조사는 분리해줄 필요가 존재함

즉,  띄어쓰기 단위가 영어처럼 독립적인 단어라면 띄어쓰기 단위로 토큰화를 하면 되겠지만 한국어는 어절이 독립적인 단어로 구성되는 것이 아니라 조사 등의 무언가가 붙어있는 경우가 많아서 이를 전부 분리해줘야 한다는 의미

 

한국어 토큰화에서는 형태소(morpheme) 개념 이해가 필수적임

 

2) 형태소

: 뜻을 가진 가장 작은 말의 단위

  • 자립 형태소 : 접사, 어미, 조사와 상관없이 자립하여 사용할 수 있는 형태소. 그 자체로 단어가 됨. 체언(명사, 대명사, 수사), 수식언(관형사, 부사), 감탄사 등이 있음
  • 의존 형태소 : 다른 형태소와 결합하여 사용되는 형태소. 접사, 어미, 조사, 어간을 의미

Ex) 문장 : 에디가 책을 읽었다

띄어쓰기 단위 토큰화 -> ['에디가', '책을', '읽었다']

하지만 이를 형태소 단위로 분해하면 다음과 같음

  • 자립 형태소 : 에디, 책
  • 의존 형태소 : -가, -을, 읽-, -었, -다

한국어에서 영어에서의 단어 토큰화와 유사한 형태를 얻으려면 어절 토큰화가 아니라 형태소 토큰화를 수행해야함

 

3) 한국어는 띄어쓰기가 영어보다 잘 지켜지지 않는다.

한국어는 띄어쓰기가 지켜지지 않아도 글을 쉽게 이해할 수 있는 언어

-> 수많은 코퍼스에서 띄어쓰기가 무시되는 경우가 많아 자연어 처리가 어려워졌음

 

품사 태깅(Part-of-speech tagging)

: 단어 토큰화 과정에서 각 단어가 어떤 품사로 쓰였는지를 구분해놓는 것

 

단어는 표기는 같지만 품사에 따라서 단어의 의미가 달라지기도 하기에, 결국 단어의 의미를 제대로 파악하기 위해서는 해당 단어가 어떤 품사로 쓰였는지 보는 것이 주요 지표가 될 수도 있기 때문

  • NLTK : Penn Treebakn POS Tags라는 기준을 이용해 품사를 태깅함
  • KoNLPy : 한국어 자연어 처리에 사용되는 파이썬 패키지 - 형 태소 분석기: Okt(Open Korea Text), 메캅(Mecab), 코모란(Komoran), 한나눔(Hannanum), 꼬꼬마(Kkma) 존재
    • morphs : 형태소 추출
    • pos : 품사 태깅(Part-of-speech tagging)
    •  nouns : 명사 추출

 

3-2. 텍스트 데이터의 정제와 정규화

코퍼스에서 용도에 맞게 토큰을 분류하는 작업을 토큰화(tokenization)라고 하며, 토큰화 작업 전, 후에는 텍스트 데이터를 용도에 맞게 정제(cleaning) 및 정규화(normalization)하는 일이 항상 함께함

  • 정제(cleaning) : 갖고 있는 코퍼스로부터 노이즈 데이터를 제거함
  • 정규화(normalization) : 표현 방법이 다른 단어들을 통합시켜서 같은 단어로 만들어줌

완벽한 정제 작업은 어려운 편이라서, 대부분의 경우 이 정도면 됐다.라는 일종의 합의점을 찾기도 함

 

> 규칙에 기반한 표기가 다른 단어들의 통합

ex) USA와 US는 같은 의미를 가지므로 하나의 단어로 정규화

 

> 대, 소문자 통합

영어권 언어에서 대, 소문자를 통합하는 것은 단어의 개수를 줄일 수 있는 또 다른 정규화 방법임

물론 무작정 통합해서는 안됨. 미국을 뜻하는 단어 US와 우리를 뜻하는 us는 구분되어야 함 & 회사 이름(General Motors)나, 사람 이름(Bush) 등은 대문자로 유지되는 것이 옳음

 

> 불필요한 단어의 제거

정제 작업에서 제거해야하는 노이즈 데이터(noise data)는 자연어가 아니면서 아무 의미도 갖지 않는 글자들(특수 문자 등)을 의미하기도 하지만, 분석하고자 하는 목적에 맞지 않는 불필요 단어들을 노이즈 데이터라고 하기도 함

1) 등장 빈도가 적은 단어

2) 길이가 짧은 단어 (영어권 언어)

영어 단어의 평균 길이는 6~7 정도 -> 갖고 있는 텍스트 데이터에서 길이가 1인 단어를 제거하는 코드를 수행하면 대부분의 자연어 처리에서 의미를 갖지 못하는 단어인 관사 'a'와 주어로 쓰이는 'I'가 제거됨 

 

> 정규 표현식(Regular Expression)

얻어낸 코퍼스에서 노이즈 데이터의 특징을 잡아낼 수 있다면, 정규 표현식을 통해 이를 제거할 수 있는경우가 많음

ex) HTML 문서로부터 가져온 코퍼스라면 문서 여기저기에 HTML 태그가 존재

 

3-3. 불용어(Stopwords)

: 문장에서는 자주 등장하지만 실제 의미 분석을 하는데는 거의 기여하는 바가 없는 경우

Ex) I, my, me, over, 조사, 접미사 같은 단어들

  • stopwords.words("english")는 NLTK가 정의한 영어 불용어 리스트를 리턴함

NLTK를 통해 불용어 제거하기

example = "Family is not an important thing. It's everything."
stop_words = set(stopwords.words('english')) 

word_tokens = word_tokenize(example)

result = []
for word in word_tokens: 
    if word not in stop_words: 
        result.append(word) 

print('불용어 제거 전 :',word_tokens) 
print('불용어 제거 후 :',result)
불용어 제거 전 : ['Family', 'is', 'not', 'an', 'important', 'thing', '.', 'It', "'s", 'everything', '.']
불용어 제거 후 : ['Family', 'important', 'thing', '.', 'It', "'s", 'everything', '.']

 

결과적으로 'is', 'not', 'an'과 같은 단어들이 문장에서 제거되었음

 

3-4. 정규 표현식

파이썬의 re 모듈 -> 특정 규칙이 있는 텍스트 데이터 빠르게 정제 가능

 

정규 표현식 문법

1) * 기호

Ex) "ab*c" : 반드시 a로 시작하고, b가 0번 이상 나올 수 있으며(즉 b가 없어도 됨), 마지막으로 c로 끝나는 문자열

r = re.compile("ab*c")
r.search("a") # 아무런 결과도 출력되지 않음
r.search("ac") # <_sre.SRE_Match object; span=(0, 2), match='ac'>

 

  • a : 문자열이 a로 시작해야 함을 의미
  • b* : b가 0번 이상 반복될 수 있음을 의미. 즉, b가 없을 수도 있고 여러 개 있을 수도 있음
  • c : 문자열이 c로 끝나야 함을 의미

2) {숫자} 기호

Ex) ab{2}c : a와 c 사이에 b가 존재하면서 b가 2개인 문자열에 대해서 매치

r = re.compile("ab{2}c")

# 아무런 결과도 출력되지 않음
r.search("ac")
r.search("abc")
r.search("abbbbbc")

r.search("abbc") # <_sre.SRE_Match object; span=(0, 4), match='abbc'>

 

3) {숫자1, 숫자2} 기호

Ex) ab{2,8}c : a와 c 사이에 b가 존재하면서 b는 2개 이상 8개 이하인 문자열에 대해서 매치

r = re.compile("ab{2,8}c")

# 아무런 결과도 출력되지 않음
r.search("ac")
r.search("abc")
r.search("abbbbbbbbbc")

r.search("abbc") # <_sre.SRE_Match object; span=(0, 4), match='abbc'>
r.search("abbbbbbbbc") # <_sre.SRE_Match object; span=(0, 10), match='abbbbbbbbc'>

 

 

정규 표현식을 이용한 토큰화

from nltk.tokenize import RegexpTokenizer

text = "Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop"

tokenizer1 = RegexpTokenizer("[\w]+")
tokenizer2 = RegexpTokenizer("\s+", gaps=True)

print(tokenizer1.tokenize(text))
print(tokenizer2.tokenize(text))
['Don', 't', 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', 'Mr', 'Jone', 's', 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop']
["Don't", 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name,', 'Mr.', "Jone's", 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop']

 

tokenizer2의 결과는 위의 tokenizer1의 결과와는 달리 아포스트로피나 온점을 제외하지 않고 토큰화가 수행된 것 확인 가능

  • \w+ : 문자 또는 숫자가 1개 이상인 경우
    • +는 최소 1개 이상의 패턴을 찾아낸다는 의미
  • \s+ : 공백을 찾아내는 정규표현식
  • gaps=true : 해당 정규 표현식을 토큰으로 나누기 위한 기준으로 사용한다는 의미
    • 만약 gaps=True라는 부분을 기재하지 않는다면, 토큰화의 결과는 공백들만 나오게 됨

 

3-5. 전처리 실습

자연어 처리는 일반적으로 토큰화, 단어 집합 생성, 정수 인코딩, 패딩, 벡터화의 과정을 거침

 

  • 단어 집합(vocabuary) : 중복을 제거한 텍스트의 총 단어의 집합(set)
  • 패딩(padding) : 길이가 다른 문장들을 모두 동일한 길이로 바꿔주는 작업. 정해준 길이로 모든 샘플들의 길이를 맞춰주되, 길이가 정해준 길이보다 짧은 샘플들에는 'pad' 토큰을 추가하여 길이를 맞춰줌
max_len = max(len(l) for l in encoded)
print('리뷰의 최대 길이 : %d' % max_len) # 63
print('리뷰의 최소 길이 : %d' % min(len(l) for l in encoded)) # 1
print('리뷰의 평균 길이 : %f' % (sum(map(len, encoded))/len(encoded))) # 13.9

 

가장 길이가 긴 리뷰의 길이 = 63 -> 모든 리뷰의 길이를 63으로 통일

for line in encoded:
    if len(line) < max_len: # 현재 샘플이 정해준 길이보다 짧으면
        line += [word_to_index['pad']] * (max_len - len(line)) # 나머지는 전부 'pad' 토큰으로 채움

 

 

'AI > PyTorch로 시작하는 딥러닝' 카테고리의 다른 글

[PyTorch] Chapter 11  (0) 2024.07.16
[PyTorch] Chapter 10  (0) 2024.07.16
[PyTorch] RNN & LSTM & GRU  (0) 2024.07.16
[PyTorch] Functional API  (0) 2024.03.21
[PyTorch] Sequential API - tokenizer(), Sequential(), Dense()  (0) 2024.03.21

RNN(Recurrent Neural Network)

시퀀스(Sequence) 모델로, 입력과 출력을 시퀀스 단위로 처리하는 모델임

피드 포워드 신경망과(Feed Forward Neural Network) 달리 은닉층의 노드에서 활성화 함수를 통해 나온 결과값을 출력층 방향으로도 보내면서, 다시 은닉층 노드의 다음 계산의 입력으로 보내는 특징 가짐

  • 피드 포워드 신경망 : 은닉층에서 활성화 함수를 지난 값이 오직 출력층 방향으로만 향하는 신경망

  • x : 입력층의 입력 벡터
  • y : 출력층의 출력 벡터
  • b : 편향 (그림에서는 생략됨)
  • t : 현재 시점
  • cell : 은닉층에서 활성화 함수를 통해 결과를 내보내는 역할을 하는 노드. 메모리 셀 또는 RNN 셀이라고도 표현함
    • 은닉층의 메모리 셀은 각각의 시점(time step)에서 바로 이전 시점에서의 은닉층의 메모리 셀에서 나온 값을 자신의 입력으로 사용 = 재귀적 활동

RNN의 다른 표현

 

RNN의 뉴런 단위 시각화

  • 위의 그림은 입력 벡터의 차원이 4, 은닉 상태의 크기가 2, 출력층의 출력 벡터의 차원이 2인 RNN이 시점이 2일 때의 모습
  • 뉴런 단위로 해석하면, 입력층의 뉴런 수는 4, 은닉층의 뉴런 수는 2, 출력층의 뉴런 수는 2

 

은닉 상태(hidden state)

메모리 셀이 출력층 방향으로 또는 다음 시점 t+1의 자신에게 보내는 값

t 시점의 메모리 셀은 t-1 시점의 메모리 셀이 보낸 은닉 상태값을 t 시점의 은닉 상태 계산을 위한 입력값으로 사용함

 

RNN의 종류

RNN은 입력과 출력의 길이를 다르게 설정 가능함

  • 일 대 다 :하나의 입력에 대해 여러 개의 출력 ex) 이미지 캡셔닝
  • 다 대 일 : 단어 시퀀스에 대해 하나의 출력 ex) 감성 분류, 스팸 메일 분류
  • 다 대 다 : 입력 문장으로부터 대답 문장 출력 ex) 챗봇, 번역기, 품사 태깅

 

RNN 수식

 

  • h_t : 현 시점 t에서의 은닉 상태값
  • W_x : 입력층에서 입력 값을 위한 가중치
  • W_h : 이전 시점 t-1의 은닉 상태값인 h_t-1을 위한 가중치

 

  • h_t 계산을 위한 활성화 함수로 주로 tanh가 많이 사용되지만, ReLU로 바꿔 사용하는 시도도 존재함
  • y_t 계산을 위한 활성화 함수로는 이진 분류의 경우 시그모이드 함수를, 다양한 카테고리 중 선택하는 문제라면 소프트 맥스함수를 사용

 

RNN에서의 입력 x_t는 대부분의 경우 단어 벡터로 간주할 수 있는데, 단어 벡터의 차원을 d, 은닉 상태의 크기를 D_h라고 하면 각 벡터와 행렬 크기는 다음과 같다. 

 

파이썬 pseudocode

메모리 셀에서 은닉 상태를 계산하는 식 구현

hidden_state_t = 0 # 초기 은닉 상태를 0(벡터)로 초기화
for input_t in input_length: # 각 시점마다 입력을 받는다.
    output_t = tanh(input_t, hidden_state_t) # 각 시점에 대해서 입력과 은닉 상태를 가지고 연산
    hidden_state_t = output_t # 계산 결과는 현재 시점의 은닉 상태가 된다.

 

  • hidden_state_t : t시점의 은닉 상태
  • input_length : 입력 데이터의 길이. 이 경우 입력 데이터는 총 시점의 수(timesteps)이 됨
  • input_t : t 시점의 입력값

각 메모리 셀은 각 시점마다 input_t와 hidden_state_t(이전 상태의 은닉 상태)를 입력으로 활성화 함수인 tanh를 통해 현 시점의 hidden_state_t를 계산한다. 

 

양방향 RNN

RNN이 과거 시점(time step)의 데이터들을 참고해서, 찾고자하는 정답을 예측하지만 실제 문제에서는 과거 시점의 데이터만 고려하는 것이 아니라 향후 시점의 데이터에 힌트가 있는 경우도 많음

-> 이전 시점의 데이터뿐만 아니라, 이후 시점의 데이터도 힌트로 활용하기 위해서 고안된 것이 양방향 RNN

 

양방향 RNN은 하나의 출력값을 예측하기 위해 기본적으로 두 개의 메모리 셀을 사용함

  • 첫 번째 메모리 셀 : 앞 시점의 은닉 상태를 전달받아 현재의 은닉 상태 계산 (주황색)
  • 두 번째 메모리 셀 : 뒤 시점의 은닉 상태를 전달받아 현재의 은닉 상태 계산 (초록색)

이 두 개 모두가 출력층에서 출력값을 예측하기 위해 사용됨

두 개의 은닉층을 가지는 양방향 RNN

 

 

  • 양방향 RNN을 구현할 땐 nn.RNN()의 인자 bidirectional = True로 설정하면 됨

 

LSTM (Long Short-Term Memory)

바닐라 RNN의 장기 의존성 문제 (the problem of Long-Term Dependencies)

바닐라 RNN은 출력 결과가 이전의 계산 결과에 의존함

하지만 바닐라 RNN은 비교적 짧은 시퀀스에 대해서만 효과를 보인다는 단점이 존재함 

= time step이 길어질 수록 앞의 정보가 뒤로 충분히 전달되지 못하는 현상이 발생

= 시점이 지날수록 x_1의 정보량이 손실되고, 시점이 충분히 긴 상황에서는 x_1의 전체 정보에 대한 영향력은 거의 의미가 없어질 수도 있음

 

LSTM (Long Short-Term Memory)

LSTM의 전체적인 내부 모습

 

 

은닉층의 메모리 셀에 입력 게이트, 망각 게이트, 출력 게이트를 추가하여 불필요한 기억을 지우고, 기억해야할 것들을 정함

=> LSTM은 은닉 상태(hidden state)를 계산하는 식이 전통적인 RNN보다 조금 더 복잡해짐 & 셀 상태(cell state)라는 값 추가됨

  • C_t : t 시점의 셀 상태 (셀 상태 : 아래 그림에서 왼쪽에서 오른쪽으로 가는 굵은 선)

 

 

 

은닉 상태값과 셀 상태값을 구하기 위해 새로 추가 된 3개의 게이트 사용함

  • 각 게이트는 입력 게이트, 삭제 게이트, 출력 게이트라고 부르며 이 3개의 게이트에는 공통적으로 시그모이드 함수가 존재
  • 시그모이드 함수를 지나면 0과 1사이의 값이 나오게 되는데 이 값들을 가지고 게이트를 조절함
  • 이하 식에서 sigma는 시그모이드 함수 의미, tanh는 하이퍼볼릭탄젠트 함수 의미
  • W들은 각 게이트에서 사용되는 가중치들 의미
  • b들은 각 게이트에서 사용되는 편향 의미 

 

(1) 입력 게이트 : 현재 정보를 기억하기 위한 게이트

 

  • i_t : 현재 시점 t의 x값과 입력 게이트로 이어지는 가중치 W_xi를 곱한 값과 이전 시점 t-1의 은닉 상태가 입력 게이트로 이어지는 가중치 W_hi를 곱한 값을 더해 시그모이드 함수를 지남
  • g_t : 현재 시점 t의 x값과 입력 게이트로 이어지는 가중치 W_xi를 곱한 값과 이전 시점 t-1의 은닉 상태가 입력 게이트로 이어지는 가중치 W_hg를 곱한 값을 더해 하이퍼볼릭탄젠트 함수를 지남

시그모이드 함수를 지나 0과 1 사이의 값과 하이퍼볼릭 탄젠트 함수를 지나 -1과 1 사이의 값 두 개가 나옴

 

(2) 삭제 게이트 : 기억을 삭제하기 위한 게이트

 

현재 시점 t의 x값과 이전 시점 t-1의 은닉 상태가 시그모이드 함수를 지나고, 0과 1 사이의 값이 나오게 됨

-> 이 값이 곧 삭제 과정을 거친 정보의 양이 됨

  • 0에 가까울수록 정보가 많이 삭제된 것이고, 1에 가까울수록 정보를 온전히 기억한 것
  • 이를 이용해 셀 상태를 구하게 됨

 

(3) 셀 상태(장기 상태)

- 셀 상태 C_t를 LSTM에서는 장기 상태라고 부르기도 함

 

입력 게이트에서 구한 i_t, g_t 두 개의 값에 대해 원소별 곱을 진행함

  • 원소별 곱( ∘ ): 같은 크기의 두 행렬이 있을 때 같은 위치의 성분끼리 곱하는 것

-> 입력 게이트에서 선택된 기억을 삭제 게이트의 결과값과 더함(= 시점 t의 셀 상태). 이 값은 다음 t+1 시점의 LSTM 셀로 넘겨짐

 

  • 삭제 게이트의 출력값인 f_t가 0 -> 이전 시점의 셀 상태값인 C_t-1은 현재 시점의 셀 상태값을 결정하기 위한 영향력이 0이 됨 -> 오직 입력 게이트의 결과만이 현재 시점의 셀 상태값 C_t을 결정할 수 있음
    • => 삭제 게이트가 완전히 닫히고 입력 게이트를 연 상태 의미
  • 입력 게이트의 i_t값이 0 -> 현재 시점의 셀 상태값 C_t는 오직 이전 시점의 셀 상태값 C_t-1의 값에만 의미
    • => 입력 게이트를 완전히 닫고 삭제 게이트만을 연 상태 의미

즉, 삭제 게이트는 이전 시점의 입력을 얼마나 반영할지를 의미하고, 입력 게이트는 현재 시점의 입력을 얼마나 반영할지를 결정함

 

(4) 출력 게이트와 은닉 상태(단기 상태)

 

출력 게이트는 현재 시점 t의 x값과 이전 시점 t-1의 은닉 상태가 시그모이드 함수를 지난 값임

해당 값은 현재 시점 t의 은닉 상태를 결정하는 일에 쓰임

 

은닉 상태를 단기 상태라고 하기도 하는데, 은닉 상태는 장기 상태의 값이 하이퍼볼릭탄젠트 함수를 지난 -1과 1 사이의 값을 의미함. 해당 값은 출력 게이트의 값과 연산되면서, 값이 걸러지는 효과가 발생함

 

파이토치의 nn.LSTM()

LSTM을 파이토치에서 사용하는 방법은 아래와 같음

nn.LSTM(input_dim, hidden_size, batch_fisrt=True)

 

 

게이트 순환 유닛 (Gated Recurrent Unit, GRU)

LSTM의 장기 의존성 문제에 대한 해결책을 유지하면서, 은닉 상태를 업데이트하는 계산을 줄인 것

-> GRU는 성능은 LSTM과 유사하면서 복잡했던 LSTM의 구조를 간단화 시킨 모델임

 

  • LSTM에서는 3개의 게이트가 존재했는데, GRU에서는 업데이트 게이트와 리셋 게이트 두 가지 게이트만 존재함
  • LSTM보다 학습 속도가 빠르지만 여러 평가에서 GRU는 LSTM과 비슷한 성능을 보인다고 알려져있음

 

GRU와 LSTM 중 어떤 것이 모델의 성능면에서 더 낫다라고 단정지어 말할 수 없으며, 기존에 LSTM을 사용하면서 최적의 하이퍼파라미터를 찾아낸 상황이라면 굳이 GRU로 바꿔서 사용할 필요는 없음

  • 경험적으로 데이터 양이 적을 때는 매개 변수의 양이 적은 GRU가 조금 더 낫고, 데이터 양이 더 많으면 LSTM이 더 낫다고도함
  • GRU보다 LSTM에 대한 연구나 사용량이 더 많은데, 이는 LSTM이 더 먼저 나온 구조이기 때문이라고 함

 

 

한글 번역 : CS231N_17_KOR_SUB/kor/Lecture 2 Image Classification.ko.srt at master · visionNoob/CS231N_17_KOR_SUB (github.com)

 

CS231N_17_KOR_SUB/kor/Lecture 2 Image Classification.ko.srt at master · visionNoob/CS231N_17_KOR_SUB

CS231N 2017 video subtitles translation project for Korean Computer Science students - visionNoob/CS231N_17_KOR_SUB

github.com

 


1. Image Classification

이미지 분류 = 컴퓨터 비전의 핵심 작업 => "어떻게 이미지 분류 작업을 할까?"

 

 

이미지를 분류할 때, 이미지(ex: 고양이)를 input으로 받고, 시스템은 어떤 미리 정해진 카테고리나 레이블을 알고 있음

-> 컴퓨터는 그림을 보고 정해진 카테고리 레이블로 지정함

 

 

컴퓨터는 엄청난 숫자 그리드로 이미지를 표현함

  • 위의 이미지는 800 * 600 pixel인데, 각 픽셀은 3가지의 숫자로 표현되어 픽셀에 대한 빨강, 초록, 파랑 값을 줌

컴퓨터에게는 단지 큰 그리드 숫자일 뿐이기에 이 숫자에서 고양이 성질을 끌어내기는 어려움

=> 위의 문제를 "의미적 차이(semantic gap)"라 함

  • 고양이라는 생각(혹은 라벨)은 사람이 부여한 의미적 라벨이므로 고양이라는 의미적 아이디어와 컴퓨터가 보는 이 픽셀 값 사이엔 엄청난 차이가 존재하는 것

 

이미지 분류를 할 때는 다양한 챌린지들이 존재함

그림은 매우 작은 변화로도 전체적으로 픽셀이 바뀌는데, 이미지에는 여러 챌린지들이 나타날 수 있음

 

1) 시점 변화

ex : 같은 고양이를 찍어도 고양이가 가만히 앉아 있기만 하지는 않음. 카메라를 다른 방향으로 움직이면 그리드에서 모든 픽셀 값이 완전히 달라짐. 그러나 우리 알고리즘은 같은 고양이를 나타내야 하므로, 이러한 변화에도 견고해야 함

 

2) 조명, 형태 변화

ex : 장면 마다 다른 조명 조건일 경우에도 알고리즘은 동작해야 하고, 물체가 형태(포즈)를 바꿨을 경우에도 동작해야 함

 

3) 가림

ex: 고양이를 일부만 보게 되는 경우도 존재함

 

4) 배경 변화

ex: 배경이 어수선할 경우도 존재함

 

5) 클래스 내 변화

ex) 고양이다움이 여러 다양한 시각적 모습에 걸쳐 나타날 수 있음. 고양이는 다양한 모양과 크기와 색깔과 나이로 나타나기에 이러한 변화에도 알고리즘은 대응할 수 있어야 함

 

 

2. Image Classifier

숫자 리스트 정렬과는 달리, 고양이나 다른 클래스 인식을 위한 명확한 명시적인 알고리즘은 존재하지 않음

이러한 직관적인 감각을 만드는 혹은 어떻게 이런 객체를 인식할지에 대한 알고리즘은 없음

 

비주얼 인식에 있어서 중요한 것은 edge임

-> 이미지의 엣지를 계산해 다양한 코너와 경계를 분류해보려는 시도가 존재했음

하지만 이러한 알고리즘은 매우 불안정하고, 확장 가능한 방법이 아니기에 잘 동작하지 않는 걸로 판명이 남

-> 인식 작업을 훨씬 더 자연스럽게 확장할 수 있는 알고리즘과 메소드를 생각해내 모든 물체를 인식하려고 함

-> data-driven(데이터 추진) 접근 방법 아이디어 이용

 

Data-driven Approach 방법

: 딥러닝보다 훨씬 일반적인 아이디어임 

  • 고양이에게 필요한 규칙들, 강아지에게 필요한 규칙들을 만드는것이 아니라, 그냥 엄청나게 방대한 고양이 사진, 강아지 사진을 컴퓨터한테 제시하고, Machine Learning Classifier을 학습시키는 것

1) 이미지와 레이블로 된 데이터셋을 모음

: 인터넷에서 다양한 카테고리에 대한 매우 많은 이미지를 모음

 

2) 머신 러닝을 사용해 classifier를 훈련시킴

: 위의 데이터셋을 가지면, 머신러닝 분류기를 훈련시킴

 

3) classifier를 이용해 새로운 이미지 판별

: 학습 모델을 사용해 새로운 이미지에 적용해봄

이때 두개의 함수가 존재하는데, 하나는 학습이라 이미지와 레이블을 입력받아 모델을 출력하는 것이고, 다른 하나는 모델을 받아 이미지에 대한 예측을 수행하는 함수임

 

NN (Nearest Neighbor Classifier) - Data-driven Approach 방법 중 가장 단순한 분류기

1) 훈련 단계 : 학습 데이터를 단순 암기함

2) 예측 단계 : 새 이미지를 받아 학습 데이터 중 그것과 가장 비슷한 것을 찾아 그 이미지의 레이블로 예측함

 

 

구체적으로 CIFAR 10이라는 데이터셋으로 살펴볼 수 있는데, 아래와 같음

 

 

NN 알고리즘을 적용하면 학습 데이터의 가장 비슷한 예를 찾을 수 있음

가장 가까운 예의 레이블을 학습 셋에서 확인할 수 있고, 그럼 테스트 이미지가 개라고 이야기하는 것

-> 테스트 이미지를 받으면 모든 학습 이미지와 비교해야 하는데, 한 쌍의 이미지가 주어지면 그걸 어떻게 비교할 수 있을까?

=> 비교 함수를 이용함 - L1 거리, L2 거리 

 

L1 거리(맨해튼 거리)

 

 

L1 거리 (맨해튼 거리) - 이미지 비교에 쓸 수 있는 가장 간단하고 쉬운 아이디어

: 이미지 내의 각각의 픽셀을 비교함

  • ex :픽셀 값은 테스트 이미지의 왼쪽 위 픽셀 값에서 학습 이미지의 왼쪽 위 값을 뺀 후 절대값을 취함. 이 과정으로 두 이미지의 차이가 구해지고, 모든 차이를 더하는 것

학습 데이터를 외우기만 하면 되기에 학습 함수는 간단한 형태임 

 

테스트 시에는 테스트 이미지를 받아서 이 학습 예들과 L1 거리 함수를 이용해 비교함

그 후 학습 데이터셋에서 가장 비슷한 예를 찾음

 

한 가지 짚고 넘어가야 할 점은, 위 코드에서 시간 복잡도가 train에서보다 predict에서 더 많이 걸린다는 것임

학습은 O(1), 테스트는 데이터셋 N개의 예에 대해 테스트 이미지와 비교해야 하므로 O(N)

-> 실제로 우리가 바라는 것은 학습시에는 느리고, 테스트 시에는 빠른 것임. 따라서 NN은 우리의 바람과는 반대

 

 

 

또한 위의 가장 왼쪽 사진의 가운데 노란 점처럼 노이즈와 같은 부분들이 존재할 수 있다는 문제점이 존재함

=  결정 경계가 robust하지 않음

-> NN 알고리즘을 일반화한 KNN 알고리즘이 등장

 

KNN (K-Nearest Neighbor Classifier) 알고리즘

하나의 최근접 이웃을 찾기 보다 거리 매트릭에 따라 K개의 최근접 이웃을 찾아서 투표를 진행하고, 가장 많은 표를 가진 이웃이 예측값이 됨

  • K=3일 때, 녹색 안에 있는 노란 점이 그 주변 영역을 노란색으로 만들지 않음 & 빨강과 파란색의 길게 튀어나온 부분들이 부드럽게 없어지기 시작함
  • K=5일 때, 파랑과 빨강 사이의 결정 경계(decision boundary)가 매우 부드러워지고 좋아짐
    -> KNN 분류기를 쓸 땐 1보다 큰 어떤 K값 사용해야 결정 경계가 부드러워지고 결과가 좋아짐 = 점점 robust 해짐

 

*) 컴퓨터 비전에서 이미지를 생각할 때 아래의 관점으로 이해해보는 게 tip

1) 이미지를 고차원 공간의 하나의 점이라 생각하기 

2) 구체적인 이미지를 보는 것. 이미지 자체로 생각하기 - 이미지의 픽셀들을 고차원 벡터로 생각할 수 있기 때문

위 두가지 관점 사이에서 왔다 갔다하는 것이 좋음

 

L2 거리(유클리드 거리)

제곱의 합에 제곱근을 구한 거리

L1 거리 : 픽셀의 차이를 절대값으로 더함

 

 

다른 거리 미터법을 쓴다는 건 다른 가정을 한다는 의미임

= 근간에 깔려 있는 기하학 혹은 위상 공간에서 예상하는 가정이 다르다는 것

  • L1 거리 : 원점을 중심으로 한 사각형 모양 & 그 사각형 위의 각점은 원점으로부터 같은 거리임
    • L1 거리에서는 좌표 프레임을 회전하면 L1 거리 점들간의 거리는 변화함
      -> 우리의 좌표 시스템 선택에 의존적임
  •  L2 거리 : 원 모양
    • L2 거리에서 좌표 프레임이 어떻게 회전하든 거리가 같음
      -> 좌표 프레임을 변경하는 건 상관이 없음

=> 만약 입력 피쳐 (feature)의 벡터의 각 항목이 작업에 중요한 의미를 가진다면, L1이 자연스럽게 맞는 것일 수 있고, 만약 공간에서의 포괄적인 벡터라면, 혹은 어떤 벡터의 각 항목의 의미를 모른다면, L2가 좀 더 자연스러울 수 있음

 

다른 거리 미터법을 사용해서, K-최근접 이웃을 벡터나 이미지만이 아니라 매우 다양한 타입의 데이타로 일반화할 수 있음

  • ex : 텍스트 조각을 분류하고 싶다고 할 때 KNN을 사용하기 위해서 해야 할 건, 두 단락이나 두 문장 사이의 거리 거리 함수를 정의하는 것임. 단지 다른 거리 미터법을 지정하는 것만으로 이 알고리즘을 매우 일반적으로 만들어서 근본적으로 모든 데이타 타입에 적용할 수 있게 됨
  • KNN은 단순한 알고리즘이지만, 새로운 문제를 볼 때, 일반적으로 제일 처음 해볼 수 있는 것임

 

다른 거리 미터법을 골랐을 때의 기하학적 차이

 

  • L1 : 좌표축을 따라 그어지는 경향(L1은 좌표축에 의존적이기 때문)
  • L2 : 좌표축을 상관하지 않고 경계가 자연스럽게 그려지고 있음

 

하이퍼 파라미터

K, 거리 미터법 등을 하이퍼 파라미터라 할 수 있음

학습하기보다는 지정해야 하는 알고리즘에 관한 선택값. 문제에 따라 매우 다르기에 먼저 값들을 시도해보고 뭐가 제일 잘 되는지 봐야 함

 

하이퍼 파라미터 설정의 아이디어

1) 데이터에 대해 최고의 정확도 혹은 성능을 내는가

: 가장 나쁜 아이디어라 할 수 있음. K=1이면 학습 데이터에서 항상 완벽하게 동작하기 때문임

 

2) 데이터를 훈련과 테스트로 나누고, 테스트 데이터에서 가장 잘 동작하는 하이퍼파라미터 고르기

: 나쁨. 새로운 데이터에서 알고리즘이 어떻게 동작할 지 알 수 없기 때문

 

3) 데이터를 훈련, 검증, 테스트로 나누고, 검증에서 가장 잘 동작하는 하이퍼 파라미터로 테스트 평가

: 가장 많이 사용되는 방법. 데이터의 대부분을 훈련 셋에 넣고, 검증 셋과 테스트 셋을 만드는 것

모든 개발과 디버깅을 한 후, 검증 셋에서 제일 잘 되는 분류기를 테스트 셋에서 돌림. 이 결과가 알고리즘이 보지 않은 데이터에 대해 어떻게 동작할 지 얘기해줌

 

 

4) 교차 검증

데이터셋 중에 마지막 부분을 테스트 셋으로 하고 나머지를 하나의 검증 세트와 훈련 세트 파티션으로 하기 보다, 여러 개로 나누는 것

-> 어떤 부분이 검증 셋이 될지 고르는 것을 반복함

  • 주로 작은 데이터셋에서 사용됨. 딥러닝에서는 별로 사용되지 않음
    • 실제로 딥러닝에서는 큰 모델을 훈련할 때 컴퓨팅 비용이 비싸기 때문

 

 

KNN을 이미지에 사용하지 않는 이유

1) KNN은 테스트시 너무 느리다는 문제가 존재함. 우리가 원하는 것은 테스트시가 더 빠른 것

2) L1, L2 거리가 이미지간 거리 척도로 적절하지 않음 

  • 이 일종의 벡터 거리 함수는 이미지들에 있어서 사람의 인식의 유사성과 일치하지 않기에 사람이 이미지 차이를 인식하는 것과는 다름
  • ex: 아래 사진의 왼쪽 3개는 유클리드 거리를 계산했을 때 모두 같은 L2 거리를 가짐 -> 이것으로 이미지 간의 인식적 차이를 잡아내는 것은 좋은 결과를 내지 못함

 

 

 

 

3) 차원의 저주

 

KNN은 학습 데이터 주변으로 페인트를 떨어뜨려 공간을 분리하는 데 사용함

Knn이 잘 동작하려면 전체 공간을 조밀하게 커버할 만큼의 충분한 트레이닝 샘플이 필요함

  • 그렇지 않으면 최근접 이웃이 꽤 멀것이고, 테스팅 포인트와 유사하지 않을 수 있기 때문

공간을 밀도 높게 커버한다는 것은 많은 훈련 예제가 필요하다는 것인데, 문제의 차원은 지수로 증가하기에 고차원의 이미지의 경우 모든 공간을 커버할 만큼의 데이터를 모으는 일은 현실적으로 불가능함

 

 

3. Linear Classification

NN(Neural Network)과 CNN의 기반이 되는 알고리즘으로, parametric model의 기초임

  • NN이 레고 블럭이라면 Linear Classifier는 기본 블럭이라고 할 수 있음
  • 딥러닝 어플리케이션에서 가장 기초적인 빌딩 블록(building block)이 선형 분류기

 

Parametric model

 

선형 분류기는 파라미터 모델의 가장 간단한 예임

파라미터 모델은 input으로 고양이 이미지를 받고 2개의 component(X, W)를 가짐

  • input data : X
  • parameter(or weights) : W
  • f : 데이터 X와, 파라미터 W를 받고 CIFAR 10에 있는 10개의 카테고리에 해당하는 점수를 나타나는 10개의 숫자를 내뱉는 함수
    • 10개의 숫자는 데이터셋의 각 클래스에 해당하는 스코어의 개념으로, "고양이" 클래스의 스코어가 높다면 입력 X가 "고양이"일 확률이 크다라는 의

 

KNN : 파라미터를 이용하지 않았고, 전체 트레이닝 셋을 테스트에서 다 비교하는 방식

parametric 접근법 : train 데이터의 정보를 요약해서 파라미터 W에 모아주는 것이라 생각할 수 있음

-> 따라서 test시에 더이상 트레이닝 데이터를 직접 비교하지 않고, W만 사용할 수 있게 된 것

-> 딥러닝이란 여기서 이 함수 f를 잘 설계하는 일임

 

f(X, W) = WX

W와 X를 조합하는 가장 간단한 예는 둘을 곱하는 것 -> 이것이 linear classifier

 

먼저 입력 이미지(32x32x3)을 하나의 열벡터로 피면 (3072x1)이 됨

= 하나당 3072개 항목을 가지는 것

 

우리는 10개의 클래스 점수로 만들고 싶은 것이므로, 이 이미지에 대해 10개 카테고리에 대한 숫자로 만들어야 함

-> matrix W는 10 by 3072가 되어야 함

결론적으로 이 둘을 곱하면 하나의 열로 된 벡터, 즉 10 by 1의 클래스 스코어를 얻을 수 있게 됨

 

f(X, W) = WX + b

: bias 항을 더해준 식

 

  • bias는 데이터와 무관하게 (x와 직접 연산되지 않음) 특정 클래스에 우선권을 부여할 수 있음
    = 각 클래스에 scaling offsets를 추가해줄 수 있는 것
  • bias는 상수 벡터로 10개의 원소로 이루어져 있고, 학습 데이터와는 상호작용하지 않고 데이터와 무관한 선호도를 제공함
    = 다른 클래스보다 어떤 클래스가 더 좋다는 것을 의미하는 값이 bias 
    • ex: 고양이가 개보다 많다면 고양이에 해당하는 bias 항목이 다른 것들보다 높을 것

 

Linear Classifier의 동작 방식

 

  • input으로 2 x 2 이미지를 받아서, 4개의 항목으로 된 행 벡터 하나로 늘여 놓음
    • 이미지 2 x 2 -> 전체 4개 픽셀
  • dog, cat, ship의 3개의 클래스만 사용하므로 가중치 매트릭스는 4 x 3
    •  4개의 픽셀과 3개의 클래스기 때문 
  • 각 카테고리에 대해 데이터에 독립적인 bias 항을 줌
    • 3개의 항목의 bias 벡터 존재

 

Linear classifier는 템플릿 매칭의 관점에서도 볼 수 있음

가중치 행렬 W의 각 행은 각 이미지에 대한 템플릿으로 볼 수 있고, 결국 w의 각 행과 x는 내적이 되는데, 이는 결국 클래스의 탬플릿(w)과 인풋 이미지(x)의 유사도를 측정하는것으로 이해할 수 있음

 

고양이 점수는 이미지 픽셀과 매트릭스의 첫번째 행의 내적 (inner product) + bias 항

  • dot product 계산 : 클래스 템플릿과 이미지의 픽셀간의 유사성을 보여줌
  • bias : 데이타와 상관없는 스케일링 오프셋 (scaling offset)을 각각의 클래스에 제공함

 

가중치 matrix의 행으로 이미지를 풀어내기가 가능한데, 그 템플릿을 이미지로 시각화하면 이 선형 분류기가 우리의 데이터를 이해하기 위해 뭘 하고 있는지를 알 수 있게 됨

  • 아래의 10개 사진들은 CIFAR 10에서의 학습을 마친 가중치 행렬 W를 시각화 한 것임
  • 입력 이미지와 연산되었을 대 자신의 점수를 최대로 만드는 값으로 수렴한 것이라고 보면 됨

 

선형 분류기의 문제

= 단지 하나의 클래스에 대해 하나의 템플릿만 배운다는 것! (각각의 카테고리를 인식하기 위해 하나의 템플릿만 사용함)

-> 그 클래스가 어떻게 보이는지에 대해 변화(variant)가 있다면 그 모든 다양함을, 즉 다르게 보임을 모두 평균화시키기 때문

-> 이러한 문제점은 신경망의 사용으로 해결이 가능함

  • 신경망으로 갈수록, 더 복잡한 모델로 갈수록 하나의 카테고리에 대해 하나의 템플릿만 배워야 한다는 제한이 없기 때문

 

각각의 이미지는 고차원 공간에서 점과 같다고 볼 수 있는데(tip의 관점 1), 선형 분류기는 각 클래스를 구분시켜주는 선형 결정 바운더리 역할을 함 (하나의 카테고리와 다른 카테고리들 사이에 선형 분리선을 그리는 것)

  • 왼쪽 위의 비행기 훈련 이미지로 훈련 프로세스를 거쳐, 선형 분류기는 비행기 클래스를 다른 모든 클래스와 분리하기 위해 이 파란 선을 그릴 것
  • 이 선들은 랜덤하게 시작해서 데이터를 적절하게 분리하기 위해 자리를 잡게 됨

 

Linear Classifier가 분류하기 어려워하는 경우

 

 

1) 2개의 카테고리의 데이터셋이 있다고 했을 때, 영역이 왼쪽 그림과 같이 하나의 선형 라인을 그릴 수 없게끔 만들어 질 때

  • ex : 홀수와 짝수를 나누는 것은 전통적으로 선형 분류기가 힘들어하는 것임

2) multi modes 상황

오른쪽처럼  공간의 여러 영역들로 나눠져있는 클래스 같은 멀티 모드 데이터는 선형 분류기가 어려워하는 대상임

 

=> 즉, 직선 하나로 분류할 수 없는 문제라면 선형 분류기를 통해 풀기가 힘들다는 것

 

 


[cs231n] 2강 이미지 분류 (1/4, 챌린지) :: 소프트웨어공학-Software Engineering (tistory.com)

 

[cs231n] 2강 이미지 분류 (1/4, 챌린지)

지난 시간엔 컴퓨터 비전이 무엇인지와 역사에 대해 배웠죠. 그리고 이 강좌 개요에 대해서도요. 오늘은 세부 사항들을 들여다 보겠습니다. 이 알고리즘이 어떻게 동작하는지에 대해서요. 첫 강

softwareeng.tistory.com

[cs231n] 2강 이미지 분류 (2/4, 최근접 이웃 / nearest neighbors) :: 소프트웨어공학-Software Engineering (tistory.com)

 

[cs231n] 2강 이미지 분류 (2/4, 최근접 이웃 / nearest neighbors)

이미지 분류를 위한 API가 뭔지 생각해 보면, 파이썬으로 이런 메소드를 아마 작성할 겁니다. 이미지를 받아서 어떤 미친 마법을 부려서 고양이인지 개인지 아무것도 아닌지 레이블을 뱉어내는

softwareeng.tistory.com

[cs231n] 2강 이미지 분류 (3/4, K-최근접 이웃/ K-Nearest Neighbors) :: 소프트웨어공학-Software Engineering (tistory.com)

 

[cs231n] 2강 이미지 분류 (3/4, K-최근접 이웃/ K-Nearest Neighbors)

손가락처럼 튀어 나온 이런 것들이 이 알고리즘을 일반화하고 싶은 동기를 유발합니다. 그래서 나온 것이 K-최근접 이웃 알고리즘이죠. 하나의 최근접 이웃을 찾기 보다는, 약간 더 멋진 걸 하는

softwareeng.tistory.com