스탠포드 대학교의 CS231n 강의를 듣고 요약, 필기한 글입니다.
인터넷과 이미지 매체의 발전, ImageNet과 같은 거대 데이터셋의 구축, 빠르게 늘어난 컴퓨터의 연산 능력과 GPU의 성능은 딥러닝과 컴퓨터 비전의 발전에 크게 기여하였다.
컴퓨터 비전 분야는 그동안 많은 진보를 거쳤고 지금도 빠르게 발전하고 있는 분야지만, 이미지에서 서로 다른 객체 간의 관계를 파악한다거나, 배경지식을 통해 숨어있는 맥락을 읽어낸다거나... 등등 아직 더 가야 할 길이 한참 남아있는 분야이기도 하다.
컴퓨터가 인간처럼 이미지를 인식하고 분류하기 위해서는 수많은 어려움을 극복해야 한다.
똑같은 객체여도 사진의 구도나 조명이 바뀌거나, 다른 물체에 일부가 가려지거나, 배경과 비슷해 보이는 이미지가 있을 수 있음. 우리의 알고리즘은 이런 상황에 대한 '강인함'이 필요함.
Semantic Gap: 컴퓨터에게 이미지는 인간과 달리 '수많은 숫자들의 집합'으로 보일 뿐임. 이미지의 형태가 조금만 달라지더라도 실제로는 수많은 픽셀 값들이 변동됨.
이미지를 인식하는 알고리즘을 만들기 위해서 다음 방법을 떠올릴 수 있다.
CIFAR-10: 10가지 카테고리와 50,000여 개의 학습용 이미지, 10,000여 개의 테스트 이미지로 이루어진 거대한 이미지 데이터셋.
Nearest Neighbor(NN) 알고리즘: 훈련 단계에서는 모든 학습 데이터를 기억하고, 예측 단계에서는 새로운 이미지가 들어오면 기존 학습 데이터를 비교해서 '가장 비슷한 이미지'로 레이블을 예측함.
O(1)
, 예측 단계에선 기억한 모든 데이터와 비교를 거쳐야 하므로 O(N)
의 시간이 걸림. ⇒ 보통은 훈련이 느리고 시험이 빠른 것이 좋음... (반대!)K-Nearest Neighbor(KNN) 알고리즘: NN 알고리즘의 개선 버전. 거리 척도를 통해 가까운 이웃을 K개 찾고, 이웃끼리 투표를 해서 가장 많은 득표수를 획득한 레이블로 예측함.
위 이미지를 보면 K 값이 높아질수록 분류 경계가 부드러워지고, 동떨어져 있던 예측값도 자연스럽게 주변의 분류로 흡수되는 것을 알 수 있다.
💡 L1과 L2 중 어떤 것을 '거리 척도'로 선택해야 할까?
- 문제와 데이터의 성질에 따라 달라짐. 직접 시도해 보고 더 좋은 것을 택하자!
- 강의에서는 특징 벡터 각각의 요소들이 자체적인 의미를 갖고 있을 때 L1 distance가 좀 더 어울린다는 식으로 설명됨.
K 값과 거리 척도처럼 학습을 통해서 얻어지지 않고 사람이 직접 지정해야 하는 매개변수를 '하이퍼파라미터'라고 한다. 그럼 어떻게 하이퍼파라미터를 선택해야 할까?
'훈련 데이터'의 정확도와 성능을 최대화하는 것을 선택
⇒ 안 좋음! 실제 데이터를 잘 분류하는 것이 더 중요함.
데이터를 '훈련 데이터'와 '시험 데이터'로 나누고, 시험 데이터에서 가장 최적의 결과를 내는 것을 선택
⇒ 역시 안 좋음! 시험 데이터에 대해서만 잘 동작하는 하이퍼파라미터를 고른 것일 수 있음.
데이터를 '훈련', '검증', '시험' 데이터 3가지로 나누고, 검증 데이터에 대해 가장 좋았던 분류기를 가지고 시험 데이터를 통해 성능을 평가
⇒ ✅ 가장 일반적. 시험 데이터는 모델을 완성한 후 '오직 한 번만' 사용해야 함.
Cross-Validation: 먼저 시험 데이터를 정해놓고, 나머지 데이터를 여러 부분으로 나눈 후 그중에서 검증 데이터를 번갈아가면서 지정함. 실제 딥러닝에선 잘 쓰이지 않음.
실제 이미지 분류에는 K-NN 분류기를 쓰지 않는다. 일단 너무 느리고, L1/L2 거리 척도가 이미지 간의 '지각적 유사도'를 측정하기에 적절하지 않기 때문이다.
💡 '차원의 저주'란?
⇒ 차원이 증가할수록 모든 공간을 조밀하게 채우기 위해 필요한 데이터가 기하급수적으로 늘어나는 현상을 말한다. N차원에서의 부피를 생각하면 된다.
선형 분류자는 신경망을 이루는 가장 기본적인 블록 역할을 한다. 'Parametric Model'의 가장 단순한 형태이기도 하다.
위 그림의 예시에서 는 입력 이미지 와 파라미터(가중치) 를 받아 10개의 숫자(카테고리별 점수)를 출력한다.
2×2 크기의 단일 채널 이미지를 받아 3가지 분류 중 하나로 분류하는 간단한 예시를 들면 이런 식으로 연산이 이루어진다.
한편, 아래 그림은 학습을 마친 가중치 행렬 를 시각화한 것이다. 각 분류에 해당하는 입력 이미지와 연산되었을 때 자신의 점수를 최대로 만드는 값으로 수렴한 것이라 보면 될 것 같다.
손실 함수는 예측 함수와 문제의 정답을 입력으로 받아서 현재 가중치가 '얼마나 잘못 예측하는지'를 정량적으로 알려주는 함수이다.
여러 분류를 다루기 위한 '이진 SVM'의 일반화된 형태이다.
💡 SVM이란?
서포트 벡터 머신(Support Vector Machine)으로, 두 분류 중 주어진 데이터가 어디에 속하는지 결정하는 '이진 선형 분류' 모델이다. 데이터가 존재하는 공간에서 가장 큰 폭을 갖는 경계를 찾는 것이 목표다. (참고 게시글)
위 수식에 따르면 각 데이터마다 '정답이 아닌 분류로 예측한 점수'에서 '올바른 분류로 예측한 점수'를 빼주고 있으며, 이 값은 '정답 점수가 오답 점수보다 더 커질 때' 음수가 된다. 해당 값에 마진을 더한 값과 0 중에서 더 큰 값을 손실로 두는 것이다.
처음 학습을 시작할 때 행렬 W는 임의의 작은 수들로 초기화되므로 결과 점수들이 임의의 일정한 값을 갖게 됨. 즉, 모든 점수가 0에 가깝고 값이 서로 비슷하다면 마진 * (클래스의 수 - 1)
만큼의 손실이 나옴.
오차를 구할 때 제곱을 사용하면 '나쁜 것을 곱절로 나쁘게' 보는 것이 됨. 즉, '조금 잘못된 것'과 '많이 잘못된 것'의 차이를 강조하고 싶을 때 사용.
학습의 궁극적인 목적은 훈련 데이터가 아닌 시험 데이터에 대한 최적의 성능을 갖게 만드는 것이며, 만약 훈련 데이터에만 '꼭 맞게(fit)' 학습시킨다면 실질적인 성능은 떨어질 수 있다.
이를 방지하는 기법이 바로 'Regularization'이다.
Regularization은 손실 함수에 일종의 '페널티' 역할을 하는 항을 추가하여 모델이 좀 더 '단순한' 를 선택하도록 돕는다.
소프트맥스는 딥러닝에서 주로 사용하는 손실 함수로, 점수 자체에 추가적인 의미를 부여한다.
'어떻게 하면 손실을 최소화하는 가중치 W를 찾을 수 있을까?'
이는 지도가 없는 매우 복잡한 산맥에서 가장 밑바닥의 낮은 곳을 찾는 일과 같다.
그 대신, 현재 위치에서 '기울어진' 방향을 찾아 조금씩 이동하는 것을 반복한다면 가장 낮은 곳에 도달할 수 있지 않을까?
그래디언트의 방향은 함숫값을 가장 많이 증가시키는 방향이므로, 내려갈 때는 그 반대 방향을 사용하면 될 것이다.
그래디언트를 구하는 방법은 다음 두 가지로 나뉜다.
한편, 전체 손실은 각 훈련 데이터셋에 대한 손실의 평균으로 정의되는데, 만약 데이터 수가 매우 많아진다면 그만큼 작업 시간이 크게 늘어나며, 그래디언트를 구할 때에도 매번 손실 값이 필요하므로 문제가 생길 것이다.
DNN(심층 신경망) 이전에는 이미지의 특징 표현들을 계산한 후 한데 모아 연결시켜(concat) 하나의 특징 벡터로 만들고, 그것을 선형 분류자의 입력으로 사용했었다.
원래는 선형으로 분류할 수 없었던 특징들을 적절한 변환을 통해 선형 분류가 가능하게끔 만드는 것이다.
강의에서 소개된 여러 특징 변환의 예는 다음과 같다.
하지만 CNN과 DNN은 이렇게 '이미 만들어 놓은 특징들'을 사용하는 대신, 데이터로부터 직접 특징들을 학습하려 한다는 것이 가장 큰 차이점이다.
Computational Graph(계산 그래프)는 함수의 연산 과정을 노드와 에지를 갖는 그래프 형태로 나타낸 것으로, Backpropagation(역전파)라는 기술을 사용할 수 있게 해준다.
역전파를 계산하는 방법은 다음과 같다.
각 노드마다 자신의 '입력에 대한 출력의 미분(= Local Gradient)'을 계산한 뒤, 가장 끝에서부터 거슬러 올라가며 노드별 미분들을 곱해나간다.
이러한 '국소적 미분'을 이용하면 아무리 복잡한 수식의 함수라도 덧셈, 곱셈, 상수배, 역수, 지수 등의 기초적인 연산 노드들로 분해하여 차근차근 그래디언트들을 계산할 수 있다.
만약 입력이 스칼라값이 아닌 벡터라면 어떻게 될까?
거의 비슷하지만 그래디언트가 Jacobian 행렬이 된다는 점이 다르다.
f(x) = max(0, x)
)라면, 입력 벡터의 각 요소는 오직 출력 벡터에서 자신과 같은 위치의 요소에만 영향을 미치므로, 편미분 시 그 외 원소들은 0이 되어 대각 행렬의 형태가 될 것임. (즉, 실제 Jacobian 행렬을 작성하고 공식화할 필요 없음)참고로 벡터의 그래디언트는 항상 원본 벡터의 크기와 동일하며, 그래디언트의 각 요소는 함수의 최종 출력에 얼마만큼의 영향을 미치는지를 의미한다.
구체적인 예시를 보면서 과정을 이해해 보자.
📌 행렬 내적(Affine 계층)의 역전파
수식으로 요약하면 이렇다: 일 때, 이고
- 전치 행렬의 존재와 내적의 순서 때문에 다소 복잡해 보일 수 있지만, 내적 역시 일종의 '곱연산'이라 생각하면 곱셈 노드가 상류의 역전파에 '순전파 때의 반대편의 입력'을 곱하여 흘려보낸다는 점과 유사함을 느낄 수 있다.
- 여기에 '그래디언트의 형상은 원래 입력과 동일하다'는 사실을 추가로 고려하면, 상류의 역전파에 반대편의 입력을 어떻게 내적해야 원래 입력과 동일한 형상을 갖게 될지를 떠올리면서 자연스럽게 식을 유도할 수 있다.
실제 코드로 신경망을 구현할 때는 각 노드(게이트)를 forward()
, backward()
메서드를 가진 클래스로 정의하여 모듈화한다. 그리고 여러 게이트의 게이트들을 순차적으로 호출하면서 순전파를 계산하고, 다시 역순으로 호출하면서 역전파를 계산하게 한다.
이때 순전파 때의 값을 게이트 내부에 저장(캐싱)하여, 역전파 계산 시 사용할 수 있게 하자.
신경망은 함수들의 집합으로, 비선형의 복잡한 함수를 만들기 위해서 간단한 함수들을 계층적으로 여러 개 쌓아올린 집합이다.
위 그림은 가장 간단한 형태의 2계층 신경망을 나타낸 것이며, max()
가 비선형성을 추가하는 역할을 한다.
은닉층이 추가됨으로써 선형 분류자와 달리 하나의 클래스에 대해 여러 중간 단계의 템플릿을 학습할 수 있고, 따라서 더 다양한 특징들을 잡아낼 수 있게 되어 성능이 높아진다. (⇒ mode 문제 해결!)
Fully Connected Layer(완전 연결 계층): 입력 데이터를 받아 길게 펴서 벡터로 만든 후, 가중치 행렬과 내적한 결과를 출력함.
Convolution Layer(합성곱 계층): 완전 연결 계층과 달리 입력 데이터(이미지)의 구조를 그대로 유지함. 가중치 역할을 하는 필터가 이미지를 슬라이딩하면서 공간적으로 내적을 수행함.
합성곱 계층에서는 여러 개의 필터를 사용하여 각 필터마다 다른 특징을 추출하도록 하며, 이때 필터 개수만큼의 서로 다른 Activation Map을 얻게 된다.
위 그림에서 파란색 육면체가 출력으로, 내부에 있는 5개의 점은 이미지의 동일한 위치에서 서로 다른 5개의 필터에 의해 추출된 서로 다른 특징들을 의미한다.
보통 CNN은 여러 겹의 합성곱 계층과 활성화 계층을 갖게 된다. 출력층에 가까운 필터일수록 점점 더 복잡한 형태의 특징을 학습하게 된다.
위 그림에서 각 그리드는 필터(뉴런)가 학습한 가중치를 시각화한 것으로, '입력 이미지가 어떻게 생겨야 해당 뉴런의 활성화 정도(출력)를 최대화 시키는지'를 나타낸다.
아무튼, 전체적인 CNN의 구조는 이런 식이다.
출력 행렬(Activation map)의 크기는 입력 행렬과 달라지게 되며, 입력 이미지와 필터의 크기, 슬라이딩 방법에 영향을 받는다.
출력 크기 = (입력 크기 - 필터 크기) / 스트라이드 + 1
한편, 입력 이미지에서 가장자리의 값은 필터의 중앙 부근에 닿지 않으므로 일종의 연산적인 불균형이 생길 수 있다. 이는 입력 이미지에 Zero-Padding을 추가하여 보완할 수 있다.
출력 크기 = (입력 크기 + 2*패딩 - 필터 크기) / 스트라이드 + 1
(각 필터를 구성하는 원소 수 + 편향 1개) * 총 필터 개수
가 됨.풀링 계층은 각 표현들을 더 작고 관리하기 쉽도록 Down-sampling(공간적으로 축소) 한다.
풀링 시에도 필터 크기를 정할 수 있으며, '얼마만큼의 영역을 묶을지'를 뜻한다. 스트라이드는 필터 적용 영역이 겹치지 않도록 주는 것이 일반적이다.
CNN의 끝부분에는 완전 연결 계층이 존재하며, 마지막 합성곱 계층의 출력인 3차원 데이터를 전부 펴서 1차원 벡터로 만든 후 입력으로 사용한다.
공간적인 구조를 신경쓰지 않고 모든 출력을 전부 다 하나로 통합시켜 최종적인 추론을 하는 것이 역할이다. 예를 들어, 분류 문제의 경우 마지막에 각 카테고리에 대한 최종 점수를 산출하기 위해 소프트맥스가 활성화 함수로 사용된다.
활성화 함수는 뉴런의 활성화 정도를 조정하고, 비선형의 힘을 가하는 역할을 한다.
대표적인 활성화 함수의 종류는 아래와 같다.
📌 현재는 활성화 함수로 ReLU가 표준처럼 사용되며, Leaky ReLU와 Maxout, ELU도 실험적으로 사용되는 편이라고 한다. (시그모이드는 쓰지 말 것!)
대표적인 전처리 과정은 'Zero-Mean'으로 만든 후 'Normalize'하는 것이다. 이 외에도 'Decorrelate', 'Whiten' 등의 전처리 방법이 있으나 이미지에서는 보통 'Zero-Mean'만 수행한다고 한다.
학습을 시작하기 전, 가중치의 초깃값은 어떻게 정해야 할까? 모든 가중치를 0으로 두면 어떤 일이 벌어질까?
그럼 임의의 작은 값으로 초기화 해보자. 예를 들어 표준정규분포에서 가중치를 뽑은 후 0.01배로 스케일링하여 사용해 보면 어떨까?
만약 가중치의 스케일링 값을 0.01이 아닌 1로 두면 어떻게 될까?
따라서 가중치의 초깃값을 아무렇게나 두기 보다는, '널리 알려진 좋은 방법'을 사용하는 것이 좋다.
(입력의 개수 / 2)
를 나눠주는 식으로 보완할 수 있다!우리는 각 계층의 출력이 'Unit Gaussian'을 따르길 원한다. 배치 정규화는 바로 그 역할을 한다.
배치 단위로 한 계층에 입력으로 들어오는 모든 값들을 이용해서 각 차원(Feature Element)별로 평균과 분산을 구하고, 이를 통해 정규화를 시켜준다.
배치 정규화 계층은 완전 연결 계층 또는 합성곱 계층 바로 뒤에 붙여서 'Bad Scaling Effect'를 상쇄시켜 줄 수 있다.
이때 합성곱 계층에서는 각 차원마다 독립적으로 정규화하지 않고, 같은 Activation Map의 같은 채널에 있는 요소들을 다 같이 정규화한다. (즉, 각 깊이(채널)마다 평균과 분산을 하나씩)
정규화 이후에는 스케일링 및 쉬프트 연산을 통해 정규화 정도(= Saturation 되지 않는 정도)를 조정한다. 중요한 점은 스케일링 인자 와 쉬프트 인자 는 네트워크가 학습 가능한 파라미터라는 것이다.
배치 정규화를 거치면 그래디언트의 흐름을 원활하게 하여 빠르고 효과적인 학습을 가능하며, 각 계층의 출력이 하나의 데이터에 결정적인 값이 아닌 배치 내의 전체 데이터와 연관되는 효과를 준다. (= Regularization)
전체적인 신경망의 학습 과정은 다음과 같다.
1e-3
~1e-5
사이의 값을 사용)📌 간혹 손실(Loss)과 정확도(Accuracy)가 비례하여 감소하지 않는 경우가 있는데, 이는 뭔가가 잘못됐다기보단 두 값의 정의가 다르기 때문이다.
- Loss: 모델이 예측한 결과와 정답 사이의 '거리'
- Accuracy: 전체 예측 결과 중 정답인 것의 '비율'
하이퍼파라미터를 선택하는 일은 실제로 꽤 어렵고 예술의 영역에 가깝다고 한다...
학습 상태를 잘 모니터링하면서 적절한 하이퍼파라미터를 결정할 수 있도록 하자.
기존 SGD 방식의 문제 중 하나는 손실 함수가 '한 방향의 가중치 변화에는 매우 민감하지만, 다른 방향으로는 둔감한' 형태를 갖고 있다면 (또는 현재 지점에서의 기울기의 방향과 실제 최솟값이 위치한 방향이 다르다면) 그래디언트가 매우 비효율적으로 갱신된다는 것이다.
또한, 손실 함수에 Local Minima(극소점)이나 Saddle Point(안장점)이 존재할 경우, 최솟값이 아님에도 기울기가 0이므로 그곳에서 갱신이 멈춰버릴 수도 있다.
또한, SGD는 전체 데이터 대신 미니배치의 데이터를 통해 손실을 계산하므로(= 'Stochastic') 실제 그래디언트가 아닌 Noisy Estimate(추정값)만을 구하게 되고 이 역시 갱신을 비효율적으로 만든다.
이런 문제를 해결하기 위해 SGD에 '모멘텀'을 추가할 수 있다.
방법은 매우 간단하다. 기존 SGD에서 기울기를 갱신하는 수식의 끝에 Velocity(속도)의 역할을 하는 항을 추가하면 된다.
rho
는 Velocity의 영향력을 조정하는 하이퍼파라미터로, 대략 0.9
또는 0.99
정도로 설정한다.이렇게 되면 손실 함수에서 매 지점의 기울기에만 의존하는 대신, 일종의 속도를 지니게 되므로 기울기가 0인 지점을 만나더라도 탈출할 수 있는 힘을 갖게 된다.
먼저 Velocity의 방향으로 한 번 이동한 후, 해당 지점에서의 그래디언트 방향으로 다시 한 번 이동하는 방법이다.
💡 'Convex'란?
'볼록 함수'에서의 볼록하다는 뜻으로, 여기서는 기울기가 0이 되는 지점이 곧 Global Minimum인 환경을 뜻한다. 즉, 경사하강법을 통해 반드시 최솟값을 찾을 수 있음이 보장된다.
반대로 'Non-convex' 하다는 것은 극솟값, 안장점 등 여러 Local Minimum이 존재하는 환경을 말한다.
학습 과정에서 계산되는 매 그래디언트의 제곱을 누적한 값(Grad Squared Term)으로 현재 단계에서 갱신될 값을 나눠주는 방법이다.
AdaGrad의 문제를 개선한 방법. 제곱 항을 누적할 때 Decay Rate를 곱해서 더해준다. (모멘텀과 비슷!)
0.9
또는 0.99
를 주로 사용함.Momentum과 RMSProp을 절반씩 조합한 방법으로, 거의 모든 아키텍쳐와 다양한 문제에서 매우 잘 동작하는 방법이다. 기본 코드는 다음과 같다.
위 코드의 문제는 처음엔 second_moment
값이 매우 작으므로 초기 Step이 매우 커진다는 것이다. Adam에서는 이를 보완하기 위해 Bias Correction 항을 추가한다.
beta_1
은 0.9
, beta_2
는 0.999
, 학습률은 1e-3
~1e-4
정도를 사용한다.Loss가 일정 값으로 수렴한다는 것은 학습률이 너무 높아서 더 좁은 곳으로 들어가지 못하고 계속 왔다 갔다(Bouncing Around) 하고 있다는 뜻일 수 있다. 이때 임의로 학습률을 낮추는 기법이 사용된다.
지금까지의 방법은 1차(First-Order) 미분만을 사용한 방법이었다.
어느 한 점에서의 1차 미분을 통해 그래디언트를 얻고, 그로부터 손실 함수를 선형 함수로 근사한 뒤, 근사 함수를 실제 손실 함수라고 가정하고 내려가는 것이다.
반면, 2차(Second-Order) 근사를 이용하면 근사 함수가 선형 함수가 아닌 2차 함수의 모양이 되며, 최솟값에 더 잘 근접할 수 있다. 이 개념을 다차원으로 확장시킨 것을 'Newton Step'이라 한다.
Newton Step의 가장 큰 특징은 Learning Rate가 불필요하다는 것이다. 하지만 실제로는 Hessian Matrix의 크기가 N×N으로 매우 크기 때문에 바로 딥러닝에 사용할 수는 없다.
지금까지의 방법들은 훈련 단계에서 손실 함수를 최소화하기 위한 방법이었다. 하지만 정말 중요한 건 훈련 오차와 검증/시험 오차 간의 격차를 줄이는 것이다.
즉, 손실 함수에 대한 최적화를 마친 상황에서 '한 번도 보지 못한 데이터'에 대한 성능을 올려야 한다. 모델 앙상블은 그 방법 중 하나이다.
모델 앙상블에서는 여러 개의 모델을 독립적으로 학습시킨 후 각 모델별 결과의 평균을 이용한다. 약 2%의 성능 향상을 기대할 수 있다고 한다.
드롭아웃은 신경망에서 주로 사용하는 Regularization 기법으로, 각 순전파 과정마다 임의의 일부 뉴런을 0으로 만든다.
코드도 매우 간단하다. 각 계층마다 일정 확률(주로 0.5)로 뉴런을 통과시키는 랜덤한 마스크를 생성하여 적용하면 된다.
드롭아웃은 특징들 사이의 상호작용(Co-Adptation)을 방지한다. 네트워크가 일부 특징에만 과도하게 의존하는 것을 막고 모든 특징을 골고루 이용할 수 있게 한다.
또한 드롭아웃을 이용하면 단일 모델만으로 앙상블 효과를 얻을 수 있다. 파라미터를 공유하는 거대한 서브네트워크 앙상블을 동시에 학습시키는 것과 비슷하기 때문이다.
드롭아웃은 기존 신경망에 랜덤한 마스크(z
)라는 '임의성(Stochasticity)'을 부여한다. 하지만 시험 단계에서 임의성을 추가하는 것은 좋지 않으므로, 일종의 'Average-Out(평균을 내어 상쇄)' 하는 절차가 필요하다. 이때 필요한 복잡한 적분식을 직접 푸는 대신 간단히 근사화하여 해결하는 방법이 있다.
훈련 단계와 시험 단계에서 각 네트워크의 출력의 기댓값을 비교해 보면, '뉴런이 임의로 0이 될 확률'(= Dropout Probability)에 따라 차이가 발생하는 것을 볼 수 있다. 이 두 기댓값의 차이를 메우는 방법은 시험 단계에서 각 네트워크의 출력에 드롭아웃 확률만큼의 값을 곱해주는 것이다.
📌 Regularization 기법의 공통적인 특징은 훈련 단계에서 임의성을 추가하여 신경망이 훈련 데이터에 과하게 적응하지 않도록 방해하고, 시험 단계에서 추가했던 임의성을 평균화 시키는 것이다.
훈련 단계에서 데이터(이미지)의 레이블을 바꾸지 않으면서 무작위로 변환(좌우반전, 크롭 등)하여 학습 시키는 기법으로, 일종의 Regularization 효과를 얻을 수 있다.
시험 단계에서는 임의성을 평균화하기 위해 이미지를 '4개의 가장자리'와 '중앙' 부위로 잘라내고, 또 이것의 반전 버전을 만들어서 총 10개의 이미지를 사용한다.
그 외에 강의에서 소개된 Regularization 기법들에는 이런 것들이 있다.
ImageNet과 같은 매우 큰 데이터셋으로 학습된 기존 CNN으로부터, 학습된 특징들을 이용해 더 작은 데이터셋을 가진 다른 유사한 문제를 푸는 모델을 만들 수 있다. 이러한 방법을 전이 학습이라 부른다.
만약 데이터가 좀 더 많다면 전체 네트워크를 'Fine-Tuning' 할 수도 있다. 즉, 한 계층이 아닌 좀 더 많은 부분을 갱신할 수 있는 것이다.
'밑바닥부터 시작하는 딥러닝'을 먼저 읽은 후 이번 강의를 들어 보았는데, 책에 비해 어떤 부분은 더 간단히만 짚은 후 넘어가기도 했고, 또 어떤 부분은 더 깊고 자세한 내용까지 다루기도 한 느낌이다. 일단은 강의 전반부(1~7강)에서 해당 책이 담고 있던 범위의 대부분을 다룬 것 같다.
강의 후반부에서는 아마 조금 더 CNN, 컴퓨터 비전과 관련된 내용이 나올 것 같다. 지금까지 배운 내용 중 부족한 부분을 복습한 후 넘어가야겠다.