페이지

2022년 8월 19일 금요일

14.1 문제의 원인

 왜 x에 대한 미분값(x.grad)이 틀리게 나왔을까요? 원인은 Variable클래스의 다음 위치에 있습니다.

class Variable:

  def __init__(selfdata):
    if data is not None:
      if not isinstance(data, np.ndarray):
        raise TypeError('{}은(는) 지원하지 않습니다.' .format(type(data)))
    self.data = data
    self.grad = None
    self.creator = None

  def set_creator(selffunc):
    self.creator = func


  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]  
      gxs = f.backward(*gys)   
      if not isinstance(gxs, tuple):  
        gxs = (gxs,)
      
      for x, gx in zip(f.inputs, gxs):  
        x.grad = gx   # 여기가 실수!

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

이 코드에서 알 수 있듯이 현재 구현에서 출력 쪽에서 전해지는 미분값을 그대로 대입합니다. 따라서 같은 변수를 반복해서 사용하면 전달되는 미분값이 덮어 써지는 것입니다. 예를 들어 앞의 덧셈 예에서는 미분값이 [그림 14-2]처럼 전파됩니다.



[그림 14-2]에서 전파되는 미분값도 표시했습니다. 이때 x의 미분은 1 + 1 = 2가 되어야 올바른 결과입니다. 즉, 전파되는 미분값의 '합'을 구해야 합니다. 그러나 지금의 구현에서는 그냥 덮어 쓰고있습니다.

댓글 없음: