역 전파 알고리즘 소스 | [딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파) 상위 263개 베스트 답변

당신은 주제를 찾고 있습니까 “역 전파 알고리즘 소스 – [딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파)“? 다음 카테고리의 웹사이트 th.taphoamini.com 에서 귀하의 모든 질문에 답변해 드립니다: https://th.taphoamini.com/wiki/. 바로 아래에서 답을 찾을 수 있습니다. 작성자 혁펜하임 이(가) 작성한 기사에는 조회수 16,255회 및 좋아요 248개 개의 좋아요가 있습니다.

Table of Contents

역 전파 알고리즘 소스 주제에 대한 동영상 보기

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

d여기에서 [딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파) – 역 전파 알고리즘 소스 주제에 대한 세부정보를 참조하세요

딱 한번만 머리 아프면 앞으로 모든게 쉬워짐
hidden layer 두 개까진 shallow neural network,
세 개부턴 deep neural network 라고 하네요~!
#Deep_Neural_Network #Backpropagation #역전파 #chain_rule
혁펜하임 응원하기!: youtube.com/c/혁펜하임/join
혁펜하임 홈페이지: https://hyukppen.modoo.at/
혁펜하임 인스타: https://instagram.com/hyukppen
—————————————————–
\”퍼펙트\” 신호 및 시스템
https://youtube.com/playlist?list=PL_iJu012NOxcDuKgSjTKJZJd3bQtkAyZU
\”꽂히는\” 딥러닝
https://youtube.com/playlist?list=PL_iJu012NOxdDZEygsVG4jS8srnSdIgdn
\”트이는\” 강화학습
https://youtube.com/playlist?list=PL_iJu012NOxehE8fdF9me4TLfbdv3ZW8g
\”탄탄한\” 최적화
https://youtube.com/playlist?list=PL_iJu012NOxeMJ5TPPW1JZKec7rhjKXUy
\”쓰이는\” 선형대수학 (NEW!)
https://youtube.com/playlist?list=PL_iJu012NOxdZDxoGsYidMf2_bERIQaP0
—————————————————–
0:00 – Deep Neural Net 이란?
1:35 – 일단 weight들 변수로 표현
6:00 – 본능적으로 아는 chain rule
7:34 – 얕은 layer 미분
9:24 – 깊은 layer 미분
15:33 – Backpropagation 식 유도
21:19 – Backpropagation 직관적으로 이해하기

역 전파 알고리즘 소스 주제에 대한 자세한 내용은 여기를 참조하세요.

[Deep Learning-딥러닝]Backpropagation (역전파) 및 Delta …

소스 구성은 델타룰 알고리즘 및 제곱합을 Python으로 구현한 소스와 두 번째는 Tensorflow를 이용한 구현 두 가지입니다. 선행 학습으로 “경사하강법”, “ …

+ 더 읽기

Source: ynebula.tistory.com

Date Published: 12/3/2021

View: 2722

C++::BackPropagation (역전파) – 홍귀찬

만약 어떤 뉴런의 input x값과 output y 값을 알고 잇을때 어떤 W(가중치) 와 b(바이어스)를 넣어야지 원하는 y값에 도달하게 할수잇을까? w와 b에 …

+ 여기에 자세히 보기

Source: redbinalgorithm.tistory.com

Date Published: 8/12/2021

View: 8139

[밑시딥] 오직! Numpy로 오차역전파를 사용한 신경망 학습 구현 …

1. 활성화 함수(Sigmo, Relu) 와 손실 함수(Cross-entropy Error). 먼저 활성화 함수들에 대한 넘파이 소스코드이다. import numpy as np …

+ 여기에 더 보기

Source: techblog-history-younghunjo1.tistory.com

Date Published: 2/7/2021

View: 8196

04-3) 역전파(BackPropagation) 이해하기 – 딥 러닝을 이용한 …

인공 신경망이 순전파 과정을 진행하여 예측값과 실제값의 오차를 계산하였을 때 어떻게 역전파 과정에서 경사 하강법을 사용하여 가중치를 업데이트하는지 직접 계산 …

+ 여기에 표시

Source: wikidocs.net

Date Published: 5/12/2021

View: 4836

오차역전파 (Backprogation)의 개념을 쉽게 이해해 봅시다

소스 구성은 델타룰 알고리즘 및 제곱합을 Python …

+ 여기를 클릭

Source: ko.taphoamini.com

Date Published: 12/16/2021

View: 1351

[35편] 딥러닝의 핵심 개념 – 역전파(backpropagation) 이해하기1

심층 신경망을 학습하는데 유용하게 활용되는 역전파(backpropagtion) 알고리즘도 결국 이 경사하강법을 이용합니다. 그러면 역전파가 무엇인지 그 …

+ 더 읽기

Source: m.blog.naver.com

Date Published: 3/7/2022

View: 6611

오차역전파 (Backprogation)의 개념을 쉽게 이해해 봅시다

이에 대한 추가 정보 역 전파 알고리즘 소스 …

+ 자세한 내용은 여기를 클릭하십시오

Source: ko.nataviguides.com

Date Published: 3/2/2022

View: 4743

주제와 관련된 이미지 역 전파 알고리즘 소스

주제와 관련된 더 많은 사진을 참조하십시오 [딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파). 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

[딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파)
[딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파)

주제에 대한 기사 평가 역 전파 알고리즘 소스

  • Author: 혁펜하임
  • Views: 조회수 16,255회
  • Likes: 좋아요 248개
  • Date Published: 2020. 4. 27.
  • Video Url link: https://www.youtube.com/watch?v=aUd2MKLvDsc

[Deep Learning-딥러닝]Backpropagation (역전파) 및 Delta Rule을 이용한 가중치 조정 방법 소스 구현

이번 포스팅은 MLP 구조를 이용하여 XOR 연산법을 구현하는 방법에 대해서 알아보겠습니다.

요새 좋은 라이브러리도 많아서 굳이 이런 걸 만들 필요가 있을까도 생각이 들겠지만, Tensorflow에서 제공하는 방법으로 구현은 당연하고, 학습 알고리즘을 더욱 잘 이해하려면 직접 구현이 꼭 필요하다고 생각이 들어서 직접 구현해 봤습니다.

파이썬을 다루어 본 적이 없어 Doc 사이트 및 많은 구글링을 하였습니다. 또한 국내 많은 개발자는 대부분 DB를 이용하여 데이터를 처리하는 업무를 많이 합니다. 저 역시 이런 일을 많이 했습니다. 행렬 계산이 머릿속에 잘 그려지지 않아 많은 시행착오가 있었습니다.

소스 구성은 델타룰 알고리즘 및 제곱합을 Python으로 구현한 소스와 두 번째는 Tensorflow를 이용한 구현 두 가지입니다.

선행 학습으로 “경사하강법”, “Solving XOR Problem with MLP”과 “Back propagation” 이론이 필요하므로 “https://ynebula.tistory.com/14”, “https://ynebula.tistory.com/22”, “https://ynebula.tistory.com/24” 포스팅 참고 바랍니다.

학습 내용 및 신경망 구성

XOR 연산을 제곱합 비용함수와 델타룰 학습 알고리즘으로 구현합니다. 신경망 구성은 다음과 같습니다.

Network

직접 구현에서는 구현 편의상 편차는 0으로 가정하고 구현하였습니다.

제곱합 및 델타룰 알고리즘 구현

소스 구성은 “Sigmoid 함수”, “제곱합 학습 알고리즘”, “가중치 초기화 및 학습 훈련”, “학습 테스트” 부분으로 구성되어 있습니다. 학습 방법은 SGD 방식으로 구현했습니다. 또한 행렬곱 연산과 행렬합 연산 방법을 이해해야 소스 원리를 알 수 있습니다.

1. Sigmoid 구현

Source-1

Sigmoid 함수를 구현하기 위해 numpy 라이브러리를 import 합니다. 개인적으로 학습률은 너무 높지 않은 수로 설정하는 것이 좋다고 생각됩니다. 과거에 학습률을 0.9로 했을 때 결과가 잘 나오지 않았던 기억이 있습니다. N은 데이터가 4개로 되어 있으므로 4로 설정합니다.

2. 제곱합 학습 알고리즘

Source-2

backpropagationXOR 함수는 인공신경망의 가중치를 조정해서 반환하는 기능을 합니다. 인자로 가중치와 학습 데이터를 넘겨받아 새로 갱신된 가중치를 반환합니다. 인자의 역할은 다음과 같습니다.

– W1: 입력층-은닉층 가중치 행렬을 보관하는 변수 – W2: 은닉층-출력층 가중치 행렬을 보관하는 변수 – X: 학습 데이터의 입력 데이터 – D: 학습 데이터의 정답 데이터

Feed forward 부분은 가중 합 및 활성함수를 적용하였습니다. 오차 부분에서 주의할 점은 은닉층의 오차를 구할 때 W(가중치)를 전치(transpose) 했다는 점입니다. 이 오차를 사용해 은닉층의 델타를 구합니다. SGD 방식을 사용했으므로 데이터를 학습할 때마다 가중치를 갱신합니다.

Source-3

학습이 완료되면 최종 W1, W2을 이용해서 훈련 같은 방법으로 출력 값을 구하면 됩니다.

Source-4

텐서플로

은닉층, 출력층의 가중 합을 구하기 위해 행렬 곱을 연산하는 tf.matmul 함수를 사용합니다. 행렬 연산이 끝나면 편차 더해줍니다. 그리고 활성함수 tf.sigmoid를 적용하여 출력값을 계산합니다.

reduce_mean 함수는 텐서의 차원을 1차원으로 줄이고 elements의 평균을 계산합니다. 즉 정답과 출력값의 차이인 오차의 평균을 반환합니다. GradientDescentOptimizer 함수는 경사하강법 알고리즘을 구현한 함수입니다. 이 함수는 Cost가 최소가 되도록 합니다. GradientDescentOptimizer 함수는 compute_gradient와 apply_gradients 함수를 결합한 형태입니다.

텐서플로는 Session() 함수를 통해 세션을 생성하고 프로그램을 Tensorflow 라이브러리와 연결이 됩니다. 즉, 텐서플로가 알고리즘을 실행하기 위해서는 Session을 생성하고 run 메서드에 train 매개변수를 넣어 호출해야 합니다. 또한 앞에서 선언한 변수를 initialize_all_variable() 메서드를 사용해서 먼저 초기화해야 합니다. 텐서의 자료형, 구조 및 이름을 매개변수로 설정합니다. feed_dict() 의 매개변수로 전달합니다.

Source

다음 git URL에서 전체 소스를 다운받을 수 있습니다.

https://github.com/ynebula/First-Contact-with-Books/blob/master/Deep_Learning/Backpropagation.ipynb

감사합니다.

[Reference]

딥러닝 첫걸음

www.tensorflow.org

C++::BackPropagation (역전파)

반응형

만약 어떤 뉴런의 input x값과 output y 값을 알고 잇을때 어떤 W(가중치) 와 b(바이어스)를 넣어야지 원하는 y값에 도달하게 할수잇을까? w와 b에 임의값을 주어 원하는값을 찾는다는것은 거의 불가능 하다. 이때 필요한것이 backpropagation(역전파)라고 한다.

E는 오류 함수라고 하는데 구하자고 하는 값을 Y target 이라 하고 현재 Y의 차이의 제곱을 2로 나눈값으로 정의 하고있다.

E 와 W의 관계에 대한 그래프이다. 오류가 가장 적어지게 하는 W값이 어느 구간에 존재할텐데 그 구간을 미분을 통해서 알수가 있다. 오류가 작아지는 방향으로 W를 갱신 하다보면 원하는 값에 도달할수 있다. 이때 알파 값은 접근하는 속도인데 그 값이 너무 크다면 오류값의 계산에 오류가 생길 것이고 너무 작다면 W값을 찾는데 너무 많은 시간이 걸릴 것이다. 이두개의 가장 적절한 값을 배치 하는것이 중요하다. 지금 그래프에서는 미분값이 양수 이므로 반대 방향으로 가야하기 때문에 현재 가중치에 – 를 하는것이다.

(그래프가 이차 곡선을 이루므로 양수일때는 기울기가 0인 방향에 오른쪽에 있기 때문이다.)

이값은 어떻게 구할까??

가중치는 시그마에 영향을 미치고 시그마는 함수에 함수는 y(출력값)에 y는 오류 값에 영향을 미친다.

당연히 체인룰을 통해서 간단하게 구할수가 있다.

b(bias)값도 이와 같은 형식으로 우리는 구할수가 있다.

이제는 C++로 구현해보도록 하겠다.

class Neuron { public: double w_; double b_; double input_; double output_; // saved for back-prop Neuron(); Neuron(const double& w_input,const double& b_input); double getAct(const double& x); double feedForward(const double& _input); double getActGrad(const double& x); void propBacward(const double& target); };

뉴런의 클래스 구조이다. 클래스 내의 각각의 함수를 살펴보자!(생성함수 제외)

double Neuron::feedForward(const double& _input) // 시그마와 함수 과정 { input_ = _input; const double sigma = w_ * input_ +b_; output_ = getAct(sigma); return output_; }

feedForward 라는 함수는 입력에 값이 들어오면 sigma 값을 계산하고 활성화 함수를 이용해서 바로 y값을 린턴하는 함수이다.

double Neuron::getActGrad(const double& x) { // linear or idenity activation fucntion return 1.0; }

getActGrad 는 getAct라는 함수의 미분값을 반환하는 함수이다.

여기선 1을 반환한다.

노란색 과정이다. f(sigma)= sigma 인데 일차적인 관계 이므로 이값은 1

void Neuron::propBacward(const double& target) { const double alpha = 0.1; // lerning rate const double grad = (output_ – target) * getActGrad(output_); w_ -= alpha * grad * input_; // last input_) came from d(wx+b)/dw =x b_ -= alpha * grad * 1.0; // last 1.0 came from d(wx+b)/db = 1 }

propBacward 역전파 과정이다. 내가 목표로 하는 타겟을 찾는 과정에서 w값과 b값을 조정한다.

여기서 알파는 0.1로 고정 했다.

위쪽에 설명한 식을 구하기 위해서 라운드E/라운드Y값을 알수있다.

(output_ – target)이 되고 라운드Y/라운드F 값은 1인것은 생각해보면 알수있다.

(출력값 자체가 어떤 함수 f라는 것의 통과해야만 나오는 결과이므로 1:1관계임)

getActGrad는 라운드f/라운드 sigma 값이다.

이값은 input_값으로 할수있다. 왜냐 sigma 는 (wx+b) 값인데 x는 입력값이다. 미분해보면 input값만남는다.

b_의 경우에는 미분하면 1이기에 1.0을 곱한다.

int main() { Neuron My_neuron(2.0,1.0); for(int i=0;i<100;i++) { cout<<"Trainin "<[밑시딥] 오직! Numpy로 오차역전파를 사용한 신경망 학습 구현하기

🔊 해당 포스팅은 밑바닥부터 시작하는 딥러닝 1권의 교재 내용을 기반으로 딥러닝 신경망을 Tensorflow, Pytorch와 같은 딥러닝 프레임워크를 사용하지 않고 순수한 Numpy로 구현하면서 딥러닝의 기초를 탄탄히 하고자 하는 목적 하에 게시되는 포스팅입니다. 내용은 주로 필자가 중요하다고 생각되는 내용 위주로 작성되었음을 알려드립니다.

밑바닥부터 시작하는 딥러닝

저번 포스팅에서 행렬 곱을 연산하는 계층과 활성화 함수가 적용된 계층의 역전파 방법까지 알아보면서 신경망 학습의 오차역전파 방법을 모두 이해해보았다. 이번 포스팅에서는 그동안 배운 내용들을 기반으로 오직 넘파이를 활용한 오차역전파 신경망 학습을 구현해보자.

먼저 복습 차원에서 활성화 함수와 손실 함수를 넘파이로 구현하는 소스코드를 보고 가자.

1. 활성화 함수(Sigmoid, Relu) 와 손실 함수(Cross-entropy Error)

먼저 활성화 함수들에 대한 넘파이 소스코드이다.

import numpy as np # 1.sigmoid def sigmoid(x: np.array): return 1 / (1 + np.exp(-x)) # 2.relu def relu(x: np.array): return np.maximum(0, x) # 3.softmax def softmax(x: np.array): if x.ndim == 2: x = x.T x = x – np.max(x, axis=0) y = np.exp(x) / np.sum(np.exp(x), axis=0) return y.T x = x – np.max(x) return np.exp(x) / np.sum(np.exp(x))

다음은 CEE(Cross-Entropy Error) 손실함수에 대한 넘파이 소스코드이다.

# 4.cross-entropy-error def cross_entropy_error(y: np.array, t: np.array): if y.ndim == 1: t = t.reshape(1, t.size) y = y.reshape(1, y.size) # 레이블(t)가 원-핫 형태라면 레이블 형태로 변환 if t.size == y.size: t = t.argmax(aixs=1) batch_size = y.shape[0] return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7)) / batch_size

그리고 추후에 알아볼 오차역전파의 기울기 검증을 위해서 오차역전파 방법과 다르게 파라미터의 변화량값들인 기울기를 구하는 또 다른 방법으로서 수치 미분을 계산하는 소스코드도 보고 가자.

# 5. 수치 미분 계산 함수 def numerical_gradient(f, x: np.array): h = 1e-4 grads = np.zeros_like(x) it = np.nditer(x, flags=[‘multi_index’], op_flags=[‘readwrite’]) while not it.finished: idx = it.multi_index tmp_val = x[idx] # f(x+h) x[idx] = tmp_val + h fx1 = f(x) # f(x-h) x[idx] = tmp_val – h fx2 = f(x) grads[idx] = (fx1 – fx2) / (2*h) x[idx] = tmp_val it.iternext() return grads

2. 활성화 함수(Relu, Sigmoid) 계층

이제 활성화 함수 각 종류에 맞게 순전파, 역전파를 수행하는 계층 클래스를 만들자. 먼저 Relu 함수에 대한 소스코드이다.

# 1.Relu 계층 class Relu: def __init__(self): self.mask = None def forward(self, x: np.array): 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 다음은 Sigmoid 계층 소스코드이다. # 2.Sigmoid 계층 class Sigmoid: def __init__(self): self.y = None def forward(self, x: np.array): y = sigmoid(x) self.y = y return y def backward(self, dout): dx = dout * self.y * (1 - self.y) return dx 3. 행렬 곱(Affine) 계층 이번에는 행렬 곱 연산을 의미하는 Affine 계층을 넘파이로 구현하는 소스코드이다. # 3.Affine 계층 class Affine: def __init__(self, W, b): self.W = W self.b = b self.x = None self.original_x_shape = None self.dW = None self.db = None def forward(self, x: np.array): self.original_x_shape = x.shape x = x.reshape(x.shape[0], -1) self.x = x y = np.matmul(self.x, self.W) + self.b return y def backward(self, dout): dx = np.matmul(dout, self.W.T) self.dW = np.matmul(self.x.T, dout) self.db = np.sum(dout, axis=0) dx = dx.reshape(*self.original_x_shape) return dx 4. Softmax-with-Loss 계층 이번엔 Softmax와 Loss(여기서는 Cross-Entropy Error)를 하나의 계층으로 하는 계층을 넘파이로 구현하는 소스코드이다. # 4.Softmax-with-Loss 계층 class SoftmaxWithLoss: def __init__(self): self.loss = None # for loss 계층 self.t = None self.y = None def forward(self, x: np.array, t: np.array): 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.t.shape[0] dx = (self.y - self.t) / batch_size return dx 이제 오차역전파를 수행할 때 필요한 활성함수, 손실함수, 그리고 각 활성함수와 손실함수에 맞는 계층 클래스들도 알아보았다. 이를 기반으로 2층 신경망 클래스를 만들어보자. 참고로 OrderedDict라는 순서가 있는 딕셔너리 객체를 호출했는데, 이는 딕셔너리에 추가한 순서를 기억하는 특징 때문이다. 이를 활용해서 순전파 때 호출한 레이어 순서를 역전파 시 뒤바꾸어서 호출할 수 있기 때문이다. import numpy as np from collections import OrderedDict class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01): # 2층 신경망의 파라미터 딕셔너리 self.params = {} self.params['W1'] = np.random.randn(input_size, hidden_size) * weight_init_std self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = np.random.randn(hidden_size, output_size) * weight_init_std self.params['b2'] = np.zeros(output_size) # 2층 신경망의 계층 생성 self.layers = OrderedDict() self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1']) self.layers['Relu1'] = Relu() self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2']) self.lastlayer = SoftmaxWithLoss() def predict(self, x): for layer in self.layers.values: x = layer.forward(x) return x def loss(self, x, t): y = self.predict(x) loss = self.lastlayer.forward(y, t) return loss def accuracy(self, x, t): y = self.predict(x) y = np.argmax(y, axis=1) if t.ndim != 1: t = np.argmax(t, axis=1) acc = np.sum(y == t) / float(y.shape[0]) return acc def gradient(self, x, t): # 순전파 수행 self.loss(x, t) # 역전파 수행 - 1.Softmax-with-Loss 계층 dout = 1 dout = self.lastlayer.backward(dout) # 역전파 수행 - 2.나머지 계층 layers = list(self.layers.values()) layers.reverse() for layer in layers: dout = layer.backward(dout) # 역전파 수행한 결과의 파라미터 변화량 보관 grads = {} grads['W1'] = self.layers['Affine1'].dW grads['b1'] = self.layers['Affine1'].db grads['W2'] = self.layers['Affine2'].dW grads['b2'] = self.layers['Affine2'].db return grads # 수치미분으로 기울기 계산(for 오차역전파 기울기 검증 목적) def numerical_gradient(self, x, t): loss_w = lambda w: self.loss(x, t) grads = {} # 여기의 numerical_gradient 함수는 바깥에서 정의한 수치미분 계산 함수임! grads['W1'] = numerical_gradient(loss_w, self.params['W1']) grads['b1'] = numerical_gradient(loss_w, self.params['b1']) grads['W2'] = numerical_gradient(loss_w, self.params['W2']) grads['b2'] = numerical_gradient(loss_w, self.params['b2']) return grads 위 2층 신경망 클래스를 가지고 MNIST 데이터를 학습시켜보자. import numpy as np from dataset.mnist import load_mnist (X_train, y_train), (X_test, y_test) = load_mnist(normalize=True, one_hot_label=True) # 2층 신경망 설계 network = TwoLayerNet(input_size=28*28, hidden_size=50, output_size=10) steps = 1000 train_size = X_train.shape[0] batch_size= 100 learning_rate = 0.1 train_loss = [] train_acc = [] test_acc = [] # Mini-batch로 학습 for i in range(steps): batch_mask = np.random.choice(train_size, batch_size) X_batch = X_train[batch_mask] y_batch = y_train[batch_mask] # 오차역전파로 학습 수행 grads = network.gradient(X_batch, y_batch) # SGD로 경사하강법 수행 for key in ('W1', 'b1', 'W2', 'b2'): network.params[key] -= learning_rate * grads[key] # SGD로 파라미터 갱신 후 다시 Loss값 얻기 loss = network.loss(X_batch, y_batch) train_loss.append(loss) # 성능 중간 체크 if i % 10 == 0: tr_acc = network.accuracy(X_batch, y_batch) te_acc = network.accuracy(X_test, y_test) train_acc.append(tr_acc) test_acc.append(te_acc) print(f'{i+1}번째 학습 후 Train Acc:', round(tr_acc, 3)) print(f'{i+1}번째 학습 후 Test Acc:', round(te_acc, 3)) print() 다음은 오차역전파를 통해서 구한 기울기 값이 정말 잘 구해졌는지 검증하기 위한 방법으로 수치 미분을 활용할 수 있다. 수치 미분은 상대적으로 오차역전파보다 계산이 오래걸린다고 했다. 하지만 직접 수학적인 계산을 했기 때문에 해석적 방법을 사용하는 오차역전파 결과를 검증하는 데 자주 사용된다. 이를 기울기 확인(Gradient Check) 과정이라고도 한다. 각자 2가지 방법을 활용해 기울기를 구한 값 차이를 확인해보는 소스코드이다. 두 값 차이가 0에 가깝다면 오차역전파를 통한 기울기 계산이 잘 되었다고 할 수 있다. from dataset.mnist import load_mnist # load data (X_train, y_train), (X_test, y_test) = load_mnist(normalize=True, one_hot_label=True) # model network = TwoLayerNet(input_size=28*28, hidden_size=50, output_size=10) # Batch X_batch = X_train[:3] y_batch = y_train[:3] # 수치미분 grad_numerical = network.numerical_gradient(X_batch, y_batch) grad_propagation = network.gradient(X_batch, y_batch) for key in grad_numerical.keys(): diff = np.mean(np.abs(grad_numerical[key] - grad_propagation[key])) print('key:', key, 'diff:', diff)

04-3) 역전파(BackPropagation) 이해하기

인공 신경망이 순전파 과정을 진행하여 예측값과 실제값의 오차를 계산하였을 때 어떻게 역전파 과정에서 경사 하강법을 사용하여 가중치를 업데이트하는지 직접 계산을 통해 이해해봅시다.

1. 인공 신경망의 이해(Neural Network Overview)

우선 예제를 위해 사용될 인공 신경망을 소개합니다. 역전파의 이해를 위해서 여기서 사용할 인공 신경망은 입력층, 은닉층, 출력층 이렇게 3개의 층을 가집니다. 또한 해당 인공 신경망은 두 개의 입력과, 두 개의 은닉층 뉴런, 두 개의 출력층 뉴런을 사용합니다. 은닉층과 출력층의 모든 뉴런은 활성화 함수로 시그모이드 함수를 사용합니다.

위의 그림은 여기서 사용할 인공 신경망의 모습을 보여줍니다. 은닉층과 출력층의 모든 뉴런에서 변수 $z$가 존재하는데 여기서 변수 $z$는 이전층의 모든 입력이 각각의 가중치와 곱해진 값들이 모두 더해진 가중합을 의미합니다. 이 값은 뉴런에서 아직 시그모이드 함수를 거치지 않은 상태입니다. 즉, 활성화 함수의 입력을 의미합니다. $z$ 우측의 |를 지나서 존재하는 변수 $h$ 또는 $o$는 $z$가 시그모이드 함수를 지난 후의 값으로 각 뉴런의 출력값을 의미합니다. 이번 역전파 예제에서는 인공 신경망에 존재하는 모든 가중치 $w$에 대해서 역전파를 통해 업데이트하는 것을 목표로합니다. 해당 인공 신경망은 편향 $b$는 고려하지 않습니다.

2. 순전파(Forward Propagation)

주어진 값이 위의 그림과 같을 때 순전파를 진행해봅시다. 위의 그림에서 소수점 앞의 0은 생략하였습니다. 예를 들어 .25는 0.25를 의미합니다. 파란색 숫자는 입력값을 의미하며, 빨간색 숫자는 각 가중치의 값을 의미합니다. 앞으로 진행하는 계산의 결과값은 소수점 아래 여덟번째 자리까지 반올림하여 표기합니다.

각 입력은 입력층에서 은닉층 방향으로 향하면서 각 입력에 해당하는 가중치와 곱해지고, 결과적으로 가중합으로 계산되어 은닉층 뉴런의 시그모이드 함수의 입력값이 됩니다. $z_{1}$과 $z_{2}$는 시그모이드 함수의 입력으로 사용되는 각각의 값에 해당됩니다.

$$z_{1}=w_{1}x_{1} + w_{2}x_{2}=0.3 \text{×} 0.1 + 0.25 \text{×} 0.2= 0.08$$ $$z_{2}=w_{3}x_{1} + w_{4}x_{2}=0.4 \text{×} 0.1 + 0.35 \text{×} 0.2= 0.11$$ $z_{1}$과 $z_{2}$는 각각의 은닉층 뉴런에서 시그모이드 함수를 지나게 되는데 시그모이드 함수가 리턴하는 결과값은 은닉층 뉴런의 최종 출력값입니다. 식에서는 각각 $h_{1}$과 $h_{2}$에 해당되며, 아래의 결과와 같습니다. $$h_{1}=sigmoid(z_{1}) = 0.51998934$$ $$h_{2}=sigmoid(z_{2}) = 0.52747230$$ $h_{1}$과 $h_{2}$ 이 두 값은 다시 출력층의 뉴런으로 향하게 되는데 이때 다시 각각의 값에 해당되는 가중치와 곱해지고, 다시 가중합 되어 출력층 뉴런의 시그모이드 함수의 입력값이 됩니다. 식에서는 각각 $z_{3}$과 $z_{4}$에 해당됩니다. $$z_{3}=w_{5}h_{1}+w_{6}h_{2} = 0.45 \text{×} h_{1} + 0.4 \text{×} h_{2} = 0.44498412$$ $$z_{4}=w_{7}h_{1}+w_{8}h_{2} = 0.7 \text{×} h_{1} + 0.6 \text{×} h_{2} = 0.68047592$$ $z_{3}$과 $z_{4}$이 출력층 뉴런에서 시그모이드 함수를 지난 값은 이 인공 신경망이 최종적으로 계산한 출력값입니다. 실제값을 예측하기 위한 값으로서 예측값이라고도 부릅니다. $$o_{1}=sigmoid(z_{3})=0.60944600$$ $$o_{2}=sigmoid(z_{4})=0.66384491$$ 이제 해야할 일은 예측값과 실제값의 오차를 계산하기 위한 오차 함수를 선택하는 것입니다. 오차(Error)를 계산하기 위한 손실 함수(Loss function)로는 평균 제곱 오차 MSE를 사용합니다. 식에서는 실제값을 target이라고 표현하였으며, 순전파를 통해 나온 예측값을 output으로 표현하였습니다. 그리고 각 오차를 모두 더하면 전체 오차 $E_{total}$가 됩니다. $$E_{o1}=\frac{1}{2}(target_{o1}-output_{o1})^{2}=0.02193381$$ $$E_{o2}=\frac{1}{2}(target_{o2}-output_{o2})^{2}=0.00203809$$ $$E_{total}=E_{o1}+E_{o2}=0.02397190$$

3. 역전파 1단계(BackPropagation Step 1)

순전파가 입력층에서 출력층으로 향한다면 역전파는 반대로 출력층에서 입력층 방향으로 계산하면서 가중치를 업데이트해갑니다. 출력층 바로 이전의 은닉층을 N층이라고 하였을 때, 출력층과 N층 사이의 가중치를 업데이트하는 단계를 역전파 1단계, 그리고 N층과 N층의 이전층 사이의 가중치를 업데이트 하는 단계를 역전파 2단계라고 해봅시다.

역전파 1단계에서 업데이트 해야 할 가중치는 $w_{5}, w_{6}, w_{7}, w_{8}$ 총 4개입니다. 원리 자체는 동일하므로 우선 $w_{5}$에 대해서 먼저 업데이트를 진행해보겠습니다. 경사 하강법을 수행하려면 가중치 $w_{5}$를 업데이트 하기 위해서 $\frac{∂E_{total}}{∂w_{5}}$를 계산해야 합니다.

$\frac{∂E_{total}}{∂w_{5}}$를 계산하기 위해 미분의 연쇄 법칙(Chain rule)에 따라서 이와 같이 풀어 쓸 수 있습니다. $$\frac{∂E_{total}}{∂w_{5}} = \frac{∂E_{total}}{∂o_{1}} \text{×} \frac{∂o_{1}}{∂z_{3}} \text{×} \frac{∂z_{3}}{∂w_{5}}$$ 위의 식에서 우변의 세 개의 각 항에 대해서 순서대로 계산해봅시다. 우선 첫번째 항에 대해서 계산해보겠습니다. 미분을 진행하기 전에 $E_{total}$의 값을 상기해봅시다. $E_{total}$은 앞서 순전파를 진행하고 계산했던 전체 오차값입니다. 식은 다음과 같습니다. $$E_{total}=\frac{1}{2}(target_{o1}-output_{o1})^{2} + \frac{1}{2}(target_{o2}-output_{o2})^{2}$$ 이에 $\frac{∂E_{total}}{∂o_{1}}$는 다음과 같습니다. $$\frac{∂E_{total}}{∂o_{1}}=2 \text{×} \frac{1}{2}(target_{o1}-output_{o1})^{2-1} \text{×} (-1) + 0$$ $$\frac{∂E_{total}}{∂o_{1}}=-(target_{o1}-output_{o1})=-(0.4-0.60944600)=0.20944600$$

이제 두번째 항을 주목해봅시다. $o_{1}$이라는 값은 시그모이드 함수의 출력값입니다. 그런데 시그모이드 함수의 미분은 $f(x) \text{×} (1-f(x))$입니다. 앞으로의 계산 과정에서도 계속해서 시그모이드 함수를 미분해야 하는 상황이 생기므로 기억해둡시다. 이에 따라서 두번째 항의 미분 결과는 다음과 같습니다.

(시그모이드 함수 미분 참고 링크 : https://en.wikipedia.org/wiki/Logistic_function#Derivative)

$$\frac{∂o_{1}}{∂z_{3}}=o_{1}\text{×}(1-o_{1})=0.60944600(1-0.60944600)=0.23802157$$ 마지막으로 세번째 항은 $h_{1}$의 값과 동일합니다. $$\frac{∂z_{3}}{∂w_{5}}=h_{1}=0.51998934$$ 우변의 모든 항을 계산하였습니다. 이제 이 값을 모두 곱해주면 됩니다.

$$\frac{∂E_{total}}{∂w_{5}} = 0.20944600 \text{×} 0.23802157 \text{×} 0.51998934 = 0.02592286$$ 이제 앞서 배웠던 경사 하강법을 통해 가중치를 업데이트 할 때가 왔습니다! 하이퍼파라미터에 해당되는 학습률(learning rate) $α$는 0.5라고 가정합니다.

$$w_{5}^{+}=w_{5}-α\frac{∂E_{total}}{∂w_{5}}=0.45- 0.5 \text{×} 0.02592286=0.43703857$$ 이와 같은 원리로 $w_{6}^{+},\ w_{7}^{+},\ w_{8}^{+}$을 계산할 수 있습니다.

$$\frac{∂E_{total}}{∂w_{6}} = \frac{∂E_{total}}{∂o_{1}} \text{×} \frac{∂o_{1}}{∂z_{3}} \text{×} \frac{∂z_{3}}{∂w_{6}} → w_{6}^{+}=0.38685205$$ $$\frac{∂E_{total}}{∂w_{7}} = \frac{∂E_{total}}{∂o_{2}} \text{×} \frac{∂o_{2}}{∂z_{4}} \text{×} \frac{∂z_{4}}{∂w_{7}} → w_{7}^{+}=0.69629578$$ $$\frac{∂E_{total}}{∂w_{8}} = \frac{∂E_{total}}{∂o_{2}} \text{×} \frac{∂o_{2}}{∂z_{4}} \text{×} \frac{∂z_{4}}{∂w_{8}} → w_{8}^{+}=0.59624247$$

4. 역전파 2단계(BackPropagation Step 2)

1단계를 완료하였다면 이제 입력층 방향으로 이동하며 다시 계산을 이어갑니다. 위의 그림에서 빨간색 화살표는 순전파의 정반대 방향인 역전파의 방향을 보여줍니다. 현재 인공 신경망은 은닉층이 1개밖에 없으므로 이번 단계가 마지막 단계입니다. 하지만 은닉층이 더 많은 경우라면 입력층 방향으로 한 단계씩 계속해서 계산해가야 합니다.

이번 단계에서 계산할 가중치는 $w_{1}, w_{2}, w_{3}, w_{4}$입니다. 원리 자체는 동일하므로 우선 $w_{1}$에 대해서 먼저 업데이트를 진행해보겠습니다. 경사 하강법을 수행하려면 가중치 $w_{1}$를 업데이트 하기 위해서 $\frac{∂E_{total}}{∂w_{1}}$를 계산해야 합니다.

$\frac{∂E_{total}}{∂w_{1}}$를 계산하기 위해 미분의 연쇄 법칙(Chain rule)에 따라서 이와 같이 풀어 쓸 수 있습니다. $$\frac{∂E_{total}}{∂w_{1}} = \frac{∂E_{total}}{∂h_{1}} \text{×} \frac{∂h_{1}}{∂z_{1}} \text{×} \frac{∂z_{1}}{∂w_{1}}$$ 위의 식에서 우변의 첫번째항인 $\frac{∂E_{total}}{∂h_{1}}$는 다음과 같이 다시 식을 풀어서 쓸 수 있습니다.

$$\frac{∂E_{total}}{∂h_{1}} = \frac{∂E_{o1}}{∂h_{1}} + \frac{∂E_{o2}}{∂h_{1}}$$ 위의 식의 우변의 두 항을 각각 구해봅시다. 우선 첫번째 항 $\frac{∂E_{o1}}{∂h_{1}}$에 대해서 항을 분해 및 계산해보겠습니다.

$$\frac{∂E_{o1}}{∂h_{1}} = \frac{∂E_{o1}}{∂z_{3}} \text{×} \frac{{∂z_{3}}}{∂h_{1}} = \frac{∂E_{o1}}{∂o_{1}} \text{×} \frac{∂o_{1}}{∂z_{3}} \text{×} \frac{{∂z_{3}}}{∂h_{1}}$$ $$= -(target_{o1}-output_{o1}) \text{×} o_{1}\text{×}(1-o_{1}) \text{×} w_{5}$$ $$= 0.20944600 \text{×} 0.23802157 \text{×} 0.45 = 0.02243370$$ 이와 같은 원리로 $\frac{∂E_{o2}}{∂h_{1}}$ 또한 구합니다. $$\frac{∂E_{o2}}{∂h_{1}} = \frac{∂E_{o2}}{∂z_{4}} \text{×} \frac{{∂z_{4}}}{∂h_{1}} = \frac{∂E_{o2}}{∂o_{2}} \text{×} \frac{∂o_{2}}{∂z_{4}} \text{×} \frac{{∂z_{4}}}{∂h_{1}} = 0.00997311$$

$$\frac{∂E_{total}}{∂h_{1}} = 0.02243370 + 0.00997311 = 0.03240681$$ 이제 $\frac{∂E_{total}}{∂w_{1}}$를 구하기 위해서 필요한 첫번째 항을 구했습니다. 나머지 두 항에 대해서 구해보도록 하겠습니다. $$\frac{∂h_{1}}{∂z_{1}} = h_{1}\text{×}(1-h_{1}) = 0.51998934(1-0.51998934)=0.24960043$$ $$\frac{∂z_{1}}{∂w_{1}} = x_{1} = 0.1$$ 즉, $\frac{∂E_{total}}{∂w_{1}}$는 다음과 같습니다. $$\frac{∂E_{total}}{∂w_{1}} = 0.03240681 \text{×} 0.24960043 \text{×} 0.1 = 0.00080888$$ 이제 앞서 배웠던 경사 하강법을 통해 가중치를 업데이트 할 수 있습니다. $$w_{1}^{+}=w_{1}-α\frac{∂E_{total}}{∂w_{1}}=0.3- 0.5 \text{×} 0.00080888=0.29959556$$ 이와 같은 원리로 $w_{2}^{+},\ w_{3}^{+},\ w_{4}^{+}$을 계산할 수 있습니다.

$$\frac{∂E_{total}}{∂w_{2}} = \frac{∂E_{total}}{∂h_{1}} \text{×} \frac{∂h_{1}}{∂z_{1}} \text{×} \frac{∂z_{1}}{∂w_{2}} → w_{2}^{+}=0.24919112$$ $$\frac{∂E_{total}}{∂w_{3}} = \frac{∂E_{total}}{∂h_{2}} \text{×} \frac{∂h_{2}}{∂z_{2}} \text{×} \frac{∂z_{2}}{∂w_{3}} → w_{3}^{+}=0.39964496$$ $$\frac{∂E_{total}}{∂w_{4}} = \frac{∂E_{total}}{∂h_{2}} \text{×} \frac{∂h_{2}}{∂z_{2}} \text{×} \frac{∂z_{2}}{∂w_{4}} → w_{4}^{+}=0.34928991$$

5. 결과 확인

업데이트 된 가중치에 대해서 다시 한 번 순전파를 진행하여 오차가 감소하였는지 확인해보겠습니다.

$$z_{1}=w_{1}x_{1} + w_{2}x_{2}=0.29959556 \text{×} 0.1 + 0.24919112 \text{×} 0.2= 0.07979778$$ $$z_{2}=w_{3}x_{1} + w_{4}x_{2}=0.39964496 \text{×} 0.1 + 0.34928991 \text{×} 0.2= 0.10982248$$ $$h_{1}=sigmoid(z_{1}) = 0.51993887$$ $$h_{2}=sigmoid(z_{2}) = 0.52742806$$ $$z_{3}=w_{5}h_{1}+w_{6}h_{2} = 0.43703857 \text{×} h_{1} + 0.38685205 \text{×} h_{2} = 0.43126996$$ $$z_{4}=w_{7}h_{1}+w_{8}h_{2} = 0.69629578 \text{×} h_{1} + 0.59624247 \text{×} h_{2} = 0.67650625$$ $$o_{1}=sigmoid(z_{3})=0.60617688$$ $$o_{2}=sigmoid(z_{4})=0.66295848$$ $$E_{o1}=\frac{1}{2}(target_{o1}-output_{o1})^{2}=0.02125445$$ $$E_{o2}=\frac{1}{2}(target_{o2}-output_{o2})^{2}=0.00198189$$ $$E_{total}=E_{o1}+E_{o2}=0.02323634$$ 기존의 전체 오차 $E_{total}$가 0.02397190였으므로 1번의 역전파로 오차가 감소한 것을 확인할 수 있습니다. 인공 신경망의 학습은 오차를 최소화하는 가중치를 찾는 목적으로 순전파와 역전파를 반복하는 것을 말합니다.

https://medium.com/@14prakash/back-propagation-is-very-simple-who-made-it-complicated-97b794c97e5c

https://www.youtube.com/watch?v=ZMgax46Rd3g

역 전파 알고리즘 소스 답을 믿으세요 – Ko.taphoamini.com

당신은 주제를 찾고 있습니까 “역 전파 알고리즘 소스 – 오차역전파 (Backprogation)의 개념을 쉽게 이해해 봅시다“? 다음 카테고리의 웹사이트 Ko.taphoamini.com 에서 귀하의 모든 질문에 답변해 드립니다: Ko.taphoamini.com/photos. 바로 아래에서 답을 찾을 수 있습니다. 작성자 테디노트 TeddyNote 이(가) 작성한 기사에는 조회수 14,055회 및 좋아요 328개 개의 좋아요가 있습니다.

여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!

오차역전파 (Backpropagation)에 대한 수학적 이해를 도와드리는 영상입니다.

편미분, Chain Rule에 대한 개념이 부족하신 분들은 이전 영상을 먼저 보시고 오세요.

#오차역전파 #딥러닝 #설명

텐서플로우 자격증 취득 강의: https://bit.ly/tfcert-vod

테디노트(깃헙 블로그) : https://teddylee777.github.io

머신러닝 혼자서 스터디 : https://github.com/teddylee777/machine-learning

소스 구성은 델타룰 알고리즘 및 제곱합을 Python으로 구현한 소스와 두 번째는 Tensorflow를 이용한 구현 두 가지입니다. 선행 학습으로 “경사하강법”, “ …

+ 더 읽기

Source: ynebula.tistory.com

Date Published: 7/7/2021

View: 5545

만약 어떤 뉴런의 input x값과 output y 값을 알고 잇을때 어떤 W(가중치) 와 b(바이어스)를 넣어야지 원하는 y값에 도달하게 할수잇을까? w와 b에 …

+ 여기에 더 보기

Source: redbinalgorithm.tistory.com

Date Published: 6/19/2022

View: 2177

먼저 활성화 함수들에 대한 넘파이 소스코드이다. import numpy as np # 1.sigmo def sigmo(x: np …

+ 여기에 더 보기

Source: techblog-history-younghunjo1.tistory.com

Date Published: 11/23/2022

View: 8167

(비용 함수와 역전파). Backpropagation Algorithm (역전파 알고리즘). In the previous veo, we talked about a cost function for the neural network …

+ 여기에 자세히 보기

Source: brunch.co.kr

Date Published: 7/5/2022

View: 6329

텐서플로우 같은 라이브러리가 역전파 알고리즘을 모두 자동으로 처리해 주는 데 굳이 numpy 로 정방향(forward pass), 역방향(backward pass, …

+ 여기에 더 보기

Source: tensorflow.blog

Date Published: 5/17/2022

View: 3320

[C#/COMMON] 신경망 역전파 알고리즘 사용하기 … totalWeightCount) { throw new Exception(“잘못된 소스 가중치 배열 길이 입니다.

+ 자세한 내용은 여기를 클릭하십시오

Source: icodebroker.tistory.com

Date Published: 9/28/2022

View: 3638

차시별 강의 ; 퍼셉트론 Tensorflow 코드 구현, URL ; 퍼셉트론 활용, 소스 URL ; 4. 다층퍼셉트론 및 오류 역전파 알고리즘, URL.

+ 여기에 보기

Source: www.kocw.net

Date Published: 11/18/2021

View: 2249

주제와 관련된 더 많은 사진을 참조하십시오 오차역전파 (Backprogation)의 개념을 쉽게 이해해 봅시다. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

# 1.Relu 계층 class Relu: def __init__(self): self.mask = None def forward(self, x: np.array): 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 다음은 Sigmoid 계층 소스코드이다. # 2.Sigmoid 계층 class Sigmoid: def __init__(self): self.y = None def forward(self, x: np.array): y = sigmoid(x) self.y = y return y def backward(self, dout): dx = dout * self.y * (1 - self.y) return dx 3. 행렬 곱(Affine) 계층 이번에는 행렬 곱 연산을 의미하는 Affine 계층을 넘파이로 구현하는 소스코드이다. # 3.Affine 계층 class Affine: def __init__(self, W, b): self.W = W self.b = b self.x = None self.original_x_shape = None self.dW = None self.db = None def forward(self, x: np.array): self.original_x_shape = x.shape x = x.reshape(x.shape[0], -1) self.x = x y = np.matmul(self.x, self.W) + self.b return y def backward(self, dout): dx = np.matmul(dout, self.W.T) self.dW = np.matmul(self.x.T, dout) self.db = np.sum(dout, axis=0) dx = dx.reshape(*self.original_x_shape) return dx 4. Softmax-with-Loss 계층 이번엔 Softmax와 Loss(여기서는 Cross-Entropy Error)를 하나의 계층으로 하는 계층을 넘파이로 구현하는 소스코드이다. # 4.Softmax-with-Loss 계층 class SoftmaxWithLoss: def __init__(self): self.loss = None # for loss 계층 self.t = None self.y = None def forward(self, x: np.array, t: np.array): 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.t.shape[0] dx = (self.y - self.t) / batch_size return dx 이제 오차역전파를 수행할 때 필요한 활성함수, 손실함수, 그리고 각 활성함수와 손실함수에 맞는 계층 클래스들도 알아보았다. 이를 기반으로 2층 신경망 클래스를 만들어보자. 참고로 OrderedDict라는 순서가 있는 딕셔너리 객체를 호출했는데, 이는 딕셔너리에 추가한 순서를 기억하는 특징 때문이다. 이를 활용해서 순전파 때 호출한 레이어 순서를 역전파 시 뒤바꾸어서 호출할 수 있기 때문이다. import numpy as np from collections import OrderedDict class TwoLayerNet: def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01): # 2층 신경망의 파라미터 딕셔너리 self.params = {} self.params['W1'] = np.random.randn(input_size, hidden_size) * weight_init_std self.params['b1'] = np.zeros(hidden_size) self.params['W2'] = np.random.randn(hidden_size, output_size) * weight_init_std self.params['b2'] = np.zeros(output_size) # 2층 신경망의 계층 생성 self.layers = OrderedDict() self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1']) self.layers['Relu1'] = Relu() self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2']) self.lastlayer = SoftmaxWithLoss() def predict(self, x): for layer in self.layers.values: x = layer.forward(x) return x def loss(self, x, t): y = self.predict(x) loss = self.lastlayer.forward(y, t) return loss def accuracy(self, x, t): y = self.predict(x) y = np.argmax(y, axis=1) if t.ndim != 1: t = np.argmax(t, axis=1) acc = np.sum(y == t) / float(y.shape[0]) return acc def gradient(self, x, t): # 순전파 수행 self.loss(x, t) # 역전파 수행 - 1.Softmax-with-Loss 계층 dout = 1 dout = self.lastlayer.backward(dout) # 역전파 수행 - 2.나머지 계층 layers = list(self.layers.values()) layers.reverse() for layer in layers: dout = layer.backward(dout) # 역전파 수행한 결과의 파라미터 변화량 보관 grads = {} grads['W1'] = self.layers['Affine1'].dW grads['b1'] = self.layers['Affine1'].db grads['W2'] = self.layers['Affine2'].dW grads['b2'] = self.layers['Affine2'].db return grads # 수치미분으로 기울기 계산(for 오차역전파 기울기 검증 목적) def numerical_gradient(self, x, t): loss_w = lambda w: self.loss(x, t) grads = {} # 여기의 numerical_gradient 함수는 바깥에서 정의한 수치미분 계산 함수임! grads['W1'] = numerical_gradient(loss_w, self.params['W1']) grads['b1'] = numerical_gradient(loss_w, self.params['b1']) grads['W2'] = numerical_gradient(loss_w, self.params['W2']) grads['b2'] = numerical_gradient(loss_w, self.params['b2']) return grads 위 2층 신경망 클래스를 가지고 MNIST 데이터를 학습시켜보자. import numpy as np from dataset.mnist import load_mnist (X_train, y_train), (X_test, y_test) = load_mnist(normalize=True, one_hot_label=True) # 2층 신경망 설계 network = TwoLayerNet(input_size=28*28, hidden_size=50, output_size=10) steps = 1000 train_size = X_train.shape[0] batch_size= 100 learning_rate = 0.1 train_loss = [] train_acc = [] test_acc = [] # Mini-batch로 학습 for i in range(steps): batch_mask = np.random.choice(train_size, batch_size) X_batch = X_train[batch_mask] y_batch = y_train[batch_mask] # 오차역전파로 학습 수행 grads = network.gradient(X_batch, y_batch) # SGD로 경사하강법 수행 for key in ('W1', 'b1', 'W2', 'b2'): network.params[key] -= learning_rate * grads[key] # SGD로 파라미터 갱신 후 다시 Loss값 얻기 loss = network.loss(X_batch, y_batch) train_loss.append(loss) # 성능 중간 체크 if i % 10 == 0: tr_acc = network.accuracy(X_batch, y_batch) te_acc = network.accuracy(X_test, y_test) train_acc.append(tr_acc) test_acc.append(te_acc) print(f'{i+1}번째 학습 후 Train Acc:', round(tr_acc, 3)) print(f'{i+1}번째 학습 후 Test Acc:', round(te_acc, 3)) print() 다음은 오차역전파를 통해서 구한 기울기 값이 정말 잘 구해졌는지 검증하기 위한 방법으로 수치 미분을 활용할 수 있다. 수치 미분은 상대적으로 오차역전파보다 계산이 오래걸린다고 했다. 하지만 직접 수학적인 계산을 했기 때문에 해석적 방법을 사용하는 오차역전파 결과를 검증하는 데 자주 사용된다. 이를 기울기 확인(Gradient Check) 과정이라고도 한다. 각자 2가지 방법을 활용해 기울기를 구한 값 차이를 확인해보는 소스코드이다. 두 값 차이가 0에 가깝다면 오차역전파를 통한 기울기 계산이 잘 되었다고 할 수 있다. from dataset.mnist import load_mnist # load data (X_train, y_train), (X_test, y_test) = load_mnist(normalize=True, one_hot_label=True) # model network = TwoLayerNet(input_size=28*28, hidden_size=50, output_size=10) # Batch X_batch = X_train[:3] y_batch = y_train[:3] # 수치미분 grad_numerical = network.numerical_gradient(X_batch, y_batch) grad_propagation = network.gradient(X_batch, y_batch) for key in grad_numerical.keys(): diff = np.mean(np.abs(grad_numerical[key] - grad_propagation[key])) print('key:', key, 'diff:', diff) 온라인 강의 플랫폼 코세라의 창립자인 앤드류 응 (Andrew Ng) 교수는 인공지능 업계의 거장입니다. 그가 스탠퍼드 대학에서 머신 러닝 입문자에게 한 강의를 그대로 코세라 온라인 강의 (Coursera.org)에서 무료로 배울 수 있습니다. 이 강의는 머신러닝 입문자들의 필수코스입니다. 인공지능과 머신러닝을 혼자 공부하면서 자연스럽게 만나게 되는 강의입니다. Neural Networks : Learning 인공 신경망 : 학습 Cost Function and Backpropagation (비용 함수와 역전파) Backpropagation Algorithm (역전파 알고리즘) In the previous video, we talked about a cost function for the neural network. In this video, let’s start to talk about an algorithm, for trying to minimize the cost function. In particular, we’ll talk about the back propagation algorithm. 지난 강의에서 신경망의 비용 함수를 설명했습니다. 이번 강의에서 비용 함수를 최소화하기 위한 알고리즘인 역전파(Back Propagation)를 설명합니다. Here’s the cost function that we wrote down in the previous video. What we’d like to do is try to find parameters theta to try to minimize j of theta. In order to use either gradient descent or one of the advance optimization algorithms. What we need to do therefore is to write code that takes this input the parameters theta and computes j of theta and these partial derivative terms. Remember, that the parameters in the the neural network of these things, theta superscript l subscript ij, that’s the real number and so, these are the partial derivative terms we need to compute. In order to compute the cost function j of theta, we just use this formula up here and so, what I want to do for the most of this video is focus on talking about how we can compute these partial derivative terms. 여기 지난 강의에서 배운 정규화된 비용 함수가 있습니다. 비용 함수 J(Θ)를 최소화하기 위한 파라미터 Θ를 찾기 위해 경사 하강법 또는 고급 최적화 알고리즘 중 하나를 사용합니다. 파라미터 Θ 값을 활용하여 비용 함수 J(Θ)와 J(Θ)의 편미분항을 계산하는 코드를 작성합니다. 신경망 파라미터 Θ^(l)ij (위 첨자 l, 아래 첨자 ij)는 실수이고 편미분 함수입니다. 비용 함수 J(Θ)는 이미 설명하였고, J(Θ)의 편미분항에 대해 설명합니다. Let’s start by talking about the case of when we have only one training example, so imagine, if you will that our entire training set comprises only one training example which is a pair xy. I’m not going to write x1y1 just write this. Write a one training example as xy and let’s tap through the sequence of calculations we would do with this one training example. 전체 학습 데이터 셋이 (x, y)의 쌍입니다. 학습 데이터 셋 예제를 (x^(1), y^(1))이 아닌 (x, y)로 적습니다. 학습 데이터 셋 예제가 하나일 때부터 계산 절차를 살펴봅니다. 학습 예제 (x, y)를 계산하는 순서를 살펴봅니다. The first thing we do is we apply forward propagation in order to compute whether a hypotheses actually outputs given the input. Concretely, the called the a(1) is the activation values of this first layer that was the input there. So, I’m going to set that to x and then we’re going to compute z(2) equals theta(1) a(1) and a(2) equals g, the sigmoid activation function applied to z(2) and this would give us our activations for the first middle layer. That is for layer two of the network and we also add those bias terms. Next we apply 2 more steps of this four and propagation to compute a(3) and a(4) which is also the upwards of a hypotheses h of x. So this is our vectorized implementation of forward propagation and it allows us to compute the activation values for all of the neurons in our neural network. 입력 x에 대한 가설이자 출력 값을 계산하기 위해 순전파 알고리즘을 적용합니다. 첫 번째, 입력층이자 첫 번째 층 a^(1)는 학습 예제 x의 값입니다. 두 번째, 두 번째 층 a^(2)는 시그모이드 함수 g(z^(2))이고, z^(2)= θ^(1)*a^(1)입니다. 값이 1인 바이어스 유닛 a^(2)0를 추가합니다. 세 번째, 세 번째 층 a^(3)는 시그모이드 함수 g(z^(3)이고, z^(3) = g(θ^(2)*a^(2))입니다. 값이 1인 바이어스 유닛 a^(3)0를 추가합니다. 네 번째, 출력층 a^(4)는 시그모이드 함수 g(z^(4)이고, z^(4) = g(θ^(3)*a^(3)) 입니다. 출력 유닛 a(4)는 가설 hΘ(x)와 같습니다. 이것이 순전파 알고리즘을 벡터화 구현한 것입니다. 순전파 알고리즘은 신경망의 모든 유닛의 활성화 함수를 계산합니다. Next, in order to compute the derivatives, we’re going to use an algorithm called back propagation. The intuition of the back propagation algorithm is that for each node we’re going to compute the term delta superscript l subscript j that’s going to somehow represent the error of node j in the layer l. So, recall that a superscript l subscript j that does the activation of the j of unit in layer l and so, this delta term is in some sense going to capture our error in the activation of that neural network. So, how we might wish the activation of that node is slightly different. Concretely, taking the example neural network that we have on the right which has four layers. And so capital L is equal to 4. For each output unit, we’re going to compute this delta term. So, delta for the j of unit in the fourth layer is equal tojust the activation of that unit minus what was the actual value of 0 in our training example. So, this term here can also be written h of x subscript j, right. So this delta term is just the difference between when a hypotheses output and what was the value of y in our training set whereas y subscript j is the j of element of the vector value y in our labeled training set. 다음으로, 미분항을 계산하기 위해 역전파 알고리즘을 사용합니다. 역전파 알고리즘은 단순하게 각 층의 노드인 델타δ^(l)j을 계산합니다. δ^(l)j는 l 번째 층의 j 노드가 오차가 있는 지를 나타냅니다. 즉, a^(l)j는 l층에 있는 j유닛의 활성화 함수이고, δ^(l)j는 활성화된 노드의 오차를 나타냅니다. 그래서 노드의 활성화는 약간 다릅니다. 예를 들어, 여기 4 개 층을 갖는 신경망이 있습니다. 총층의 수 L은 4입니다. 각 출력 유닛에서 델타 δ^(l) j을 계산합니다. 네 번째 층에 있는 j 번째 δ^(4)j = a^(4)j – yj입니다. 출력값 a^(4)j와 가설 (hθ(x))j는 같습니다 δ(델타)항은 가설들의 출력 중 하나와 학습 데이터 셋의 y 벡터에서 j 번째 성분인 yj 값의 차이입니다. And by the way, if you think of delta a and y as vectors then you can also take those and come up with a vectorized implementation of it, which is just delta 4 gets set as a4 minus y. Where here, each of these delta 4 a4 and y, each of these is a vector whose dimension is equal to the number of output units in our network. So we’ve now computed the era term’s delta 4 for our network. What we do next is compute the delta terms for the earlier layers in our network. Here’s a formula for computing delta 3 is delta 3 is equal to theta 3 transpose times delta 4. And this dot times, this is the element y’s multiplication operation that we know from MATLAB. So delta 3 transpose delta 4, that’s a vector; g prime z3 that’s also a vector and so dot times is in element y’s multiplication between these two vectors. This term g prime of z3, that formally is actually the derivative of the activation function g evaluated at the input values given by z3. If you know calculus, you can try to work it out yourself and see that you can simplify it to the same answer that I get. But I’ll just tell you pragmatically what that means. What you do to compute this g prime, these derivative terms is just a3 dot times1 minus A3 where A3 is the vector of activations. 1 is the vector of ones and A3 is again the activation the vector of activation values for that layer. Next you apply a similar formula to compute delta 2 where again that can be computed using a similar formula. Only now it is a2 like so and I then prove it here but you can actually, it’s possible to prove it if you know calculus that this expression is equal to mathematically, the derivative of the g function of the activation function, which I’m denoting by g prime. And finally, that’s it and there is no delta1 term, because the first layer corresponds to the input layer and that’s just the feature we observed in our training sets, so that doesn’t have any error associated with that. It’s not like, you know, we don’t really want to try to change those values. And so we have delta terms only for layers 2, 3 and for this example. δ^(4)j = a^(4)j – yi 에서 각 δ, a, y를 벡터화 구현한 식은 다음과 같습니다. 여기서 δ^(4), a^(4), y는 인공 신경망의 출력 유닛의 수와 같은 차원 벡터입니다. 이제 신경망에서 δ^(4) 오차 항을 계산했습니다. 다음으로 바로 전 층의 δ^(3)을 계산합니다. 공식은 다음과 같습니다. 여기서 ‘ .* ‘는 두 벡터의 성분 간의 곱셉입니다. g'(z^3)는 시그모이드 함수 g(z^(3))을 미분한다는 의미입니다. g'(z^(3))과 g'(z^(2))의 미분을 합니다. a^(3)와 a^(2)는 활성화 벡터입니다. 1 = [1; 1; 1;… ; 1]처럼 생긴 활성화 벡터입니다. 여기서 다루지 않겠지만, 미분된 활성화 함수 g'()와 수학적으로 동일하다는 것을 증명할 수 있습니다. δ^(1)항은 없습니다. 첫 번째 층은 입력층이고 학습 데이터 셋의 피처 x의 값입니다. 오차나 에러가 있을 수 없고, 학습 데이터의 피처 값을 변경하지 않습니다. δ항은 2, 3, 4 층만 있습니다. The name back propagation comes from the fact that we start by computing the delta term for the output layer and then we go back a layer and compute the delta terms for the third hidden layer and then we go back another step to compute delta 2 and so, we’re sort of back propagating the errors from the output layer to layer 3 to their to hence the name back complication. 역전파란 이름은 δ의 계산을 출력층부터 시작해서 세 번째 은닉층의 δ^(3)를 거쳐 δ^(2)까지 역으로 계산한다는 의미로 붙여졌습니다. 역전파의 결과로 인하여 출력층의 오차를 3층에서 2층으로 역으로 계산합니다. Finally, the derivation is surprisingly complicated, surprisingly involved but if you just do this few steps steps of computation it is possible to prove viral frankly some what complicated mathematical proof. It’s possible to prove that if you ignore authorization then the partial derivative terms you want are exactly given by the activations and these delta terms. This is ignoring lambda or alternatively the regularization term lambda will equal to 0. We’ll fix this detail later about the regularization term, but so by performing back propagation and computing these delta terms, you can, you know, pretty quickly compute these partial derivative terms for all of your parameters. 마지막으로 미분은 놀라울 정도로 복잡합니다. 그러나 몇 단계의 계산을 수행하면 수학적으로 증명할 수 있습니다. 정규화를 무시한다면 편미분 항은 활성화 항과 δ항으로 주어진 다는 것으로 증명할 수 있습니다. 이것은 람다(λ)를 무시거나 정규화 변수 λ값이 0과 같다고 처리한 것입니다. 나중에 정규화 항을 자세히 수정할 것입니다. 역전파 알고리즘을 활용하여 δ를 계산하고 모든 파라미터에 대해 편미분항을 빠르게 계산합니다. So this is a lot of detail. Let’s take everything and put it all together to talk about how to implement back propagation to compute derivatives with respect to your parameters. And for the case of when we have a large training set, not just a training set of one example, here’s what we do. Suppose we have a training set of m examples like that shown here. The first thing we’re going to do is we’re going to set these delta l subscript i j. So this triangular symbol? That’s actually the capital Greek alphabet delta. The symbol we had on the previous slide was the lower case delta. So the triangle is capital delta. We’re gonna set this equal to zero for all values of l i j. Eventually, this capital delta l i j will be used to compute the partial derivative term, partial derivative respect to theta l i j of J of theta. So as we’ll see in a second, these deltas are going to be used as accumulators that will slowly add things in order to compute these partial derivatives. Next, we’re going to loop through our training set. So, we’ll say for i equals 1 through m and so for the i iteration, we’re going to working with the training example xi, yi.So the first thing we’re going to do is set a1 which is the activations of the input layer, set that to be equal to xi is the inputs for our i training example, and then we’re going to perform forward propagation to compute the activations for layer two, layer three and so on up to the final layer, layer capital L. Next, we’re going to use the output label yi from this specific example we’re looking at to compute the error term for delta L for the output there. So delta L is what a hypotheses output minus what the target label was? And then we’re going to use the back propagation algorithm to compute delta L minus 1, delta L minus 2, and so on down to delta 2 and once again there is now delta 1 because we don’t associate an error term with the input layer. 지금부터 모든 학습 데이터 셋을 입력할 때 파라미터 행렬 Θ에 대한 미분을 계산하는 역전파를 구현하는 방법을 설명합니다. 단 하나의 예제를 가진 학습 데이터 셋이 아닌 엄청나게 많은 예제를 가진 학습 데이터 셋에 대해 살펴봅시다. 1) m의 학습 데이터 셋이 있습니다. 2) 델타 Δ^(l)ij을 초기화합니다. 삼각형 기호는 그리스의 알파벳 델타입니다. δ기호는 소문자 델타이고, Δ은 대문자 델타입니다. Δ 행렬의 모든 성분을 0으로 초기화합니다. 3) 모든 학습 예제에 대한 For 루프를 구동합니다. 3-1) 학습 데이터 셋을 입력층 a^(1)에 입력합니다. 3-2) 순전파 알고리즘으로 a^(l)을 계산합니다. 3-3) Δ^(l)ij는 비용 함수 J(θ)에 대한 편미분 항을 계산합니다. 즉, 출력층의 오차를 계산합니다. 3-4) 모든 층의 모든 유닛에 대해 경사를 계산하고 경사를 업데이트 다음으로 Δ는 편미분을 계산한 값들을 계속 업데이트합니다. 그리고, 이 과정을 반복합니다. i=1부터 m까지 반복하면서 신경망은 학습 예제 (x^(i), y^(i))를 학습합니다. 첫 번째 루프에서 입력층의 활성화된 a^(1)ii 번째 훈련 예제를 x^(i)에 대입합니다. 두 번째 층과 세 번째 층, 그리고 마지막 층 L까지의 순방향 전파를 진행합니다. 그다음에 출력 레이블 y^(i)를 에러항인 δ^(L)을 계산하기 위해 사용합니다. 그래서 δ^(L) = 가설의 출력 a(L) – yi입니다. 그리고 역전파 알고리즘을 δ^(L-1), δ^(L-2),…, δ^(2)까지 계산합니다. 다시 한번 설명하지만, δ^(1)은 입력층이기 때문에 오차와 무관합니다. And finally, we’re going to use these capital delta terms to accumulate these partial derivative terms that we wrote down on the previous line. And by the way, if you look at this expression, it’s possible to vectorize this too. Concretely, if you think of delta ij as a matrix, indexed by subscript ij. Then, if delta L is a matrix we can rewrite this as delta L, gets updated as delta L plus lower case delta L plus one times aL transpose. So that’s a vectorized implementation of this that automatically does an update for all values of i and j. 마지막으로 편미분 항의 값을 축적하기 위해서 델타 Δ^(l)ij를 사용합니다. 각각을 For 루프로 계산하는 것보다 벡터화 구현이 훨씬 쉽습니다. 여기서, Δij를 행렬로 생각하고 아래 첨자 ij로 성분으로 표현한 것입니다. 이것은 모든 i, j의 값에 대해서 자동으로 업데이트합니다. Finally, after executing the body of the four-loop we then go outside the four-loop and we compute the following. We compute capital D as follows and we have two separate cases for j equals zero and j not equals zero.The case of j equals zero corresponds to the bias term so when j equals zero that’s why we’re missing is an extra regularization term. Finally, while the formal proof is pretty complicated what you can show is that once you’ve computed these D terms, that is exactly the partial derivative of the cost function with respect to each of your perimeters and so you can use those in either gradient descent or in one of the advanced authorizationalgorithms. 마지막으로 For 루프를 완료한 후 정규화 항을 추가하고 학습 데이터 셋의 수로 나누어 줍니다. 대문자 D는 정규화를 하는 항과 하지 않는 항을 구분합니다. j=0은 바이어스 항을 나타내므로 추가적인 정규화 항이 없습니다. 공식 증명은 꽤 복잡하지만, 일단 D 항을 계산해보면 각 파라미터에 대한 비용 함수의 편미분입니다. 최적의 파라미터 D을 경사 하강법이나 다른 고급 알고리즘에서 사용할 수 있습니다. So that’s the back propagation algorithm and how you compute derivatives of your cost function for a neural network. I know this looks like this was a lot of details and this was a lot of steps strung together. But both in the programming assignments write out and later in this video, we’ll give you a summary of this so we can have all the pieces of the algorithm together so that you know exactly what you need to implement if you want to implement back propagation to compute the derivatives of your neural network’s cost function with respect to those parameters. 지금까지 역전파 알고리즘과 인공 신경망의 비용 함수를 미분하는 방법을 설명했습니다. 이번 강의는 많은 내용을 담고 있고 많은 사항들이 서로 얽혀 있습니다. 그러나, 프로그래밍 실습과 이 과정에서 좀 더 쉽게 설명을 할 것입니다. 여러분들이 모든 종류의 알고리즘을 함께 다룰 수 있을 것이고, 신경망의 비용 함수와 관련된 파라미터를 계산하는 미분을 계산하는 역전파를 구현하는 방법을 더 잘 이해할 수 있을 것입니다. 앤드류 응의 머신러닝 동영상 강의 정리하며 비용 함수와 미분항을 계산하는 방법은 다음과 같습니다. 순전파 알고리즘으로 비용 함수를 계산하고 역전파 알고리즘으로 미분항을 계산합니다. 문제 풀이 두 개의 훈련용 데이터 셋 (x^(1), y^(1)), (x^(2), x^(2)) 이 있습니다. 기울기를 계산하기 위한 순서로 올바른 것은? (FP는 순전파이고, BP는 역전파임) 정답은 4번입니다. 첫 번째 훈련용 데이터 셋에 대한 순전파와 역전파를 실행하고, 두 번째 훈련용 데이터 셋에 대해 순전파와 역전파를 수행합니다.

[35편] 딥러닝의 핵심 개념 – 역전파(backpropagation) 이해하기1

1958년 퍼셉트론이 발표된 후 같은 해 7월 8일자 뉴욕타임즈는 앞으로 조만간 걷고, 말하고 자아를 인식하는 단계에 이르는 컴퓨터 세상이 도래할 것이라는 다소 과격한 기사를 냈습니다.

하지만 1969년, 단순 퍼셉트론은 ​XOR 문제도 풀 수 없다는 사실을 MIT AI 랩 창시자인 Marvin Minsky 교수가 증명하였고, 다층 퍼셉트론(MLP)으로 신경망을 구성하면 XOR 문제를 풀 수 있으나, 이러한 MLP를 학습시키는 방법은 존재하지 않는다고 단정해버렸습니다.

이로 인해 떠들석했던 인공신경망과 관련된 학문과 기술은 더 이상 발전되지 않고 침체기를 겪게 됩니다.

그런데 1974년, 당시 하버드 대학교 박사과정이었던 Paul Werbos는 MLP를 학습시키는 방법을 찾게 되는데, 이 방법을 Minsky 교수에게 설명하지만 냉랭한 분위기속에 무시되버립니다.

Paul Werbos가 Minsky 교수에게 설명한 MLP를 학습시킬 수 있는 획기적인 방법이 바로 오류 역전파 (Backpropagation of errors)라는 개념입니다.

이제 오류 역전파(앞으로 그냥 역전파라고 부르겠습니다)가 무엇인지 살펴보도록 합니다.

심층 신경망을 학습한다는 것은 최종 출력값과 실제값의 오차가 최소가 되도록 심층 신경망을 이루는 각 층에서 입력되는 값에 곱해지는 가중치와 바이어스를 계산하여 결정하는 것을 말합니다.

우리는 [6편] 아달라인을 학습할 때 인공 신경망의 출력값과 실제값의 오차가 최소가 되도록 가중치를 결정하는 방법인 경사하강법에 대해 다룬적이 있습니다.

경사하강법은 오차 곡선을 따라 일정한 크기로 내려가면서 최소값을 찾아가는 방법인데, 일정한 크기는 해당 지점에서 접선의 기울기와 learning rate으로 결정한다고 했지요.

기억이 가물거리면 다시 [6편]을 학습하고 옵니다.

☞ 경사하강법 다시보러 가기

심층 신경망을 학습하는데 유용하게 활용되는 역전파(backpropagtion) 알고리즘도 결국 이 경사하강법을 이용합니다. 그러면 역전파가 무엇인지 그 개념에 대해 대충(?) 살펴보도록 합니다.

먼저 아래와 같은 2-2-2 다층 퍼셉트론이 있다고 생각해봅니다. 여기서는 역전파의 개념만 살펴볼 예정이므로 각 층에 존재하는 바이어스는 생략했습니다. 또한 용어의 통일성을 위해 입력층의 x1, x2는 a1(1), a2(1)로 표기하기로 합니다.

[34편]에서 l층의 i번째 노드와 l+1층의 j번째 노드를 연결하는 가중치 w를 다음과 같이 정의했지요~

이 구조에서 적용되는 활성 함수는 시그모이드 함수 φ입니다.

입력층 -> 은닉층 사이의 값의 흐름은 다음과 같습니다.

[식1]

그리고 은닉층 -> 출력층 사이의 값의 흐름은 다음과 같습니다.

[식2]

이와 같이 입력층의 a1(1), a2(1)을 시작으로 출력층의 a1(3), a2(3) 값이 출력되는 과정을 순전파(feedforward)라 부릅니다.

우리는 아달라인을 다룰 때 오차제곱합을 비용함수로 도입해서, 이 비용함수가 최소가 되도록 가중치를 결정했습니다. 물론 가중치를 결정하는 방법은 경사하강법이었죠.

여기서도 비용함수 J를 오차제곱합으로 정의를 해보면 다음과 같이 될 겁니다.

여기서 y1, y2는 트레이닝 데이터에 대한 각 노드에 대응되는 실제값입니다. 순전파 1회가 마무리되면 J1과 J2의 값이 결정되겠죠.

입력값 a1(1), a2(1)과 실제값 y1, y2는 고정된 값이므로 J1과 J2는 결국 가중치 w1,1(1)~w2,2(2)를 변수로 가지는 함수가 됩니다.

우리의 목표는 J1과 J2의 값이 최소가 되도록 w1,1(1)~w2,2(2)를 결정해야 합니다.

아달라인에서와 마찬가지로 다층 퍼셉트론에서도 비용함수의 최소값을 찾아가는 방법으로 경사하강법을 활용한다고 했습니다. 각 층에서 가중치를 업데이트하기 위해서는 결국 각 층에서의 비용함수(오차로 불러도 됩니다.)의 미분값이 필요하게 되는 것이지요.

이를 매우 효율적으로 해결하기 위한 방법이 바로 역전파 알고리즘입니다.

역전파란 역방향으로 오차를 전파시키면서 각층의 가중치를 업데이트하고 최적의 학습 결과를 찾아가는 방법입니다.

자, 이 경우를 한번 생각해봅니다.

순전파에 있어서 가중치의 값을 매우 미세하게 변화시키면 비용함수 J1, J2도 매우 미세하게 변화될 겁니다. 매우 미세하게 변화시킨다는 것은 미분을 한다는 이야기입니다. 그런데, 매우 미세한 영역으로 국한할 때 가중치의 미세변화와 이에 따른 비용함수의 미세변화가 선형적인 관계가 된다고 알려져 있습니다. 선형적인 관계라는 이야기는 결국 비용함수를 매우 미세하게 변화시키면 이에 따라 가중치도 매우 미세하게 변화되는데 이 역시 선형적인 관계라는 이야기입니다.

이런 원리에 의해, 순전파를 통해 출력층에서 계산된 오차 J1, J2의 각 가중치에 따른 미세변화를 입력층 방향으로 역전파시키면서 가중치를 업데이트하고, 또 다시 입력값을 이용해 순전파시켜 출력층에서 새로운 오차를 계산하고, 이 오차를 또다시 역전파시켜 가중치를 업데이트하는 식으로 반복합니다.

역전파를 이용한 가중치 업데이트 절차는 아래와 같이 요약될 수 있습니다.

주어진 가중치 값을 이용해 출력층의 출력값을 계산함(순전파를 통해 이루어짐 ) 오차를 각 가중치로 미분한 값(실제로는 learning rate을 곱한 값)을 기존 가중치에서 빼줌(경사하강법을 적용하는 것이며, 역전파를 통해 이루어짐) 2번 단계는 모든 가중치에 대해 이루어짐 1~3단계를 주어진 학습회수만큼 또는 주어진 허용오차값에 도달할 때가지 반복함

2번 단계의 가중치 업데이트 식을 수식으로 표현하면 다음과 같습니다.

여기서 Jtotal은 해당 노드가 영향을 미치는 오차의 총합입니다. 예를 들면 출력층의 노드 a1(3)에서는 다른 노드의 오차에 영향을 전혀 미치지 않으므로 해당 노드에서 오차인 J1만 따지면 되지만, 은닉층의 a1(2) 노드는 출력층의 a1(3), a2(3) 노드의 오차에 영향을 미치므로 J1, J2 모두 더한 것이 Jtotal 값이 됩니다.

이번에는 역전파를 통한 가중치 업데이트 메커니즘을 살펴볼 것이므로 편의상 learning rate η는 1로 둡니다.

자, 그러면 실제로 역전파를 이용해 가중치를 업데이트 해보도록 하죠. 먼저 가중치 w1,1(2)에 대해서 계산을 해봅니다.

w1,1(2)에 대한 업데이트 식은 아래와 같습니다.

미분의 연쇄법칙에 의해 오차의 가중치에 대한 미분값은 아래의 식으로 표현될 수 있습니다.

이제 위 식의 오른쪽 항에 있는 3개의 미분값을 하나하나 구해보도록 하지요~ 참고로 이 포스팅의 첫부분에서 서술한 순전파를 통한 값의 흐름을 요약한 수식을 참고하기 바랍니다.

역전파의 출발노드인 a1(3)에서 Jtotal의 값은 J1입니다. 따라서 위 식 오른쪽 항은 아래와 같이 계산됩니다.

따라서

역전파에서 가중치 업데이트를 위해 사용되는 오차의 가중치에 대한 미분값이 결국 역전파의 출발 노드의 활성 함수 값과 도착 노드의 활성 함수 값, 그리고 실제값만으로 표현되는 것을 알 수 있습니다.

​위 식의 오른쪽 항에서 처음 두 식의 값을 아래와 같이 δ1(3)으로 둡니다.

[식3]

역전파에 의해 업데이트 되는 w1,1(2)는 다음과 같습니다.

마찬가지 방법으로 w1,2(2)에 대한 업데이트 수식도 다음과 같습니다.

δ2(3)을 아래와 같은 수식으로 정의하고,

[식4]

w2,1(2), w2,2(2)에 대해서도 계산을 해보면

여기까지 서술해보니 뭔가 규칙성이 보입니다. 출력층에서 은닉층으로 역전파를 통해 전달되는 값이 결국 δ1(3) 과 δ2(3) 뿐이더라도 관련된 가중치를 업데이트하는데 충분하다는 것을 알 수 있습니다.

이제, 은닉층에서 입력층으로 향하는 역전파를 통해 w1,1(1)의 값을 업데이트 해보겠습니다.

w1,1(1)을 업데이트 하기 위해서 a1(2)에서 Jtotal을 w1,1(1)로 편미분한 값을 계산해야겠지요? 앞에서 적용한 것과 마찬가지로 미분의 연쇄법칙을 활용하면 다음과 같은 식이 됩니다.

위에서 언급했듯이 a1(2)에서 Jtotal은 J1과 J2를 더한 값이 됩니다. 따라서 위 식 오른쪽 항의 첫 번째 편미분값은 아래와 같이 계산됩니다.

그런데 출력층 -> 은닉층으로 역전파를 통한 가중치 계산시에 등장한 [식3]과 [식4]와 [식1], [식2]를 참고하여 계산해보면 다음과 같은 결과가 나옵니다.

가 됩니다.

나머지 편미분 값은 이미 해본 계산이므로 쉽게 계산됩니다. w1,1(1)을 업데이트 하기 위한 편미분 값은 다음과 같습니다.

위 식의 오른쪽 항에서 처음 두 식을 δ1(2)로 둡니다.

최종적으로 w1,1(1)의 업데이트 식은 아래와 같게 됩니다.

동일하게 w1,2(1)의 업데이트 식은 아래와 같습니다.

마찬가지로, δ2(2)를 다음과 같이 두고,

w2,1(1), w2,2(2)에 대한 업데이트 식을 나타내면 다음과 같습니다.

따라서 모든 가중치에 대한 업데이트 식은 아래와 같이 표현할 수 있습니다.

여태까지 다룬 역전파 알고리즘 개념을 그림으로 도식화하여 나타내보면 다음과 같습니다.

이와 같이 순전파 -> 역전파 -> 가중치 업데이트 -> 순전파 …. 로 계속 반복해나가면 오차값이 0에 가까와지게 됩니다.

이상으로 역전파 알고리즘 및 가중치 업데이트 원리를 살펴보았습니다. 역전파 알고리즘을 이해하기가 쬐금은 어렵지만, 이 부분이 딥러닝의 핵심적인 역할을 하는 부분이며, 완전한 이해가 힘들더라도 그 개념만이라도 알고 있으면 많은 도움이 됩니다.

키워드에 대한 정보 역 전파 알고리즘 소스

다음은 Bing에서 역 전파 알고리즘 소스 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.

이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!

사람들이 주제에 대해 자주 검색하는 키워드 [딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파)

  • 머신 러닝
  • 기계 학습
  • Machine learning
  • Deep Neural Network
  • Neural Network
  • Backpropagation
  • 역전파
  • Partial derivative
  • 편미분
  • chain rule
[딥러닝] #6-1강. #딥러닝 #시대를 #열어준 #단 #한줄의 #수식!! #Backpropagation #(역전파)


YouTube에서 역 전파 알고리즘 소스 주제의 다른 동영상 보기

주제에 대한 기사를 시청해 주셔서 감사합니다 [딥러닝] 6-1강. 딥러닝 시대를 열어준 단 한줄의 수식!! Backpropagation (역전파) | 역 전파 알고리즘 소스, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.

See also  Antena Dvb T Opticum Ax900 | Обзор Комбо Антенн Olympia Bx1000 Combo И Opticum Ax 900+ Dvb-T2 Vhf + Uhf С Lte Фильтрами Мв+Дмв 답을 믿으세요

Leave a Comment