본문 바로가기
Study 공부할레나

[스터디/밑시딥3] 제 1고지 미분 자동 계산_2.변수를 낳는 함수

by LENA-cfg 2023. 8. 12.

2.1 함수란

- 어떤 변수로부터 다른 변수로의 대응 관계를 정한 것

- 위의 그림은 변수 x,y와 함수 Function과의 관계를 보여주고 원, 사각형의 노드들을 화살표로 연결해 계산과정을 표현한 그림(=계산 그래프), 화살표는 방향이 있는 에지에 해당함

- 그래프는 노드와 에지로 구성된 데이터 구조 또는 구조를 나타낸 그림

 

2.2 Function 클래스 구현

- Function 클래스는 Variable 인스턴스를 입력받아 Variable 인스턴스를 출력

- Variable 인스턴스의 실제 데이터는 인스턴스 변수인 data에 있음

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

- __call__메서드의 인수 input은 Variable 인스턴스라고 가정, 실제 데이터는 input.data에 존재

-데이터를 꺼낸 후 원하는 계산을 하고 결과는 Variable이라는 변수에 담아 돌려줌

 

** __call__메서드는 파이썬의 특수 메서드, f = Function() 형태로 함수의 인스턴스를 변수 f에 대입해두고, 나중에 f(...)형태로 __call__ 메서드를 호출할 수 있음

 

2.3 Function 클래스 이용

x = Variable(np.array(10))
f = Function()
y = f(x)

print(type(y))
print(y.data)

- 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()

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

__call__메서드는 Variable에서 데이터 찾기와 계산 결과를 Variable에 포장하기를 함

 

** Function 클래스의 forward 메서드는 예외를 발생시킴, 이렇게 하면 Function 클래스의 forward 메서드를 직접 호출한 사람에게 '이 메서드는 상속하여 구현하여야한다'는 사실을 알려줄 수 있음

 

Square 클래스는 Function 클래스를 상속하기 때무에 __call__ 메서드는 그대로 계승됨

 

# 전체 소스코드

import numpy as np

# Variable 클래스
class Variable:
    def __init__(self, data): # Variable 클래스를 선언해줄때마다 실행되는 메서드
        self.data = data 

# 함수 클래스인데 상속해서 사용
class Function:
    def __call__(self, input):
        x = input.data
        y = self.forward(x)
        output = Variable(y)
        return output

    def forward(self, in_data):
        raise NotImplementedError()

# Function 클래스 상속받아 forward 메서드에서 제곱 연산을 진행하는 클래스
class Square(Function):
    def forward(self, x): 
        return x ** 2

# 1번
x = Variable(np.array(10)) # 10을 Variable 클래스에 넣어 데이터를 x라는 인스턴스 이름에 저장해줌
# 2번
f = Square() # f라는 객체를 생성해줌
y = f(x) # x 변수에 저장한 데이터를 넣어줌 # f.forward(수치자료형)해서 값 확인해도됨
print(type(y))
print(y.data)

1번: 전 포스팅에서 설명했던 것처럼 어레이 담아주고

2번

f라는 이름의 Square() 인스턴스를 만들어 준 다음, y값을 구해주는데 f(x값을)넣어줌

프로그램 진행 순서는 ➀=>➆순으로 이어짐

 

(추가) y값을 구할 때 x값을 제곱하고 돌려주는데 데이터 형식이 달라지는데

이는, 배열의 모든 요소의 Sum을 때리거나 값을 1개로 반환할 때 형식이 달라지며 연산의 특성이나 목적에 따라 최적의 데이터 형태를 반환하기 때문임