Deep Learning from Scratch1 - Ch5 활성화함수 계층
2 minute read
ReLU 계층
계산 그래프
- 순전파 때의 입력이 0보다 크면 역전파는 상류의 값을 그대로 하류로 흘려보낸다.
- 순전파 때의 입력이 0 이하면 역전파 때는 신호를 차단한다.
구현
class ReLu:
def __init__(self):
self.mask = None
def forward(self, x):
self.mask = (x<=0)
out = x.copy()
out[self.mask] = 0
return out
def backward(self, dout):
dout[self.mask] = 0
dx = dout
return dx
- self.mask = (x<=0): 하나의 기법으로 넘파이 배열 x의 원소 중 0 이하인 원소의 인덱스에는 True, 그외는 False로 구성된 넘파이 배열을 형성한다.
- x.copy(): 전혀 다른 메모리공간에 값만 같은 배열을 복사한다. out과 x는 완전히 독립적이다.
- out[self.mask] = 0: mask의 원소 중 True에 해당하는 인덱스의 원소를 0으로 초기화한다.
- dout[self.mask] = 0: 순전파때 입력이 0이하인 원소들에 대해서 역전파의 값은 0이 되어야한다. 바로 위 내용과 같은 원리이다.
- dx=dout: 순전파때 입력이 0보다 큰 경우 상류의 값을 그대로 흘려보낸다.
Sigmoid 계층
계산 그래프
- 순전파의 출력 y만으로 역전파를 계산할 수 있다.
구현
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):
dx = dout * self.out * (1.0 - self.out)
return dx
- 인스턴스변수 out은 순전파의 출력값을 기억해두기 위함이다.
Affine 계층
- 신경망의 순전파때 수행하는 행렬의 곱을 기하학에서는 어파인 변환(Affine Transformation)이라고 한다.
계산 그래프
- dot노드의 역전파는 행렬의 대응하는 차원의 원소 수가 일치하도록 곱을 조립하여 구할 수 있다.
- 순전파의 편향 덧셈은 각각의 데이터에 더해진다. 따라서 역전파 때는 각 데이터의 역전파 값이 편향의 원소에 모여야한다.
- 편향(b)의 역전파는 각 데이터에 대한 미분을 데이터마다(열의 방향으로) 더해서 구한다.
구현
class Affine:
def __init__(self, W, b):
self.W = W
self.b = b
self.x = None
self.dW = None
self.db = 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)
self.dW = np.dot(self.x.T, dout)
self.db = np.sum(dout, axis=0)
return dx
Softmax-with-Loss 계층
계산그래프
- 소프트맥스 함수는 입력 값을 정규화하여 출력한다. (출력의 합이 1이 되도록 변형된다.)
- 역전파의 결과를 살펴보면 (Softmax 출력 - 정답 레이블) 이라는 오차를 나타낸다는 것을 알 수 있다.
- 신경망의 역전파에서는 오차가 앞 계층에 전해진다는 의미로 신경망 학습에서 중요한 성질이다.
- 소프트맥스의 손실함수로 “교차엔트로피 오차 함수”를 이용하였기 때문에 이러한 말끔한 결과가 나올 수 있는 것이다.
- 항등함수의 손실함수로 “오차제곱합”을 이용하는 것도 같은 이유때문이다.
class SoftmaxWithLoss:
def __init__(self):
self.loss = None
self.y = None
self.t = None
def forward(self, x, t):
self.t = t
self.y = softmax(x)
self.loss = cross_entropy_error(self.y, self.t)
return self.loss
def backward(self, dout=1):
batch_size = self.t.shape[0]
dx = (self.y - self.t) / batch_size
return dx
- 인스턴스 변수에 손실함수의 결과, 소프트맥스 계층의 출력, 정답레이블을 담는다.
- 역전파 때는 전파하는 값을 배치의 수(batch_size)로 나눠서 데이터 1개당 오차를 앞 계층에 전파한다.
[참고자료]
Leave a comment