좋습니다 
지금까지 흥미로운 내용이었죠
이번 강의에서는 경사 하강법을 
구현하는 방법을 알아보겠습니다
한 개의 은닉층을 가진
신경망에 대해서 말이죠
이 강의에서는 여러분이 구현해야 할
식들을 드릴 것입니다
이것은 역전파를 계산하거나
경사 하강법을 
적용하기 위한 식들입니다
그리고 이 부분을 마친 후에는
저는 추가적인 설명을
해드릴 것인데요
이 물리적인 식들이
왜 신경망에서 경사를 계산하는데
있어서 올바른 식인지 말이죠
현재 여러분의 단일층 신경망은
w^[1], b^[1], w^[2], b^[2]의
변수를 가집니다
그리고 기억하시는 것처럼
n_x는  n^[0]를
입력 특성으로 가지고
n^[1]은 은닉 유닛으로 가지며
n^[2]를 출력 유닛으로 가집니다
우리가 사용한 샘플에서는
n^[2]는 1이었습니다
그러면 행렬 w^[1]은
(n^[1], n^[0]) 차원을 가집니다
그리고 b^[1]은 n^[1] 차원을
가지는 벡터가 됩니다
(n^[1], 1) 차원이라고 적을 수 있겠죠
따라서 행 벡터가 될 겁니다
w^[2]은 (n^[2], n^[1]) 차원이 되고
b^[2]는 (n^[2], 1) 차원이 됩니다
이것은 한 개의 은닉 유닛을 가진
n^[2]가 1인 예시를 사용한 경우입니다
그리고 여기에 신경망의
비용 함수가 있습니다
여기서는 여러분이 
이진 분류를 하고 있다고 가정하겠습니다
이 경우에
각 변수들에 대한 비용은
다음과 같이
손실함수의 평균이 됩니다
여기서 L은 신경망이 
예측한 ŷ값에 대한 손실입니다
여기 부분은 실제로는
a^[2]가 되겠죠
y는 참 값을 말합니다
여러분이 이진 분류를 하는 경우에
손실 함수는 로지스틱 회귀에서
사용한 것과 같을 것입니다
이제 이 알고리즘에서 
변수들을 훈련시키기 위해서
경사 하강법을 사용해야 합니다
신경망을 훈련시킬 때
0이 아닌 값으로 
변수를 초기화하는 것이 중요합니다
이것에 대해서는
나중에 이야기하겠습니다
변수를 어떤 값으로 초기화 한 후
경사 하강법이 반복될 때마다 
예측값을 계산합니다
다시 말해서 
ŷ^[i]를 계산하는 것이 됩니다
i는 1부터 m까지의 
정수가 되죠
그리고 이제 도함수를 계산해야 합니다
dw^[1]을 계산하는데
이 값은 변수 w^[i]에 대한
비용 함수의 도함수를 의미합니다
또한 db^[1]을 계산해야 하는데
이 값은 b^[1]에 대한
비용 함수의 도함수가 되는 것이죠
w^[2]와 b^[2]에 대해서도 
비슷하게 도함수를 계산합니다
결국 경사 하강법은
w^[1]을 w^[1] - α dw^[1]으로 바꿉니다
여기서 α는 학습률을 의미합니다
b^[1]은 b^[1] - α db^[1]으로 바꿉니다
w^[2]와 b^[2]에 대해서도
비슷하게 적용됩니다
콜론이 붙은 등호 또는
일반 등호를 사용하는데
두 표기법 모두 괜찮습니다
이제 이것이 경사 하강법의
한 반복이 됩니다
그리고 변수들이 수렴할 때 까지
이것을 반복하게 되는 것이죠
이전 강의에서 어떻게 예측값을 
계산하는지 배웠습니다
또 어떻게 벡터화된 방법으로
출력값을 계산하는지 배웠죠
여기서 중요한 것은 어떻게
이 편미분을 계산하는지 입니다
dw^[1]과 db^[1],
그리고 dw^[2], db^[2]까지 말이죠
이제 제가 하려고 하는 것은
이 도함수를 계산할 수 있도록
몇 가지 식을 드리는 것입니다
그리고 이 식들이 어떻게 나왔는지는
다음 강의에서 설명하는 것으로 하겠습니다
여기에 정방향 전파에 대한 식들을 
다시 정리해보겠습니다
z^[1]은 
w^[1]X + b^[1] 이 됩니다
각 층에서의
활성화 함수인 A[1]은
z^[1]에 대한 함수이므로 
이렇게 됩니다
z^[2]는 
w^[2] A^[1] + b^[2]가 되고
마지막으로
그리고 여기서의 모든 샘플은
벡터화된 상태입니다
A^[2]는 g^[2](z^[2])가 됩니다
여기서는 이진 분류를 하고 있기 때문에
이 활성화 함수는 실제로는
시그모이드 함수가 될 것입니다
여기에 이렇게 적도록 하겠습니다
이것이 정방향 전파에 대한 식입니다
또는 신경망에서 왼쪽에서 오른쪽으로의
진행과정이라고 할 수 있습니다
이제 도함수를 계산해보겠습니다
이것은 역전파 단계에 관한 것이죠
먼저 dz^[2]를 계산하는데
이것은 A^[2]에서 
참 값 Y를 뺀 것과 같습니다
여기선 모두 벡터화된 샘플을
사용하기 때문에
행렬 Y는 (1, m)행렬이 됩니다
m가지의 모든 샘플을 
가로로 나열하는 것이죠
이제 dw^[2]는
이런 형태의 식이 됩니다
이 세 개의 식은 로지스틱 회귀에서의
경사 하강법과 굉장히 비슷합니다
여기서 axis=1이 되고
keemdims는 True가 됩니다
이것에 대해서 
약간 더 설명해드리자면
np.sum은 파이썬 numpy 명령어인데
행렬의 어떤 축 방향으로
덧셈을 계산 할 때 사용합니다
이 경우에는 가로로 더하는 것이죠
keepdims가 하는 역할은
파이썬이 잘못된 1차원 배열을
출력하지 않게 하는 것입니다
여기에서는 (n, )의 
차원을 가지게 됩니다
따라서 keepdims를 True로 설정하면
db^[2] 대한 파이썬의 출력값은
(n, 1) 벡터가 될 것입니다
정확히는 (n^[2], 1)이 되겠죠
그리고 이 경우에는 (1, 1)이 되기 때문에
영향을 미치진 않습니다
하지만 나중에 이것이
중요한 경우가 있습니다
지금까지 로지스틱 회귀와 굉장히
비슷한 것을 했습니다
역전파 계산을 계속
진행해 보겠습니다
이것을 계산하면
w^[2]T dz^[2] * g^[1]'(z^[1])이 됩니다
이 g^[1]'은 은닉층에서 사용했던 
활성화 함수의 도함수입니다
출력층에서는 시그모이드 함수를 이용해
이진 분류를 합니다
dz^[2]는 
이미 앞서 구했습니다
이 곱셈은 요소별 곱셈입니다
이 부분은 (n^[1], m) 행렬이 되고
이 부분 또한
(n^[1], m) 행렬이 됩니다
따라서 이 곱셈은 두 행렬의
요소별 곱셈이 되어야 하는 것이죠
그리고 마지막으로
dw^[1]은 이런 형태가 되고
db^[1]은 이렇게 됩니다
np.sum(dz^[1], axis=1,
keepdims=True)가 되죠
위에서 n^[2]가 1일 때
keepdims는 영향이 없다고 했습니다
단순히 (1, 1) 행렬이기 때문이죠
여기서 db^[1]은 
(n^[1], 1) 벡터가 됩니다
파이썬의 np.sum을 사용한다면
그 출력값도 같은 차원의 벡터가 되겠죠
잘못된 형태의 1차원 배열은
아닐 것입니다
그 1차원 배열은 나중에 계산을
어렵게 만들 수도 있습니다
keepdims 변수를 사용하지 않는
다른 방법은
reshpae 함수를 를 호출하는 것입니다
이것은 np.sum의 출력값을 
다시 재배열해서
db에 맞는 차원으로 만들 수 있습니다
여기까지 정방향 전파에는
 네 개의 식을 사용했고
역전파에는 여섯 개의 식을 사용했습니다
제가 여기서는 식들을
써내려가기만 했지만
다음 강의에서는 이것에 대해서
조금 더 설명하도록 하겠습니다
역전파 알고리즘에서 어떻게 
여섯 개의 식을 유도할 수 있는지 말이죠
이 강의는 보셔도 좋고
그렇지 않아도 좋습니다
굳이 강의를 보지 않더라도
정방향 전파와 역전파 알고리즘을
올바르게 구현할 수 있습니다
그리고 도함수를 
계산하는 것도 가능합니다
신경망의 변수를 학습시키기 위해
경사 하강법을 사용할 때 말이죠
미적분학에 깊은 이해가 없이도
이 알고리즘을 구현할 수 있습니다
이미 많은 성공적인 딥러닝
사용자들이 그렇게 하고 있죠
하지만 다음 강의를 들으신다면
이 식들을 어떻게 유도하는지에 대해
더 이해할 수 있을 겁니다
