Part1 인공신경망의 동작 원리
Chapter 1. 인간에게는 쉽고 기계에게는 어려운
핵심 정리
- 컴퓨터에게는 쉽지만 사람에게는 어려운 작업이 있다.
- ex) 수백만 개 숫자의 곱셈 연산
- 컴퓨터에게는 어렵지만, 사람에게는 쉬운 작업이 있다.
- ex) 사진 속에서 사람의 얼굴을 인식하는 작업
컴퓨터는 전자로 구성되어 있으므로 컴퓨터에 인공지능을 부여한다는 것은 어려운 문제를 해결하는 새로운 방법, 즉 새로운 알고리즘을 찾아주는 것이 될 것이다. 완벽하지는 않더라도 인간과 비슷한 정도의 지능만이라도 부여할 수 있다면, 충분히 도움이 되는 경우가 많다.
Chapter 2. 간단한 예측자
이러한 기계를 생각해보자.
질문→생각→대답
이를 적당한 용어를 사용하면, 다음과 같이 변환 가능하다.
입력→처리(연산)→출력
ex) 3x4를 입력 시 연산을 4+4+4를 하면, 12를 출력한다.
이제 킬로미터를 마일로 변환해주는 기계가 있다고 생각하자.
킬로미터→연산→마일
연산할 때 그 변환 공식을 모른다고 가정하면, 우리가 아는 것은 킬로미터와 마일의 관계가 **선형(linear)**라는 것 뿐이다. 그러므로 마일을 2배로 늘리면, 킬로미터도 2배로 늘어나게 될 것이다.
그럼 마일=킬로미터 x c(c는 상수)
상수 c를 찾기 위해 **임의의(random)**값을 하나 정해서 대입해보자.
100킬로미터→마일=킬로미터x0.5→50마일.
예측한 50은 정답인 62.137가 오차가 존재한다.
오차 = 실제 값 - 계산 값 = 62.137 - 50 = 12.137
이제 오차를 줄이기 위해 c를 0.5가 아닌 0.6으로 넣게 되면, 60마일이 되므로, 정답과 비슷하게 된다. 그럼 첫번째 시도에서 얻은 오차를 거울삼아 두 번째 시도를 하게 된다.
이제 c값을 0.6이 아닌, 0.7을 넣어보자.
100킬로미터 →마일=킬로미터 x 0.7 →계산된 값 70마일이 된다. 그럼 실제값과 오차가 -7.863이므로 **오버슈팅(overshooting)**이 일어났다. 오차 = 실제 값 - 계산 값이므로 오차가 음수라는 것은 계산 값이 실제 값보다 크다는 것을 의미한다.
그럼 c값을 0.6에서 조금만 올려서 0.61로 하면, 결과값은 61마일로 실제 값 62.137과 오차는 1.137정도이다.
결국 우리는 직전 시도를 거울삼아 c값을 조금씩 조정했다.
결과 값이 실제 값에 접근하게 되면(즉, 오차가 작아지게 되면) 변화를 너무 크게 가져가면 안 된다. 이런 식으로 우리는 오버슈팅을 방지할 수 있다.
이 과정들이 인공 신경망을 학습시키는 핵심 과정이다.
학습이라는 과정을 통해 인공 신경망은 점점 더 정답에 가까운 답을 낼 수 있게 된다.
우리는 c를 단순히 방정식을 이용해 한 번에 답을 구할 수 잇지만, 이번에는 상수 c값으로 임의의 값을 넣어보고 오차를 구해 개선해나가는 식으로 시행착오를 거치는 접근 방식을 이용했는데 이러한 과정을 **반복(iteration)**이라고 한다. 여러 번 반복해서 결과 값을 조금씩 개선해나간다는 의미이다.
핵심 정리
- 컴퓨터는 입력→연산→출력 시스템이다. 인공신경망도 마찬가지이다.
- 어떤 것의 동작 원리를 정확히 파악할 수 없을 때 취할 수 있는 한 방식은 우리가 조정할 수 있는 매개변수 값을 포함하는 모델을 만들어보는 것이다. 우리는 킬로미터를 마일로 어떻게 변환해야 할 지 모른다고 가정하고, 이를 조정 가능한 매개변수를 포함하는 선형함수 모델로 만들었다.
- 모델을 정교화해나가는 좋은 방법은 오차에 기초해 매개변수 값을 조정해나가는 것이다.
Chapter 3. 분류는 예측과 그다지 다르지 않습니다.
앞 장에서 살펴봤던 단순한 기계는 입력 값에 대해 출력 값이 어떻게 나올 지를 예측하므로 이 기계를 **예측자(predictor)**라고 부른다.
곤충들의 폭과 길이 그래프에서 x축이 폭, y축이 길이라고 하면, 애벌레는 날씬하고 길이가 길어서 왼쪽 위에 위치하게 되고, 무당벌레는 통통하고 길이가 짧아서 오른쪽 아래에 위치하게 된다.
이떄, 아까 킬로미터 말할 때, 선형함수가 있었는데, 선형함수에서 매개변수 값인 C 값을 조정함으로써 직선의 **기울기(scope)**를 변화시킬 수 있었다.
그래프에 직선을 올리게 되면, 미지의 곤충들을 측정 값(폭과 길이)에 기초해 **분류(classify)**하는 용도로 사용될 수 있다. 깔끔하게 분류할 때 이 직선을 곤충의 **분류자(classifier)**로 이용할 수 있다고 한다.
이제 그 직선을 통해 미지의 곤충을 분류할 수 있다.
그런데 이 직선의 기울기는 어떻게 구할까?
애벌레와 무당벌레를 분류해주는 위와 같은 형태의 직선이 과연 최선일까?
만약 이 직선이 최선이 아니라면 어떻게 개선할 수 있을까?
이 질문에 대한 대답은 신경망이 학습하는 방법을 이해하는 데 가장 중요한 부분이다.
이제 이에 대해 살펴보자.
Chapter 4. 분류자 학습시키기
우리는 선형 분류자를 학습(train)시켜서 애벌레와 무당벌레를 잘 분류할 수 있게 만들고자 한다. 앞에서 살본 바와 같이, 이 문제는 2개의 그룹을 분리하는 직선의 기울기를 어떻게 결정하느냐 하는 단순한 문제로 귀결된다.
애벌레와 무당벌레의 폭과 길이를 가진 값들은 예측자 또는 분류자에게 실제 값을 알려주는 역할을 수행하는 예제 데이터가 되며, 이를 학습 데이터(training data)라고 부른다.
컴퓨터 과학자들은 이러한 특정 목적을 가진 일련의 컴퓨터 명령을 알고리즘(algorithm)이라고 부른다.
핵심정리
- 우리는 간단한 계산을 통해 선형 분류자의 오차와 기울기 매개변수 간의 관계를 이해할 수 있다. 즉, 오차를 제거하기 위해 얼마만큼 기울기를 조정해야 하는지 알 수 있다.
- 이러한 조정 과정의 문제점은 이전의 학습 데이터는 무시하고 최종 학습 데이터에만 맞춰 업데이트된다는 것이다. 이를 해결하기 위해 학습률을 도입해 업데이트의 정도를 조정해준다. 이를 통해 단일 학습 데이터가 학습에 지배적인 영향을 주는 것을 방지할 수 있다.
- 현실에서 학습 데이터는 잡음이 섞여 있거나 오차를 가진다. 학습률을 이용한 업데이트는 이러한 데이터의 오류의 영향을 제한하는 효과도 있다.
Chapter 5. 분류자 1개로는 충분치 않을 수 있습니다.
불 논리 함수에서 논리곱은 AND, 논리합은 OR. 논리곱에서는 모든 조건이 참인 경우에만 참이 되며, 조건 중 1개만 참이면 결과는 거짓이 된다. 논리합에서는 조건의 일부만 충족되어도 참이 된다.
입력 A, 입력 B→논리함수→출력
이떄, 선형 분류자가 불 논리곱과 불 논리합 함수를 학습하는 것이 가능하다.
불 함수 중에는 배타적 논리합(exclusive or)이라는 것도 있다. 보통 XOR로 표시한다. 배타적 논리합에서 결과 값은 입력 A와 입력 B가 서로 다른 값인 경우에 참이 된다. 다시 말해 모두 탐이거나 또는 모두 거짓인 경우에는 거짓이 된다.
이때, 단순한 선형 분류자는 XOR 함수에 좌우되는 학습 데이트들을 분류할 방법을 학습하는 것이 불가능하다. 이것이 바로 단순한 선형 분류자의 한계이다.
해결 방법은 바로 여러 개의 분류자를 이용하는 것이고 이것은 인공 신경망에서 매우 중요한 개념이다.
핵심 정리
- 데이터 자체가 단일 선형 프로세스에 의해 좌우되지 않는 경우라면 단순한 선형 분류자로 데이터를 분류해낼 수 없다. 예를 들어 배타적 논리합에 의해 좌우되는 데이터는 단일 선형 분류자에 의해 분류가 불가능한 점을 살펴봤다.
- 이런 경우 해결 방법은 간단하며, 여러 개의 분류자를 이용해 데이터를 분류하면 되는 것이다.
Chapter 6. 대자연의 컴퓨터, 뉴런
컴퓨터 뇌: 순차적
동물의 뇌: 병렬적, 불명확성
생물학적 뇌의 기본 단위인 뉴런(신경세포)를 보면, 종류에 상관없이 모든 뉴런은 한쪽 끝에서 다른 쪽 끝으로 전기신호를 전송한다. 즉, 가지돌기(dendrite)에서 축삭(axon)을 거쳐 축삭말단(axon terminal)까지 전송하는 것이다. 이런 식으로 신호를 하나의 뉴런에서부터 다른 뉴런으로 계속해서 전달한다.
뉴런의 동작 원리를 살펴보면, 전기 입력을 받아 또 다른 전기신호를 발생시키는데, 이는 우리가 앞에서 살펴본 분류 또는 예측자에서 입력을 받아 어떤 처리를 해 결과를 출력하는 것과 매우 유사해 보인다.
뉴런을 선형함수로 표현할 수 있을까? 단순히 선형함수로 안 된다.
과학자들의 관찰에 의하면 뉴런은 입력을 받았을 때, 입력 값이 어떤 분계점(threashold)에 도달해야 출력이 발생한다. 이처럼 입력 신호를 받아 특정 분계점을 넘어서는 경우에 출력 신호를 생성해주는 함수를 활성화 함수(activation function)이라고 한다. 수학적으로 다양한 활성화 함수가 존재한다.
이때, 활성화 함수 중 가장 단순한 형태는 계단 함수(step function)이다. 입력 값이 작은 경우 출력 값은 0이지만, 일단 입력 값이 분계점 이상이 되면, 출력 값은 갑자기 올라가게 된다. 이와 같은 인공 뉴런의 반응은 우리 뇌에 있는 생물학적 뉴런의 반응과 유사한 면이 있다. 이처럼 입력 값이 분계점에 이르러 출력을 발생시키는 현상을 뉴런이 작동한다(fire)라고 말한다.
이번에는 계단 함수를 좀 더 개선해서 S자 모양의 함수를 시그모이드 함수라고 한다. 우리는 앞으로 인공신경망을 만들 때 이처럼 부드러운 S자 형태를 가지는 시그모이드 함수를 활용할 것이다.
시그모이드 함수는 때로 로지스틱 함수라고 부른다. y=1/1+e^-x
뉴런은 여러 개의 입력을 받아 어떻게 처리할까?
생물학적 뉴런은 여러 개의 입력을 받아 각각의 입력을 더해서 그 합을 시그모이드 함수의 입력 값으로 전달하고, 시그모이드 함수는 이 입력 값을 이용해 출력을 생성한다.
그러니까, 입력 a,b,c→입력의 합 x=a+b+c가 되고, 이를 시그모이드 분계점 함수에 넣어 y를 출력한다.
만약, 입력a,b,c의 합인 x가 분계점을 넘어설 정도로 충분히 크지 않다면 시그모이드 함수는 아무것도 출력하지 않게 된다. 반대로 x가 분계점을 넘으면 시그모이드 함수는 이 뉴런을 작동시킨다.
흥미로운 점은 나머지 입력 값들이 매우 작다고 하더라도 단지 1개의 입력 값만 충분히 크다면 뉴런은 작동할 수 있다!!!
각각의 뉴런은 1개가 아니라 여러 개의 뉴런으로부터 입력을 받게 되며, 각각의 뉴런은 한번 작동될 때 여러 개의 뉴런으로 신호를 전달하게 된다.
이러한 생물학적 뉴런을 인공적으로 모델화하려면 어떻게 할까?
바로 뉴런을 여러 계층(layer)에 걸쳐 위치시키고, 각각의 뉴런은 직전 계층과 직후 계층에 있는 모든 뉴런들과 상호 연결되어 있는 식일 것이다.
그림에서, 3개의 계층이 존재하며, 각각의 계층에는 뉴런이 3개씩 존재하는데, 이 각각의 인공 뉴런을 노드(node)라고 부른다. 각 노드는 직전 계층과 직후 계층에 존재하는 다른 모든 노드와 연결되어 있다.
그렇다면 이런 구조에서 과연 어떤 부분이 학습을 하는 것일까?
학습 데이터를 통해 학습을 진행하게 되면, 도대체 무엇을 조정해야 하는 것일까?
우선 분명한 것 한 가지는 노드 간 연결의 강도를 조정해나가야 한다는 점이다. 각각의 연결에 적용할 가중치(weight)를 함께 표현했다. 낮은 가중치는 신호를 약화하며 높은 가중치는 신호를 강화한다.
핵심 정리
- 생물학적 뇌는 최첨단 컴퓨터에 비해 저장 능력과 연산 속도가 떨어져 보이지만, 하늘을 날고 음식을 찾아내고 언어를 학습하고 포식자로부터 도망가는 등 수준 높고 정교한 업무를 잘 수행한다.
- 생물학적 뇌는 손상되었거나 완전하지 않은 신호에 대해 전통적인 컴퓨터 시스템에 비해 놀라울 정도로 탄력적인 반응을 한다.
- 인공 신경망은 상호 연결된 뉴런으로 구성된 생물학적 뇌로부터 영감을 받아 구축되었다.
Chapter 7. 신경망 내의 신호 따라가기
2계층의 2노드씩 존재할 때, 입력 값이 1.0, 0.5일때, 시그모이드 함수에서의 x는 해당 노드로 들어온 입력 값들에 가중치를 곱한 값들의 합이 된다. 그래서 x=(노드 1의 출력 값 * 가중치)+(노드 2의 출력 값*가중치)가 된다. 이를 입력의 합이라고 부르며 이렇게 입력의 합을 구하는 것을 조합한다고 표현하기도 한다.
신경망에서 학습을 하는 대상은 가중치이다. 즉 점점 더 나은 결과를 얻기 위해 가중치의 값을 반복적으로 업데이트해나가는 것이 바로 신경망의 학습이므로 가중치가 반드시 포함되어야 한다. 이제 2계층의 노드1에 그 입력의 합이 x-1.05라고 계산이 되었다고 하면, 이제 활성화 함수(시그모이드 함수)에 입력 값을 넣어줌으로써 최종적으로 이 노드의 출력 값을 계산할 준비가 되었다. 그럼 계층 2의 노드 중 1개 노드의 출력 값을 실제로 계산할 수 있다. 나머지 1개도 마찬가지로 할 수 있다.
훨씬 더 많은 계층이 존재하고 노드가 수백 개일 때 해결할 수 있는 수학적 방법이 행렬이다.
Chapter 8. 솔직히 행렬곱은 유용합니다.
행렬의 유용한 점
- 행렬은 이 모든 복잡한 계산을 매우 간단한 형태로 압축해서 표현할 수 있도록 도와준다.
- 대부분의 컴퓨터 프로그래밍 언어는 행렬 작업을 잘 처리하므로 이런 복잡한 업무를 행렬 기반으로 잘 만들어서 컴퓨터에게 넘기기만 하면 컴퓨터가 알아서 이를 매우 빠르고 효율적으로 처리할 수 있게 된다.
행을 먼저 쓰고 열을 나중에 쓰며, 2행 3열이면, 2X3행렬
둥근 괄호 또는 각괄호 [] 사용.
변수도 행렬의 원소가 될 수 있음.
행렬곱 수행 시, 2개의 행렬에 대해 첫째 행렬의 열 수와 둘째 행렬의 행 수가 다르면 행렬곱은 불가능하다. 첫번째 행렬의 열의 수와 두번째 행렬의 행의 수가 같아야만 행렬곱이 성립한다.
이러한 행렬곱을 점곱(dot product) 또는 내적(inner product)라고 한다.
계층2의 각 노드에 전달되는 입력의 합의 계산을 행렬곱을 이용해 표현할 수 있다. X=W·I
여기서 W는 가중치의 행렬이며 I는 입력 값들의 행렬이다. 그리고 X는 계층 2로 들어온 신호들의 조정된 합으로 이루어진 행렬이 된다. (행렬 표기 시, 굵은 글씨로 표현)
이렇게 되면, 각각의 계층에 노드가 몇 개씩 존재하는 지 크게 신경쓸 필요 없이 W · I로 표기할 수 있다. 그리고 이러한 연산은 컴퓨터가 알아서 해 줄 것이다.
이제 다음으로 활성화 함수를 살펴보면, 활성화 함수 계산은 간단하고 행렬곱을 필요로 하지 않아서 행렬 X의 각각의 원소에 대해 시그모이드 함수를 적용해주면 된다.
O=sigmoid(X)
O는 신경망의 마지막 계층의 모든 결과 값을 포함하는 행렬이다.
핵심 정리
- 신경망에서 신호를 전달하는 연산은 행렬곱을 통해 표현할 수 있다.
- 행렬곱을 활용하면 그 크기에 상관없이 신경망을 간결하게 표현할 수 있다.
- 많은 컴퓨터 프로그래밍 언어는 행렬을 잘 인식하고 행렬 연산을 빠르고 효율적으로 처리할 수 있다.
Chapter 9. 3계층 신경망에 행렬곱 적용하기
3계층 신경망이 존재할 때,
계층 1은 입력 계층(input layer)라고 부르며,
마지막 계층인 게층 3은 출력 계층(ouput layer)라고 부르며,
중간에 위치하는 계층 2는 은닉 계층(hidden layer)라고 한다.
W input_hidden 행렬은 입력 계층과 은닉 계층 간의 가중치의 행렬이기 때문이며,
마찬가지로 W hidden_output 행렬은 은닉 계층과 출력 계층 간의 가중치의 행렬이 된다.
이제 은닉 계층의 입력 값을 X hidden이라고 부를때,
X hidden = W input_hidden · I 이다.
컴퓨터로 행렬곱을 계산하는 방법은 이 책의 2부에서 확인할 것이다. 2부에서는 파이썬을 이용해 이 값을 계산할 것이다.
이제 우리는 은닉 계층의 입력 값을 구했으며, 그 입력 값은 계층 2의 입력값이 된다.
신호를 보다 자연스럽게 전달하기 위해 시그모이드 활성화함수를 적용했던 것을 기억해보자. 은닉 계층의 각각의 노드에 이를 적용하겠다.
O hidden = sigmoid(X hidden)
이를 거쳐 O hidden 행렬을 구하면, 시그모이드 함수의 결과 값을 얻을 수 있다.
즉, 지금까지 우리는 입력 계층의 입력 값과 가중치를 행렬 곱 연산해 은닉 계층의 입력 값을 구했으며, 이 값에 활성화 함수를 적용함으로써 최종적으로 은닉 계층의 결과 값을 구했다.
마찬가지로 3계층을 거치려면
X output = W hidden_output · O hidden 이 된다.
초기 입력 신호를 가중치와 조합하여 마지막 계층 쪽으로, 즉 앞쪽으로 전달(feed forward)하는 모습을 볼 수 있다. 이러한 방식을 전파법(순전파)(forward propagation)이라고 한다.
이제 남은 것은 출력 계층에 시그모이드 활성화 함수를 적용하는 것뿐이다.
최종 결과값을 얻게 되면, 지금 얻은 결과 값을 학습 데이터의 실제 값과 비교해 오차를 구하는 것이 되며, 오차를 이용해 신경망을 정교하게 업데이트해서 개선된 결과 값을 내는 것이 우리가 할 일이다. 이 부분이 인공 신경망에서 가장 중요하면서도 이해가 어려운 부분이라고 한다.
Chapter 10. 여러 노드에서 가중치 학습하기
여러 개의 노드가 결과 값과 오차에 영향을 주는 경우에는 가중치를 어떻게 업데이트해야 할까?
한 가지 방법은 모든 연결된 노드에 대해 오차를 균일하게 나누어 분배하는 것이다.
또 다른 방법은 오차를 나누어 분배하지만 차별을 두는 것인데, 더 큰 가중치를 가지는 연결에 더 큰 오차를 분배하는 것이다. 더 큰 가중치를 가진다는 것은 그만큼 오차의 형성에 더 큰 영향을 줬다는 의미이기 때문이다.
각각의 연결이 오차에 영향을 주는 정도에 비례해서 전달하면 된다.
따라서 우리는 가중치를 두 가지 방법으로 활용한다는 점을 확인할 수 있다.
우선 앞에서 봤듯이, 신호를 하나의 게층에서 다음 계층으로 전파하는 데에 가중치를 이용하는 것이다.(전파법)
두 번째로, 오차를 하나의 계층에서 직전 계층으로, 즉 역으로 전파하는 데에도 가중치를 이용하는 것이다.(역전파=backpropagation)
Chapter 11. 여러 노드에서의 오차의 역전파
2개의 입력 i1, i2를 통해 두 개의 계층(각각 2개의 노드)을 거쳐 출력된 결과 o1, o2가 있고, 각각 결과 값의 오차가 e1,e2라고 할때, 오차 e1은 w11과 w21의 가중치의 값에 비례하므로 w11을 업데이트 하기 위해 사용되는 e1의 일부는 w11/w11+w21이 된다. 그리고 w21을 업데이트하기 위해 사용되는 e1의 일부는 w21/w21+w11이다. 결국 오차 e1은 나뉘어 전달될 때, 작은 가중치를 가지는 연결 노드보다 큰 가중치를 가지는 연결 노드에 더 많이 전달된다.
정리
오차를 이용해서 네트워크 내의 매개변수들의 값(가중치)를 조정해나간다는 사실.
최종 출력 계층으로부터 그 직전 계층으로 가는 연결 노드의 가중치를 업데이트하는 방식을 살펴봤는데 여러 개의 출력 노드가 있는 경우에도 그저 각각의 출력 노드를 개별적으로 처리하면 될 뿐, 복잡해질 것이 전혀 없다는 사실.
그렇다면 2개보다 더 많은 계층을 가지는 신경망에 대해서는 어떻게 할까?
다시 말해, 최종 출력 계층에 인접하는 계층이 아니라, 멀리 떨어져 있는 계층과 관련된 가중치는 어떻게 업데이트를 해야 할까?
Chapter 12. 다중 계층에서의 오차의 역전파
입력 계층, 은닉 계층, 출력 계층이 존재할 때, 출력 계층의 오차의 값을 이용해 은닉 계층의 오차를 구하는 것도 가능하다.
e hidden,1 = 연결 노드 w11, w12로 나뉘어 전달되는 오차의 합
= e output,1 * w11/w11+w21 + e output,2 * w12/w12+w22
이렇게 오차의 역전파를 이용해 연결 노드에 대해 나뉜 오차를 재조합할 수 있다. 은닉 계층의 첫 번째 노드의 오차는 이 은닉 계층에서 다음 계층으로 연결되는 모든 연결 노드에 있는 나뉜 오차들의 합이 된다.
또한, 한 단계 더 나아가 입력 계층, 은닉 계층, 출력 계층이 존재할 떄, 은닉 계층의 오차의 값을 이용해 입력 계층의 오차를 구하는 것도 가능하다.
핵심 정리
- 인공 신경망에서 학습이란 연결 노드의 가중치를 업데이트하는 과정을 의미한다. 가중치의 업데이트는 오차에 의해 주도되는데, 오차는 학습 데이터로부터 주어진 정답과 출력 값 간의 차이를 의미한다.
- 출력 노드의 오차는 실제 값(정답)과 출력 값 사이의 차이를 의미한다.
- 중간 계층에 존재하는 노드들의 오차는 명백하지 않다. 한 가지 접근 방법은 출력 계층의 노드들의 오차를 이와 연결된 가중치의 크기에 비례해 나눠서 역전파하고 이를 재조합하는 방법이다.
Chapter 13. 행렬곱을 이용한 오차의 역전파
우리는 앞에서 전파법에 대해 행렬곱으로 계산한 바가 있다.
그럼 역전파에도 행렬곱을 이용할 수 있을까?
이번에는 오차의 역전파를 행렬곱으로 간결하게 만들 수 있는지 보기 위해서, 단계별로 기호를 이용해 적어보겠다. 이렇게 행렬곱으로 표현하는 방식을 벡터화한다.(vectorize)라고 한다.
행렬 사용 이유?
컴퓨터가 반복적인 유사한 연산을 순식간에 처리→훨씬 더 효율적으로 작업 수행하는 장점
최종 출력 계층으로부터 나오는 오차로부터 시작해보자.
$$ error_{output} = \begin{pmatrix} e1\\e2 \end{pmatrix}
$$
$$ error_{hidden} = \begin{pmatrix} w_{11}/w_{11}+w_{21} & w_{12}/w_{12}+w_{22} \\ w_{21}/w_{21}+w_{11} & w_{22}/w_{22}+w_{12} \end{pmatrix}·\begin{pmatrix}e1 \\e2\end{pmatrix} $$
위 수식을 다시 보면, 이 수식에서 핵심은 출력 오차인 e_n과 w_ij의 곱셈 연산이다.
가중치가 크면 클수록 더 많은 출력 오차가 은닉 계층으로 돌아오게 된다. 이것이 핵심이다.
분수에서 분모 부분은 일종의 정규화 인자(normalizing factor)라고 할 수 있다. 만약 이 정규화 인자를 무시한다고 해도 우리는 되돌아오는 오차의 일정 비율 정도를 잃을 뿐이므로 따라서 e1w11/(w11 + w21)을 간단하게 e1w11로 표현해도 된다.
이를 적용하면 행렬곱은 훨씬 보기 좋아진다.
$$ error_{hidden} = \begin{pmatrix} w_{11} & w_{12} \\ w_{21} & w_{22} \end{pmatrix}·\begin{pmatrix}e1 \\e2\end{pmatrix} $$
가중치 행렬은 우리가 8장에서 만들었던 행렬과 유사해 보이지만, 자세히 보면, 대각선 방향으로 원소가 뒤바뀐 것을 알 수 있다. 즉, 우측 상단의 가중치와 좌측 하단의 가중치가 바뀌어 있다. 이처럼 행렬의 행과 열을 바꾸는 것을 전치(transpose)한다고 하며, 행렬 W의 전치행렬을 기호로는 W^T라고 표기한다.
$$ error_{hidden} = W^T_{hiddenoutput}·error_{output} $$
다음과 같이 오차의 역전파를 행렬을 통해 간단하게 표현하였다.
간결하게 표현해서 좋기는 하지만, 정규화 인자를 생략해도 괜찮은 걸까?
결론부터 말하면, 잘 작동한다.
오차에 대한 책임을 분산시키는 데 지침이 되는 것은 가중치의 크기이므로 역전파되는 오차가 연결 노드의 가중치의 크기를 중시한다는 점이 핵심이다.
핵심정리
- 오차의 역전파를 행렬곱으로 표현할 수 있다.
- 오차의 역전파를 행렬곱으로 표현함으로써 우리는 네트워크의 크기에 상관없이 이를 간결하게 표현할 수 있으며, 컴퓨터를 통해 보다 효율적이고 빠르게 업무를 처리하게 할 수 있다.
- 이제 우리는 전파법과 역전파 모두 행렬곱을 통해 효율적으로 처리할 수 있다는 사실을 알게 되었다.
Chpater 14. 가중치의 진짜 업데이트
아직 우리는 인공 신경망에서 가중치를 어떻게 업데이트해야 하는가의 핵심적인 질문에 답하지 않았고, 이를 풀기 위해 한 아이디어만 더 이해하면 된다.
가중치 계산
신경망에는 너무나도 많은 가중치의 조합이 존재하고 이를 공식화하는 게 어렵다.
그럼 차라리 가중치들을 랜덤하게 추측해서 구해보는 것은 어떨까? 무차별 대입.
무차별 대입(brute force) 방법은 비밀번호를 크래킹(cracking)하는 데에 사용되기도 한다.
현실적으로 제대로 된 신경망에서 무차별 대입이 전혀 실용적이지 못하다.
경사 하강법
그렇다면 가중치를 어떻게 구해야 할까?
경사 하강법(gradient descent)는 경사를 내려갈 때, 한 걸음을 내딛고 나서 다시 한번 어느 방향이 우리의 목적지로 가는 가장 빠른 지름길인지를 파악하기 위해 주변을 살피게 되고, 그러고 나서 그 방향으로 다시 한 걸음을 내딛는 이 과정을 목적지에 도달할 때까지 반복하는 것을 말한다.
여기서 경사는 지형의 기울기를 의미한다.
즉, 우리는 매 상황에서 경사가 가장 급한 방향으로 한 걸음씩 내딛느 과정을 반복한다.
그렇다면, 경사 하강법과 신경망의 연결 고리는 무엇일까?
복잡하고 어려운 함수가 신경망의 오차라고 한다면, 최저점을 찾기 위해 아래로 내려가는 것은 오차를 최소화해나가는 과정이라고 할 수 있다.
우리는 신경망의 결과 값을 개선해나갈 수 있다.
경사하강법이 빛을 발하는 때는 많은 매개변수를 가지는 함수에 대응해야 하는 경우이다.
또한, 잘못된 계곡에 빠지는 것을 피하려면 각각 다른 출발점에서 시작해 여러 번 학습하는 방법을 취할 수 있고, 출발점이 다르다는 것은 매개변수의 초기값을 다르게 준다는 것이다. 즉, 인공 신경망에서는 가중치의 초기 값을 다르게 준다는 것을 의미한다.
중간 정리
- 경사 하강법은 함수의 최저점을 구하기 좋은 접근 방법이다. 특히 함수가 매우 복잡하고 어려워 대수학을 이용해 수학적 접근 방식으로 풀기 어려울 떄도 잘 동작한다.
- 매개변수가 많아서 다른 접근 방법들이 실패하거나 현실적이지 못한 경우에도 경사 하강법은 잘 동작한다.
- 데이터가 불완전하거나 함수가 완벽하게 표현되지 못하거나 잘못된 발걸음을 내디딘 경우에도 경사 하강법은 탄력적으로 대응한다.
여러 가지 오차함수
- (목표 값-실제 값)→오차의 합이 0으로 나와서 오차가 서로 상쇄된다는 점에서 전체 오차를 구하는 합리적인 방법이 아님.
- (목표 값-실제 값)의 절댓값→최저점 근처에 가면 기울기가 연속적이지 않으며 이로 인해 경사 하강법이 잘 작동하지 않을 수 있다.(ex) V자 형태의 계곡)
- (목표 값-실제 값)^2인 제곱 오차 방식
- 가장 선호됨.
- 오차함수로 제곱오차 방식을 사용하면 경사 하강법의 기울기를 구하는 대수학이 간단해짐.
- 오차함수가 부드럽고 연속적이므로 경사 하강법이 잘 동작하게 된다. 값이 갑자기 상승하거나 빈 틈이 존재하지 않게 된다.
- 최저점에 접근함에 따라 경사가 점점 작아지므로 목표물을 오버슈팅할 가능성이 작아진다.
미분으로 오차함수 구하기
경사 하강법을 사용하려면 가중치에 대한 오차함수의 기울기를 구해야 한다.
이 작업을 하기 위해서는 미분(calculus)이 필요하다!
미분은 어떤 하나의 변화가 다른 것의 변화에 어떤 영향을 주는지를 구하는 수학적 접근 방법이다.
오차함수의 기울기를 가중치의 값이 변화함에 따라 오차의 값이 얼마만큼 변하는지로 정의할 수 있다.
핵심 정리
- 신경망의 오차는 가중치의 함수이다.
- 신경망을 개선한다는 것은 가중치의 변화를 통해 오차를 줄인다는 뜻이다.
- 최적의 가중치를 직접 찾는 것은 매우 어렵다. 이를 대체하는 접근 방법은 작은 발걸음으로 오차함수를 줄여가면서 반복적으로 가중치를 개선해가는 방법이다. 각 발걸음은 현재 위치에서 볼 때 가장 급격히 낮아지는 경사의 방향으로 취해진다. 이런 방법을 경사 하강법이라고 한다.
- 오차 기울기는 미분을 이용해 계산할 수 있으며 알고 보면 별로 어렵지 않다????
Chapter 15. 가중치 업데이트 예제
Chpater 16. 데이터 준비하기
핵심 정리
- 신경망의 디자인과 실제 풀고자 하는 문제에 적합하게 입력 값, 출력 값, 가중치의 초기 값을 설정해야 신경망이 잘 동작하게 된다.
- 흔히 발생하는 문제로는 포화가 있다. 포화란 보통 큰 가중치에 의해 커진 신호 때문에 활성화 함수의 기울기가 매우 얕은 곳에 존재하게 되는 현상을 의미한다. 이렇게 되면 더 나은 가중치로 업데이트해가는 학습 능력이 저하된다.
- 또 다른 문제로는 신호 또는 가중치가 0의 값을 가지는 문제가 있다. 이 또한 가중치 학습 능력을 죽이게 된다.
- 가중치는 임의의 작은 값으로 설정되어야 한다. 0은 반드시 피해야 한다. 노드로의 연결 노드가 많을수록 가중치의 크기를 줄이는 등의 정교한 방법을 이용하기도 한다.
- 입력 값은 작은 값으로 조정되어야 하되, 0으로 설정해서는 안 된다. 일반적인 범위는 0.01~0.99 또는 -1 ~ 1이다. 문제에 따라 적합한 범위를 선택하면 된다.
- 출력 값은 활성화 함수가 생성할 수 있는 범위 내에 있어야 한다. 로지스틱 시그모이드 함수에서 0 이하 또는 1 이상의 값을 불가능하다. 학습의 목표 값ㅇ르 이 범위 외의 값으로 설정하면 이는 더 큰 가중치를 만들어내게 될 것이며 그 결과는 포화로 이어질 것이다. 적당한 범위는 0.01~0.99이다.