58번째 줄: |
58번째 줄: |
| | | |
| == softmax == | | == softmax == |
| + | 원리는 다음 affine 계층에서의 역전파를 참고하자. |
| | | |
| == affine == | | == affine == |
| 딥러닝의 중간 층들에선 행렬 계산이 이루어지는데, 이런 행렬의 곱을 affine변환이라 부른다. 때문에 중간 뉴런들에 대한 층은 어파인층이라 부르고, 이들의 역전파를 통해 어파인층 학습도 가능하다. | | 딥러닝의 중간 층들에선 행렬 계산이 이루어지는데, 이런 행렬의 곱을 affine변환이라 부른다. 때문에 중간 뉴런들에 대한 층은 어파인층이라 부르고, 이들의 역전파를 통해 어파인층 학습도 가능하다. |
| | | |
− | 오차함수에 대하여 각 입력에 대한 편미분은 <math>\frac{\partial E}{\partial X} = \left ( \frac{\partial E}{\partial x_1} , \frac{\partial E}{\partial x_2} , \ldots \right )</math> 형태이다. 핵심은 <math>\frac{\partial E}{\partial X} = \left ( \frac{\partial E}{\partial x_1} , \frac{\partial E}{\partial x_2} , \ldots \right )</math> | + | 오차함수에 대하여 각 입력에 대한 편미분은 <math>\frac{\partial E}{\partial X} = \left ( \frac{\partial E}{\partial x_1} , \frac{\partial E}{\partial x_2} , \ldots \right )</math> 형태이다. 핵심은 <math>\left ( X+\frac{\partial E}{\partial X} \right ) W = \left ( Y + \frac {\partial E}{\partial Y} \right )</math>에서 <math> X W = Y</math>이므로 <math>\frac{\partial E}{\partial X} W = \frac{\partial E}{\partial Y}</math>이런 관계를 갖는다는 말이다. 즉, <math>\frac{\partial E}{\partial X} = \frac{\partial E}{\partial Y} W^T</math> 로 역전파와 가중치의 전치행렬을 통해 다음층으로 보낼 보낼 영향을 구할 수 있으며, 달리 쓰면 <math>\frac{\partial E}{\partial W} = \frac{\partial E}{\partial Y} X^T</math>을 통해 이전층에서 왔던 신호의 전치행렬을 통해 가중치의 영향력을 구할 수 있다. |
| + | |
| + | === 구현 === |
| + | <syntaxhighlight lang="python"> |
| + | class Affine: |
| + | def __init__(self, W, b): # 처음에 만들 때 가중치와 편향값을 부여한다. |
| + | self.W = W |
| + | self.b = b |
| + | self.x = None # 앞 층으로부터 받을 x. 이 값은 저장해뒀다가 W의 미분 때 쓰인다. |
| + | self.dW = None # 가중치의 영향력(미분값)을 담을 것. |
| + | |
| + | def forward(self, x): |
| + | self.x = x |
| + | out = np.dot(x, self.W) + self.b |
| + | return out |
| + | def backward(self, dout): |
| + | dx = np.dot(dout, self.W.T) # x로 전파할 값을 구한다. |
| + | self.dW = np.dot(self.x.T, dout) |
| + | self.db = np.sum(dout, axis=0) # +의 역전파는 그냥 더할 뿐이니, 전파된 값들을 다 더해 하나의 축으로 만든다. |
| + | </syntaxhighlight> |