인공지능-기계학습/스탠포드 강의

스탠포드 머신러닝 강의 12 Lecture 12 - Backprop & Improving Neural Networks | Stanford CS229: Machine Learning

The Yellow Lion King 2022. 4. 23. 10:00
반응형

 

 

주요 내용

  • Backprop - 백프로파게이션(역전파)
  • Improving Neural Networks - 신경망을 더 개선시키는 방법
    • Activation Function - 활성화/활성 함수
    • Initialization Methods - 초기 웨이트 설정 방법
    • Optimization - 최적화 방법

 

지난 시간에는 딥러닝의 첫번째 시간으로 선형회귀 모델과 간단한 신경망을 비교해서 만들고 설명했습니다.  이미지 중에 고양이가 있는지 없는지를 분류하는 네트워크를 만들었습니다. 그 때정의한 Cost Function과 Loss Function(빨간색 박스안의 내용), 그리고 Update 방법은 아래와 같습니다.

업데이트를 할때 미분을 하는데 이때 아웃풋에 제일 가까운 레이어(w[3]) 부터 미분하는 것이 계산하기 좋다는 것 까지 지난 시간에 이야기 했습니다.

 

 

Backprop(역전파)


역전파, 백프로파게이션, Backprop을 해 보겠습니다.  w[3]부터 계산합니다. J (Cost Function)의 값을 w[3] 값으로 미분합니다.

이렇게 계산을 진행하기 위해서는 사실 먼저 알아야할 전제사항/공식이 있는데요 아래와 같습니다.

 

J를 w[3]로 미분하는 위에 위에 있는 이미지에서, 마지막에 a[2]에 왜 Transpose 를 할까요? 바로 행렬간의 계산을 할 수있도록 해주기 위해서 입니다. 아래에서 처럼 transpose를 해주어야 (1, 2) 행렬이 됩니다.

 

계속 풀어보면 다음과 같습니다.

 

이것을 m개의 훈련 데이터에 대해서 평균을 내는 것은 아래와 같습니다.

 

w[3]에 대한 계산이 끝났으니 그 이후에는 w[2]에 대한 미분입니다. 어떻게 하면 더 효율적으로 계산할 수 있을까요? 

로스 함수를 w[3]로 미분한다는 것은 아래의 오른쪽 내용 처럼 분리가 가능한데요.. 이 내용을 자세히 보면 이전에 구했던 왼쪽의 내용에서  변형할 수 있는 값을 유추할 수 있습니다. 바로 a[2]T가 z[3]를 w[3]로 미분한 것과 같다는 것 입니다.

 

그래서 w[2]로 미분하는 공식에 대하여 동등한 내용을 빨간색으로 표시해 보면 아래와 같습니다.

그래서 동등한 내용으로 재 정리하면 아래와 같습니다. 그런데 중간에 행렬의 크기가 일치하지 않아서 행렬 연산이 안되기 때문에 Elementwise dot (모든 요소간의 곱)이 필요합니다. 그렇게 해서 행렬의 크기를 동일하게 맞출 수 있습니다.

상기 내용을 어떻게 프로그래밍 해야할지 걱정하지 않아도 됩니다. 많은 머신러닝 프레임웍에서 이런 계산을 대신해 주기 때문입니다.

포워드 프로파게이션을 하는 동안 계산 내용을 모두 메모리에 저장해 놓았다가 백워드 프로파게이션 시에 사용함으로써 메모리 사용을 줄이고 계산 속도를 높일 수 있습니다.

 

 

 

 

 

Imporving Neural Networks

A) Activation Function

지금까지 배운 내용으로 신경망을 만들고 훈련해도 만족할 만한 성과를 못 얻을 수 있습니다. 그래서 더 좋은 성능을 내는 신경망을 어떻게하면 만들 수 있는지에 대해서 알아보겠습니다.

제일 먼저 가능한 것은 Activation Funcion(활성화 함수)을 바꾸는 것 입니다.

시그모이드 함수나 탄젠트h 함수는 z 값이 아주 커지거나 작아지면 출력값의 차이가 작아져서 w를 업데이트 하는 영향이 거의 없어집니다. 즉, gradient vanishing 문제를 발생하게 됩니다. ReLu는 이런 문제를 해결하는 함수 입니다.

그럼 왜 활성화 함수가 필요할 까요?

위의 두 이미지에서 보면 알 수 있듯이 활성화 함수가 없다면 네트워크의 깊이가 아무리 깊어도 선형 함수의 분류기와 같을 뿐입니다.  

보통 같은 레이어에서는 같은 활성화 함수를 이용합니다. 다른 레이어에는 다른 활성화 함수를 사용할 수 있습니다. 위에서 살펴본 시그모이드 함수(Sigmoid), 레루 함수(ReLu), 탄젠트h 함수(tanh) 이외에도 여러가지가 있지만 기본적인 함수는 이 정도가 됩니다.

 

 

B) Initialization Methods

두번째로는 초기화 방법에 대해서 알아보겠습니다. 아래 이미지는 평균으로 정규화할 경우 변화되는 내용을 설명합니다.

표준편차를 통해 정규한 내용이며 이럴 경우 최적값을 찾아가는 경로가 훨씬 단축되게 됩니다. 그래서 정규화를 하는 것이지요.

상기에서 사용한 평균이나 표준편차는 모두 훈련 데이터에서 계산된 것을 말하며 이것은 테스트 시에도 동일한 값을 이용해서 계산되야 합니다.

 

베니싱 그레디언트(Vanishing Gradient)에 대해서 좀더 자세히 알아보겠습니다. 아래와 같이 히든 레이어가 10개, 활성화 함수는 Identical 함수(그냥 통과하는 함수), 그리고 바이어스는 0인 신경망을 만들었다고 하겠습니다. 아래 계산에서도 볼 수 있듯이 w 의 값이 초기값에 L 승으로 곱한 결과가 됩니다. 따라서 초기 값이 1보다 조금만 커도 결과 값은 아주 큰 값으로 설정이 되고 1보다 작은 값을 설정을 해도 결과 값은 아주 작은 값으로 설정되게 됩니다. 0.9, 1.1 처럼 1 근처의 값으로 주면 그나마 변화량이 덜 할 것입니다. 그러나 조금만 커져도 엄청낙게 큰 값으로 바뀌고 조금만 더 작아져도 엄청나게 작은 값으로 바뀝니다. 그래서 활성화 함수가 중요합니다.

 

 

하나의 뉴런을 가지고 예를 들어보겠습니다. 보시는 것처럼 n이 커지면 w(i)가 작아집니다.  따라서 w(가중치)의 초기 값을 1/n으로 설정하는 것도 좋은 가중치 초기화 방법 중에 하나 입니다.

그래서 시그모이드 활성화 함수에 대해서는 아래와 같은 코드로 초기화 하는 것이 동작을 잘 합니다.

다른 초기화 방법으로 Xavier Initialization(자비어 초기화)이 있습니다.

 

C) Optimization

세번째 방법으로 옵티마이제이션에 대해서 알아보겠습니다.

아래는 이렇게 배치로 최적화 할때랑 아닐때랑을 비교한 비용함수 곡선입니다.

배치 그레디언트 디센트(Batch Gradient Descent) 방법을 2차원에서 그려보면 아래의 녹색 선과 같이 움직입니다. 이상적인 빨간색 경로보다는 돌아가는 것 같지만 하나의 이터레이션을 훨씬 빠르게 실행할 수 있습니다.

 

또 약간 다른 Gradient Descent와 Momentum(모멘텀) 알고리즘을 소개합니다. 일반적으로 GD를 쓰면 빨간색 선과 같이 움직이면서 최적값을 찾아가는데, 여기에 모멘텀을 더하면 녹색 선과 같이 움직이게 됩니다. GD는 지나온 과거의 움직임을 고려하지 않고 앞으로 나아 갑니다. 반면에 모멘텀은 과거 움직임을 고려해서 앞으로의 방향을 조정합니다. 처음 시작점에서 두번째 점으로 이동했을때 가로, 세로의 변화량을 보면 세로의 변화량은 큰데 가로의 변화량은 작습니다. 이것을 눈치첸 모멘텀은 가로를 더 많이 가게 조정해서 녹색 선의 세번째  점을 향하게 됩니다. 이런 방법으로 학습하면 훨씬 더 빠르게 최적화를 할 수 있습니다.  

모멘텀의 구현방법은 아래와 같습니다.

물론 이러한 방법은 기본적인 내용이며, 이 밖에도 많은 최적화 방법이 있습니다. 그 중에서 특히, Adam과 RMSProp은 신경망에서 많이 쓰이는 최적화 방법들이 있습니다. 

 

 

 

 

 

아래는 강의 동영상 입니다.

https://www.youtube.com/watch?v=zUazLXZZA2U&list=PLoROMvodv4rMiGQp3WXShtMGgzqpfVfbU&index=13 

 

반응형