코딩하는 해맑은 거북이
[딥러닝] 신경망과 로지스틱 회귀, 벡터화 본문
본 게시물의 내용은 'Google ML Bootcamp 2023 커리큘럼의 Coursera 강의,
Neural Networks and Deep Learning(Andrew Ng)'를 듣고 정리하여 작성하였다.
해당 글은 아래의 3가지를 다룬다.
📌 딥러닝 소개
📌 신경망과 로지스틱 회귀
📌 파이썬과 벡터화
📌 딥러닝 소개
🔷 What is a Neural Netrworks?
입력 x와 출력 y를 매칭해주는 함수를 찾는 과정이다.
cf) 예를 들어, 집의 크기에 따른 집의 가격을 예측하는 과정은 아래의 그림으로 이해할 수 있다.
집의 크기와 가격의 데이터의 분포로 하나의 직선을 만들어 낼 수 있고, 가격은 음수가 되지 않으므로 음수가 될 직선부분의 가격이 0인 직선을 그려낼 수 있다. 해당 직선은 집의 크기에 따른 집의 가격을 예측하는 함수라고 할 수 있다.
(여기서 해당 함수는 ReLU(Rectified Linear Unit) 함수라고 불린다.)
이러한 함수를 간단한 신경망으로 생각하면, 입력 x(집의 크기)로 원형의 노드를 거쳐 출력 y(집의 가격)가 나오게 된다.
해당 원형의 노드가 신경망에 존재하는 하나의 뉴런을 의미한다.
하지만, 집의 가격(출력 y)을 예측하는데, 침실의 갯수/우편번호/재력 등의 다양한 특성이 입력 x로 사용될 수 있다.
아래의 그림처럼 4개의 입력값이 들어감으로써 더 큰 신경망이 된다. 여기서 4개의 입력값의 특성으로 Hidden Unit을 통과하여 출력 y를 예측하는 것이 신경망의 역할이다.
*모든 입력 특성은 원형의 노드인 각 뉴련에 모두 연결되어야 하며, 입력값들의 관계 여부는 신경망이 학습하면서 알아서 조절해준다.
*충분한 양의 x와 y를 훈련 예제로 준다면, 연결하는 함수를 더 잘 알아낼 수 있다.
🔷 Supervised Learning with Neural Networks - 신경망을 이용한 지도학습
지도 학습(Supervised Learning)이란 정답이 주어져있는 데이터를 사용하여 컴퓨터를 학습시키는 방법을 뜻한다.
대부분의 신경망을 통해 만들어진 경제적인 가치들은 머신러닝의 한 종류인 지도 학습(Supervised Learning)을 통해 만들어 졌다. 아래의 표는 지도학습의 사례들이다.
- 집의 특성으로 집의 가격 예측하기 - 부동산
- 사용자 정보에 따라 광고 클릭 여부를 예측하기 - 온라인 광고
- 부동산, 온라인 광고는 표준적인 신경망(Standard NN)을 사용한다.
- 컴퓨터 비전에서 이미지 특징을 파악하여 특정 클래스로 태깅하기 - 사진 태깅
- 이미지나 영상 데이터의 기반은 주로 합성곱 신경망(CNN, Convolutional NN)을 사용한다.
- 음성 파일에서 텍스트 대본을 추출하기 - 음성 인식
- 영어를 중국어로 번역하기 - 기계 번역
- 음성이나 언어 데이터 등의 시퀀스 데이터는 순환 신경망(RNN, Recurrent NN)을 사용한다.
- 이미지, 레이더 정보를 통해 다른 차의 위치 정보 학습 - 자율 주행
- 자율주행은 이미지를 사용하는 부분은 CNN, 레이더 정보는 Custom이나 Hybrid 신경망을 사용한다.
머신러닝에서 데이터 구조는 '구조적 데이터(Structured Data)'와 '비구조적 데이터(Unstructured Data)'가 있다.
- 구조적 데이터는 기본적으로 데이터베이스로 표현된 데이터를 의미한다.
- 비구조적 데이터는 음성 파일, 이미지, 텍스트 데이터가 있고, 여기서 특성은 이미지의 픽셀값, 텍스트의 각 단어를 의미한다.
비구조적 데이터는 구조적 데이터보다 컴퓨터가 작업하기 훨씬 어렵다. 하지만, 딥러닝 덕분에 컴퓨터가 비구조적 데이터를 인식할 수 있게 되었다.
🔷 Why is Deep Learning taking off? - 왜 딥러닝이 뜨고있는가
딥러닝의 발전은 아래의 3가지 요인으로 향상되었다.
- 데이터 양 증가 (Data)
- 디지털 세상으로 발생하는 데이터 양이 급증하였다.
- 컴퓨터 성능 향상 (Computation)
- CPU나 GPU의 하드웨어 발전으로 아주 큰 신경망 훈련이 가능해졌다.
- 신경망 학습(Idea → Code → Experiment)의 많은 경우가 반복적인데, 컴퓨터 성능 향상으로 시간이 단축되어 빠른 실험 결과를 얻을 수 있고, 더 많은 아이디어를 실험할 수 있게 되었다.
- 알고리즘의 개선 (Algorithms)
- Sigmoid 함수가 아닌 ReLU 함수를 사용함으로써 Gradient 소멸 문제를 해결하였다.
아래 그림을 보면, 단순히 신경망을 크게 키울수록 더 좋은 성능을 보인다.
즉, 아주 좋은 성능을 발휘하기 위해서는 많은 양의 데이터와 충분히 큰 신경망이 필요하다.
*여기서 x축의 Amount of data는 레이블이 있는 데이터를 의미한다. 레이블이 있는 데이터는 (입력 x와 출력 y가 함께있는 훈련세트)이고, 앞으로의 강좌에서 이를 m으로 표현한다.
📌 신경망과 로지스틱 회귀
🔷 Binary Classification - 이진 분류
이진 분류(Binary Classification)란 '그렇다/아니다'와 같이 분류되는 항목이 2가지인 것을 의미한다.
cf) 예를 들어, 특정 이미지가 고양이인지 아닌지를 구분하는 문제는 이진 분류 문제이다.
입력 이미지가 고양이라면 1, 고양이가 아니라면 0으로 2가지로 분류되어 출력하기 때문이다.
아래의 이미지 예시(64x64)를 보면 R,G,B의 3가지 채널이 존재하는 컬러 이미지이므로, 이에 대응하는 64x64x3 행렬로 나타난다. 64x64x3의 총 12,288개의 모든 픽셀값은 해당 이미지를 벡터화하여 한 열로 표현하고, 이것이 입력 x의 특징 벡터이다.
단 하나의 훈련 샘플을 (x, y)로 표기할 때, x는 \(n_x\) 차원 상의 특징 벡터이고, y는 0 또는 1이다.
훈련 세트는 m개의 훈련 샘플을 포함하고, {\((x^{(1)}, y^{(1)})\), \((x^{(2)}, y^{(2)})\), ..., \((x^{(m)}, y^{(m)})\)}로 표기할 수 있다.
이러한 훈련 샘플들을 더 간결하게 표기하기 위해 'm개의 훈련 샘플의 특징 벡터로 나열한 각각의 x를 붙여서' 행렬 X를 표기할 수 있다. (전치하여 표기할수도 있지만, 신경망을 구현할 때 전치하지 않은 것이 더 구현하기 쉬움)
최종적으로, 행렬 X는 \(n_x\) x m 차원으로, 출력 레이블 Y는 1 x m 차원으로 표기할 수 있다.
*Standard Notations
🔷 Logistic Regression - 로지스틱 회귀
로지스틱 회귀(Logistic Regression)란 출력값이 0 또는 1로 정해져있는 이진 분류에서 사용되는 알고리즘이다.
특징 벡터 X를 통해 y의 예측값인 \(\hat{y}\)은 y가 1일 확률을 의미하며, \(0 ≤ \hat{y} ≤ 1\) 사이의 값을 가져야 한다.
선형 회귀시 \(\hat{y} = W^TX + b\) 함수로 계산하지만, 0~1 사이의 값으로 추정하기 위해 시그모이드 함수를 적용해준다.
시그모이드 함수는 σ 로 축약해서 표현하여, \(\hat{y} = \sigma(W^TX + b)\)로 식을 구할 수 있다.
\(z = W^TX + b\) 라고 할 때, z의 값이 매우 크면 1에 가깝고, 매우 작으면 0에 가까워진다.
🔷 Logistic Regression Cost Function - 로지스틱 회귀의 비용 함수
손실 함수(loss function)는 하나의 입력 x에 대한 실제값(y)과 예측값(\(\hat{y}\))의 오차를 계산하는 함수이다.
비용 함수(cost function)은 모든 입력에 대한 실제값(y)과 예측값(\(\hat{y}\))의 오차를 계산한 손실 함수의 평균값이다.
이를 통해 실제값(y)과 가까운 예측값(\(\hat{y}\))을 구하는 것이 목표이므로, 손실 함수 및 비용 함수를 최소화하는 파라미터 w와 b를 찾는 것이 중요하다.
보통 손실 함수는 평균 제곱 오차(Mean Squared Error; MSE) 인 아래의 식을 사용하지만, 로지스틱 회귀에서는 이러한 손실 함수를 사용하면 지역 최소값에 빠질 수 있기 때문에 사용하지 않는다.
그렇기 때문에, 로지스틱 회귀에서 사용하는 손실함수는 아래의 식과 같고, 이를 크로스 엔트로피 오차(Cross Entropy Error; CEE) 라고 부른다.
- y = 1 인 경우, \(-log{\hat{y}}\) 만 남아있고, 손실 함수가 작으려면 \(log{\hat{y}}\) 이 엄청 커져야 한다. 이는 \(\hat{y}\) 이 엄청 커지는 것과 동일하다. \(\hat{y}\) 은 시그모이드 함수를 사용하여 최대인 1에 수렴하게 된다.
- y = 0 인 경우, \(-log{(1-\hat{y})}\) 만 남아있고, 손실 함수가 작으려면 \(log{(1-\hat{y})}\) 이 엄청 커져야 한다. 이는 \(\hat{y}\) 이 엄청 작아지는 것과 동일하다. \(\hat{y}\) 은 시그모이드 함수를 사용하여 최소인 0에 수렴하게 된다.
🔷 Gradient Descent - 경사하강법
앞서 로지스틱의 회귀 분석의 비용 함수를 최소화하는 파라미터 w와 b를 찾는 것이 중요하다고 하였다.
이를 찾는 방법 중 하나가 경사하강법(Gradient Descent)이다.
우선 경사하강법을 통해 최적의 파라미터인 w와 b를 찾기 위해서는, 비용 함수는 볼록한 형태여야 한다.
경사하강법은 임의의 시작점에서 함수의 기울기를 따라 최적의 값으로 반복하여 최적점(optimum)에 도달하는 방법이다.
*해당 최적점은 항상 전역 최적점(global optimum)을 보장하지 않고 찾는 것도 어려운 작업이다. 또한, 때로는 지역 최적점(local optimum)에 갇힐 수 있다.
경사하강법의 수식은 다음의 w와 b값은 현재의 w와 b값을 통해 기울기를 계산하고, 학습률 α 만큼의 스텝으로 이동하여 찾아가는 것이다. 여기서 d는 도함수라고 하며, 미분을 통해 구한 값이다.
그리고, \(\frac{dJ(w, b)}{dw}\)를 dw라고 표기하기도 한다.
최적점(optimum)에 도달하는 과정을 아래의 그림을 통해 더 자세하게 살펴보면,
- dw > 0 라면, \(-\alpha\frac{dJ(w, b)}{dw}\)가 음수로 기존의 w보다 작아지는 방향으로 이동한다.
- dw < 0 라면, \(-\alpha\frac{dJ(w, b)}{dw}\)가 양수로 기존의 w보다 커지는 방향으로 이동한다.
*하나의 변수에 대한 도함수는 \(dw = \frac{dJ(w, b)}{dw}\) 라고 표현하고,
두 개 이상의 변수에 대한 도함수는 \(dw = \frac{\partial{J(w, b)}}{\partial{w}}\) 로 표현한다. (\(d\)와 \(\partial\)의 차이)
cf) 함수의 도함수?
함수의 도함수는 입력변수 x의 작은 변화가 f(x)에 얼만큼 영향을 미치는지를 설명한다.
즉, 도함수는 주어진 x에서의 함수의 순간적인 기울기를 나타내고, 미분을 통해 구할 수 있다.
함수의 기울기는 함수의 위치에 따라 다른 값을 가질 수 있다. (단, 직선이면 같은 기울기를 가짐)
🔷 Computation Graph - 계산 그래프
신경망의 계산은 정방향 전파(Forward pass)와 역방향 전파(Backward pass)로 나눌 수 있다.
정방향 전파(Forward pass)는 신경망의 출력값을 계산하고, 역방향 전파(Backward pass)는 도함수를 계산한다.
함수 J(a,b,c) = 3(a+bc) 에 대한 계산 그래프로 만들어보면 아래 그림과 같다.
해당 계산 그래프에서 역전파를 진행해보면, 아래 그림과 같이 구할 수 있다.
\(\frac{dJ}{da}\)를 구하기 위해서 \(\frac{dJ}{dv}\)와 \(\frac{dv}{da}\)의 곱으로 표현할 수 있다. 이러한 법칙을 연쇄법칙이라한다.
또한, 코드 작성시 편의를 위해 표기법을 아래와 같이 정의한다. 예를 들어, \(\frac{dJ}{da} = da\)를 의미한다는 것이다.
🔷 Logistic Regression Gradient Descent - 로지스틱 회귀의 경사하강법
로지스틱 회귀의 경사하강법을 계산 그래프를 통해 역전파를 진행해보면 아래 그림과 같이 표현할 수 있다.
📌 파이썬과 벡터화
🔷 Vectorization - 벡터화
벡터화란 기본적으로 코딩에서 for loop를 제거하는 기술이다.
\(z=w^Tx+b\)를 계산할 때, w와 x가 벡터화되지 않은 구현은 for loop를 통해 계산해야 하는데,
벡터화된 구현은 numpy 라이브러리에서 np.dot(w, x)를 통해 계산하고, 해당 방법이 벡터화되지 않은 구현보다 300배 빠르다.
즉, 컴퓨터 계산의 효율성을 위해 가능하면 for loop를 피하는 것이 좋다.
또한, 딥러닝에서 큰 데이터셋을 학습시킬 때, 코드가 빠르게 실행되는게 중요하기 때문에 벡터화가 중요한 기술이 되었다.
*SIMD(Single Instruction Multiple Data)는 병렬프로세서의 한 종류로, 병렬화의 장점으로 빠른 계산과 벡터화 연산을 가능하게 해준다. (GPU와 CPU상의 계산에서 모두 적용된다)
🔷 Vectorizing Logistic Regression - 로지스틱 회귀의 벡터화
>> 로지스틱 회귀에서 비용 함수를 for loop를 통해 계산하는 방법 (특징의 개수를 2개로 가정; x1, x2)
해당 방법은 특징의 개수가 많아진다면 이로 인해 계산속도가 느려지게 된다.
>> 로지스틱 회귀에 벡터화 적용하여 계산하는 방법
기존에는 \(z^{(i)}\)를 계산할 때, for문을 통해 i 값을 변화시키며 계산하였다.
이를 벡터화된 구현으로 변경시키면 아래와 같이 계산할 수 있다.
여기서 상수 b는 (1 x m) 크기의 행렬로 브로드캐스팅되어 더해진다.
Z = np.dot(np.transpose(W), X) + b
'AI' 카테고리의 다른 글
[Google ML Bootcamp 2023 4기] 수료 및 졸업식 후기 (0) | 2023.12.01 |
---|---|
[딥러닝] 얕은 신경망, 심층 신경망 네트워크 (0) | 2023.09.07 |
[컴퓨터비전] Semantic Segmentation - FCN 한계를 극복한 Model (0) | 2023.06.13 |
[컴퓨터비전] Semantic Segmentation - FCN (0) | 2023.06.13 |
[컴퓨터비전] Advanced Object Detection (0) | 2023.05.04 |