딥러닝과 인공신경망: Forward 와 Backward를 활용한, 계산 그래프 구현하기

Yougurt_Man·2022년 8월 2일
0

Machine Learning Theory

목록 보기
15/18

순전파(Foward)와 역전파(Backward)를 코드로 구현해보자.

각 Layer는 클래스로 구현 후, 변수를 인스턴스화 하여 Foward 된 신호를 저장 후, 역전파에서 해당 신호를 활용하도록 한다.

곱셈 계층 구현하기

class MulLayer:
  def __init__(self): # initialize x and y 
    self.x = None 
    self.y = None 

  def foward(self, x, y):
    self.x = x 
    self.y = y 
    out = x * y 

    return out 
  
  def backward(self, dout):
    dx = dout * self.y # 곱셈 노드에서 역전파는 x 와 y를 스위칭 하여 이전 입력 신호에 곱하여 다음 노드로 전달 한다. 
    
    dy = dout * self.x 

    return dx, dy 

사과 계산그래프의 각 노드에 대한 순전파 / 역전파 코드를 구현한다.

apple = 100 # 사과 가격 
apple_num = 2 # 개수 
tax = 1.1 # 소비세 

# Layer 

mul_apple_layer = MulLayer() # 순전파 / 역전파 계층 인스턴스화
mul_tax_layer = MulLayer() 

# foward 

apple_price = mul_apple_layer.foward(apple,apple_num) # 사과 가격을 구하기 위한 순전파 

price = mul_tax_layer.foward(apple_price, tax) # 소비세를 고려한 최종 가격  

print(price)

# backward 

dprice = 1 # 전달할 미분값 dz/dz = 1 

dapple_price, dtax = mul_tax_layer.backward(dprice) # 곱에 대한 역전파 신호는 x 와 y가 스위칭. 

print("dapple_price: {0} \ndtax: {1}".format(dapple_price, dtax))

dapple, dapple_num = mul_apple_layer.backward(dapple_price)

print("dapple: {0} \ndapple_num: {1}".format(dapple,dapple_num))

최종 가격과, 역전파후 값들에 대해 출력하면 다음과 같다.

220.0000000000000
dapple_price: 1.1 
dtax: 200
dapple: 2.2 
dapple_num: 110.00000000000001

Add 계층 구현하기

Add 계층은 단순하다. 단순히 입력신호를 다음 노드로 전달한다.

class AddLayer:
  def __init__(self):
    pass
  
  def foward(self, x,y):
    out = x + y 
    return out 
  
  def backward(self, dout): 
    dx = dout * 1 
    dy = dout * 1 

    return dx, dy 

순전파와 역전파 계층 코드 구현 응용

사과가격을 계산 하기위한 계산 그래프 구현해 보았으니, 이를 응용하여 사과와 오렌지 가격 계산을 위한 계산 그래프를 구현 해보자.

각 연산 노드 (곱셈 및 덧셈)노드는 클래스로 선언한, MulLayer AddLayer를 사용한다.

apple = 100 
apple_num = 2 
orange = 150
orange_num = 3 
tax = 1.1 

# layers 

mul_apple_layer = MulLayer()
mul_orange_layer = MulLayer()
add_apple_orange_layer = AddLayer() 
mul_tax_layer = MulLayer() 

# foward 

apple_price = mul_apple_layer.foward(apple, apple_num) # Apple price without tax 
orange_price = mul_orange_layer.foward(orange, orange_num) # Orange price without tax 

all_price = add_apple_orange_layer.foward(apple_price, orange_price) # price including tax 

price = mul_tax_layer.foward(all_price, tax) # Final Output 

# backward 

d_price = 1 # dz / dz = 1

d_all_price, d_tax= mul_tax_layer.backward(d_price) # x = y, y = x 스위치 

print(d_all_price, d_tax) 

d_apple_add_price, d_orange_add_price = add_apple_orange_layer.backward(d_all_price) 

print(d_apple_add_price, d_orange_add_price)

d_apple_price, d_apple_num = mul_apple_layer.backward(d_apple_add_price)

print(d_apple_price, d_apple_num)

d_orange_price, d_orange_num = mul_orange_layer.backward(d_orange_add_price)

print(d_orange_price, d_orange_num)

계산결과는 다음과 같다.

1.1 650
1.1 1.1
2.2 110.00000000000001
3.3000000000000003 165.0
profile
Greek Yogurt

0개의 댓글