728x90
반응형
SMALL
728x90
반응형
SMALL

지난 글을 통해 계산 그래프의 역전파가 연쇄 법칙에 따라서 진행되는 모습을 이야기해 보았습니다. 

2024.02.15 - [Programming/Deep Learning] - [Python/DeepLearning] #10.3. 역전파) 계산 그래프를 통한 역전파 이해

 

[Python/DeepLearning] #10.3. 역전파) 계산 그래프를 통한 역전파

지난 시간, 수식을 통한 오차역전파법에 대하여 이해해 보았습니다. 2024.02.08 - [Programming/Deep Learning] - [Python/DeepLearning] #10.2. 역전파) 수식을 통한 오차역전파

yuja-k.tistory.com

이번에는 덧셈 노드와 곱셈 노드의 역전파의 구조에 대하여 알아보도록 하겠습니다!

 

단순한 계층부터 구현하기

 

수치적인 오차역전파법, 계산 그래프를 이용한 역전파의 의미에 대해 살펴보았습니다. 본격적으로 파이썬으로 역전파를 구현하고, 이를 신경망에 집어넣어 실제 오차역전파를 구현해 보도록 하겠습니다. 일전에 수식을 이용해 오차역전파법을 공부했고, 계산 그래프를 이용해 쇼핑에 대한 역전파도 공부해 보았습니다. 신경망이라고 해서 별 다를 것이 없는 게, 신경망의 모든 계산은 덧셈과 곱셈을 이용해 수행됩니다. 따라서 아주 간단한 덧셈 계층과 곱셈 계층부터 구현해 보도록 하겠습니다. 모든 계층은 순전파와 역전파를 모두 처리할 수 있도록 공통의 메소드를 구현할 것입니다.

  • forward : 순전파
  • backward : 역전파

 

덧셈 노드의 역전파

먼저 𝑧=𝑥+𝑦라는 식을 대상으로 역전파를 살펴보도록 하겠습니다. 우선 𝑧=𝑥+𝑦의 미분은 다음과 같이 계산할 수 있을 것입니다.

𝑥, 𝑦에 대한 각각의 편미분 값이 모두 1이 되는 것을 확인할 수 있습니다. 계산 그래프로는 다음과 같이 표현이 가능합니다.

 

역전파 때는 상류에서 보내진 미분 값( 여기에서는 𝐿𝑧 )에 1을 곱하여 하류로 흘려보냅니다. 즉, 덧셈 노드의 역전파는 1을 곱하기만 할 뿐 입력된 값을 그대로 다음 노드로 보내게 됩니다. 위 예에서는 상류에서 전해진 미분 값을 𝐿𝑧로 표현 하였는데 이는 최종적으로 𝐿이라는 값을 출력하는 큰 계산 그래프를 가정하였기 때문입니다.

 

즉, 국소적 미분이 가장 오른쪽의 출력에서 시작하여 노드를 타고 역방향(왼쪽)으로 전파된 것을 그렸다고 생각하면 됩니다. 덧셈 노드에 대한 역전파를 간단하게 살펴보겠습니다. 가령 10+5=15라는 계산이 있고, 상류에서 (오른쪽) 1.3이라는 값이 흘러나오면 다음과 같이 계산 그래프를 그려볼 수 있습니다.

 

다시 말해, 덧셈 노드 역전파는 입력 신호를 다음 노드로 출력할 뿐이므로 1.3을 그대로 다음 노드로 전파합니다. 바로 코드로 구현해 보도록 하겠습니다.

  • 순전파 : 단순히 두 값을 더한다.
  • 역전파 : 다음 노드로부터 들어온 미분값을 그대로 흘려보낸다.
  • 순전파 시에 입력된 값을 저장하고 있을 필요는 없다.
import numpy as np

class AddLayer:

  def __init__(self):
    pass

  # 덧셈 노드로 들어온 값을 더해서 리턴
  def forward(self, x, y):
    out = x + y
    return out

  def backward(self, dout):
    # 모양새 맞추기
    dx = dout * 1
    dy = dout * 1

    return dx, dy

곱셈 노드의 역전파

이번엔 곱셈 노드의 역전파입니다.𝑧=𝑥𝑦 라는 식을 예로 들어 보겠습니다. 이 식의 미분은 다음과 같습니다.

계산 그래프로는 다음과 같이 그릴 수 있습니다.

 

곱셈 노드의 역전파는 상류의 값에 순전파 때의 입력 신호들을 서로 바꾼 값을 곱해서 하류로 보내고 있습니다. 즉, 순전파 때 𝑥였다면 역전파에서는 𝑦, 순전파 때 𝑦였으면 역전파에서는 𝑥로 바꾼다는 의미가 됩니다. 구체적인 예로 10⋅5=50이라는 계산이 있고, 역전파 때 상류에서 1.3 값이 흘러온다고 가정해 보겠습니다. 이를 계산 그래프로 그리면 다음과 같이 됩니다.

  • 순전파 : 두 값을 곱한다
  • 역전파 : 들어온 두 값에 미분값을 곱해서 반대로 전달한다.
  • 곱할 값들을 저장하고 있어야 한다. 역전파시에 미분값을 곱한 다음 반대로 전달해야 하니까
class MulLayer:

  def __init__(self):
    self.x = None
    self.y = None


  def forward(self, x, y):
    # 계산할 값들을 노드에 저장하고 있는다.
    self.x = x
    self.y = y

    out = x * y
    return out

  def backward(self, dout):
    dx = dout * self.y
    dy = dout * self.x

    return dx, dy

 

곱셈의 역전파에서는 입력 신호를 바꾼 값을 곱하여야 하는1.35=6.5. 다른 하나는 1.310=13이 되는 것이 확인됩니다. 덧셈의 역전파에서는 상류의 값을 그대로 흘려보내서 순방향 입력 신호의 값은 필요하지 않았습니다만, 곱셈의 역전파에서는 순방향 입력신호의 값이 필요합니다. 그래서 곱셈 노드를 구현할 때는 순전파의 입력 신호를 변수에 저장해 둡니다.

 

2024.02.15 - [Programming/Deep Learning] - [Python/DeepLearning] #10.3. 역전파) 계산 그래프를 통한 역전파 이해

 

[Python/DeepLearning] #10.3. 역전파) 계산 그래프를 통한 역전파

지난 시간, 수식을 통한 오차역전파법에 대하여 이해해 보았습니다. 2024.02.08 - [Programming/Deep Learning] - [Python/DeepLearning] #10.2. 역전파) 수식을 통한 오차역전파

yuja-k.tistory.com

앞서 #10. 3에서 사과와 귤 계산 기억하시나요? 사과 쇼핑의 예를 다시 한번 이어가 보자면!

이 문제에서는 '사과의 가격', '사과의 개수', 소비세'라는 세 변수 각각이 최종 금액에 어떻게 영향을 주느냐를 풀고자 합니다. 이는

  • 사과 가격에 대한 지불 금액의 미분
  • 사과 개수에 대한 지불 금액의 미분
  • 소비세에 대한 지불 금액의 미분을 구하는 것에 해당합니다. 이를 계산 그래프의 역전파를 사용해서 풀면 다음 그림과 같게 됩니다.

곱셈 노드의 역전파에서는 입력 신호를 서로 바꿔서 하류로 흘려보내는 것이 보입니다. 위 그림의 결과를 보면 사과 가격의 미분은 2.2, 사과 개수의 미분은 110, 소비세의 미분은 200입니다. 이를 해석해 보면

  • 소비세와 사과 가격이 같은 양만큼 오른다면
    • 최종 금액에는 소비세가 200의 크기로, 사과 가격이 2.2 크기로 영향을 준다고 할 수 있겠습니다.
    • 단, 소비세 1은 100%, 사과 가격 1은 1원

정리할 겸 해서 '사과와 귤 쇼핑'의 역전파를 풀어보죠!

 

초기화 함수인 init에서는 단순히 인스턴스 변수 x, y를 초기화시킵니다. 이 두 변수는 순전파 시의 입력값을 유지하기 위해 사용됩니다. forward 메소드는 순전파로써, x, y 를 입력받아 그 값을 인스턴스 변수에 저장한 후 곱해서 반환 합니다. backward 메소드는 상류에서 넘어온 미분값(dout)을 입력받아 서로 바꿔 곱한 후 반환하여 하류로 흘려보냅니다. 사과 쇼핑의 예를 들어보면 다음처럼 그림으로 설명이 가능합니다. MulLayer를 사용하여 위 그림의 순전파를 다음과 같이 확인해 볼 수 있습니다.

# 사과만 테스트
apple = 100 # 사과 1개당 가격
apple_cnt = 2 # 사과 개수
tax = 1.1 # 소비세

# 계층은 2개가 필요함
# (apple * apple_cnt) * tax

# 레이어 준비
mul_apple_layer = MulLayer()
mul_tax_layer   = MulLayer()

# 순전파 먼저 수행
apple_price = mul_apple_layer.forward(apple, apple_cnt)
price       = mul_tax_layer.forward(apple_price, tax)

print("최종 사과 가격 : {}".format(price))

각 변수에 대한 미분은 backward에서 구할 수 있습니다.

# 역전파 구현

dprice = 1 # d돈통 / d포스기 # 최종 가격에 대한 미분. d가격 / d가격 = 1
dapple_price, dtax = mul_tax_layer.backward(dprice)
dapple, dapple_cnt = mul_apple_layer.backward(dapple_price)

print("사과 가격 * 사과 개수에 대한 미분값 : {}".format(dapple_price))
print("사과 가격에 대한 미분값 : {}".format(dapple))
print("사과 개수에 대한 미분값 : {}".format(dapple_cnt))
print("소비세에 대한 미분값 : {}".format(dtax))

여기서 눈여겨보아야 할 것은 backward()의 호출 순서는 forward() 호출 순서의 반대라는 점입니다. 그리고 backward()가 받는 매개변수는 '순전파 출력에 대한 미분'임을 주의해야 합니다.

덧셈 계층 구현

두 번째로 구현할 계층은 덧셈 계층입니다.

 
덧셈 계층에서는 초기화 자체가 필요 없기 때문에 init에서 아무런 일도 하지 않습니다. 덧셈 계층의 forward() 에서는 입력받은 두개의 매개변수 x, y를 더해서 반환시키겨, backward() 에서는 상류에서 내려온 미분(dout)을 그대로 하류로 흘릴 뿐입니다. 이제 사과 2개와 귤 3개를 사는 상황을 그려 보겠습니다.
# 사과와 귤 계산하기
apple = 100
apple_cnt = 2

orange = 150
orange_cnt = 3

tax = 1.1

 

1 계층

  • 각 과일에 대한 개수 계산 ( 과일 가격 * 개수 )
mul_apple_layer = MulLayer() # 사과 개수 * 사과 가격
mul_orange_layer = MulLayer() # 귤 개수 * 귤 가격

 

2 계층

  • 사과 총 가격 + 귤 총 가격
add_apple_orange_layer = AddLayer() # 사과 총 가격 + 오렌지 총 가격

3 계층

  • 과일들의 총 가격 * 소비세
mul_tax_layer = MulLayer() # 과일 총 가격 * 소비세

 

연산 수행 (순전파)
# 1 계층
apple_price = mul_apple_layer.forward(apple, apple_cnt)
orange_price = mul_orange_layer.forward(orange, orange_cnt)

# 2 계층
total_price = add_apple_orange_layer.forward(apple_price, orange_price)

# 3 계층
price = mul_tax_layer.forward(total_price, tax)

print("최종 가격 : {}".format(int(price)))

연산 수행 (역전파)
dprice = 1 # d돈통 / d포스기

# dprice / dtotal_price, dprice / dtax
dtotal_price, dtax = mul_tax_layer.backward(dprice)

# d돈통 / dapple_price = ( d돈통 / d포스기 ) * (d돈통 / dtotal_price) * (dtotal_price / dapple_price)
dapple_price, dorange_price = add_apple_orange_layer.backward(dtotal_price)

dorange, dorange_cnt = mul_orange_layer.backward(dorange_price)
dapple, dapple_cnt = mul_apple_layer.backward(dapple_price)

print("사과 개수에 대한 미분값 : {}".format(dapple_cnt))
print("사과 가격에 대한 미분값 : {}".format(dapple))

print("귤 개수에 대한 미분값 : {}".format(dorange_cnt))
print("귤 가격에 대한 미분값 : {}".format(dorange))

지금까지 역전파의 덧셈 노드와 곱셈 노드를 알아보았습니다! 길고 긴 역전파의 마지막 종착지는 활성화 함수의 계층 구현으로 마무리하려 합니다. 다음 시간에는 신경망 레이어 만들기를 설명해 보도록 하겠습니다.

728x90
반응형
LIST
728x90
반응형
SMALL

지난 시간, 수식을 통한 오차역전파법에 대하여 이해해 보았습니다.

2024.02.08 - [Programming/Deep Learning] - [Python/DeepLearning] #10.2. 역전파) 수식을 통한 오차역전파법 이해

 

이번 시간에서는 계산 그래프를 통한 역전파에 대하여 알아보도록 하겠습니다!

오차역전파법을 위한 계산 그래프

 

일전에 수식으로 풀어본 오차역전파법은 수학을 오랫동안 놓았거나 수식으로만 생각하면 본질을 놓칠 우려가 있습니다. 이번에 우리가 해볼 내용은 계산 그래프를 이용해 오차역전파법을 이해하는 것인데요, 수식으로 오차역전파법을 이해하는 것보다는 약간은 부정확할 수 있으나 최종적으로는 수식으로 알아본 오차역전파법을 이해할 수 있고, 실제 코드 구현까지 해보도록 하겠습니다. 계산 그래프로 설명한다는 아이디어는 안드레 카패스의 블로그 또 그와 페이페이 리 교수가 진행한 스탠퍼드 대학교 딥러닝 수업 CS321n을 참고했습니다.

 

계산 그래프

 

계산 그래프(computational graph)는 계산 과정을 그래프로 그려낸 것입니다. 그래프는 우리가 잘 아는 그래프 자료 구조 형태로 되어 있으며, 처음에 쉽게 접근하기 위해 계산 그래프를 통한 간단한 문제를 풀어보도록 하겠습니다. 먼저 익숙해지자!라는 이야기입니다. 예를 들어 다음과 같은 예시가 있다고 하죠, "A라는 사람이 1개 100원인 사과를 2개 샀습니다. 이때 지불 금액을 구하세요, 단 소비세 10%가 부과됩니다."라는 예시를 계산그래프로 표현하면 다음과 같아집니다.

 

처음에 사과의 100원이 'x 2' 노드로 흘러 200원이 된 다음 소비세 계산을 위해 'x 1.1' 노드를 거쳐 최종적으로는 220원이 됩니다. 위 그래프에 따르면 최종 답은 220원이 된다는 사실을 알 수 있네요 위의 그림에서는 계산 노드를 각각 'x 2', 'x 1.1'로 표현했지만 '2'와 '1.1'을 각각 사과의 개수와 소비세에 대한 변수가 되기 때문에 따로 빼서 다음과 같이 표기할 수 있습니다.

 

그럼 다음 문제를 풀어 보도록 하겠습니다.

"A가 사과를 2개, 귤을 3개 샀습니다. 사과는 1개에 100원, 귤은 1개 150원입니다. 소비세가 10% 부과될 때 A가 지불해야 할 금액은?" 위 문제도 계산그래프로 풀어볼 수 있습니다. 이때의 계산 그래프는 다음과 같겠네요!

 

위 문제에서는 새로운 노드인 덧셈 노드가 추가되었습니다. 덧셈 노드가 추가되어 사과의 가격과 귤의 가격을 합치는 모습이 보이고 있습니다. 왼쪽에서 오른쪽으로 순차적으로 계산을 끝내고 제일 마지막에 1.1을 곱하면 우리가 원하는 값인 715원이 나오고 끝나게 됩니다. 계산 그래프를 이용한 문제풀이는 다음과 같이 해석할 수 있습니다.

  1. 계산 그래프를 구성
  2. 그래프에서 계산을 왼쪽에서 오른쪽으로 진행

이처럼 '계산을 왼쪽에서 오른쪽으로 진행'하는 단계를 순전파(forward propagation)라고 합니다. 순전파는 계산 그래프의 출발점부터 종착점으로의 전파단계를 그려줍니다. 역전파(backword propagation)는 무엇일까요? 바로 '오른쪽에서 왼쪽으로 전파되는 단계를 의미합니다!


국소적 계산

 

계산 그래프의 특징은 '국소적 계산'을 전파함으로써 최종 결과를 얻는다는 점에 있습니다. 여기서 '국소적'이란, "자신과 직접 관계된 작은 범위"를 의미하는데, 뭔가 떠오르지 않으시나요? 수학으로 따지면 바로 편미분을 의미한다는 것입니다. 즉, 국소적 계산은 전체에서 어떤 일이 벌어지든 상관없이 자신과 관계된 정보만을 토대로 결과를 낼 수 있다는 이야기입니다. 구체적인 예를 들어 보겠습니다. 여러분이 마트에서 사과 2개를 포함한 여러 가지의 물품들을 구매하는 상황을 구해보겠습니다. 그렇다면 사과에 대한 국소적 계산을 진행한다고 이해할 수 있는데요, 그래프로 확인해 보겠습니다.

 

위 그림에서 여러 식품을 구매하여( 복잡한 계산을 하여) 4,000원이라는 금액이 나왔고, 여기에 사과 가격인 200원을 더해 총 4,200원이 나왔습니다. 이는 '사과에 대한 국소적 계산'이기 때문에, 4,000원이 어떻게 나왔는지는 전혀 신경 쓸게 없다는 이야기가 됩니다. 그냥 단순히 복잡한 계산의 결과물인 4,000원과 사과의 가격인 200원을 더해 4,200을 알아내면 된다는 것이죠. 중요한 점은 계산 그래프는 이처럼 국소적 계산에 집중한다는 것입니다. 전체 계산 자체가 아무리 복잡해도 각 단계에서 하는 일은 해당 노드의 '국소적 계산'일뿐입니다. 국소적 계산은 단순하지만 그 결과를 전달함으로써 전체를 구성하는 복잡한 계산을 해낼 수 있습니다. 마치 자동차 조립을 하는 것과 비슷한데요, 각각의 부품을 복잡하게 만들어 내고, 최종적으로 합쳐 차를 완성하는 단계라고 볼 수 있습니다.

 

계산 그래프를 사용하는 이유

 

계산 그래프의 이점은 무엇일까요? 바로 국소적 계산입니다. 전체가 아무리 복잡해도 각 노드에서는 단순한 계산에 집중하여 문제를 단순화시킬 수 있기 때문이지요, 또한 계산 그래프는 중간 계산 결과를 모두 보관할 수 있습니다. 에지에 저장되어 있는 숫자들이 그것을 의미하고 있지요, 하지만 이것 때문에 계산 그래프를 사용하진 않습니다! 계산 그래프를 사용하는 가장 큰 이유는 역전파를 통해 '미분'을 효율적으로 계산할 수 있기 때문입니다.

계산 그래프의 역전파 첫 번째 문제에 대한 계산 그래프는 사과 2개를 사서 소비세를 포함한 최종 금액을 구하는 것이었습니다. 여기서 새로운 문제를 제시해 보겠습니다. "사과 가격이 오르면 최종 금액에 어떠한 영향을 미칠 것인가?"가 문제입니다. 즉 이는 사과 가격에 대한 지불 금액의 미분을 구하는 문제에 해당됩니다. 사과 값을 x로, 지불 금액을 L이라 했을 때

로 표현이 가능하다는 것이죠, 즉 이 미분값은 사과 값이 '아주 조금' 올랐을 때 지불 금액이 얼마나 증가하느냐를 표시한 것입니다. 즉, '사과 가격에 대한 지불 금액의 미분' 같은 값은 계산 그래프에서 역전파를 하면 구할 수 있게 됩니다. 다음 그림에서는 계산 그래프 상의 역전파에 의해 미분을 구할 수가 있습니다. 아직 역전파가 어떻게 이뤄지는지에 대해서는 이야기하지 않았습니다!

위 그림에서 굵은 화살표로 역전파를 표현해 보았습니다. 이 전파는 각각 노드에 대한 국소적 미분을 전달합니다. 즉, 들어오고 있는 사과의 개수나 소비세에 대한 국소적으로 미분을 진행하였기 때문에, 소비세와 사과의 개수 같은 변수에 대한 미분만 진행했다는 이야기입니다. 그리고 그 미분값은 화살표 방향으로 적어내고 있습니다. 이 예에서 역전 파는 오른쪽에서 왼쪽으로 '1 -> 1.1 -> 2.2' 순으로 미분값을 전달하고 있습니다. 이 결과로부터 알 수 있는 사실은 '사과 가격에 대한 지불금액이 미분'값은 2.2라는 것을 알 수 있게 됩니다. 즉, 사과 가격이 1원 오르면 최종 가격은 2.2원 오른다는 것이죠. 여기에서는 사과 가격에 대한 미분만 구했지만, '소비세에 대한 지불 금액의 미분'이나 '사과 개수에 대한 지불 금액의 미분'도 같은 순서로 구해낼 수가 있습니다. 그리고 그때는 중간까지 구한 미분 결과를 공유할 수 있어서 다수의 미분을 효율적으로 계산할 수 있습니다. 이처럼 계산 그래프의 이점은 순전파와 역전파를 활용해서 각 변수의 미분을 효율적으로 구할 수 있다는 것입니다.

 

연쇄법칙과 계산 그래프

 

연쇄법칙 계산을 계산 그래프로 나타낼 수 있습니다. 2 제곱 계산을 '**2' 노드로 나타내면 다음과 같습니다.

오른쪽에서 왼쪽으로 신호가 전파되는 모습을 볼 수 있습니다. 역전파에서의 계산 절차는 노드로 들어온 입력 신호에 그 노드의 국소적 미분인 편미분을 곱한 후 다음 노드로 전달합니다. 예를 들어 **2 노드에서의 역전파를 보면 입력은 𝑧∂𝑧이며, 이에 대한 국소적 미분인 𝑧𝑡를 곱해 다음 노드로 넘깁니다. 맨 왼쪽의 역전파를 보면 x에 대한 z의 미분이 연쇄법칙에 따라서

가 된다는 사실을 알아낼 수 있고, 이를 계산하면

가 된다는 사실을 알아낼 수 있습니다.

지금까지 아주아주 긴 오차역전파법을 위한 계산 그래프를 위한 이해를 수식으로 알아보았습니다! 다음 세션을 통해 최종적으로 코드 구현을 해보겠습니다.

728x90
반응형
LIST
728x90
반응형
SMALL

 

이번 블로그부터는 역전파 시리즈를 시작해 보도록 하겠습니다!

 

오차역전파법을 수식으로 이해하기 위해서는 미분의 연쇄법칙에 대해서 먼저 이야기해봐야 합니다. 계산 그래프를 통한 이해에도 연쇄법칙을 알고 들어가야 하기 때문에, 먼저 미분의 연쇄법칙부터 살펴보겠습니다.

합성 함수

 

함수 𝑦=𝑓(𝑢) 𝑢 𝑔(𝑥)라면 𝑦=𝑓(𝑔(𝑥))라고 중첩해서 표현이 가능합니다. 이때 중첩 함수 𝑓(𝑔(𝑥))를 함수 𝑓(𝑢) 𝑔(𝑥)의 합성 함수라고 합니다. 예를 들어 함수 𝑧=(2𝑦)2) 2은𝑢=2𝑦와 함수 𝑧=𝑢2의 합성 함수라고 할 수 있습니다. 신경망에서의 예를 들어보면

𝑦=𝑎(𝑤1𝑥1+𝑤2𝑥2+...+𝑤𝑛𝑥𝑛+𝑏)

에서 출력 함수 𝑦는 𝑥1,𝑥2,...𝑥𝑛의 1차함수 𝑓와 활성화 함수 𝑎의 합성 함수라고 볼 수 있겠습니다. 𝑧=𝑓(𝑥1,𝑥2,...,𝑥𝑛)=𝑤1𝑥1+𝑤2𝑥2+...+𝑤𝑛𝑥𝑛+𝑏𝑦=𝑎(𝑧) 즉 다음과 같은 상황을 그려볼 수 있겠네요.

1) 데이터 입력 𝑥1,𝑥2,...,𝑥𝑛

2) 가중 입력 𝑧=𝑓(𝑥1,𝑥2,...,𝑥𝑛)=𝑤1𝑥1+𝑤2𝑥2+...+𝑤𝑛𝑥𝑛+𝑏

3) 출력 𝑦=𝑎(𝑧) 일

변수 함수의 연쇄법칙

 

함수 𝑦=𝑓(𝑢)의 변수 𝑢가 일변수 𝑢=𝑔(𝑥)일 때, 합성함수 𝑓(𝑔(𝑥))의 도함수(미분)는 다음과 같이 정의할 수 있습니다.


 

위 식을 합성 함수의 미분공식이라고 볼 수 있습니다. 또한 이를 연쇄 법칙 - chain rule이라고도 합니다. 위 식을 토대로 살펴보면𝑥가 변화 했을 때 𝑦의 변화량을 구하기 위해

  1. 𝑢의 변화량에 대한 𝑦의 변화량을 구하고
  2. 𝑥의 변화량에 대한 𝑢의 변화량을 구해서 곱한다

또한 𝑑𝑥, 𝑑𝑦, 𝑑𝑢를 하나의 변수로 놓고 생각해 봤을 때 좌변은 우변의 𝑑𝑢를 약분한 것입니다. 따라서 합성함수의 미분은 분수처럼 약분할 수 있다고 생각할 수 있겠네요. 이 규칙을 토대로 𝑦 𝑢의 함수, 𝑢가 𝑣의 함수, 𝑣가 𝑥의 함수일 때, 𝑑𝑦𝑑𝑥는 다음과 같습니다.

 


 

또 다른 예를 들어 보겠습니다. 시그모이드 함수와 다른 함수를 합성해서 가정해 볼 텐데요 예를 들어 다음과 같은 식이 있다고 가정합니다.


 

y는 시그모이드 함수이므로, 시그모이드 함수를 미분하였을 때 다음 식으로 바꿀 수 있습니다.


 

그다음,𝑑𝑢𝑑𝑥  𝑢 𝑥에 관해 미분하면 𝑑𝑢𝑑𝑥=𝑤 이므로 최종적인 결과는 다음처럼 계산이 가능합니다.


 

다변수 함수의 연쇄법칙

 

변수가 여러 개인 다변수 함수에도 연쇄법칙을 적용할 수가 있습니다. 위처럼 분수를 다루듯이 미분 방정식을 변형하겠지만 관련된 모든 변수에 연쇄법칙을 적용할 필요가 있으므로 단순하지는 않습니다.

먼저 변수가 2개인 함수일 때를 생각해 보도록 하겠습니다. 𝑧=𝑓(𝑢,𝑣)라는 함수가 있고, 𝑢 𝑣 역시 각각 𝑢=𝑔(𝑥,𝑦) 𝑣=(𝑥,𝑦)라는 함수라는 함수라고 생각할 때, 𝑧=𝑓(𝑔(𝑥,𝑦),(𝑥,𝑦))라고 바꿀 수 있습니다. 이때 다음과 같은 다변수 함수의 연쇄법칙이 성립하게 됩니다.

x에 대한 편미분을 구해서 x가 포함된 모든 함수에 대한 미분값에 연쇄법칙을 적용시킨 다음 더해주면 됩니다. 다변수 함수의 예를 한번 들어보겠습니다.

이변수 함수가 𝐶=𝑢2+𝑣2이고, 𝑢=𝑎𝑥+𝑏𝑦, 𝑣=𝑝𝑥+𝑞𝑦 (𝑎,𝑏,𝑝,𝑞 는 상수)라면 연쇄법칙의 계산 과정은 다음과 같습니다.

오늘은 간단하게 미분의 연쇄법칙에 대하여 알아보았습니다.

다음 세션으로는 수식을 통한 오차역전파법을 이해해 보도록 하겠습니다.

728x90
반응형
LIST

+ Recent posts