딥러닝 입문 with Kaggle 내용 정리 part1
4장. 구글 코랩과 데이터 분석의 기초
구글 코랩과 kaggle 연동을 통해 kaggle에서 데이터를 직접 다운 받거나 결과를 캐글에 업로드 할 수 있는 방식을 코드로 알아보고자 한다. 실제 타이타닉 데이터와 코로나19 확진자 추이 데이터를 이용해 직접 분석해보자.
아래 파일에 상세 내용과 코드를 제공한다
5장. 딥러닝의 개념
딥러닝 모델의 기본 구조
▶ 딥러닝 모델은 입력이 주어졌을 때, 그 입력에 대한 해석을 출력하는 일종의 블랙박스이다. 따라서, 딥러닝은 이러한 딥러닝 모델을 만들어내는 과정이라고 볼 수 있다.
딥러닝 모델의 학습
▶ 딥러닝의 학습 방식은 Trial-and-Error 방식을 따른다. Trial-and-Error 방식은 선제적 학습 없이 질문을 하고, 답이 잘못된 경우 올바른 결과를 낼 수 있도록 모델 내부를 수정해 나가는 방식이다.
→ 즉, 최초의 가르침없이 아무것도 가르쳐주지 않은 상태에서 무작정 물어보고, 잘못 대답하면 올바른 대답이 나오도록 모델 내부를 직접 수정한다.
그럼 딥러닝 모델은 조건문과 다른걸까?
다르다. 그 이유는 딥러닝 모델은 일반화의 과정을 거치기 때문이다. 그리고 우리는 이것을 '학습'이라고 부른다. '학습'의 핵심은 입력된 정보를 바탕으로 원리를 이해하고, 새롭게 주어지는 문제를 올바르게 풀 수 있다는 걸 의미한다. 따라서, 새롭게 주어지는 문제를 해결하는데 한계가 있는 조건문이나 문제와 정답을 단순히 외워버리는 알고리즘과는 차이가 있다.
앞서 말한 일반화는 주어진 정보를 정리하여 다른 데이터에서도 잘 적용할 수 있도록 만드는 기술이다.
ex. 강아지와 고양이 사진을 각각 8개씩 주고 학습시킨 다음, 새로 무언가의 사진을 보여주었을 때 그 이미지가 고양이인지 강아지인지 잘 맞추었을 때, 학습의 일반화가 이루어졌다고 볼 수 있다.
딥러닝 모델과 네트워크 층
▶딥러닝 모델은 서로 간에 데이터를 주고받을 수 있는 여러 개의 네트워크 층으로 구성되어 있다. 네트워크 층은 크게 입력층, 중간층, 출력층으로 이루어져 있다.
층의 구성
입력층: 주어지는 데이터 그 자체
중간층: 입력을 받아 출력을 내고, 다음 층으로 출력 전달
출력층: 마지막 중간층의 출력이 보여지는 곳
이렇게 입력된 데이터는 각 층을 지날 때마다 다양한 연산을 통해 변환되어 전달되는데, 이 연산의 목적은 입력된 이미지가 특정 이미지에 더 가까울수록 그 이미지의 노드 값을 더 크게 만들기 위함이다.
여기서 '변환 연산'은 각 층 별로 서로 다르지만, 각 층의 변환 연산은 입력되는 데이터와는 관계없이 일정하게 적용된다.
→ 딥러닝 모델에서 '학습'의 정의를 좀 더 구체화해보면 주어진 데이터를 잘 분류할 수 있도록 층과 층 사이의 변환 연산을 개선해 나가는 과정이다.
딥러닝 모델의 네트워크 구조
▶ 딥러닝 모델의 네트워크 구조는 모델의 여러 층들이 그래프 형태로 연결되어 있다. 딥러닝 네트워크는 매우 많은 수의 중간층들이 연결되어 구성되는 것이 대부분이다. 딥러닝 네트워크는 하나의 층이 여러 개의 층과 연결되는 복잡한 구조를 가지기도 하지만, 하나의 층이 그 다음 층 하나와만 연결되는 직렬 구조(Sequential 구조)를 가지기도 한다.
네트워크 구조의 깊이와 복잡도는 데이터의 크기, 복잡도, 분류해야 하는 패턴의 개수 등에 따라 달라진다.
이 말은 즉, 데이터의 규모가 작을수록, 데이터의 형태가 단순할수록 네트워크 구조가 더 단순해진다.
네트워크의 입력과 출력
▶ 딥러닝 네트워크의 입력과 출력은 모두 숫자(float형)로 이루어진다.
입력의 경우, 네트워크에 이미지를 입력하면, 이미지가 픽셀 값(0 ~ 255)으로 변환하여 입력된다.
출력의 경우, 분류할 수 있는 class(카테고리)만큼의 출력값들이 나온다. 이 출력값들은 입력 데이터가 각 class(카테고리)일 것으로 추정되는 정를 나타내며 이 중 가장 큰 출력값을 가지는 class(카테고리)로 정답을 해석하게 된다.
범주형 데이터의 수치화
▶ 성별 데이터와 같이 범주로 저장된 데이터를 딥러닝 모델에 넣기 위해서는 숫자형 데이터로 변환하는 과정이 필요하다. 이때 원-핫-인코딩을 통해 범주의 개수만큼 항목을 만들고, 각각의 항목이 각 범주를 나타내도록 하는 데이터의 표현 방식을 사용하면 된다.
ex. 타이타닉 티켓 등급이 1, 2, 3의 범주를 가질 때 원-핫-인코딩
값: 1 → 원-핫-인코딩: [1 0 0]
값: 2 → 원-핫-인코딩: [0 1 0]
값: 3 → 원-핫-인코딩: [0 0 1]
수치형 데이터의 정규화
▶ 모델에 입력되는 수치형 데이터는 보통 0과 1 사이의 숫자로 조정하여 사용한다. 이것을 데이터 정규화라고 한다. 예를 들어, 이미지를 입력으로 받는 경우 0~255 값을 255로 나누어 0과 1 사이의 숫자로 조정하는 경우이다.
수치형 데이터 정규화 방법
(원 데이터 - 최솟값) / (최댓값 - 최솟값)
ex. 타이타닉 나이를 0과 1 사이의 값으로 정규화 해보자
값: 3 → 정규화: 0
값: 28 → 정규화: 0.32467532
값: 21 → 정규화: 0.23376623
값: 67 → 정규화: 0.83116883
값: 80 → 정규화: 1
값: 53 → 정규화: 0.64935065
타이타닉 데이터의 수치화 및 정규화
실제 타이타닉 데이터에 위의 내용을 적용해보자. 아래에 나와있는 총 5가지 항목에 대해 원 핫 인코딩과 정규화를 적용했다.
성별: female → [1 0] / male → [0 1]
나이: 정규화 적용
티켓 등급: 1→ [1 0 0] / 2 → [0 1 0] / 3 → [0 0 1]
형제, 자매, 배우자 수: 정규화 적용
부모, 자녀 수: 정규화 적용
생존 여부: 0(사망) → [1 0] / 1(생존) → [0 1]
아래 파일에 상세 내용과 코드를 제공한다
6장. 완전 연결층과 다층 신경망
완전 연결층
완전 연결층은 내부적으로 여러개의 노드로 이루어져 있으며 완전 연결층만을 사용하는 딥러닝 모델은 다층 신경망(MLP)이다. 여기서 '다층'은 여러 개의 완전 연결층으로 이루어져 있다는 의미이다.
우선 하나의 층으로 이루어진 모델을 먼저 살펴보자. 완전 연결층 내부는 입력 데이터를 보관하는 입력 노드, 다음 층으로 데이터를 전달하기 위한 출력 노드, 이러한 두 종류의 노드를 연결하는 에지로 구성되어 있으며 각 에지는 가중치를 갖고 있다.
완전 연결층은 전달받은 입력 데이터에 가중치를 곱하고 합산하여 출력값을 만든다.
이러한 출력값은 범위를 특정할 수 없고 가중치에 따라 값이 무한히 작아지거나 커질 수 있기 때문에 출력값을 제한시킬 필요가 있다. 그래서 우리는 활성화 함수를 이용해 출력값을 조정할 수 있다.
완전 연결층의 출력은 2개가 될 수 있다. 이 경우 출력 O1과 O2는 입력 노드와 모두 연결되어 있는 상태이고 각각 생존과 사망(ex. O1: 1, O2: 0)을 나타낸다. 즉, 데이터가 원 핫 인코딩된 상태로 이해할 수 있으며 더 큰 값을 가지는 출력 노드가 결과가 된다.
다층 신경망
완전 연결층은 2개 이상 연속으로 연결될 수 있으며, 이를 여러 개 사용하는 신경망을 다층 신경망이라고 한다.
주어지는 입력이 순차적으로 모델에 전달되어 최종 노드까지 전달되어 출력을 발생시키는 과정을 전파라고 한다.
이러한 전파 과정을 통해 얻은 최종 출력값과 정답 데이터를 비교해 오차값을 계산할 수 있다. 여기서 오차값은 해당 모델의 성능을 직접적으로 나타내는 지표이다.
신경망 모델의 학습은 오차값을 최소화시키는 방향으로 이루어지고, 그 방식은 오차를 모델의 역방향으로 전달시켜 각 에지의 값(가중치)을 조금씩 바꾸도록 진행된다. 이 과정을 역전파라고 한다.
정리하자면 역전파 알고리즘은 에러의 원인이 되는 에지를 찾아 해당 에지의 가중치를 수정하는 것이고, 전파는 가중치와 노드의 곱을 합산한 것이기 때문에 오차의 크기를 줄이는 방향으로, 역으로 계산하면서 원하는 결과를 얻기 위해 가중치를 어떻게 수정해야하는지 알 수 있다. 이때 가중치의 조정은 출력층에 가까운 쪽부터 순차적으로 이루어진다.
네트워크 구조를 조정하는 방법은 입력이 복잡한 데이터일 경우 복잡한 구조의 네트워크 외에도 많은 양의 데이터가 필요하다. 왜냐하면, 변수의 수가 늘어나면 파라미터의 개수도 같이 늘어나기 때문에 문제를 정확하게 풀기 위해 데이터의 개수도 많아야 한다.
→ 최적 모델을 찾아내는 정석은 학습이 올바로 수행되는 범위 내에서 모델의 크기를 충분히 크게 만든 후, 학습 성능을 체크하면서 조금씩 크기를 줄여 나가야 한다.
역전파 알고리즘
네트워크 가중치의 수정은 역방향으로 발생한다. 그리고 모델의 학습은 오차의 크기를 줄이는 방향으로 이루어져야 한다.
여기서 오차는 음의 값을 가질 수 있기 때문에 오차를 1 / 2 * (오차)^2의 형태로 변형해 이용한다. 1 / 2 * (오차)^2은 손실을 의미하기 때문에 딥러닝 학습의 목표는 이 손실을 감소시키는 것이다.
오차 = 목표치 - 출력
손실 = 1/2 * (오차)^2
그러면 가중치를 어떻게 조정해 손실을 줄일까? 편미분을 사용하면 된다. 가중치에 따른 손실함수의 변화량(기울기)을 계산하고, 이 값을 기존의 가중치에서 빼주는 것이다.
완전 연결층의 입력 노드를 i라 하고, 출력 노드를 j라고 하면 그 사이에 연결된 가중치를 w_ij라고 할 때, w_ij는 아래 식처럼 업데이트된다. 여기서 E는 노드 j에서 발생한 손실함수이고, δE / δw_ij는 가중치에 대한 손실함수의 편미분을 의미한다.
w_ij = w_ij - δE / δw_ij
편미분의 계산은 활성화 함수의 종류에 따라 달라지지만, 아래 예에서는 활성화 함수를 사용하지 않겠다.
w_ij = w_ij - 입력 * δj
δj = 출력 - 목표치
아래 예시를 통해 확인해보면 두 번째 완전 연결층의 가중치는 0.5에서 0.92로 바뀐다. 새롭게 바뀐 가중치를 이용해 전파 과정을 수행하면 출력이 0.552가 되어 이전보다 오차가 감소한걸 볼 수 있다.
이번에 완전 연결층 A의 가중치를 수정해보자. 완전 연결층 A처럼 최종 출력과 직접 연결되지 않은 완전 연결층의 가중치 수정에는 해당 층 노드들의 목표치가 존재하지 않기 때문에 완전 연결층 B에서 계산한 손실함수의 변화량을 가져와 사용해야 한다. 완전 연결층 A 가중치 w_ij의 새로운 값은 아래와 같이 계산된다. 여기서 δj는 노드 j와 연결된 완전 연결층 B의 가중치를 업데이트할 때 계산된 δ(0.3 - 1)와 가중치(0.5)의 곱을 의미한다.
w_ij = w_ij - 입력 * δj
즉, 역전파 알고리즘은 최종 출력 노드에서 발생한 손실을 네트워크 연결 가중치와 노드의 값 등에 따라 앞의 노드들에 책임을 지운다고 생각하면 된다.
이렇게 해서 수정된 가중치를 이용해 입력 신호를 순차적으로 전파시켰을 때 동일한 입력에 대해서 오차가 0.126으로, 손실값은 0.0080으로 대폭 떨어졌다는 것을 알 수 있다.
→ 모델은 주어진 데이터에 대해 전파와 역전파 과정을 반복하며 원하는 목표치를 출력하도록 내부의 가중치를 수정해 나간다. (지금까지 살펴본 역전파 수식은 활성화 함수를 제거했음에 유의)
최적화 도구와 학습률, 배치 크기
역전파 알고리즘을 사용하면 어떤 하나의 데이터 쌍(입력 데이터와 원하는 출력 데이터)에 대해 네트워크를 수정할 수 있다. 데이터가 여러 개 있는 경우 효율적으로 네트워크를 구성하기 위해서 어떻게 해야 할까?
1. 배치 크기(Batch size)
보통 가중치의 조정은 하나의 입력 데이터에 대해 바로 이루어지는 것이 아니라 여러 개의 입력 데이터에 대해 발생하는 에러를 합산한 후 한꺼번에 이루어진다. 이러한 단위를 배치라고 하며, 하나의 배치에 사용하는 데이터 수를 배치 크기라고 하는데 배치 크기는 학습 효율에 큰 영향을 준다.
2. 학습률(Learining rate)
하나의 배치에 대해서 발생한 손실을 최소화시키는 방향으로 가중치를 조정하면, 다른 배치에 대해서는 손실이 오히려 높아질 가능성이 있다. 이를 해결하기 위해서 가중치에 적절한 학습률을 곱해 가중치 크기를 조절하여 수행한다. 처음에 높은 학습률을 지정하고, 시간에 따라 학습률을 감소시키는 방법이 사용된다.
3. 에포크(Epoch)
네트워크의 학습은 데이터를 여러 개의 배치로 나누어 진행되는데, 이때 전체 데이터에 대한 학습이 1회 수행되는 것을 1에포크라고 한다. 예를 들어, 10000개의 사진을 학습시킬 때 배치 크기를 100으로 두면 전체 데이터를 한 번 학습시키기 위해서 전파-역전파를 100회 수행하는 학습 과정이 필요하고 100회의 학습이 1 에포크가 된다. 에포크의 수를 늘린다고 성능이 항상 좋아지는건 아니다.
4. 학습, 검증, 테스트 데이터
에포크를 늘려 모델의 성능을 향상시키는데 한계가 있기 때문에 검증용 데이터를 이용해 학습 결과를 평가할 수 있다.
5. 최적화 도구와 학습률
딥러닝에서 학습은 출력에서의 손실을 줄이는 방향으로 이루어진다. 이러한 딥러닝 학습은 간단해보이지만, 실제로 여러 개의 데이터에 대한 손실을 최소화하는 가중치들을 찾는 것은 어렵다. 또한, 층의 수, 노드의 수가 많아지면 가중치의 수가 기하급수적으로 증가하므로, 최적의 가중치를 찾는 것은 어렵고 시간이 많이 소요된다. 하지만 최적의 가중치를 좀 더 효율적으로 찾을 수 있다. 그 방식은 최적화 도구이다. 가중치를 조정할 때, 단순히 손실을 줄이는 방향으로만 수정하는게 아니라 이전에 수정했던 방향을 고려해서 수정할 수 있고, 가중치가 수정되는 크기와 빈도에 따라 수정되는 양을 조절할 수 있다. 최적화 도구로는 RMSProp, Stochastic Gradient Descent(SGD), Adaptive Moment Estimation(ADAM) 등이다.
실습에 필요한 추가 개념 정리
딥러닝 모델과 관련한 다양한 함수, 데이터 타입을 제공해주는 패키지들이 있다는 것을 참고하자. 텐서플로우와 케라스가 대표적이다.
1. 손실함수
가장 마지막 층의 노드에서 오차의 크기를 계산하는 방법은 다양하다. 예를 들어, 평균 제곱 오차는 에러의 제곱을 사용하는 방식으로 기대값(정답)이 실수의 연속값을 가질 때 사용하는 방식이고, 교차 엔트로피는 기대값(정답)과 출력의 로그값을 곱하여 사용하는 방식이다. 이외에도 BinaryCrossentropy, CategoricalCrossentropy, Mean Squared Error가 있다.
BinaryCrossentropy - 이진 분류 모델(출력 노드의 값이 0이나 1)에 사용
CategoricalCrossentropy - 출력 노드가 2개 이상으로 원 핫 인코딩된 분류 모델에 사용
Mean Squared Error - 수치를 직접 예측하는 경우 주로 사용
2. 활성화 함수
각 층의 출력은 입력 노드들의 값과 각각의 노드에 연결된 에지들의 가중치 곱을 합산한 결과이다. 이렇게 계산된 출력값의 범위를 예상하는 것은 매우 어렵다. 따라서, 각 층에 나오는 출력을 특정 범위로 축소시켜주는 역할이 필요한데, 그 역할을 해주는 것이 바로 활성화 함수다. 그럼 이제 다양한 종류의 활성화 함수를 알아보자.
Softmax: 분류형 네트워크 모델의 마지막 층에 사용되는 출력 함수이며, 마지막 층의 노드들이 각각 분류 그룹에 대한 일종의 확률값을 가지도록 변형함
Sigmoid, Tanh, Softsign: 출력을 특정 범위 내의 값으로 제한
ReLU: 음수 입력에 대해서만 제한
SELU, ELU, Leaky ReLU: ReLU의 변형이며, 음수 입력에 대해 값을 조금씩 감쇄시켜서 출력
Exponential: 지수함수를 그대로 사용
Softplus: 지수함수를 활용해 SELU, ELU 등과 형태를 유사하게 만듦
완전 연결층과 타이타닉 데이터
완전 연결층을 사용하여 타이타닉 데이터를 학습시키는 실습을 진행해보자. 타이타닉 데이터를 Sequential 모델에 입력해 테스트 데이터에 대한 생존 여부를 예측시켰다.
아래 파일에 상세 내용과 코드를 제공한다