[스터디 내용 정리] step02. 변수를 낳는 함수

Gamchan Kang·2023년 4월 3일
0

딥러닝

목록 보기
3/8

지난 step에서 변수를 Variable 클래스로 간단하게 구현했다.
이번 step에는 함수를 Function 클래스로 구현한다.


1. 함수란

함수의 수학적 정의도 좋지만, 좀 더 직관으로 바라보자.
함수는 입/출력의 관계이다.
함수 내부에 자체적인 연산을 포함해서 그림으로 표현하면 다음과 같다.



2. Function 클래스 구현

class Function:
    def __call__(self, input):
        x = input.data
        y = self.forward(x)
        output = Variable(y)
        return output

y = self.forward(x)는 함수의 연산을 고정하지 않고 상속을 통해 구체화 하기 위한 방법이다.

__call__ 문법이 눈에 띈다.
__init__과 다르게 __call__은 호출이 일어나면 동작이 일어난다.
더 쉬운 차이로 다음과 같다.

x = Variable(np.array(10))
f = Square()				# Square: Function에서 상속받은 자식 클래스
y = f(x)

x의 초기화 및 선언으로 Variable 객체(인스턴스)가 x에 저장되었다.
하지만 fSquare의 동작이 선언되었다.
그 결과 y = f(x)에서 xf 동작을 따라 y에 저장됐다.

정리하면,

  • Function 클래스는 Variable 인스턴스를 입력받아 Variable 인스턴스를 출력.
  • Variable 인스턴스의 실제 데이터는 내부 메소드 변수인 data에 저장.

이런 __call__ 메소드는 Define-by-Run을 가능하게 하는 요소이다.
Define-by-Run은 추후에 자세히 설명할 예정이다.


3. Function 클래스 이용

  • Function``` 클래스는 공통 기능을 구현한 기반 클래스.
  • 구체적인 연산은 자식 클래스에서 구현.

이를 위해서 위 Function 클래스 구현 코드를 살짝 수정하자.

class Function:
    def __call__(self, input):
        x = input.data
        y = self.forward(x)
        output = Variable(y)
        return output
    # 추가한 부분
    def forward(self, x):
        raise NotImplementedError()

이는 Function을 상속받은 자식 클래스가, 즉 구체적인 함수가 forward연산을 구현하지 않으면 에러를 발생하게 하는 부분이다.

실제 상속은 다음과 같이 이루어진다.

class Square(Function):
    def forward(self, x):
        return x**2


이번 step에서 __call__ 메소드 활용을 알게 됐다.
파이썬에 이런 기본 메소드를 잘 활용하면 효율적으로 동작하는 코드를 구현할 수 있겠다.

Github: https://github.com/gsgh3016/Deep-Learning-from-Scratch3/blob/main/gamchan/part_1/step02.py

profile
Someday, the dream will come true

0개의 댓글