AI 그게 뭔데
끄적끄적 개발일지
AI 그게 뭔데
전체 방문자
오늘
어제
  • 분류 전체보기 (342)
    • 논문 (5)
    • DL(Deep-Learning) (34)
      • 개념 (14)
      • Python 기초 (14)
      • Tensorflow (6)
      • Pytorch (0)
    • NLP (10)
    • OpenCV (53)
    • DevOps (10)
      • AWS (2)
      • Docker & Kubernetes (4)
      • Spark (3)
      • SQL (1)
    • MacOS (1)
    • React-Native (2)
    • BI (3)
      • GA(Google Analytics) (3)
      • Tableau (0)
    • 알고리즘 (221)
      • 백준 (76)
      • 프로그래머스 (108)
      • 기타 알고리즘 (37)

인기 글

태그

  • 알고리즘
  • 파이썬
  • 연습문제
  • 이코테
  • LEVEL2
  • level1
  • OpenCV
  • 백준
  • 프로그래머스
  • Python

최근 글

hELLO · Designed By 정상우.
AI 그게 뭔데

끄적끄적 개발일지

[DL] 오차 역전파 Error Backpropagation
DL(Deep-Learning)/개념

[DL] 오차 역전파 Error Backpropagation

2022. 1. 28. 23:45

순전파 (Feedforward)

Input에서 Output으로 가중치를 업데이트하면서 활성화 함수를 통해서 결과값을 가져오는 것을 순전파(foward)라고 한다.

 

 

 

역전파 (Backpropagation)

역전파 알고리즘은 input과 output 값을 알고 있는 상태에서 신경망을 학습 시키는 방법이다.

 

역전파 방법은 결과 값을 통해서 다시 역으로 input 방향으로 오차를 다시 보내며 가중치를 재업데이트 하는 것이다.

결과에 영향을 많이 미친 노드(뉴런)에 더 많은 오차를 돌려준다.

 

 

 


계산 그래프 (computational graph)

  • 계산 그래프(computational graph)는 계산 과정을 그래프로 나타낸 것
  • 그래프는 복수의 노드 node 와 에지 edge 로 표현된다.

 

문제 
현빈 군은 슈퍼에서 사과를 2개, 귤을 3개 샀습니다. 사과는 1개에 100원, 귤은 1개 150원입니다. 소비세가 10%일 때 지불 금액을 구하라.

 

 

계산 그래프를 이용한 문제 풀이는 다음 흐름으로 진행된다.

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

여기서 계산을 왼쪽에서 오른쪽으로 진행하는 단계를 순전파 forward propagation 이라고 한다.

 

오르쪽에서 왼쪽으로의 전파도 있다. 역전파이다. 역전파는 이후 미분을 계산할 때 중요한 역할을 한다.

 

 

✔︎  국소적 계산

국소적이란, 자신과 직접 관계된 작은 범위라는 뜻이다.

국소적 계산은 결국, 전체에서 어떤 일이 벌어지든 상관없이 자신과 관계된 정보만으로 결과를 출력할 수 있다는 것이다.

 

 

계산 그래프는 국소적 계산에 집중한다.

전체 계산이 아무리 복잡하더라도 각 단계에서 하는 일은 해당 노드의 국소적 계산이다.

국소적인 계산은 단순하지만, 그 결과를 전달함으로써 전체를 구성하는 복잡한 계산을 할 수 있다.

 

 

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

  • 국소적 계산을 통해 각 노드의 계산에 집중하여 문제를 단순화할 수 있다.
  • 역전파를 통해 '미분'을 효율적으로 계산할 수 있다. ⭐

 

 

 

연쇄 법칙 - Chain Rule

✔ 계산 그래프의 역전파

역전파 계산 예제로 y = f(x)​ 의 역전파를 계산해보자.

 

 

 

역전파 계산 순서는 신호 E​에 노드(​f)의 국소적 미분 $\frac{\partial y }{\partial x}$ ​을 곱한 후 엣지(edge)를 통해 다음 노드로 전달하는 것이다. 여기서 국소적 미분은 순전파 때의 ​$y = f(x)$에 대한 미분을 구하는 것이고, 이것은 $x$ ​에 대한 $$y​의 미분 ​을 ($\frac{\partial y }{\partial x}$) 구한다는 의미이다.

 

 

✔ 연쇄법칙이란?

  • 합성함수의 미분은 합성 함수를 구성하는 각 함수의 미분의 곱으로 나타낼 수 있다.

 

 

 

 

 

역전파

✔ 덧셈 노드의 역전파

  • 덧셈 노드의 역전파는 입력값을 그대로 흘려보낸다. 이를 보고 gradient distributor라고 하기도 한다.

 

 

✔ 곱셈 노드의 역전파

곱셈 노드의 역전파는 입력값의 위치를 서로 바꾼 다음 곱해서 흘려보낸다. 이를 보고 gradient switcher라고 부르기도 한다.

 

 

 

 

 

 

단순한 계층 구현하기

✔ 곱셈 계층

forward()는 순전파, backward()는 역전파이다.

 

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  # x와 y를 바꾼다.
        dy = dout * self.x
        
        return dx, dy

 

 

 

apple = 100
apple_num = 2
tax = 1.1

mul_apple_layer = MulLayer()
mul_tax_layer = MulLayer()

# forward
apple_price = mul_apple_layer.forward(apple, apple_num)
price = mul_tax_layer.forward(apple_price, tax)

print(price)

 

 

 

✔ 덧셈 계층

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

 

 

 

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

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

# forward
apple_price = mul_apple_layer.forward(apple, apple_num)  # (1)
orange_price = mul_orange_layer.forward(orange, orange_num)  # (2)
all_price = add_apple_orange_layer.forward(apple_price, orange_price)  # (3)
price = mul_tax_layer.forward(all_price, tax)  # (4)

# backward
dprice = 1
dall_price, dtax = mul_tax_layer.backward(dprice)  # (4)
dapple_price, dorange_price = add_apple_orange_layer.backward(dall_price)  # (3)
dorange, dorange_num = mul_orange_layer.backward(dorange_price)  # (2)
dapple, dapple_num = mul_apple_layer.backward(dapple_price)  # (1)

print("price:", int(price))
print("dApple:", dapple)
print("dApple_num:", int(dapple_num))
print("dOrange:", dorange)
print("dOrange_num:", int(dorange_num))
print("dTax:", dtax)

 

 

 


활성화 함수 계층 구현하기

✔ ReLU 계층

 

 

class Relu:
    def __init__(self):
        self.mask = None

    def forward(self, x):
        self.mask = (x <= 0)
        out = x.copy()
        out[self.mask] = 0

        return out

    def backward(self, dout):
        dout[self.mask] = 0
        dx = dout

        return dx

 

Relu 계층은 mask 라는 인스턴스 변수를 가진다.

mask 는 True/False 로 구성된 넘파일 배열로, 순전파의 입력인 x 원소 값이 0이하인 인덱스는 True, 그 외 0보다 큰 원소는 False 로 유지한다.

 

 

✔ Sigmoid 계층

 

 

 

 

 

 

class Sigmoid:
    def __init__(self):
        self.out = None
        
    def forward(self, x):
        out = 1 / (1 + np.exp(-x))
        self.out = out
        
        return out
    
    def backward(self, dout):
        dx = dout * (1.0 - self.out) * self.out
        
        return dx

 

 

 

Affine/Softmax 계층 구현하기

✔ Affine 계층

 

 

✔ 배치용 Affine 계층

 

class Affine:
    def __init__(self, W, b):
        self.W = W
        self.b = b
        self.x = None
        self.dW = None
        self.db = None
        
    def forward(self, x):
        self.x = x
        out = np.dot(x, self.W) + self.b
        
        return out
    
    def backward(self, dout):
        dx = np.dot(dout, self.W.T)
        self.dW = np.dot(self.x.T, dout)
        self.db = np.sum(dout, axis=0)
        
        return dx

 

 

 

✔ Softmax-with-Loss 계층

딥러닝을 학습할 때는 Softmax 계층이 필요

 

소프트맥스(softmax) 계층을 구현할때, 손실함수인 교차 엔트로피 오차(cross entropy error)도 포함하여 아래의 그림과 같이 Softmax-with-Loss 계층을 구현한다.

 

 

import os, sys
sys.path.append(os.pardir)  # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
from common.functions import softmax, cross_entropy_error
​
​
class SoftmaxWithLoss:
    def __init__(self):
        self.loss = None  # 손실
        self.y = None  # softmax의 출력
        self.t = None  # 정답 레이블(one-hot)
        
    def forward(self, x, t):
        self.t = t
        self.y = softmax(x)
        self.loss = cross_entropy_error(self.y, self.t)
        return self.loss
    
    def backward(self, dout=1):
        batch_size = self.shape[0]
        dx = (self.y - self.t) / batch_size
        
        return dx

'DL(Deep-Learning) > 개념' 카테고리의 다른 글

활성화 함수 activation function  (0) 2022.01.29
[실습] numpy로 만드는 단층 신경망 - 회귀 문제  (0) 2022.01.29
[DL] 신경망 Neural Network  (0) 2022.01.28
[DL] 퍼셉트론(Perceptron)  (0) 2022.01.28
인공지능이란?  (0) 2022.01.28
    AI 그게 뭔데
    AI 그게 뭔데
    공부와 개발 그리고 AI가 약간 첨가된 흔적 남기기

    티스토리툴바