5. 심층 신경망 네트워크
📌더 많은 층의 심층 신경망(C1W4L01)
핵심어: 얕은 모델(Shallow Model), 심층 신경망(Deep Neural Network)
지금까지 로지스틱 회귀 분석 뿐만이 아니라, 단일 은닉층을 가진 신경망의 순방향 전파와 역전파를 살펴보았고, 벡터화와 왜 무작위로 가중치를 초기화하는 것이 중요한지도 학습함. 지금까지 배운 내용들을 모두 합쳐 심층 신경망을 구현 가능한 것.

위 슬라이드에 로지스틱 회귀의 예식, 단일 은닉층을 가진 신경망의 예시, 아래에는 두 개의 은닉층과 다섯 개의 은닉층을 가진 신경망의 예시가 있음. 우리는 로지스틱 회귀를 매우 얕은 모델이라고 하는데, 반면 아래쪽 모델들은 더 깊이 있는 모델들임. 얕음과 깊음은 정도의 문제인데, 이 두 개의 층을 가진 신경망은 여전히 얕지만 로지스틱 회귀만큼은 아님. 기술적으로 로지스틱 회귀는 한 층의 신경망인데, 지난 몇 년 동안 기계 학습(ML)의 커뮤니티의 인공지능이 얕은 모델은 보통 할 수 없는 학습을 심층 신경망으로 가능하게 하는 함수가 있다는 것을 깨달았음. 어떤 주어진 문제에서 얼마나 깊은 신경망을 사용해야 하는지 미리 정확하게 예측하는 것은 어렵기 때문에, 로지스틱 회귀를 시도하고 그 다음에 두 개의 은닉층을 시도함. 은닉층의 개수가 또 다른 하이퍼파라미터가 됨. 개발 설정 과정에서 다양한 값을 시도하고 검증 데이터에서 평가함.

이번에는 심층 신경망을 설명하기 위한 표기법을 알아볼 것. 위 1, 2, 3, 4개 층의 신경망이 있고 은닉층은 3개, 각각의 은닉층의 유닛 개수는 5, 5, 3이고 한 개의 출력 유닛이 존재함. 대문자 L을 써서 네트워크의 층의 수를 나타낼 것인데, 이 경우 L은 4가 됨(층의 개수). 그리고 n에 위첨자 l을 사용하여 소문자 l층의 단위의 개수를 나타내도록 함. 예를 들어 n[1]은 첫 번째 레이어에 5개의 은닉층이 있기 때문에 5가 되는 것. 입력층, 즉 n[0]은 n_x와 같고 3임.
또한 각각의 층 l에 대해서 a[l]을 사용하는데, 이는 층 l에서의 활성값을 나타냄. 나중에 보게될 정방향 전파에서 a[l]은 z[l]에 대해 활성화 함수 g를 계산한 값이 됨. 그리고 활성화 함수도 층 l에 의해 순서가 매겨짐.
w[l]의 경우 z[l]의 값을 계산하기 위한 가중치를 나타내거나 비슷하기 z[l]을 계산하기 위해 b[l]이 사용됨.
마지막으로 표시법을 정리하면 입력 특징은 X라고 불림. X는 층 0의 활성화값과 같은데, 따라서 a[0]은 X와 같으며 마지막 층의 활성값인 a[L]은 Y의 예측값과 같고 이것은 신경망의 예측된 출력값과 같음.
<표기법 정리>
- L: 네트워크 층의 수
- n[l]: l층에 있는 유닛 개수
- a[l]: l층에서의 활성값
- a[0]: 입력 특징(X)
- a[L]: 예측된 출력값(yhat)
📌정방향전파와 역방향전파(C1W4L02)
핵심어: 정방향 전파(Forward Propagation), 역방향 전파(Back Propagation)

입력 a[l-1]과 출력a[l], 캐시된 z[l]이 무엇을 하는지 기억해보면,구현의 관점에서 보았을 때 W[l]과 b[l]을 캐시하는 것임. 또한 프로그래밍 예제에서 함수 호출을 더 쉽게 만들어주는데, 해당 등식은 익숙해지는 것이 좋음.
네 번째 함수를 구현하는 방법은 z[l] = W[l]*a[l-1]+b[l] 그리고 a[l]은 z[l]에 활성화 함수를 적용시킨 것과 같음. 만약 벡터화 구현을 원한다면 z[l] = W[l]*A[l]+b[l], 그리고 A[l]은 z[l]에 적용된 g[l]임. 네 번째 단계에 대한 다이어그램(정방향 박스의 체인)을 기억해보면, A[0]을 넣어서 초기화시켰음(A[0] 값은 X와 동일). 여기서 첫 번째 것에 대한 입력값 a[0]은 한 번에 하나씩 할 경우의 학습 데이터에 대한 입력 특성이고, A[0]은 전체 학습 세트를 진행할 때의 입력 특성임. 따라서 체인에서 첫 번째 정방향 함수에 대한 입력값이 되는 것. 그리고 이 과정을 반복하는 것은 왼쪽에서 오른쪽으로 가는 정방향 전파를 계산할 수 있게 함.

다음으로 역전파 단계에 대해 알아보자면, 여기 입력 da[l]과 출력 da[l-1], dW[l], db[l]이 있음. 이것을 계산하기 위한 단계를 작성하자면 다음과 같음.
- dz[l] = da[l]*g[l]'(z[l]) 합성함수의 미분
- dw[l]' = dz[l]*a[l-1] (명시적으로 캐시에 저장하지 않았지만 이것 또한 해줘야 함)
- 따라서 db[l] = dz[l]
- 마지막으로 da[l-1] = w[l]T*dz[l]
da의 정의를 적용시키면 dz[l]을 계산하는 식을 얻을 수 있음.
dz[l] = w[l+1]Tdz[l+1]*g[l]'(z[l]) 이는 지난 번 강의에서 다루었던 역전파 식과 동일함(심층 신경망에서 하나의 은닉층만 사용한 경우) 다만 이번에는 요소별 곱셈이기 때문에, 역함수를 구현하는 데 필요한 것은 dz[l]부터 da[l-1]까지의 네 가지 식임.
슬라이드의 오른쪽 부분에서 왼쪽 부분의 식들에 대한 벡터화를 보여주고 있음.
da[l]의 값을 입력하고, 출력 dW[l], db[l]과 필요한 도함수를 통해 da[l-1]를 계산할 수 있게 됨.

따라서 정리하자면, 입력 X를 받고 ReLU를 활성화 함수로 갖는 첫 번째 층이 있고 두 번째 층에는 또 다른 ReLU 활성화 함수가 있음. 세 번째 층에는 시그모이드 활성화 함수를 사용할 수도 있음(이진 분류의 경우). 이 출력은 y의 예측값, yhat이 되고 이를 통해 손실을 계산할 수 있음.
역으로 반복하는 과정 도함수를 계산하는 역전파를 구현할 수 있음. 그리고 이를 계산하는 과정에서 캐시에서 z[1], z[2], z[3]을 옮김. 이렇게 해서 3개의 층을 가진 심층 신경망에서 정방향 전파와 역전파를 구현할 수 있는 것.
마지막 세부사항은, 정방향 반복은 입력 데이터 X로 초기화하지만 역방향 반복의 경우, da[l]은 로지스틱 회귀에서 이진분류를 할 때 -y/a+(1-y)/(1-a)와 같으므로 출력, 즉 y의 예측값에 대응되는 손실 함수의 도함수는 da의 식과 같다고 보여질 수 있음(미분적분학 공식을 이용하여 손실함수 L을 미분해보면 da의 식을 얻을 수 있음). 따라서 최종 층인 L에 대한 da를 사용해야 하는 것. 그리고 벡터화까지 적용하면 dA[1]으로 m번째 학습 데이터까지 반영함.
📌심층 신경망에서의 정방향 전파(C1W4L03)
핵심어: 심층 신경망(Deep Neural Network), 정방향 전파(Forward propatation)

우선 단일 학습 데이터인 x에 대한 정바향 전파를 살펴보고, 그 후에는 전체 학습 데이터에 대한 정방향 전파를 수행하는 벡터화된 버전을 살펴볼 것.
주어진 단일 학습 데이터 x에 대해 첫 번째 층에 대한 활성화를 계산하는 방법인데, X: z[1] = w[1]*x + b[1]과 같음.
w[1]과 b[1]은 층 1에서 활성화에 영향을 주는 파라미터들. 그리고 해당 층에 대한 활성화 함수는 g(z[1])와 같으(활성화 함수는 층마다 상이) 따라서 층 1에 대한 활성화 함수를 계산하는 것.
마찬가지로 층 2에서는 z[2] = w[2]*a[1] + b[2]이 되며 따라서 츠2의 활성화는 가중치 행렬에 층 1의 출력(a[1])을 곱한 것에 층 2의 편향 벡터를 더한 값.그럼 a[2]는 z[2]에 활성화 함수를 적용한 값이 됨. 이것이 층 2에 대한 계산으로, 이런 식으로 출력 층인 층 4에 이를 때까지 계속함. z[4]는 해당 층의 파라미터에 이전 층의 활성화를 곱한 것에 편향 벡터를 더해준 것이 되고, 비슷하게 a[4]는 g[4](z[4])와 같음. 이것이 추정된 y의 예측값을 계산하는 방법이 됨.
여기서 x는 a[0]와 같은데, 입력 요인 벡터 x는 층 0의 활성화이기 때문임. 따라서 z[1] 식에서 x를 지우고 a[0]를 넣으면 기본적으로 모든 수식들이 동일한 모양을 가지게 됨. 일반적인 규칙은 z[l] = w[l]*a[l-1] + b[l], a[l] = g[l](z[l]). 이것이 일반적인 정방향 전파 수식이 됨. 이제까지 단일 학습 데이터에 대해 알아보았고, 전체 학습 세트에 대한 벡터화된 방법을 알아볼 것.
수식은 첫 번째 층에 대해 전과 비슷한 방식으로 작성하 Z[1] = w[1]*X + b[1], A[1] = g[1](Z[1])이 됨. X 대신 A[0]를 넣을 수 있음. 다음 층에 대해서도 마찬가지로 Z[2] = w[2]*A[1] + b[2], A[2] = g[2](Z[2])이 됨. z와 a 벡터의 값을 얻어 쌓은 것과 같으며, 예를 들어 z[1](1)는 첫 번째 학습 데이터에 대한 z벡터이고, z[2](2)는 두 번째 학습 데이터에 대한 z벡터가 됨. 이런 식으로 m번째 학습 데이터까지 계산하고 이들을 열에 저장해서 Z라고 함. A도 비슷한 과정으로 계산하며, X처럼 모든 학습 데이터는 왼쪽에서 오른쪽으로 저장된 열 벡터의 형태. 이 과정은 Y의 예측값인 g(Z[4]), 즉 A[4]로 끝나며 이는 수평으로 저장된 모든 학습 데이터에 대한 예측값이 됨. 이를 통해 정방향 전파의 벡터화된 버전으로 바꿀 수 있으며, A[0]가 X인 전체 학습 데이터셋에 대해 한 번에 수행할 수 있는 것.
벡터화 구현을 살펴보면 여기에 반복문을 사용할 수 있는데, for i = 1부터 4까지, 1에서 L까지의 i에 대해 각각의 층에 대한 활성화를 계산해야 함. 네트워크를 구현할 때는 명시적인 반복문은 보통 피하고 싶어하는데, 그러나 명시적 반복문 외에 이 부분을 구현할 수 있는 다른 방법이 존재하지 않음. 따라서 정방향 전파를 구현할 때 층 1, 2, 3, 4 각각에 대한 활성화를 계산하는 반복문을 사용하는 것은 괜찮은 방법이라고 할 수 있음.
📌행렬의 차원을 알맞게 만들기(C1W4L04)
핵심어: 행렬(Matrix), 차원(Dimensions)

예를 들어 어떤 심층 신경망에서 L은 5, 즉 입력층 제외 5개의 층이 있을 때 4개의 은닉층과 1개의 출력층이 존재함.
여기서 정방향 전파를 구현하는 첫 번째 단계는 z[1] =w[1]*X + b가 됨. 지금 편향 값 b[1]은 무시하고 w[1]에 집중하자면, 이 첫 번째 은닉층은 3개의 히든 유닛이 존재함. 이전 강의의 표기법을 사용하면 n[1], 즉 층 1의 히든 유닛의 개수는 3과 같음. 같은 방식으로 n[2]=5, n[3]=4, n[4]=2, n[5]=1이 됨. 입력층의 경우 n[0]은 n_x와 같고 이 값은 2가 됨.
이제 z, W, x의 차원을 생각하면, z는 이 첫 번째 은닉층에 대한 활성화 벡터로 (3, 1) 행렬 즉 3차원 벡터가 됨. 따라서 (n[1], 1)차원 벡터가 되는 것(n[1]=3). 입력 특성 x의 경우, x에는 두 가지 입력 특성이 있어서 이 경우 (2,1) 행렬이 됨. 더 일반적으로 (n[0], 1)이 됨. 따라서 행렬 W[1]은 (n[0], 1) 벡터를 곱했을 때 (n[1], 1)벡터가 나오도록 하는 값이어야 함. 행렬 곱의 규칙에 따라, 이는 (3, 2) 행렬이 되어야 하며 이는 (n[1], n[0]) 차원의 행렬이라고도 할 수 있음. 다시 말해 W[1]의 차원은 (n[1], n[0])이 되는 것. 더 일반화시키자면 W[l]의 차원은 (n[l], n[l-1])이 되는 것. 예를 들어 W[2]의 차원은 (5, 3), 즉 (n[2], n[1])이 되는 것. 왜냐하면 z[2] = W[2]*a[1] + b[1]을 계산할 때 a[1]은 (3,1) 행렬이고, z[2]는 (5,1)행렬이므로 W[2]는 (5,3)이 되는 것. 마찬가지로 W[3]은 해당 층의 차원과 그 전 층의 차원이므로 (4, 5)가 됨. W[4]는 (2, 4)가 되며 W[5]는 (1, 2)가 되는 것. 따라서 층 l에 대한 행렬의 일반적인 수식을 보면 해당 행렬의 차원은 (n[l], n[l-1])이 됨.
한편 지금까지 주목하지 않았던 벡터 b의 차원을 생각해보면, W[1]*x가 (3, 1)벡터이기 때문에 출력값으로 (3, 1)벡터를 얻기 위해서는 또 다른 (3, 1) 벡터를 더해줘야 함. 따라서 b[1]은 (3, 1) 벡터가 되어야 함. 더 일반적으로보자면 b[1]은 (n[1], 1) 이 되고, 비슷한 방식으로 b[2]는 (n[2], 1) 즉 (5, 1)차원이 됨. 즉 b[l] 은 (n[l], 1) 차원이라고 할 수 있음.
위 수식들을 이용해 W와 b 벡터가 올바른 차원을 가지는지 이중으로 확인할 필요가 있음. 그리고 역전파를 구현하는 경우에 dw[l]의 차원은 W[l]의 차원과 같아야 하며 db[l]은 b[l]과 같은 차원을 가져야 함. 차원 확인이 필요한 또 다른 중요한 값들은 z, x, 그리고 a[l]임. z[l]은 g[l](a[l])과 같기 때문에 네트워크 상 z와 a의 차원은 같아야 함.

이제 동시에 여러 개의 데이터를 보는 벡터화된 구현에서는 어떨지 볼 것. 벡터화된 구현에서도 당연히 W, b, dW, db의 차원은 같음. 그러나 z, a, x의 차원은 조금 달라짐.
따라서 이전에 z[1] = W[1]*x + b[1]과 같다고 이야기하고 z[1]은 (n[1], 1), W[1]은 (n[1], n[0]), x는 (n[0], 1), b[1]는 (n[1], 1)이 됨. 벡터화된 구현에서는 Z[1] = W[1]*X + b[1]이 되는데, 여기서 Z[1]은 개별적인 데이터에서 얻게 되는 것(z[1](1), z[1](2)에서 z[1](m)까지)이며 값들을 저장함. 따라서 Z[1]의 차원은 (n[1], 1) 대신 (n[1], m)이 됨(m은 훈련 샘플의 크기). W[1]의 차원은 그대로(n[1], n[0])이고, X는 (n[0], 1)이 아니라 모든 학습 데이터가 수평으로 저장되어 (n[0], m)이 됨. 따라서 (n[1], n[0]) 행렬을 (n[0], m) 행렬에 곱하면 예상했던대로 (n[1], m) 행렬이 나오게 됨. 마지막으로 b[1]은 여전히 (n[1], 1)임. 그러나 이것은 b에 더한다면 파이썬 브로드캐스팅을 통해 이것은 (n[1], m) 행렬이 되고 원소별로 더해짐.
정리하자면 앞서 다룬 z[l], a[l]의 경우 (n[l], 1)의 차원이 되는 한편 Z[l], A[l]의 경우 (n[l], m) 차원이 됨. 단 l = 0인 특별한 경우에서, 즉 A[0]가 훈련 집합의 입력 특성 X와 같을 때 차원은 (n[0], m)임. 이를 역전파에서 구현할 때는 dZ[l]과 dA[l]도 계산하게 되는데, 이들 역시 Z, A와 같은 차원을 가짐. 심층 신경망의 역전파를 구현할 때 코드를 전체적으로 읽어보면서 모든 행렬의 차원이 일치하는지 확인하는 것이 중요함. 심층신경망을 구현할 때 다양한 행렬과 벡터의 차원을 잘 알면 발생 가능한 일부 버그를 삭제하는 데 도움이 될 것.
📌왜 심층 신경망이 더 많은 특징을 잡아 낼 수 있을까요?(C1W4L05)
핵심어: 심층 신경망(Deep Neural Network)
우리는 심층 신경망이 많은 문제를 해결하는 데 도움이 된다고 알고 있으며, 단지 규모가 큰 신경망이 아니라 깊거나 많은 은닉층을 보유하는 것이 중요함. 몇 가지 예제를 통해 깊은 신경망이 잘 작동하는 이유에 대한 직관을 학습할 것.

심층망 계산이란, 얼굴 인식이나 감지 같은 시스템을 구축할 때 심층 신경망이 할 수 있는 일들을 뜻함. 얼굴 사진을 입력값으로 넣으면 심층 신경망의 첫 번째 층은 특성 탐지기나 모서리 탐지기가 될 수 있음. 위 예시에서 약 20개의 은닉층이 이 이미지를 어떻게 계산하는지 살펴볼 것. 여기서 약 20개의 은닉층은 작은 네모 상자로 시각화되는데, 예를 들어 가장 왼쪽 위 모서리의 칸은 해당 방향에서의 모서리를 알아내는 은닉 유닛을 나타냄. 그리고 맨 아랫 줄 유닛은 이 이미지에서 수평 방향의 모서리가 어디에 있는지 알아내는 것. 간단히 말하자면 신경망의 첫 번째 층에서 하는 것은 사진을 보고 모서리가 어디에 있는지 파악하는 것.
이제 모서리를 형성하기 위해 픽셀을 그룹화함으로써 사진에서 모서리가 어디에 있는지 알아볼 것. 그럼 감지된 모서리와 그룹화된 모서리를 받아서 얼굴의 일부를 형성할 수 있게 됨. 예를 들어 어떤 뉴런에서는 눈을, 다른 뉴런에서는 코의 일부를 찾을 수 있음. 따라서 많은 모서리를 한데 모아서 얼굴의 일부를 감지할 수 있게 되며, 이런 방식으로 서로 다른 얼굴의 일부를 최종적으로 모아서 서로 다른 종류의 얼굴을 감지할 수 있는 것. 직관적으로 생각하면 신경망의 초기 층에서는 모서리와 같은 간단한 함수를 감지하게 되고, 그 이후이 신경망의 층에서 이것들을 구성하여 더 복잡한 함수를 학습할 수 있도록 하는 것. 이 시각화의 기술적인 세부 사항을 설명하자면, 모서리 탐지기는 이미지에서 상대적으로 작은 영역을 보며 얼굴 탐지기는 이미지의 더 넓은 영역을 볼 수 있음. 그러나 중요한 것은 모서리처럼 간단한 것을 찾고 이를 모아 더 복잡한 것을 찾고 그것을 또 모아서 더 복잡한 것을 찾는다는 것.
이처럼 간단한 것에서 복잡한 것으로의 계층 표현 혹은 구성 표현은 얼굴 뿐만이 아니라 다른 데이터에서도 적용됨. 예를 들어 음성 인식 시스템을 구축하는 경우 음성을 어떻게 시각화할 것인가에 관한 것인데, 음성을 입력으로 줄 때 신경망의 첫 번째 층은 낮은 단계의 음성 파형 특징을 탐지함. 낮은 단계의 파형을 구성하는 것은 소리의 기본 단위 탐지를 학습하는 과정이라고 할 수 있으며 이는 언어학적으로 '음소'라고 부름(cat의 경우 c, a, t,가 각각 음소). 소리의 기본 단위를 찾는 것을 학습하고 그것을 다같이 구성해서 음성의 단어를 인식하는 데 학습하기도 하고, 단어를 구성해서 구나 문장을 인식하기도 함. 따라서 여러 개의 은닉층을 갖는 심층 신경망은 낮은 단계에서는 간단한 특징을 학습하게 되고 그 후 깊은 층에서는 탐지된 간단한 것들을 함께 모아 단어, 구, 문장같은 더 복잡한 것들을 탐지하게 됨. 이를 통해 음성 인식을 수행할 수 있는 것. 초기의 층에서 계산되는 것은 상대적으로 간단한 함수로 보여지지만, 네트워크가 더 깊어질수록 놀라울만큼 복잡한 수행이 가능해짐. 이는 마치 사람의 뇌는 모서리같은 눈에 보이는 간단한 것부터 감지하고 이를 모아 얼굴과 같은 더 복잡한 정보를 인식하는 것과 비슷하다고 볼 수 있음.

심층 신경망이 잘 작동하는 또 다른 직관은 다음과 같음. 이 결과는 회로 이론에서 나왔는데, 회로 이론은 로직 게이트의 서로 다른 게이트에서 어떤 종류의 함수를 계산할 수 있을지에 관한 것. 상대적으로 작지만 깊은 심층 신경망에서 계산할 수 있는 함수가 있는데, 작다는 것은 은닉층의 개수가 상대적으로 작다는 것을 의미함. 그러나 얕은 네트워크로 같은 함수를 계산하려고 하면, 즉 충분한 은닉층이 없다면 기하급수적으로 많은 은닉 유닛이 계산에 필요하게 될 것.
그림을 통해 하나의 예시를 살펴보자면, 모든 입력 특성에 대해 배타적 논리합 혹은 패리티를 계산한다고 가정(x1부터 xn까지). XOR 트리를 그려보면, x1과 x2, x3와 x4의 XOR을 계산하면 기술적으로 and, or, not 게이트만 사용한다면 몇 개의 층이 필요하게 될 것. 그러나 상대적으로 작은 회로에서 XOR을 계산할 수 있고 이를 바탕으로 XOR 트리를 만들 수 있게 됨. 그리고 결국에는 출력으로 이 y에 해당하는 값을 얻게 됨. y의 예측값은 y와 같고 모든 입력 비트의 배타적 논리합 또는 패리티임. 따라서 네트워크의 깊이를 계산하면 O(logn)이 됨. 따라서 노드의 개수는 네트워크의 게이트 수와 같음. 네트워크가 크지 않기 때문에, 배타적 논리합을 계산하기 위해 그렇게 많은 게이트가 필요하지 않음.
한편 만약 여러 개의 은닉층이 있는 네트워크를 만드는 것이 불가능하여 하나의 은닉층으로 함수를 계산하도록 강제한다면 이 모든 x는 어떤 은닉유닛으로 가게 되고 y가 출력됨. 그럼 XOR의 함수를 계산하기 위해 이 은닉층은 기하급수적으로 커져야 하는데, 그 이유는 근본적으로 2^n의 가능한 구성을 모두 철저하게 열거해야 할 필요가 있기 때문. 1 또는 0으로 배타적 논리합이 나오는 입력 비트의 가능한 조합임. 따라서 비트의 수에 따라 기하급수적으로 큰 은닉층이 필요해짐. 정확하게는 2^(n-1)의 은닉 유닛이 필요할 것. 그러나 이것도 O(2^n)이 되기 때문에, 비트 개수에 따라 기하급수적으로 커지게 되는 것. 따라서 얕은 네트워크보다 깊은 네트워크에서 더 계산하기 쉬운 수학적인 함수가 있다고 생각할 수 있음.
🔎배타적 논리합
X, Y가 0또는 1인 값을 가질 때 X와 Y의 배타적 논리합을 X⊕Y로 표시할 수 있음. 기본적으로 배타적 논리합은 1의 개수가 홀수개일 때 1의 값을 가짐. 예를 들어
- X가 0이고 Y가 0일 때 X⊕Y는 0
- X가 1이고 Y가 1일 때 X⊕Y는 0
- X가 1이고 Y가 0인 경우, X가 0이고 Y가 1인 경우에서 X⊕Y는 1
즉 변수 중에 1의 값을 가지는 개수가 홀수개라면 X⊕Y는 1의 값을 가지게 되는 것
(출처: https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=wari7i7&logNo=220820151116)
📌심층 신경망 네트워크 구성하기(C1W4L06)
핵심어: 심층 신경망(Deep Neural Network), 정방향 함수(Forward Function), 역방향 함수(Backward Function)
지금까지 심층 신경망을 구현하는 데 중요한 요소로 작용하는 정방향 전파와 역방향 전파의 기본적인 구성 요소들을 살펴보았는데, 이제 깊은 망을 만들기 위해 이 요소들을 어떻게 이용할지 알아볼 것.

예를 들어 적은 수의 층을 가진 네트워크가 있으면, 하나의 층을 골라서 그 층에 집중하여 계산을 해봄. 층 L에 대해 매개변수 W[l], b[l]이 있고, 정방향 전파에 대해서는 입력으로 이전 층의 활성값인 a[l-1]을 주게 되며 이 경우 출력은 a[l]임.
z[l] = W[l]*a[l-1] + b[l]과 같은데, 그럼 a[l]=g[l](z[l])이 됨. 이것이 입력 a[l-1]에서 출력 a[l]을 얻어내는 방법이 됨. 나중에 사용할 경우를 대비해 z[l]의 값을 저장하는 것이 유용함. z[l]의 값을 저장하면 역전파의 단계에서 사용 가능함.
한편 역전파의 단계에서 다시 층 L에 대한 계산을 살펴보면, 함수를 구현하게 되는데 입력으로 da[l]을 받고 출력으로 da[l-1]이 나옴. 입력 da[l]에서 저장해 놓은 z[l]을 사용하며 da[l-1]과 경사 하강법 학습을 위한 그래디언트(dw[l], db[l])을 출력함. 따라서 이것이 정방향과 역방향 단계를 구현하기 위한 기본 구조가 되며 이는 정방향 함수와 역방향 함수라고도 불림.
요약하자면 층 l에서 정방향 단계(혹은 함수)가 있는데 입력으로 a[l-1]가 들어가면 출력으로 a[l]이 나오며 계산을 위해 W[l]과 b[l]을 사용해야 함. 또한 z[l[이 포함된 캐시도 출력됨. 반면 역방향 단계(혹은 함수)에서는 입력으로 da[l]을 넣으면 출력으로 da[l-1]이 나옴. 따라서 이 활성에 대한 도함수 da[l]을 주면 이전 층의 활성에 대한 도함수를 계산함. 계산에는 W[l]과 b[l]이 활용되며 계산 과정에 따라 dz[l]도 얻음. 그리고 이 역방향 함수는 dW[l]과 db[l]을 출력함.
이 두 함수를 구현할 수 있다면 신경망의 기본 계산은 다음과 같을 것.

입력 특성 a[0]을 가져와서 집어넣으면, 이것이 첫 번째 층의 활성을 계산할 것이며 이는 a[1]이라 부름. 그리고 이것을 위해 W[1]과 b[1]이 필요함. 또한 z[1]을 캐시에 저장하며, 이 과정이 완료되면 이 값을 두 번째 층에 집어넣고 W[2]와 b[2]를 사용해서 다음 층의 활성인 a[2]를 계산하게 됨. 이 과정을 반복하고 최종적으로, a[l]을 출력하게 됨. 이 값은 y의 예측값과 같음. 이 과정에서 모든 층의 z값을 캐시에 저장함. 이것이 전방향 전파임.
역전파 단계에서 이루어지는 것은 이 반복을 역순으로 하는 것. 역방향으로 가면서 경사를 계산하는데, da[l]을 입력하면 da[l-1]이 나오고, 이런 식으로 da[2], da[1] (+ 입력 특성에 대응하는 도함수 da[0]을 얻을 수 있지만 최소한 지도 신경망의 가중치를 학습하는 데에는 유용하지 않으므로 앞에서 멈춤)을 얻을 수 있음. 역전파 과정에서 dW[l]과 db[l]을 출력하며, 마찬가지로 dW[3], db[3]을 출력하고 이 과정을 반복함. 따라서 필요한 도함수는 모두 계산하게 됨. 이 박스 역시 이 매개변수들을 사용함. 그리고 나중에 살펴볼 dz[l]도 박스 안에서 계산하게 됨. 따라서 신경망의 하나의 학습 반복은 x값인 a[0]으로 시작해서 정방향 전파를 따라 y의 예측값을 계산하고, 이 값으로 da[l]을 계산하여 역전파를 거쳐 모든 도함수를 얻게 됨. 따라서 W[l]의 값은 학습률을 곱해 W[l]- αdW[l]로 업데이트됨. 이는 각각의 층에 대한 값임. b에 대해서도 마찬가지로 역전파 계산을 통해 이 모든 도함수 값을 알 수 있으며, 이렇게 신경망에 대한 경사 하강법의 하나의 반복이 이루어짐.
구현에 대한 한 가지 세부 사항을 설명하자면, 개념적으로 여기 있는 캐시를 역방향 함수에 대한 z값을 저장하는 곳이라고 생각하는 것이 유용함. 그러나 프로그래밍 예제에서 이것을 실제로 구현할 때 캐시가 매개변수 W[1]과 b[1]의 값을 얻어 역방향 함수에 넣기에 편리한 방법이라는 것을 알게 될 것. 따라서 프로그래밍 예제에서 실제로 z[1] 뿐만 아니라 W[1]과 b[1]도 캐시에 저장하게 되며, 구현의 관점에서 이 매개변수들의 값을 저장하고 나중에 있을 역전파의 계산에서 필요한 곳에 복사해 사용하는 것이 유용함. 다시 말해 캐시는 한 곳(정방향 전파)에서 다른 곳(역방향 전파)으로 정보를 전달하는 역할을 함.
📌변수 vs 하이퍼파라미터(C1W4L7)
핵심어: 변수(Parameter), 하이퍼파라미터(Hyperparameters)

효과적으로 심층 신경망을 발전시키기 위해서는 매개변수 뿐만 아니라 하이퍼파라미터도 잘 구성해야 함.
여기서 모델의 하이퍼파라미터는 W와 b이며, 학습 알고리즘에 알려줘야 할 다른 요소들도 있음. 이를테면 학습률 α( α를 설정해야 매개변수가 어떻게 진전될지 결정됨)나 수행하는 경사 하강법의 반복의 횟수도 하이퍼파라미터가 될 수 있음. 학습 알고리즘에서 설정해야 할 다른 수들도 있는데, 예를 들어 은닉층의 개수(L), 또는 은닉 유닛의 개수(n[1], n[2] 등), 또한 활성화 함수의 선택(특히 은닉층의 함수, ReLU, TANH, Sigmoid 등)도 있음. 따라서 이 모든 것은 학습 알고리즘에 알려줘야 하는 것들임. 이 매개변수들은 궁극적으로 매개변수 W와 b를 통제하며 이들 또한 하이퍼파라미터라고 부르는데, 그 이유는 학습률, 반복의 횟수, 은닉층의 수 등은 W와 b를 통제하는 매개변수이기 때문. 이 외에도 딥러닝은 매우 다양한 하이퍼파라미터를 가지고 있음(모멘텀 항, 미니배치 크기, 다양한 형태의 정규화 매개변수 등).
초기 머신러닝의 시대와 반대로 딥러닝은 아주 많은 하이퍼파라미터를 가지고 있는데, 학습률 α를 매개변수가 아닌 하이퍼파라미터라고 부름. 이렇게 많은 하이퍼파라미터가 없었던 머신러닝의 초기 시대에는 대부분의 사람들이 α를 매개변수라 불렀고 기술적으로 α는 매개변수가 맞긴 함. 그러나 정확히는 진짜 매개변수를 결정하는 매개변수라고 할 수 있음. 따라서 α, 반복의 횟수 등을 하이퍼파라미터라고 부름. 애플리케이션에 맞게 심층망을 학습시킬 때, 시도할 필요가 있는 하이퍼파라미터에 가능한 설정들이 많다는 것을 알게 될 것.

오늘날 딥러닝을 적용하는 것은 매우 경험적인 과정인데, 예를 들어 학습률에 가장 적합한 아이디어가 있을 때 α를 0.01로 두고 시도해볼 수 있으며, 이것을 구현하고 시도해서 결과에 기반해 어떻게 작동하는지 보면 마음을 바꿔 학습률을 0.05로 바꿀 수도 있음. 어떤 값의 학습률을 사용해야 할지 확실하지 않다면, 학습률 α에 하나의 값을 넣어보고 비용함수 J가 하향하는 것을 확인 후 학습률 α에 더 큰 값을 시도해보고 비용함수가 올라가서 발산되는 것을 확인함. 만약 다른 버전을 시도했을 때 비용 함수 J가 매우 급격히 내려가면 또 다른 버전을 시도해서 비용 함수 J를 확인. 이렇게 값을 설정하는 시도를 한 뒤 이 α값이 학습을 꽤 빠르게 하고 더 낮은 비용 함수 J로 수렴한다는 것을 알 수 있으며 이 때의 α값을 사용할 수 있다고 판단 가능함.
지금까지 본 것처럼 다양한 하이퍼파라미터가 존재하는데, 새로운 애플리케이션을 시작할 때 하이퍼파라미터의 가장 적합한 값을 정확히 미리 아는 것은 매우 어려움. 따라서 자주 사용하는 방법은 다양한 값을 시도하고 이 사이클을 따라서 몇 가지 값들을 시도하는데, 예를 들어 은닉층 수를 5개로 설정하고 이를 구현, 작동 및 확인하며 이 과정을 반복함. 해당 슬라이드의 제목은 '딥러닝을 적용하는 것은 매우 경험적인 과정이다'인데, 경험적인 과정이라는 것은 많은 것을 시도하고 작동되는지 확인한다는 뜻.
또 다른 효과는 오늘날의 딥러닝은 컴퓨터 비전부터 음성 인식, 자연어 처리까지 아주 다양한 범위의 문제에 적용된다는 것. 특히 구조화된 데이터 애플리케이션에 많이 적용되는데, 온라인 광고, 웹 검색, 혹은 제품 추천 등이 그 예시임. 또한 어떤 전공의 연구원이든 서로 다른 것을 시도하면 어떤 경우에는 하이퍼파라미터에 대한 직관을 계속 이어가고, 어떤 경우는 그렇지 않음. 따라서 특히 새로운 문제를 다루기 시작한 경우, 범위별 값을 넣어보고 작동 결과가 어떠한지 확인하라는 것임. 한편 오랫동안 하나의 애플리케이션에서 작업하고 있는 경우(예를 들어 온라인 광고)에도 문제에 대한 진전은 계속됨. 학습률과 은닉 유닛 개수 등에 관한 가장 적합한 값도 바뀔 가능성이 크며, 하이퍼파라미터의 가장 적합한 값으로 시스템을 설정해 놓았어도, 지금으로부터 1년 뒤에 그 값이 바뀔 수 있다는 의미임. 이는 CPU나 GPU의 종류같은 컴퓨팅 기반 시설이 바뀔 수 있기 때문. 따라서 하나의 문제에 대해 장시간, 즉 몇 년에서 몇 달마다 하이퍼파라미터에 몇 가지 값을 시도하고 더 좋은 값이 있는지 이중으로 확인하는 것이 중요. 이 과정을 거치면 문제에 가장 적합한 하이퍼파라미터를 찾는 직관을 천천히 얻게 될 것이며, 어떤 하이퍼파라미터에 대해 모든 값을 시도해봐야 한다는 것이 딥러닝의 만족스럽지 못한 부분이 될 수 있지만 이것도 한 시대일 뿐, 딥러닝 연구는 계속 발전하고 있고 시간이 흐르면서 가장 적합한 하이퍼파라미터를 찾는데 더 나은 지침을 줄 수 있을 것. 그러나 CPU, GPU, 네트워크, 데이터가 모두 바뀌고 있기 때문에 해당 지침이 적용되지 않는 경우가 존재할 수 있으며 그런 경우에는 다양한 값을 시도하고 평가하고 이를 바탕으로 해당 문제에 작동하는 값을 선택해야 함.
📌인간의 뇌와 어떤 연관이 있을까요?(C1W4L8)
핵심어: 뉴런(Neuron)

딥러닝을 구현할 때 정방향 전파와 역전파를 하게 됨. 매우 복잡한 함수의 경사 하강법인 이 수식들이 무엇을 하는지에 대한 직관을 전달하기가 어렵기 때문에, 인간의 뇌에 대한 비유는 이 수식이 하는 일에 대해 지나치게 단순확시킨 설명임. 그러나 이 단순성은 사람들이 공식적으로 말하거나 매체에 알릴 때에 대중의 이목을 집중시킬 수 있음.
아주 느슨한 비유를 해보자면, 시그모이드 활성화 함수를 가지는 로지스틱 회귀 유닛이 있다고 가정하고, 그 옆에 뇌에 있는 하나의 뉴런 그림을 같이 보면 뇌의 신경세포인 이 뉴런은 다른 뉴런으로부터 전기적 신호를 받음(왼쪽에서 x1, x2, x3를 다른 뉴런의 a1, a2, a3로 전달하는 것처럼). 이 간단한 패치가 있는 계산을 하고 이 뉴런이 발사되면 전기 신호를 다시 보내면 긴 선인 축색돌기를 통해 다른 뉴런으로 가게 됨. 이렇게 하나의 뉴런과 단일 로지스틱 유닛 사이에는 간단한 비유를 들 수 있음. 그리고 신경망과 오른쪽에 보이는 생물학적 뉴런 사이에도 간단한 비유가 존재함. 그러나 오늘날의 신경 과학자들조차도 하나의 뉴런이 무엇을 하는지는 거의 모르며 우리가 신경과학에서 특징짓는 것보다 하나의 뉴런은 훨씬 더 복잡함. 뉴런이 하는 일 중 일부는 로지스틱 회귀와 비슷한 면이 있지만, 현재 인간의 이해력으로는 하나의 뉴런이 하는 일도 다 파악하기 어려움. 예를 들어 인간의 뇌가 학습하는 데 뉴런의 역할은 아주 불가사의한 과정임. 그리고 인간의 뇌가 역전파나 경사 하강법 등의 알고리즘을 사용하는지도 완전히 불분명함. 즉 인간의 뇌가 사용하는 학습 원리는 근본적으로 다를 수 있다는 것. 딥러닝에 대해, 지도 학습에서 X-Y 매핑, 즉 입력과 출력의 매핑을 학습하는 것처럼 매우 유연하고 복잡한 함수를 학습하기에 좋다고 볼 수 있음. 여기서 뇌에 비유할 수 있는 부분이 있긴 하지만, 딥러닝 분야와 뇌의 비유는 점점 무너져가고 있음.
'Project > DL 스터디&프로젝트' 카테고리의 다른 글
| [Euron 중급 세션 8주차] 딥러닝 2단계 2. 신경망 네트워크의 정규화 (1) | 2023.10.30 |
|---|---|
| [Euron 중급 세션 5주차] 딥러닝 2단계 1. 머신러닝 어플리케이션 설정하기 (0) | 2023.10.09 |
| [Euron 중급 세션 3주차] 4. 얕은 신경망 네트워크 (0) | 2023.09.25 |
| [Euron 중급 세션 2주차] 3. 파이썬과 벡터화 (0) | 2023.09.18 |
| [Euron 중급 세션 1주차] 2. 신경망과 로지스틱 회귀 (1) | 2023.09.11 |