TensorFlow

신경망 첫걸음, 05 가중치의 진짜 업데이트

LEEHANDS 2022. 4. 1. 22:05
반응형

 

잘설명하다가 진짜 업데이트는 또 뭔말일까?

지금까지 한것은 가짜란 말이냐?

 

맞다 가중치를 어떻게 업데이트해야하는가의 핵심적인 질문에 대한 답을 할 수 없다.

지금까지 네트워크의 각 계층에 걸쳐 역전파되는 오차를 구해봤다.

이처럼 오차를 구하는 이유는 인공 신경망이 보다 나은 답을 출력하게 하기 위해서 가중치를 조정해가는 데 지침 역할을 하는 것이 오차이기 때문이다.

 

이러한 과정은 선형 분류자 예제에서부터 입니다.

 

신경망에서 노드는 단순한 선형분류자가 아니기때문에 노드는 입력되는 신호에 가중치를 적용한 후 이의 합을 구하고 다시 여기에 시그모이드 활성화 함수를 적용하는 식으로 좀더 복잡한 구조를 가진다.

 

그렇다면 이처럼 정교한 노드사이를 연결하는 연결 노드의 가중치를 어떻게 업데이트 해야할까?

어떤 끝내주는 대 수학 공식을 이용해 가중치를 단번에 구해낼 수 없는 것일까?

 

가중치 계산

신경망에는 많은 가중치 조합이 있다.

 가중치 조합을 계산하려면 어마어마한 수식이 있다고한다 그렇게 알고 넘어가자

그래서 문제를 푸는 영웅이 되기보다 차라리 가중치들을 랜덤하게 추측해서 구해보는 것은 어떨까? 바로 랜덤(Random)

 

어려운 문제에 봉착했을 때는 이런 생각이 도움도리 수 있다.

무차별 대입 방법이라고 합니다.

 

무차별 대입방법은 비밀번호를 크래킹 (cracking) 하는데 사용되기도 합니다.

 

그런데 현실적으로는 제대로된 신경망에서 무차별 대입은 전혀 실용적이지 못하다. 너무 오래걸리기때문에

 

경사 하강법

가중치를 어떻게 구해야할까?

이해법으로 인공신경망이 폭발적으로 발전한다고한다.

 

가본적없는 산에서 내려올때 한걸음 한걸음씩 느리게 언덕을 내려오게 됩니다.

수학에서는 이러한 접근을 경사하강법이라고 부른다.

 

우리는 한걸음을 내딛고 나서 다시 한번 어느방향이 우리의 목적지로 가는 가장 빠른길인지 파악하기위해 주변을 살핀다.

그리고 이과정을 수없이 반복하게 된다.

여기서 경사란 지형의 기울기를 의미

 

우리는 복잡한 함수에 대한 이해가 없더라도 경사하강법을 이용해 최저점을 찾을 수 있다.

 

경사하강법에서는 정답에 접근하는 방식으로 단계적 접근 방식을 취하면서 우리의 위치를 조금씩 개선해나가므로 정확한 해답을 얻지 못할 수 있지만 전혀얻지못하는 것보다 낫다.

 

경사하강법과 신경망의 연결고리는 무엇일까?

복잡하고 어려운 함수가 신경망 오차라고한다면 , 최저점을 찾기 위해 아래로 내려가는 것을 오차를 최소화해나가는 과정이라고 할 수 있다.

우리는 신경망의 결과값을 개선해나갑니다.

 

경사하강법의 아이디어를 이해하기 위해 아주 간단한 예제

 

빨간 점이 시작위치라고 하고 이 시작점부터 경사하강법을 적용

화살표로 표기된 기울기는 음의 기울기임으로 x축방향으로 오른쪽으로 이동하겠습니다.

X값이 조금 증가합니다. 이것이 바로 등산객의 첫번째 발걸음이 됩니다.

 

위치가 조금 개선되어 최저점에 좀더 가까운 위치로 이동한 것을 확인할 수 있다.

 

우리의 발 아래의 기울기가 양의 기울기이므로 우리는 왼쪽으로 이동하게 됩니다.

우리는 다음 걸음이 최저점을 지나치게 될 것이며 최저점에 도달할 방법은 영원히 없을 것입니다.

여기서 가정하는 것은 우리가 최저점에 가까워질 수 록 기울기는 완만해 진다는 것

 

다만 기울기가 완만해지면 발걸음을 조정해나가는 것을 표현합니다. 그만큼 가까워진다는 것을 의미하므로

 

경사 하강법에 의해 최저점으로 접근하는 세가지 경우를 보여줍니다.

 

경사하강법은 함수의 최저점을 구하기 위한 좋은 접근방법입니다. 특히 함수가 매우 복잡하고 어려워 대수학을 이용해 수학적 방식으로 풀기 어려울 때에도 잘 동작합니다.

매개변수가 많아서 다른 접근 방법들이 실패하거나 현실적이지 못한 경우에도 경사하강법은 잘 동작한다.

데이터가 불완전하거 함수가 완벽하게 표현되지 못하거나 잘못된 발걸음을 내디딘 경우에도 경사하강법은 탄력적으로 대응

 

 

여러가지 오차함수

신경망에서 수많은 가중치라는 매개변수를 가지는 복잡하고 어려운 함수에 의해 그 결과값을 얻습니다.

경사하강법을 신경망에 이용해도될까요? 물론입니다.

필요한 것은 오차함수를 올바르게 선택하는 일입니다.

신경망의 결과 함수 자체는 오차함수가 아니다. 하지만 오차는 학습 목표값과 실제값 간의 차이를 의미하므로

우리는 결과 함수를 쉽게 오차함수로 변환할 수 있다. 

 

3개의 출력 노드에 대한 목표값, 실제 값과 함께 오차함수로 쓸 후보가 세가지 있다.

첫번 쨰 후보의 경우 오차함수는 단순히 (목표값 - 실제값)입니다.

언뜻보면 충분히 합리적인 오차함수로 보이지만 전체 노드의 오차르 ㄹ구하기 위해 합을 구해보면 그 값이 0인것을 확인할 수 있습니다.

첫번째 노드와 두번째 노드는 각각 오차르 ㄹ가지고있으므로 이 신경망이 완벽하게 학습하지 않았다는것은 분명합니다.

그런데 전체 노드의 합이 이신경망에 오차가 없다고 이야기하고있습니다.

그래서 절대값을 씌워야합니다.

 

세번째 후보는 제곱을합니다. 이런방식은 제곱오차 방식이라고합니다.

이 후보는 절댓값 방식보다 많이 사용되는데 이유는 아래와 같다.

 

오차함수로 제곱오차 방식을 사용하면 경사하강법의 기울기를 구하는 대수학이 간단해짐

오차함수가 부드럽고 연속적이므로 경사하강법이 잘 동작 값이 갑자기 상승하거나 빈틈이 존재하지 않는다.

최저점에 접근함에 따라 경사가 점점 작아지므로 오버슈팅 가능성이 낮음

 

우리는 더 복잡하고 흥미로운 오차함수를 만들어낼 수 있다.

 

미분으로 오차함수 구하기

경사 하강법을 사용하려면 가중치에 대한 오차함수 기울기를 구해야한다.

이 작업을 위해 미분이 필요합니다. 미분 = 기울기 

우리가 최소화하고자하는 함수는 신경망 의 오차

다음어가고자하는 매개변수는 가중치 입니다.

 

편의를 위해 1개의 가중치만 표시했지만 사실 신경망에는 수많은 가중치가 있다.

2개의 가중치가 존재하므로 오차함수는 3차원 표면으로 표현된다.

 

많은 매개변수를 가지는 함수는 오차를 시각화하기 어렵지만, 그경우에도 하강법을 이용해 최저점을 찾아가는 방식은 여전히 동일하다.

 

즉, 가중치 Wjk 의 값이 변화함에 따라 오차 E 의 값이 얼마만큼 변화하는지 입니다.

이값이 최저점의 방향으로 감소하기 원하는 오차 함수의 기울기 입니다.

은닉계층 (j) 과 최종 출력 계층 (k) 사이에 존재하는 연결 가중치에 집중해봅니다.

 

앞으로 미분할 때 각각의 기호의 의미를 잊지 않기 위해 그림을 계속 언급할 것입니다.

미분의 각 단계는 결코 어렵지 않으며 상세하게 살펴볼 것입니다.

단지 오차함수인 E 를 풀어 쓴것 뿐입니다.

 

노드 n 에서 결과값 On 은 오직 이와 연결되는 연결 노드로부터만 영향을 받습니다.

다시말해 노드 K의결과 값이 Ok 는 그오 ㅏ연결되는 가중치 Wjk 에 의해서만 영향을 받는 다는 것입니다. 당연하지

 

다른 관점에서 보면 노드 K 의 결과 값은 가중치 Wjb 에는 영향을 받지 않는다고 말할 수 있습니다.

즉 가중치 Wjb 는 출력노드 b 와 연결되지 K와는 연결되지 않습니다.

 

 

이ㅏ제 오차함수를 구할 때 처음부터 모든 출력 노드에 걸쳐 합을 구하지 않아도 된다는 것을 깨달았습니다.

그 이유는 노드의 결과값은 오직 연결된 가중치에 의해서만 영향을 받기 때문입니다.

이제 수식이 한층 간결해집니다.

 

이제 미분을 핵볼까요?

Tk 는 상수이므로 Wjk 의 값이 변하더라도 불변입니다.

다시말해 tk 는 Wjk 의 함수가 아닙니다.

목표값이 되는 가중치에 영향을 받는다는 점은 말이 안되기 때문입니다.

이제 우리가 처리할 것은 Wjk 에 영향을 받는 Ok 뿐입니다.

 

연쇄법칙을 이용해 미분작업을 몇 개 의 조각으로 나눠보겠습니다.

 

첫번째 항의 미분은 단순히 제곱의 미분이므로 다음과 같이 구할 수 있다.

두번째 항은 조금 더 생각을 요하기는 하지만 별로 어려울 것없다.

Ok 는 노드 K 의 결과값으로 입력 신호의 가중치 합에 시그모이드 함수를 적용한 것이라는 사실을 기억할 것입니다.

Oj 는 최종 출력 계층의 출력값이 아니라 직전 은닉계층의 노드로부터의 출력 값입니다.

시그모이드 함수의 미분값은 무엇일까요?

시그모이드 함수의 미분값은 다음과 같다.

 

많은 함수가 미분을 하면 보기만해도 겁나는 복잡한 수시긍로 변신한다

시그모이드는 미분한 결과도 식이 매우 간단하며 따라서 활용하기도 편하다.

이런 점이 시그모이드가 신경망의 활성화함수로 인기있는 이유중 하나이다.

이제 이 결과를 적용해보자

이 수식은 오차함수의 기울기를 표현함으로써 가중치  Wjk 를 조정해나갈 수 있게 해줍니다.

이 수식이 우리가 그토록 찾아왔던 마법의 수식

첫 번째항은 우리가 잘알고 있는 ( 목표값 - 실제 값) 오차입니다.

두 번째항은 시그모이드 안에 있는 합 기호는 사실 최종 계층의 노드로 들어오는 입력 신호에 불과하므로 우리는 이를 더 간단히 ik 라고 표기할 수 도 있다.

이는 활성화 함수가 적용되기 전의 신호를 의미할 뿐입니다.

마지막항은 이전 은닉 계층의 노드 j 의 결과 값입니다.

 

수식을 이렇게 나누어 살펴봄으로써 실제로 기울기에 영향을 주는 요소들에 대해 감을 잡을 수 있다.

 

최종적으로 단 한가지 작업이 남아있다.

위 수식은 은닉계층과 출력 계층 사이에 있는 가중치를 업데이트하기 위함이다.

이제 입력 계층과 은닉계층 사이에 있는 가중치들에 대해서도 유사하게 오차 기울기를 찾아보겠습니다.

 

이를 위해 복잡한 대수학을 필요가 없다는 사실은 이미 알고있다.

 

  • 이번에는 첫 번 째 부분의 오차인 (목표값 - 실제값) 이 은닉 계층에서 재조합된 역전파 오류가 되게 됩니다. 이 값을 ej 라고 부르자
  • 두번째 시그모이드 부분은 동일하지만 합 부분이 은닉계층의 노드 j 으로 들어오는 입력값에 가중치를 적용한 결과가 되고 이 입력 값을 ij 라고 표기
  • 마지막 부분은 첫번째 계층의 노드 Oi 의 결과값이 됩니다.

이제 우리는 기울기에 대한 모든 중요한 마법 수식을 구했다.

진짜 구했는지 복습 또 복습하자

 

학습률

가중치는 기울기와 반대방향으로 진행된다는 점 기억하자

학습률 인자를 적용함으로써 변화의 정도를 조정하겠습니다.

학습률은 문제에 따라 조금씩 다르게 튜닝해야합니다.

이는 앞에서 우리가 선형 분류자를 학습시킬때에도 적합하지 않은 학습데이터에서 받은 나쁜영향을 줄이고 가중치가 처죄점 근처에서 오버 슈팅하는 것을 방지하기 위해 사용한 바 있다.

업데이트 된 새로운 가중치는 방금 구한 오차 기울기에 상수를 곱한 값을 원래 가중치에서 빼줌으로써 구할 수 있다.

빼는 이유는 양의 기울기 일 경우 에는 가중치를 줄이고, 음의 기울기에서는 가중치를 늘리기 위함

여기서 상수 α 는 오버슈팅을 방지하기 위해 변화의 강도를 조정하는 역할을 하며, 이를 바로 학습률이라고 합니다.

 

이수식은 은닉 계층과 출력계층 사이의 가중치 뿐만아니라 입력계층과 은닉계층 사이의 가중치에도 동일하게 적용

 

이렇나 계산을 행렬곱으로 어떻게 표현할지 보자

여기에서는 학습률 α 를 생략했지만, 학습률은 그저 상수일뿐 우리가 행렬 곱을 수행하는데에는 아무런 영향을 주지 않는다.

 

가중치 변화의 행렬은 한계층의 노드 j 와 다음 계층의 노드 K 를 연결하는 가중치 Wjk 를 조정하는 역할을 합니다.

앞의 수식에서 앞 항은 다음 계층(노드k0으로부터의 값들을 이용

뒤 항은 전 계층(노드j)으로부터 값들을 이용하는 것을 볼 수 있다.

 

앞의 그림에서 뒤 항은 행이 하나인 행렬로 바로 직전 계층 Oj 로부터의 결과 값은 전치행렬입니다.

이러한 가중치 업데이트 행렬은 다음과 같이 표현할 수 있다.

사실 그렇게 복잡한 것은 아닙니다.

사실상 출력 노드들로 이루어진 행렬이기때문에 수식에서 시그모이드는 뺏습니다.

이게 전부입니다.

 

  • 신경망의 오차는 가중치의 함수
  • 신경망을 개선한다는 것은 가중치의 변화를 통해 오차를 줄이는 것
  • 최적의 가중치를 직접 찾는 것은 매우 어렵습니다. 이를 대체하는 접근 방법은 작은 발걸음으로 오차함수를 줄여가면서 반복적으로 가중치를 개선해가는 방법입니다. 각 발걸음은 현재 위치에서 볼때 가장 급격히 낮아지는 경사의 방향으로 취해집니다. 이런 방법을 경사하강법
  • 오차 기울기는 미분을 이용해 계산할 수 있으며 알고보면 어렵지않다?

 

가중치 업데이트 예제

가중치 업데이트가 제대로 동작하는지 확인하기 위해 예제를 실제로 살펴봅니다.

신경망은 우리가 앞에서 봤던 것인데 이번에는 은닉계층의 첫번째 노드에서의 결과 값 Oj=1 = 0.4와 두번째 노드에서의 결과 값 Oj=2 = 0.5 를 추가했습니다.

이 값들은 단지 예제를 위해 만든 가공의 값임을 참고하기 바랍니다.

신경망은 우리가 앞에서 봤던 것인데 이번에는 은닉 계층의 첫번째 노드에서 결과값 Oj=1 = 0.4 와 두번째 노드에서의 결과 값 Oj=2 = 0.5 를 추가했습니다.

이 값들은 단지 예제를 위해 만든 가공의 값임을 참고하자

 

은닉계층과 출력 계층 사이의 가중치 W11 을 업데이트 해야합니다.

현재의 값은 2.0 입니다.

 

  • 첫번째 항 (Tk - Ok) 는 오차 e1 입니다. 그림에서 볼 수 있듯이 e1 = 0.8 입니다.
  • 시그모이드 함수 내의 합(아래 식 참고) 은 (2.0 * 0.4) + (3.0 * 0.5) = 2.3입니다.

  • 그러면 시그모이드 함수의 값은 1/(1+e^-2.3) 은 0.909 가 됩니다. 따라서 두번째 항은
    0.909 * (1-0.909) = 0.083 이 됩니다.
  • 마지막항은 Oj 인데 우리는 J=1 일 때 가중치 W11 에 관심이 있으므로 Oj=1 = 0.4 입니다.

 

결국 이 세항을 모두 곱하고 ( 0.8 * 0.083 * 0.4) 맨 앞에 있던 음의 부호 (-) 를 붙이면 -0.0265 가 나옵니다.

만약 학습률이 0.1 이라면 변화량은 (0.1 * -0.0265)  = -0.00265 가 됩ㄴ디ㅏ.

따라서 새로운 W11 은 2.0 -(-0.00265) = 2.00265 가 됩니다.

 

마지막 데이터 준비하기 

학습데이터를 어떻게 준비하는지 가중치의 초기 값을 어떻게 정할지 그리고 학습 과정이 제대로 작동할 수 있도록 결과 값을 어떻게 디자인해야할지 생각해보자

신경망을 이용한다고 해서 모든 문제가 잘 해결되는 것은 아닙니다.

신경망이 제대로 동작하지 않는 데에는 여러 가지 이유가 있지만

꽤 많은 경우에는 학습 데이터, 가중치의 초기화 , 결과 값을 잘 디자인하는 것만으로 해결이 가능합니다.

 

입력값

시그모이드 활성화 함수를 보자 만약 입력값이 크면 활성화 함수는 평평한 형태를 띠는 것을 볼 수 있다.

우리는 기울기를 이용해 가중치 업데이트를 하므로 평평한 활성화 함수는 문제가 있다.

작은 기울기는 곧 학습 능력이 제한된다는 것을 의미한다.

이를 일컬어 신경망에 포화가 발생했다고 합니다.

포화가 일어나지 않게 하기 위해 우리는 입력 값을 작게 유지해야합니다.

 

웃긴건  이 수식은 입력 신호 (Oj) 에도 영향을 받는다는 것이다.

따라서 가중치를 너무 작게 만들 수 도 없습니다. 컴퓨터는 매우 작거나 매우 큰 수를 처리할 때 정화도를 잃을 수 있으므로 매우 작은 수 도 문제가 될 수 있다.

 

이럴 때 좋은 방법은 입력값이 0.0 ~ 1.0 사이에 놓이도록 그 크기를 조정하는 것입니다.

떄로는 입력값에 0.01 같은 작은 오프셋 값을 더해서 입력 값이 0되는 것을 방지하기도 합니다.

 

결과 값

신경망의 결과 값은 마지막 계층의 노드들로부터 출력되는 신호로

만약 우리가 1.0을 넘는 값을 만들어내지 못하는 활성화 함수를 사용하고 있다면 학습의 목표 값으로 이보다 큰 값을 설정하는 것은 어불성설일 것입니다.

만약 도달할 수 없는 금지된 영역의 값으로 목표값을 설정한다면 신경망을 학습하면 할수록 활성화 함수에 의해 만들어질 수 없는 더 큰 결과 값을 만들기위해 점점 더 큰 가중치를 시도하게 될것이다.

그 결과는 결국 신경망을 포화시킬 것이다.

 

0.0 에서 1.0 사이의 범위의 값을 이용하는 것이 일반적이지만 불가능한 영역인 0.0 과 1.0 으로 설정되는 것을 막기위해서

0.01 에서 0.99 사이의 값을 이용하기로 합니다.

 

임의의 값으로 가중치 초기화

입력값 출력 값과 마찬가지로 원칙이 가중치에도 적용됩니다.

가중치의 초기화 는 -1.0 ~ 1.0 사이의 임으의 값으로 하는 것이 좋은 선택일 것이다.

어떤 경우에라도 가중치의 초기 값을 같은 상수로 설정하며 ㄴ안됩니다.

특히 0 으로 설정하는 것은 절대 금지

 

 

  • 신경망의 디자인과 실제 풀고자하는 문제에 적합하게 입력값 , 출력값, 가중치의 초기값을 설정해야 신경망이 잘 동작하게 됩니다.
  • 흔히 발생하는 문제는 포화 , 포화란 보통 큰 가중치에 의해 커진 신호때문에 활성화 함수의 기울기가 매우 얕은 곳에 존재하게 되는 현상을 의미한다.
  • 또다른 문제로는 신호 또는 가중치가 0 의 값을 가지는 문제, 이또한 안된다.
  • 가중치는 임의의 작은 값을 설정되야 합니다. 0은 반드시 피하고 노드로의 연결 노드가 많을 수 록 가중치의 크기를 줄이는 등 정교한 방법을 이용하기도 합니다.
  • 입력 값은 작은 값으로 조정되어야 하되, 0으로 설정해서는 안된다. 일반적인 범위는 0.01~0.99 또는 -1 ~ 1 입니다.
  • 출력 값은 활성화 함수가 생성할 수 있는 범위 내에 있어야합니다. 로지스틱 시그모이드 함수에서 0 이하 또는 1 이상의 값은 불가능합니다. 학습의 목표 값을 이 범위 외의 값으로 설정하며 ㄴ이는 더 큰 가중치를 만들어 내게 될 것이며 그 결과는 포화로 이어질 것입니다. 적당한 범위는 0.01 ~ 0.99 입니다.
반응형