밑바닥부터 시작하는 딥러닝3 - STEP 14

2021. 3. 15. 18:01개인 공부 공간/딥러닝

같은 변수 중복 사용 시 문제 발생

14-1.PNG

기존의 코드는 같은 변수를 반복해서 사용할 경우 의도대로 동작하지 않을 수 있도대로 동작하지 않을 수 있다는 문제가 있다.

 

x = Variable(np.array(3.0))
y = add(x, x)
print('y', y.data) # 예상되는 값: 6.0

y.backward()
print('x.grad', x.grad) # 예상되는 값: 2.0

 

실행 결과

y 6.0
x.grad 1.0

 

y = x+x일 때 y = 2x 이니 미분값은 2.0 이여야 하지만 1.0 이라는 잘못된 결과가 출력되었다.

문제의 원인 & 해결책

기존에 만든 Variable 클래스 내부의 backward 메서드를 수정해야 한다.

 

class Variable:
  ....

  def backward(self):
    if self.grad is None:
      self.grad = np.ones_like(self.data)

    funcs = [self.creator]
    while funcs: # 빈 리스트가 아닐때까지
      f = funcs.pop() # 함수를 가져온다
      gys = [output.grad for output in f.outputs] # 출력 변수인 outputs에 담겨 있는 미분값들을 리스트에 담는다.
      gxs = f.backward(*gys) # 함수 f의 역전파를 호출한다.
      if not isinstance(gxs, tuple): # gxs가 튜플이 아니라면 튜플로 변환한다.
        gxs = (gxs,)

      for x, gx in zip(f.inputs, gxs): # 역전파라 전파되는 미분값을 Variable의 인스턴스 변수 grad에 저장한다.
        if x.grad is None:
          x.grad = gx
        else:
          x.grad = x.grad + gx

        if x.creator is not None:
          funcs.append(x.creator)

 

미분값(grad)을 처음 설정하는 경우에는 기존과 동일하게 출력 쪽에서 전해지는 미분값을 그대로 대입하고, 다음부터는 전달된 미분값을 더해주도록 수정한다.

 

x = Variable(np.array(3.0))
y = add(x, x)
y.backward()
print('x.grad', x.grad) # 예상되는 값: 2.0

 

실행 결과

x.grad 2.0

 

미분값 재설정

위와 같이 코드를 변경하면 같은 변수를 사용하여 다른 계산을 할 경우 계산이 꼬이는 문제가 발생한다.

 

# 첫 번째 계산
x = Variable(np.array(3.0))
y = add(x, x)
y.backward()
print(x.grad) # 예상되는 값: 2.0

# 두 번째 계산
y = add(add(x, x), x)
y.backward()
print(x.grad) # 예상되는 값: 3.0

 

실행 결과

2.0
5.0

 

이를 해결하기 위해 코드내에 미분값을 초기화하는 과정이 필요하다.

 

class Variable:
  ....

  def cleargrad(self):
     self.grad = None

 

cleargrad 메서드를 이용해 미분값을 초기화 하는 기능을 추가하였다.

 

# 첫 번째 계산
x = Variable(np.array(3.0))
y = add(x, x)
y.backward()
print(x.grad) # 예상되는 값: 2.0

# 두 번째 계산
x.cleargrad() # 미분값 초기화
y = add(add(x, x), x)
y.backward()
print(x.grad) # 예상되는 값: 3.0

 

실행 결과

2.0
3.0

출처:- 사이토 고키, 『밑바닥부터 시작하는 딥러닝3』, 개앞맵시, 한빛미디어(2020)

출처: https://privatedevelopnote.tistory.com/81 [개인노트]