728x90
반응형

확인1 : Variable 인스턴스 변수

class Variable:
    __array_priority__ = 200

    def __init__(self, data, name=None):
        if data is not None:
            if not isinstance(data, np.ndarray):
                raise TypeError('{} is not supported'.format(type(data)))

        self.data = data
        self.name = name
        self.grad = None
        self.creator = None
        self.generation = 0
  • data와 grad는 각각 순전파, 역전파 계산 시 사용
  • data와 grad 모두 ndarray 인스턴스를 저장한다.

 

확인2 : Function 클래스

class Function:
    def __call__(self, *inputs):
        inputs = [as_variable(x) for x in inputs]
		
        # 순전파 계산(메인 처리)
        xs = [x.data for x in inputs]
        ys = self.forward(*xs)
        if not isinstance(ys, tuple):
            ys = (ys,)
        outputs = [Variable(as_array(y)) for y in ys]

        if Config.enable_backprop:
            self.generation = max([x.generation for x in inputs])
            # '연결'을 만듦
            for output in outputs:
                output.set_creator(self)
            self.inputs = inputs
            self.outputs = [weakref.ref(output) for output in outputs]

        return outputs if len(outputs) > 1 else outputs[0]
  • Dezero 함수는 모두 Function 클래스를 상속한다.
  • 구체적인 계산은 상속된 클래스에서 forward 메서드에 구현한다.

 

 

확인3 : Variable 클래스의 역전파

class Variable:
	def backward(self, retain_grad=False):
        if self.grad is None:
            self.grad = np.ones_like(self.data)

        funcs = []
        seen_set = set()

        def add_func(f):
            if f not in seen_set:
                funcs.append(f)
                seen_set.add(f)
                funcs.sort(key=lambda x: x.generation)

        add_func(self.creator)

        while funcs:
            f = funcs.pop()
            
            # 역전파 계산(메인 처리)
            gys = [output().grad for output in f.outputs]  # output is weakref #1
            gxs = f.backward(*gys) #2
            if not isinstance(gxs, tuple):
                gxs = (gxs,)

            for x, gx in zip(f.inputs, gxs): #3
                if x.grad is None:
                    x.grad = gx
                else:
                    x.grad = x.grad + gx

                if x.creator is not None:
                    add_func(x.creator)

            if not retain_grad:
                for y in f.outputs:
                    y().grad = None  # y is weakref
  1. Variable의 인스턴스 변수인 grad를 리스트로 모으고, 인스턴스 변수 grad는 ndarray 인스턴스를 참조하고 있다.
  2. backward 메서드에는 ndarray 인스턴스가 담긴 리스트 가 전달된다.
  3. 출력 쪽에서 저파하는 미분값 (gxs)을 함수의 입력 변수(f.inputs)의 grad로 설정

 

 

 

 

 

 

 

 

 

 

출처 : http://www.yes24.com/Product/Goods/95343845?OzSrank=2 

 

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

코드 3줄이 딥러닝 프레임워크가 되는 마법이 책은 ‘밑바닥부터’ 직접 만들어보며 즐겁게 딥러닝을 익히는 시리즈의 장점을 그대로 따랐다. 코드 3줄로 시작해 60단계까지 차근차근 구현해보

www.yes24.com

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기