5번째 줄: |
5번째 줄: |
| | | |
| 국소 미분을 단순히 축적해가며 아랫쪽으로 역전파 해간다. 이는 미분의 연쇄법칙에 의해 가능한 트릭. | | 국소 미분을 단순히 축적해가며 아랫쪽으로 역전파 해간다. 이는 미분의 연쇄법칙에 의해 가능한 트릭. |
| + | |
| + | = 사용예 = |
| + | 각 층을 클래스로 만들고, 해당 레이어의 전방전파, 후방전파 메서드를 만들어 구현한다. |
| + | |
| + | == Relu == |
| + | <syntaxhighlight lang="python"> |
| + | class Relu: |
| + | def __init__(self): |
| + | self.mask = None # 원소값이 0 이하면 True를 반환해 저장하기 위한 것. |
| + | |
| + | def forward(self, x): # 배열을 받아 진행한다. |
| + | self.mask = (x <=0 ) # x의 배열 중 0 이하를 True 체크해 저장. |
| + | out = x.copy() # 출력값을 저장할 변수. |
| + | out[self.mask] = 0 # True인 인덱스에 0을 넣는다. |
| + | return out |
| + | |
| + | def backward(self, dout): # 미소변위라는 의미에서 d를 붙인 이름. |
| + | # 순전파에서 0이었다면, 역전파에서도 미분값은 0이 되어야 한다. 전달된 게 없으니. |
| + | dout[self.mask] = 0 # 역전파 입력값을 받아 순전파에서 0 이하였던 인덱스에 0을 넣는다. |
| + | return dout |
| + | </syntaxhighlight> |
| + | |
| + | == sigmoid == |
| + | 순전파에서 결과는 <math>y= \frac{1}{1+\exp(-x)}</math> |
| + | |
| + | # x에 -1을 곱하고( <math>y= -x</math> ) |
| + | # exp 처리를 하고 ( <math>y= \exp(x)</math> ) |
| + | # 여기에 1을 더한 후 ( <math>y= x+1</math> ) |
| + | # 분자, 분모를 뒤집는다.( <math>y= \tfrac{1}{x}</math> ) |
| + | |
| + | 역전파에선 다시 거꾸로 |
| + | |
| + | # <math>y= \tfrac{1}{x}</math>의 미분 <math>-\tfrac{1}{x^2} = -y^2</math> 으로 상류에서 흘러온 값을 제곱한 후 마이너스를 씌우고, |
| + | # <math>y= x+1</math>의 미분 1을 곱하고,(여기에서의 y는 1번에서의 최종 y와 다르다.) |
| + | # <math>y= \exp(x)</math>의 미분 <math>\exp(x)</math>을 상류에서 흘러온 값에 처리하여 <math>\exp(x)</math>를 곱하고,(여기에서의 y는 1번에서의 최종 y와 다르다.) |
| + | # <math>y= -x</math>의 미분 -1을 곱한다. |
| + | |
| + | 이들의 결과는 <math>y^2\exp(-x)</math>인데, <math>y= \frac{1}{1+\exp(-x)}</math>이므로 정리하면 <math>y(1-y)</math>가 된다. 즉, 순전파의 출력 y로부터 역전파를 구하게 되었다.<syntaxhighlight lang="python"> |
| + | class Sigmoid: |
| + | def __init__(self): |
| + | self.out = None # 순전파에서 내보낸 값을 저장하기 위함. |
| + | |
| + | def forward(self, x): |
| + | out = 1/ (1+ np.exp(-x)) |
| + | self.out = out # 출력값을 저장해둔다. |
| + | return out |
| + | |
| + | def backward(self, dout): # 미소변위라는 의미에서 d를 붙인 이름. |
| + | dx = dout * (1 - self.out) * self.out |
| + | return dx |
| + | </syntaxhighlight> |
| + | |
| + | == softmax == |
| + | |
| + | == affine == |
| + | 딥러닝의 중간 층들에선 행렬 계산이 이루어지는데, 이런 행렬의 곱을 affine변환이라 부른다. 때문에 중간 뉴런들에 대한 층은 어파인층이라 부르고, 이들의 역전파를 통해 어파인층 학습도 가능하다. |