당신은 주제를 찾고 있습니까 “다층 퍼셉트론 예제 – Ch09_01.다층신경망과 텐서플로(다층신경망이란)01“? 다음 카테고리의 웹사이트 https://you.experience-porthcawl.com 에서 귀하의 모든 질문에 답변해 드립니다: https://you.experience-porthcawl.com/blog. 바로 아래에서 답을 찾을 수 있습니다. 작성자 강서대학교 빅데이터경영학과 이상철 교수 이(가) 작성한 기사에는 조회수 2,039회 및 좋아요 14개 개의 좋아요가 있습니다.
다층 퍼셉트론 예제 주제에 대한 동영상 보기
여기에서 이 주제에 대한 비디오를 시청하십시오. 주의 깊게 살펴보고 읽고 있는 내용에 대한 피드백을 제공하세요!
d여기에서 Ch09_01.다층신경망과 텐서플로(다층신경망이란)01 – 다층 퍼셉트론 예제 주제에 대한 세부정보를 참조하세요
본강의는 KC대학교 재학생의 Blended Learning을 위해 제작되고 오픈되었습니다.
그러나 공부하시는 분들의 강의자료에 대한 요청이 많으셔서 네이버 까페를 오픈했습니다.
채널홈으로 오시면 빅데이터와 관련된 다양한 강의를 순서대로 들을 수 있습니다.
https://cafe.naver.com/kcbig
열심히 공부해서 좋은 성과가 있으시길 바랍니다. ^^
다층 퍼셉트론 예제 주제에 대한 자세한 내용은 여기를 참조하세요.
다층 퍼셉트론 모델 만들어보기 – 김태영의 케라스 블로그
본 예제에서는 비교적 쉬운 이진 분류 문제를 적용해보고자 합니다. 이진 분류 예제에 적합한 데이터셋은 8개 변수와 당뇨병 발병 유무가 기록된 ‘피마족 …
Source: tykimos.github.io
Date Published: 1/24/2021
View: 1281
3.8. 다층 퍼셉트론 (Multilayer Perceptron)
This example contains a hden layer with 5 hden units. 위 다층 퍼셉트론(multilayer perceptron)에서는 입력이 4개, 출력이 3개, 중간의 은닉층(hden layer) …
Source: ko.d2l.ai
Date Published: 11/20/2022
View: 1673
퍼셉트론(Perceptron)과 다층 퍼셉트론(MLP)
: 퍼셉트론은 다수의 신호를 받아(input) 하나의 신호(0 또는 1)로 출력(output). Perceptron Example. x1, x2라는 신호 입력이 y라는 신호로 …
Source: imjuno.tistory.com
Date Published: 7/22/2021
View: 7256
퍼셉트론의 개념 (단층 퍼셉트론 / 다층 퍼셉트론)
우리는 실제 값을 가지는 예제 데이터에 기초해 분류자 함수의 기울기를 구하게 된다. 이 때 예제 데이터를 학습 데이터(training data)라고 부른다. 학습 …
Source: 0-sunny.tistory.com
Date Published: 2/9/2022
View: 155
[머신 러닝] 다층 퍼셉트론 – Justweon
다층 퍼셉트론 예시. 은닉층을 여러 개 쌓아 올린 인공 신경망을 심층 신경망(deep neural network, DNN)이라고 합니다. 딥러닝은 심층 신경망을 연구 …
Source: justweon-dev.tistory.com
Date Published: 1/6/2021
View: 1498
다층 퍼셉트론 – 카이제곱
간단한 예제로 살펴 볼 수 있다. [그림1] 다층 퍼셉트론 모델. 하나의 퍼셉트론 은 네개의 샘플 …
Source: vision0814.tistory.com
Date Published: 11/23/2021
View: 7170
다층 퍼셉트론 예제 – 수채화 그림 – Anzieux-foot42.fr
다층 퍼셉트론 예제 anzieux-foot42.fr. 수채화 그림. 759. 텍스트를 입력하면 인공지능(AI)이 알아서 디지털 이미지를 생성한다.
Source: anzieux-foot42.fr
Date Published: 4/25/2021
View: 7722
[37편] 다층 퍼셉트론 구현하기 – 네이버 블로그 – NAVER
이번 포스팅에서는 [34편]~[36편] 내용에서 다룬 다층 퍼셉트론을 파이썬으로 구현한 코드를 소개하고, MNIST의 손글씨 숫자 60,000개의 샘플을 딥러닝 …
Source: blog.naver.com
Date Published: 1/20/2022
View: 3893
주제와 관련된 이미지 다층 퍼셉트론 예제
주제와 관련된 더 많은 사진을 참조하십시오 Ch09_01.다층신경망과 텐서플로(다층신경망이란)01. 댓글에서 더 많은 관련 이미지를 보거나 필요한 경우 더 많은 관련 기사를 볼 수 있습니다.

주제에 대한 기사 평가 다층 퍼셉트론 예제
- Author: 강서대학교 빅데이터경영학과 이상철 교수
- Views: 조회수 2,039회
- Likes: 좋아요 14개
- Date Published: 2019. 11. 21.
- Video Url link: https://www.youtube.com/watch?v=0h1piIhw2gM
다층 퍼셉트론 모델 만들어보기
import numpy as np from keras.models import Sequential from keras.layers import Dense # 랜덤시드 고정시키기 np . random . seed ( 5 )
3.8. 다층 퍼셉트론 (Multilayer Perceptron) — Dive into Deep Learning documentation
3.8. 다층 퍼셉트론 (Multilayer Perceptron)¶
이전 절들에서 옷 이미지를 10개의 카테고리 중에 어디에 속하는지를 예측하는 멀티 클래스 로지스틱 리그레션(multiclass logistic regression) (또는 softmax regression)을 구현해봤습니다. 여기서부터 재미있는 것들이 시작됩니다. 데이터를 다루고, 출력값을 유효한 확률 분포로 바꾸고, 적합한 loss 함수를 적용하고, 파라미터를 최적화하는 방법에 대해서 알아봤습니다. 기본적인 것들을 익혔으니, 이제 딥 뉴럴 네트워크를 포함하도록 우리의 도구 상자를 확장해보겠습니다.
3.8.1. 은닉층(hidden layer)¶ 이전의 것을 기억해보면, 단일 선형 변환 (single linear transformation)을 통해서 입력들을 바로 출력으로 매핑을 했고, 이는 아래과 같이 표현할 수 있습니다. \[\hat{\mathbf{o}} = \mathrm{softmax}(\mathbf{W} \mathbf{x} + \mathbf{b})\] 만약 레이블(label)들이 대략적인 선형 함수로 입력 데이터와 연관을 지을 수 있다면, 이 방법은 적절할 수 있습니다. 하지만, 이 선형성은 너무 강한 가정입니다. 선형성은 각 입력에 대해서, 입력값이 증가하면 다른 입력값과는 상관없이 결과값이 커지거나 작아지는 것을 의미합니다.
3.8.2. 하나에서 여러개로¶ 검정색이나 희색 이미지을 이용해서 강아지나 고양이를 분류하는 케이스를 생각해봅시다. 각 픽셀의 값을 증가시키면 강아지라고 판별할 확률값을 높이거나 내려가는 경우를 생각해봅시다. 이는 합당하지 않습니다. 왜냐하면, 이렇게 된다면 결국 강아지는 모두 검정색이고 고양이는 모두 흰색이거나 그 반대라는 것을 의미하기 때문입니다. 이미지에 무엇이 있는지 알아내기 위해서는 입력과 출력 간의 매우 복잡한 관계와 이를 위해서는 패턴이 많은 특성(feature)들 사이의 관계를 통해서 특정 지어지는 가능성을 고려해야합니다. 이런 경우에는, 선형 모델의 정확도는 낮을 것입니다. 우리는 한 개 이상의 은닉층(hidden layer)을 함께 사용해서 더 일반적인 함수들을 이용한 모델을 만들 수 있습니다. 이를 구현하는 가장 쉬운 방법은 각 층 위에 다른 층들을 쌓는 것입니다. 각 층의 결과는 그 위의 층의 입력으로 연결되는데, 이는 마지막 출력층까지 반복됩니다. 이런 아키텍쳐는 일반적으로 “다층 퍼셉트론(multilayer perceptron)”이라고 불립니다. 즉, MLP는 여러 층를 연속해서 쌓아올립니다. 예를 들면 다음과 같습니다. 위 다층 퍼셉트론(multilayer perceptron)에서는 입력이 4개, 출력이 3개, 중간의 은닉층(hidden layer)은 5개의 은닉 유닛(hidden unit)이 있습니다. 입력층은 어떤 연산을 수행하지 않기 때문에, 이 다층 퍼셉트론(multilayer perceptron)은 총 2개의 층(layer)을 갖습니다. 은닉층(hidden layer)의 뉴런(neuron)들은 입력층의 입력들과 모두 연결되어 있습니다. 출력층(output layer)의 뉴런과 은닉층의 뉴런들도 모두 연결되어 있습니다. 따라서, 이 다층 퍼셉트론의 은닉층과 출력층은 모두 완전 연결층(fully connected layer)입니다.
3.8.3. 선형에서 비선형으로¶ 다중 클래스 분류의 경우 위 그림이 수학적으로 어떻게 정의되는지 보겠습니다. \[\begin{split}\begin{aligned} \mathbf{h} & = \mathbf{W}_1 \mathbf{x} + \mathbf{b}_1 \\ \mathbf{o} & = \mathbf{W}_2 \mathbf{h} + \mathbf{b}_2 \\ \hat{\mathbf{y}} & = \mathrm{softmax}(\mathbf{o}) \end{aligned}\end{split}\] 위 방법의 문제점은 은닉층을 \(\mathbf{W} = \mathbf{W}_2 \mathbf{W}_1\) 과 \(\mathbf{b} = \mathbf{W}_2 \mathbf{b}_1 + \mathbf{b}_2\)를 사용해서 단일층 퍼셉트론(single layer perceptron) 식으로 재구성할 수 있기 때문에, 다층(mutilayer)이 아닌 단순한 단일층 퍼셉트론(single layer perceptron)이라는 점입니다. \[\mathbf{o} = \mathbf{W}_2 \mathbf{h} + \mathbf{b}_2 = \mathbf{W}_2 (\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1) + \mathbf{b}_2 = (\mathbf{W}_2 \mathbf{W}_1) \mathbf{x} + (\mathbf{W}_2 \mathbf{b}_1 + \mathbf{b}_2) = \mathbf{W} \mathbf{x} + \mathbf{b}\] 이를 해결하는 방법은 모든 층의 다음에 \(\mathrm{max}(x,0)\) 와 같은 비선형 함수 \(\sigma\) 를 추가하는 것입니다. 이렇게 하면, 층들을 합치는 것이 더 이상 불가능해집니다. 즉, \[\begin{split}\begin{aligned} \mathbf{h} & = \sigma(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1) \\ \mathbf{o} & = \mathbf{W}_2 \mathbf{h} + \mathbf{b}_2 \\ \hat{\mathbf{y}} & = \mathrm{softmax}(\mathbf{o}) \end{aligned}\end{split}\] 이렇게 하면, 여러 개의 은닉층들을 쌓는 것도 가능합니다. 즉, \(\mathbf{h}_1 = \sigma(\mathbf{W}_1 \mathbf{x} + \mathbf{b}_1)\) 과 \(\mathbf{h}_2 = \sigma(\mathbf{W}_2 \mathbf{h}_1 + \mathbf{b}_2)\) 를 각각 연결해서 진짜 다층 퍼셉트론을 만들 수 있습니다. 은닉 뉴런들이 각 입력의 값에 의존하고 있기 때문에 다층 퍼셉트론은 입력들 사이의 복잡한 상호 작용을 설명할 수 있습니다. 예를 들면, 입력들에 대한 논리 연산과 같이 임의의 연산을 수행하는 은닉 노드(hidden node)를 만드는 것도 쉽습니다. 다층 퍼셉트론이 보편적인 approximator라는 것이 잘 알려져 있습니다. 이것의 의미는 다음과 같습니다. 한 개의 은닉층을 갖는 다층 퍼셉트론이라도, 충분히 많은 노드와, 정확한 가중치를 설정할 수 있다면 모든 함수에 대한 모델을 만들 수 있다는 것입니다. 사실 그 함수를 학습하는 것은 매우 어려운 부분입니다. 그리고, 더 깊은 (또는 더 넓은) 뉴럴 네트워크를 이용한다면 함수를 더욱 더 간결하게 추정할 수도 있습니다. 수학적인 부분은 이어질 장들에서 다루겠고, 이 장에서는 MLP를 실제로 만들어 보겠습니다. 아래 예제에서는 2개의 은닉층과 1개의 출력층을 갖는 다층 퍼셉트론을 구현해보겠습니다.
3.8.4. 벡터화와 미니 배치¶ 샘플들이 미니 배치로 주어지는 경우에는 벡터화를 통해서 구현의 효율성을 높일 수 있습니다. 요약하면, 벡터를 행렬로 바꿀 것입니다. \(\mathbf{X}\) 는 미니 배치의 입력 행렬에 대한 표기입니다. 2개의 은닉층(hidden layer)를 갖는 MLP는 다음과 같이 표현됩니다. \[\begin{split}\begin{aligned} \mathbf{H}_1 & = \sigma(\mathbf{W}_1 \mathbf{X} + \mathbf{b}_1) \\ \mathbf{H}_2 & = \sigma(\mathbf{W}_2 \mathbf{H}_1 + \mathbf{b}_2) \\ \mathbf{O} & = \mathrm{softmax}(\mathbf{W}_3 \mathbf{H}_2 + \mathbf{b}_3) \end{aligned}\end{split}\] 위 MLP는 구현을 쉽게 할 수 있고, 최적화도 쉽게 할 수 있습니다. 표기법을 조금 남용해서, 비선형(nonlinearity) \(\sigma\) 를 정의하고, 이를 행 단위로 입력에 적용하겠습니다. 즉, 한번에 하나의 관찰 또는 한번에 한 좌표씩 적용합니다. 실제 대부분 활성화 함수는 이렇게 적용합니다. (batch normalization 은 이 규칙에 대한 예외 중에 하나입니다.)
3.8.5. 활성화 함수(activation function)¶ 활성화 함수(activation function)의 예를 더 알아보겠습니다. 결국 딥 네트워트를 동작시키는 것은 선형(linear) 항목과 비선형(nonlinear) 항목들을 서로 교차시키는 것입니다. 구현하기 간단하고 좋은 효과로 유명한 ReLU 함수가 있습니다.
3.8.6. ReLU 함수¶ ReLU (rectified linear unit) 함수는 아주 간단한 비선형 변환입니다. 주어진 \(x\) 에 대해서, ReLU 함수는 다음과 같이 정의됩니다. \[\mathrm{ReLU}(x) = \max(x, 0).\] ReLU 함수는 양수만 그대로 두고, 음수는 버리고 0으로 바꿔주는 역할을 합니다. 이해를 돕기 위해서 도표로 그려보겠습니다. 간단한 방법으로, 도표를 그리는 함수 xyplot 를 정의하겠습니다. [1]: import sys sys . path . insert ( 0 , ‘..’ ) % matplotlib inline import d2l from mxnet import autograd , nd def xyplot ( x_vals , y_vals , name ): d2l . set_figsize ( figsize = ( 5 , 2.5 )) d2l . plt . plot ( x_vals . asnumpy (), y_vals . asnumpy ()) d2l . plt . xlabel ( ‘x’ ) d2l . plt . ylabel ( name + ‘(x)’ ) 그리고, 이를 사용해서 ReLU 함수를 NDArray에서 제공하는 relu 함수를 이용해서 도식화합니다. 보이는 것처럼 활성화 함수(activation function)은 두 개의 선형 함수로 보입니다. [2]: x = nd . arange ( – 8.0 , 8.0 , 0.1 ) x . attach_grad () with autograd . record (): y = x . relu () xyplot ( x , y , ‘relu’ ) 당연히 입력이 음수일 경우 ReLU 함수의 미분 값은 0이고, 입력이 양수면 ReLU 함수의 미분 값이 1이됩니다. 하지만, 입력이 0일 경우에는 ReLU 함수는 미분이 불가능하기 때문에, 입력이 0일 때는 left-hand-side (LHS) 미분인 0으로 선택합니다. ReLU 함수의 미분은 다음과 같습니다. [3]: y . backward () xyplot ( x , x . grad , ‘grad of relu’ ) ReLU 함수는 다양한 변형이 있는데, 예를 들면 He et al., 2015. parameterized ReLU (pReLU)가 있습니다. 이는 ReLU 선형 항목을 추가해서, 입력이 음수일 경우에도 정보가 전달될 수 있도록 만들고 있습니다. \[\mathrm{pReLU}(x) = \max(0, x) – \alpha x\] ReLU를 사용하는 이유는 값이 사라지거나 그대로 전달하게 하는 식으로 미분이 아주 잘 작동하기 때문입니다. 이러한 특징으로 인해 최적화가 더 잘 되고, (나중에 설명할) vanishing gradient 문제를 줄여줍니다.
3.8.7. Sigmoid 함수¶ sigmoid 함수는 실수 값을 (0,1) 사이의 값으로 변환해줍니다. \[\mathrm{sigmoid}(x) = \frac{1}{1 + \exp(-x)}.\] sigmoid 함수는 이전의 뉴럴 네트워크에서 일반적으로 사용되었으나, 현재는 더 간단한 ReLU 함수로 대체되었습니다. “Recurrent Neural Network”장에서는 이 함수가 0과 1사이의 값으로 변환해주는 특징을 이용해서 뉴럴 네트워크에서 정보의 전달을 제어하는데 어떻게 사용하는지 보겠습니다. Sigmoid 함수의 미분은 아래 그림과 같습니다. 입력이 0에 가까워지면, Sigmoid 함수는 선형 변환에 가까워집니다. [4]: with autograd . record (): y = x . sigmoid () xyplot ( x , y , ‘sigmoid’ ) Sigmoid 함수의 미분은 아래와 같습니다. \[\frac{d}{dx} \mathrm{sigmoid}(x) = \frac{\exp(-x)}{(1 + \exp(-x))^2} = \mathrm{sigmoid}(x)\left(1-\mathrm{sigmoid}(x)\right).\] Sigmoid 함수의 미분은 아래와 같이 생겼습니다. 입력이 0이면, Sigmoid 함수의 미분의 최대값인 0.25가 됩니다. 입력값이 0에서 멀어지면, Sigmoid 함수의 미분값은 0으로 접근합니다. [5]: y . backward () xyplot ( x , x . grad , ‘grad of sigmoid’ )
3.8.8. Tanh 함수¶ Tanh (Hyperbolic Tangent) 함수는 값을 -1와 1사이 값으로 변환합니다. \[\text{tanh}(x) = \frac{1 – \exp(-2x)}{1 + \exp(-2x)}.\] Tanh 함수를 도식화를 아래와 같이 할 수 있습니다. 입력이 0에 가까워지면, Tanh 함수는 선형 변환에 가까워 집니다. 생긴 모양이 Sigmoid 함수와 비슷하지만, Tanh 함수는 좌표의 원점을 기준으로 대칭인 형태를 띕니다. [6]: with autograd . record (): y = x . tanh () xyplot ( x , y , ‘tanh’ ) Tanh 함수의 미분은 다음과 같습니다. \[\frac{d}{dx} \mathrm{tanh}(x) = 1 – \mathrm{tanh}^2(x).\] Tanh 함수의 미분은 아래와 같이 그려지는데, 입력이 0과 가까우면 Tanh 함수의 미분은 최대값이 1에 근접하게 됩니다. 입력값이 0에서 멀어지면, Tanh 함수의 미분은 0에 접근합니다. [7]: y . backward () xyplot ( x , x . grad , ‘grad of tanh’ ) 요약하면, 여러 종류의 비선형을 살펴봤고, 아주 강력한 네트워크 아키텍처를 만들기 위해서 어떻게 사용해야하는지도 알아봤습니다. 부수적으로 말하자면, 여기까지의 소개한 기법을 사용하면 1990년대의 최첨단의 딥러닝을 만들 수 있습니다. 이전과 다른 점은 예전에는 C 또는 Fortran 언어를 이용해서 수천 줄의 코드로 만들어야 했던 모델을 지금은 강력한 딥러닝 프레임워크가 있어서 몇 줄의 코드로 만들 수 있다는 점입니다.
3.8.9. 요약¶ 다층 퍼셉트론은 입력과 출력층에 한 개 이상의 완전 연결 은닉층(hidden layer)를 추가하고, 각 은닉층(hidden layer)의 결과에 활성화 함수(activation function)를 적용하는 것입니다.
일반적으로 사용되는 활성화 함수(activation function)는 ReLU 함수, Sigmoid 함수, Tanh 함수가 있습니다.
3.8.10. 문제¶ Tanh, pReLU 활성화 함수(activation function)의 미분을 구하시오. ReLU (또는 pReLU) 만을 사용해서 만든 multlayer perceptron은 연속된 piecewise linear function임을 증명하세요. \(\mathrm{tanh}(x) + 1 = 2 \mathrm{sigmoid}(2x)\) 임을 증명하세요. 층들 사이에 비선형없이 만든 다층 퍼셉트론이 있다고 가정합니다. \(d\) 입력 차원, \(d\) 출력 차원, 그리고 다른 layer는 \(d/2\) 차원을 찾는다고 했을 때, 이 네트워크는 단층 퍼셉트론(single layer perceptron) 보다 강하지 않다는 것을 증명하세요. 한번에 하나의 미니배치에 적용하는 비선형이 있다고 가정합니다. 이렇게 해서 발생하는 문제가 무엇이 있을까요?
퍼셉트론(Perceptron)과 다층 퍼셉트론(MLP)
1. 퍼셉트론(Perceptron)이란?
: 프랑크 로젠블라트가 1957년에 고안한 알고리즘으로 Neural-Network(신경망)의 기원이 되는 알고리즘.
: 가장 오래되고 단순한 형태의 판별 함수 기반 예측 모형(discriminant function based predition model) 중 하나
: 퍼셉트론은 다수의 신호를 받아(input) 하나의 신호(0 또는 1)로 출력(output).
Perceptron Example
x1, x2라는 신호 입력이 y라는 신호로 출력이 되는 과정 자체가 퍼셉트론입니다.
이때 각 입력신호(x1,x2)는 weight(w1,w2)가 곱해지게 됩니다.
** 동그라미를 뉴런 혹은 노드라고 말한다.
1) Weight(가중치), Bias(편향치), Theta(임계점)
: 입력 신호는 각 weight와 곱해져 w1*x1 + w2*x2가 되고, 이 값에 bias(b)가 더해져 w1*x1 + w2*x2 + b가 된다.
: 여러 입력신호가 하나의 신호로 출력되어야 하기 때문에 bias는 뉴런(위 그림에서 동그라미를 의미)당 1개씩 더해진다.
: 또한 출력값이 0 또는 1로 출력되어야 하기때문에 w1*x1 + w2*x2 + b를 0 또는 1로 만들어줘야한다.
: 이때 사용하는 개념이 임계점(Theta)이고, w1*x1 + w2*x2 + b이 설정해놓은 임계점을 기준으로 0 또는 1로 바뀐다.
: 예를 들어, ‘w1*x1 + w2*x2 + b < theta이면 0, w1*x1 + w2*x2 + b > theta이면 1′ 이런식으로!!
2. 단순 논리회로(AND, OR, NAND)
x1 x2 y : AND y : OR y : NAND 0 0 0 0 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 0
AND : 입력이 모두 1인 경우에만, 1을 출력(나머지 경우엔 0을 출력)
def AND(x1, x2): x = np.array([x1, x2]) w = np.array([0.5, 0.5]) b = -0.7 tmp = np.sum(w*x) + b if tmp <= 0: return 0 else: return 1 OR : 입력중 하나 이상이 1인 경우, 1을 출력(모두 0이면 0을 출력) # OR 구현 def OR ( x1 , x2 ): """ AND와 weights와 bias만 다르다 """ x = np . array ([ x1 , x2 ]) w = np . array ([ 0.5 , 0.5 ]) b = - 0.2 tmp = np . sum ( w * x ) + b if tmp <= 0 : return 0 else : return 1 NAND : AND와 반대, 모두 1인 경우 0출력 출력(나머지 경우엔 1을 출력) # NAND 구현 def NAND ( x1 , x2 ): """ AND와 weights와 bias만 다르다 """ x = np . array ([ x1 , x2 ]) w = np . array ([ - 0.5 , - 0.5 ]) b = 0.7 tmp = np . sum ( w * x ) + b if tmp <= 0 : return 0 else : return 1 (위 그림의 직선 : w1*x1 + w2*x2 + b) AND/NAND, OR은 해당 직선(판별함수라도도 할 수 있음)으로 두 영역(black, white)을 구분할 수 있다 3. 한계점 : XOR 문제 x1 x2 y : XOR 0 0 0 1 0 1 0 1 1 1 1 0 XOR : OR의 반대가 아니다!!! 입력값 모두 1인 경우만 1을 출력(나머지 경우엔 0을 출력) 직선(w1*x1 + w2*x2 + b)으로 black/white 두 영역으로 나눌 수가 없다.... Python코드를 예를 들어보면, np . random . seed ( 0 ) X_xor = np . random . randn ( 200 , 2 ) y_xor = np . logical_xor ( X_xor [:, 0 ] > 0 , X_xor [:, 1 ] > 0 ) y_xor = np . where ( y_xor , 1 , – 1 ) plt . scatter ( X_xor [ y_xor == 1 , 0 ], X_xor [ y_xor == 1 , 1 ], c = ‘b’ , marker = ‘o’ , label = ‘1’ , s = 100 ) plt . scatter ( X_xor [ y_xor ==- 1 , 0 ], X_xor [ y_xor ==- 1 , 1 ], c = ‘r’ , marker = ‘s’ , label = ‘-1’ , s = 100 ) plt . ylim ( – 3.0 ) plt . legend () plt . title ( “XOR problem” ) plt . show ()
3.1 해결책 : 다층 퍼셉트론(Multi-Layer Perceptron)
이 XOR 문제를 해결하기 위해 퍼셉트론 두 개를 이어 붙여 해결할 수 있다.
이것을 ‘층을 쌓는다’라 하며,
이렇게 만들어진 퍼셉트론을 다층 퍼셉트론(Multi-Layer Perceptron)이라 한다..
# XOR 구현 # AND, NAND, OR 조합하여 구현하기 def XOR ( x1 , x2 ): “”” 다층 구조를 가진 다층 퍼셉트론 “”” s1 = NAND ( x1 , x2 ) # 1층 s2 = OR ( x1 , x2 ) # 1층 y = AND ( s1 , s2 ) # 2층 return y
Tensorflow로 다층 퍼셉트론(MLP)를 만들어보자.
: Tensorflow로 MNIST데이터를 분류하는 MLP를 만들어보자!
: 코드 위주로 설명 진행.
0. Data Load
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data . read_data_sets ( ‘data/’ , one_hot = True )
1. Parameter Setting
이미지 데이터 1개가 28×28(흑백)으로 구성되어있는데,
위처럼 데이터를 불러오면 28×28=784로 한줄로 펴진 vector로 온다.
그래서 n_input이 784인 것이다.
n_input = 784 n_hidden_1 = 256 n_hidden_2 = 128 n_classes = 10 # set input and output x = tf . placeholder ( dtype = ‘float’ , shape = [ None , n_input ]) y = tf . placeholder ( dtype = ‘float’ , shape = [ None , n_classes ]) # set network parameters(weights, biases) stddev = 0.1 weights = { # 가중치의 초기값은 # 평균 : 0(default), 표준편차 : 0.1 인 정규분포에서 random으로 뽑는다 # hidden layer1의 노드 수는 256개, hidden layer2의 노드 수는 128개 # out layer의 노드 수 = label 갯수 = 10개(0~9, 숫자 10개) ‘h1’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_input , n_hidden_1 ], stddev = stddev )), # 784 x 256 matrix ‘h2’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_1 , n_hidden_2 ], stddev = stddev )), # 256 x 128 matrix ‘out’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_2 , n_classes ], stddev = stddev )), # 128 x 10 matrix } biases = { ‘b1’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_1 ])), # 256개 ‘b2’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_2 ])), ‘out’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_classes ])), } print ( “Network Ready!!!” )
2. Define Graph
multilayer_perceptron 함수에서 최종 출력값을 logit(Wx+b 형태)으로 뽑고,
이를 Cross Entropy에 적용
→ tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels=y, logits=pred))
# model def multilayer_perceptron ( _x , _weights , _biases ): layer_1 = tf . nn . sigmoid ( tf . add ( tf . matmul ( _x , _weights [ ‘h1’ ]), _biases [ ‘b1’ ])) # 1번째 layer 통과 layer_2 = tf . nn . sigmoid ( tf . add ( tf . matmul ( layer_1 , _weights [ ‘h2’ ]), _biases [ ‘b2’ ])) # 2번째 layer 통과 # return은 logit을 뽑아야 한다.(softmax 취하기 전 형태) # softmax취해서 return하면 성능 떨어짐… return ( tf . matmul ( layer_2 , _weights [ ‘out’ ]) + _biases [ ‘out’ ]) # prediction pred = multilayer_perceptron ( x , weights , biases ) # Loss and Optimizer cost = tf . reduce_mean ( tf . nn . softmax_cross_entropy_with_logits_v2 ( labels = y , logits = pred )) optimizer = tf . train . AdamOptimizer ( learning_rate = 0.001 ) . minimize ( cost ) correct = tf . equal ( tf . argmax ( pred , 1 ), tf . argmax ( y , 1 )) accuracy = tf . reduce_mean ( tf . cast ( correct , ‘float’ )) # Initialize init = tf . global_variables_initializer () print ( “Function Ready!!!” )
3. Run
training_epochs = 20 batch_size = 100 display_step = 4 # Launch the Graph sess = tf . Session () sess . run ( init ) # Optimize for epoch in range ( training_epochs ): avg_cost = 0 total_batch = int ( mnist . train . num_examples / batch_size ) # Iteration for i in range ( total_batch ): batch_xs , batch_ys = mnist . train . next_batch ( batch_size = batch_size ) feeds = { x : batch_xs , y : batch_ys } sess . run ( optimizer , feed_dict = feeds ) avg_cost += sess . run ( cost , feed_dict = feeds ) avg_cost = avg_cost / total_batch # Display if ( epoch + 1 ) % display_step == 0 : print ( “Epoch: %03d / %03d cost: %.9f ” % ( epoch , training_epochs , avg_cost )) feeds = { x : batch_xs , y : batch_ys } train_acc = sess . run ( accuracy , feed_dict = feeds ) print ( “Train Accuracy: %.3f ” % ( train_acc )) feeds = { x : mnist . test . images , y : mnist . test . labels } test_acc = sess . run ( accuracy , feed_dict = feeds ) print ( “Test Accuracy: %.3f ” % ( test_acc )) print ( “Optimization Finished!!” )
출력: Epoch: 003/020 cost: 0.119634462 Train Accuracy: 0.980 Test Accuracy: 0.964 Epoch: 007/020 cost: 0.047141746 Train Accuracy: 0.990 Test Accuracy: 0.975 Epoch: 011/020 cost: 0.018645706 Train Accuracy: 1.000 Test Accuracy: 0.977 Epoch: 015/020 cost: 0.006685954 Train Accuracy: 1.000 Test Accuracy: 0.981 Epoch: 019/020 cost: 0.002408720 Train Accuracy: 1.000 Test Accuracy: 0.979 Optimization Finished!!
Activation Function을 ReLU로 바꿔보자
1. Parameter Setting
n_input = 784 n_hidden_1 = 256 n_hidden_2 = 128 n_hidden_3 = 64 n_classes = 10 # set input and output x = tf . placeholder ( dtype = ‘float’ , shape = [ None , n_input ]) y = tf . placeholder ( dtype = ‘float’ , shape = [ None , n_classes ]) # set network parameters(weights, biases) stddev = 0.1 weights = { ‘h1’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_input , n_hidden_1 ], stddev = stddev )), ‘h2’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_1 , n_hidden_2 ], stddev = stddev )), ‘h3’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_2 , n_hidden_3 ], stddev = stddev )), ‘out’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_3 , n_classes ], stddev = stddev )), } biases = { ‘b1’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_1 ])), ‘b2’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_2 ])), ‘b3’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_hidden_3 ])), ‘out’ : tf . Variable ( initial_value = tf . random_normal ( shape = [ n_classes ])), } print ( “Network Ready!!!” )
2. Define Graph
# model def multilayer_perceptron ( _x , _weights , _biases ): layer_1 = tf . nn . relu ( tf . add ( tf . matmul ( _x , _weights [ ‘h1’ ]), _biases [ ‘b1’ ])) layer_2 = tf . nn . relu ( tf . add ( tf . matmul ( layer_1 , _weights [ ‘h2’ ]), _biases [ ‘b2’ ])) layer_3 = tf . nn . relu ( tf . add ( tf . matmul ( layer_2 , _weights [ ‘h3’ ]), _biases [ ‘b3’ ])) # return은 logit을 뽑아야 한다.(softmax 취하기 전 형태) # softmax취해서 return하면 성능 떨어짐… return ( tf . matmul ( layer_3 , _weights [ ‘out’ ]) + _biases [ ‘out’ ]) # prediction pred = multilayer_perceptron ( x , weights , biases ) # Loss and Optimizer cost = tf . reduce_mean ( tf . nn . softmax_cross_entropy_with_logits_v2 ( labels = y , logits = pred )) optimizer = tf . train . AdamOptimizer ( learning_rate = 0.001 ) . minimize ( cost ) correct = tf . equal ( tf . argmax ( pred , 1 ), tf . argmax ( y , 1 )) accuracy = tf . reduce_mean ( tf . cast ( correct , ‘float’ )) # Initialize init = tf . global_variables_initializer () print ( “Function Ready!!!” )
3. Run
training_epochs = 20 batch_size = 100 display_step = 4 # Launch the Graph sess = tf . Session () sess . run ( init ) # Optimize for epoch in range ( training_epochs ): avg_cost = 0 total_batch = int ( mnist . train . num_examples / batch_size ) # Iteration for i in range ( total_batch ): batch_xs , batch_ys = mnist . train . next_batch ( batch_size = batch_size ) feeds = { x : batch_xs , y : batch_ys } sess . run ( optimizer , feed_dict = feeds ) avg_cost += sess . run ( cost , feed_dict = feeds ) avg_cost = avg_cost / total_batch # Display if ( epoch + 1 ) % display_step == 0 : print ( “Epoch: %03d / %03d cost: %.9f ” % ( epoch , training_epochs , avg_cost )) feeds = { x : batch_xs , y : batch_ys } train_acc = sess . run ( accuracy , feed_dict = feeds ) print ( “Train Accuracy: %.3f ” % ( train_acc )) feeds = { x : mnist . test . images , y : mnist . test . labels } test_acc = sess . run ( accuracy , feed_dict = feeds ) print ( “Test Accuracy: %.3f ” % ( test_acc )) print ( “Optimization Finished!!” )
출력: Epoch: 003/020 cost: 0.040441343 Train Accuracy: 1.000 Test Accuracy: 0.974 Epoch: 007/020 cost: 0.011998331 Train Accuracy: 0.990 Test Accuracy: 0.978 Epoch: 011/020 cost: 0.004996898 Train Accuracy: 1.000 Test Accuracy: 0.979 Epoch: 015/020 cost: 0.004258974 Train Accuracy: 0.990 Test Accuracy: 0.979 Epoch: 019/020 cost: 0.002940170 Train Accuracy: 1.000 Test Accuracy: 0.978 Optimization Finished!!
다른거 손대지 않고 Graph만 바꿔주면 된다는 것이 TensorFlow의 장점!
참고
“데이터사이언스 스쿨”
https://datascienceschool.net/view-notebook/342b8e2ecf7a4911a727e6fe97f4ab6b/
“밑바닥으로 시작하는 딥러닝”
http://www.hanbit.co.kr/store/books/look.php?p_code=B8475831198
소스코드
https://github.com/Junhojuno/DeepLearning-Beginning/blob/master/DeepLearning_from_the_bottom/1.Perceptron.ipynb
https://github.com/Junhojuno/DeepLearning-Beginning/blob/master/5.MLP_NumberClassifier.ipynb
퍼셉트론의 개념 (단층 퍼셉트론
728×90
퍼셉트론이란 ?
퍼셉트론은 다수의 신호를 입력으로 받아 하나의 신호를 출력한다. 쉽게 말하면 입출력을 갖춘 알고리즘이며 입력을 주면 정해진 규칙에 따른 값을 출력하는 것이다. 다시 말하면, 입력 값에 대해 출력 값이 어떻게 나올지 예측하는 기계이다. 입력->연산->출력 시스템이다.
이렇게 어떠한 것의 동작 원리를 정확히 파악할 수 없을 때 취할 수 있는 방식 중 하나는 우리가 조정할 수 있는 매개변수 값을 포함하는 모델을 만드는 것이다. 가중치와 편향을 매개변수로 설정한다. 매개변수를 포함하는 선형함수 모델을 만들어보자. 이후, 예측 값과 실제 값을 비교해 오차를 도출하고 이를 기준으로 조정한다.
퍼셉트론은 사람 뇌의 단일 뉴런이 작동하는 방법을 흉내내기 위해 환원 접근법 (reductionist approach)을 이용한다.초기 가중치를 임의의 값으로 정의하고 예측값의 활성 함수 리턴값과 실제 결과값의 활성 함수 리턴값이 동일하게 나올 때까지 가중치의 값을 계속 수정하는 방법이다.
인공신경망의 처리 방식
기본적인 퍼셉트론의 경우, 초평면으로 n차원 공간을 두 개의 결정 영역으로 나뉜다. 초평면을 선형 분리 함수로 정의하며 식은 아래와 같다. 임계값 세타는 결정 경계를 옮기는 데 쓰인다.
선형 분리 함수 수식
단층 퍼셉트론이란 ?
아래 그림에서 원을 뉴런 혹은 노드라고 부르며, 입력 신호가 뉴런에 보내질 때는 각각 고유한 가중치가 곱해진다. (w1,w2) 가중치는 각 신호가 결과에 주는 영향력을 조절하는 요소로 작용한다. 즉, 가중치가 클 수록 해당 신호가 그만큼 더 중요함을 뜻한다. 그 신호를 받은 다음 뉴런은 이전 뉴런에서 보내온 신호의 총합이 정해진 한계를 넘어설 때만 1을 출력한다. 그 한계를 보통 임계 값 (theta)이라 한다. 가중치를 갖는 층이 한 층이기 때문에 단층 퍼셉트론이라고 부른다. (문헌에 따라 층을 세는 기준은 다르다.)
단층 퍼셉트론 도식
이를 수식으로 나타내면 왼쪽과 같은 식이 된다. 오른쪽은 세타를 -b로 치환한 것이다. 여기에서 b를 편향(bias)이라 하며 w1과 w2는 그대로 가중치이다.
단층 퍼셉트론 수식
더 간결한 형태로 다시 작성해보자. 이를 위해서 조건 분기의 동작을 하나의 함수로 나타낸다. 이 함수를 h(x)라 하면 다음과 같이 표현할 수 있다. 이는 계단 함수(step function)의 형태를 띄고 있다.
단층 퍼셉트론 수식2
선형적 분류 (classifier) ?
선형함수(y=ax+c)는 말 그대로 입력 값을 받아 출력 값을 출력했을 때 그 형태가 직선으로 나오게 된다. 우리는 선형함수에서 매개변수 값인 a값과 c값을 조정함으로써 직선의 기울기와 위치를 변화 시킬 수 있다. 원래의 데이터를 통해 적절한 매개변수 값을 조정하여 직선의 기울기를 변화시키고, 이 직선(분류자)을 기준으로 미지의 데이터를 분류자를 기준으로 분류해낸다. 여기서 학습이 필요하다!
그렇다면 선형 분류자를 학습시켜서 잘 분류하게 하려면 어떻게 해야 할까? 임의의 선에서 시작해서 최적의 기울기를 찾는 과정이 학습이다. 우리는 실제 값을 가지는 예제 데이터에 기초해 분류자 함수의 기울기를 구하게 된다. 이 때 예제 데이터를 학습 데이터(training data)라고 부른다.
학습의 과정은 임의의 수로 시작하여 ‘오차’를 통해 기울기를 변화시킨다. 오차는 목표 값과 실제 출력 값 간의 차이이다. 그러나 직선이 오차만을 기준으로 업데이트한다면 최종적으로는 그저 마지막 학습 데이터에 맞춰진 업데이트 결과만을 얻게 된다. 이를 해결하기 위해 업데이트의 정도를 조금씩 조정할 수 있게 해주는 학습률(learning rate)에 대한 개념이 나오게 된다. 각각의 새로운 a로 바로 점프하는 것이 아니라 일부씩만 업데이트 하는 것이다. 즉 기존 여러 번의 학습에 기초해 업데이트된 값을 유지하면서, 학습 데이터가 제시하는 방향으로 조금씩만 움직이는 것이다. 이는 좋은 의미의 부작용도 수반한다. 실제 현업에서는 학습 데이터 자체에 문제가 있는 경우가 많고, 학습 데이터 자체가 오차 또는 잡음을 가지므로 완벽하게 정확하지도 않으며 심지어 신뢰할 수 없는 경우가 많이 있는데, 업데이트의 정도를 조정해가는 방법은 이러한 학습 데이터의 오차나 잡음의 영향을 약화시켜 준다.
선형적 분류 – 신경망 첫걸음 책
이제 위에서 말로 설명한 것을 수식으로 봐보도록 하자.
우선, y=Ax에 적정한 값을 넣고 시작하여 오차를 통해 매개변수 A를 조정한다.
이후 A를 정교화 하기 위해서는 여기서 오차 E와 기울기 A의 관계를 알아야한다. 아래의 수식을 살펴보자.
오차 E가 양수면 퍼셉트론의 출력을 증가하고, 음수면 퍼셉트론의 출력을 감소한다.
오차에 기초해 매개변수 A 업데이트
하지만 위와 같은 업데이트 방식은 마지막 학습 데이터에 맞춰진 결과만을 얻게 된다.
따라서 업데이트의 정도를 조금씩 조정하기 위해 학습률을 도입해보자. 그럼 아래와 같은 수식을 얻게 된다.
이때 학습률은 1보다 작은 양의 상수이다. 예를 들어 L=0.5이면, 조정이 없을 때에 비해 1/2만큼만 업데이트 하겠다는 의미이다.
L은 학습률
선형 분류자의 한계점
1. 직선형 영역만 표현할 수 있다. 데이터들의 차이가 확연히 두드러지지 않는다면 두 가지의 종류조차도 분류하지 못할 수도 있다는 말과 같다.
2. 단층 퍼셉트론에서 논리함수를 예로 들어보면, AND, NAND, OR 논리회로를 계산할 수 있지만 XOR(배타적 논리합)의 경우 단일 선형 프로세스로 데이터를 분류해낼 수 없다. 여러 개의 선형 분류자를 이용해서 데이터를 나누거나 한 선으로는 곡선으로 나눌 수 있기 때문에 비선형 분류이다.
논리 함수 (Boolean logic)
python 단층 퍼셉트론 구현
다층 퍼셉트론?
그래서 다층 퍼셉트론이 나왔다. (Multi-layer Perceptron, MLP)
단층 퍼셉트론은 입력층과 출력층만 존재하지만, 다층 퍼셉트론은 중간에 은닉층(hidden layer)이라 불리는 층을 더 추가하였다. XOR 게이트는 기존의 AND, NAND, OR 게이트를 조합하여 만들 수 있기 때문에 퍼셉트론에서 층을 계속 추가하면서 만들 수 있다. 이렇게 층을 여러겹으로 쌓아가면서 선형 분류만으로 풀기 못했던 문제를 비선형적으로 풀 수 있게 된다. 각 층에서 오차는 역전파 알고리즘을 통해 업데이트해나간다.
다층 퍼셉트론은 은닉층이 1개 이상인 퍼셉트론을 의미한다. 은닉층이 2개일 수도 있고 수십, 수백개일 수도 있다. 은닉층이 2개 이상인 신경망을 심층 신경망 (Deep Neural Network, DNN) 이라고 한다. 복잡한 문제를 해결하기 위해서는 신경망의 층수를 여러층 쌓은 모델을 이용해야 하는데, 깊은 층수를 쌓을 경우 역전파(Backpropagtion) 학습과정에서 데이터가 사라져 학습이 잘 되지 않는 현상인 Vanishing Gradient 문제가 있다. 또한, 학습한 내용은 잘 처리하나 새로운 사실을 추론하는 것, 새로운 데이터를 처리하는 것을 잘하지 못하는 한계도 있었다. 이러한 신경망을 ‘인공 신경망’이라고 부른다.
(학습과정과 현상에 대해서는 다음 포스팅에서 알아보도록 한다)
이러한 한계를 극복한 인공신경망을 딥러닝 (Deep Learning)이라고 한다. 캐나다 토론토 대학 제프리 힌튼(Geoffrey Hinton) 교수는 2006년에 깊은 층수의 신경망 학습시 사전 학습(Pretraining)을 통해서 학습함으로써 Vanishing Gradient 문제를 해결할 수 있음을 밝혔다. 또한 새로운 데이터를 잘 처리하지 못하는 문제는 학습 도중에 고의로 데이터를 누락시키는 방법(dropout)을 사용하여 해결할 수 있음을 2012년에 밝혔다.
728×90
[머신 러닝] 다층 퍼셉트론
다층 퍼셉트론과 역전파
다층 퍼셉트론은 입력층 하나와 은닉층이라 불리는 하나 이상의 TLU 층과 출력층으로 구성됩니다.
입력층과 가까운 층을 하위 층, 출력층에 가까운 층을 상위 층이라 부릅니다.
출력층을 제외하고 모든 층은 편향 뉴런을 포함하며 다음 층과 완전히 연결돼 있습니다.
다층 퍼셉트론 예시
은닉층을 여러 개 쌓아 올린 인공 신경망을 심층 신경망(deep neural network, DNN)이라고 합니다.
딥러닝은 심층 신경망을 연구하는 분야이며 조금 더 일반적으로는 연산이 연속하여 길게 연결된 모델을 연구합니다.
다층 퍼셉트론을 훈련할 방법을 찾는 연구가 긴 시간 지속되다가
데이비드 루멜하트, 제프리 힌턴, 로날드 윌리엄스가 역전파 훈련 알고리즘을 소개했습니다.
이 알고리즘은 효율적 기법으로 그레이디언트를 자동으로 계산하는 경사 하강법입니다.
네트워크를 정방향으로 한 번, 역방향으로 한 번 통과하는 것만으로 모든 모델 파라미터에 대한
네트워크 오차의 그레이디언트를 계산할 수 있습니다.
이 알고리즘을 조금 더 자세히 살펴보겠습니다.
한 번에 하나의 미니배치씩 진행해 전체 훈련 세트를 처리합니다.
이 과정을 여러 번 반복하는 데 각 반복을 에포크라고 합니다.
각 미니배치를 이용해 정방향 계산을 합니다.
이 과정은 역방향 계산을 위해 중간 계산값을 모두 저장하는 것 외에는 예측을 만드는 것과 정확히 같습니다.
그 다음 알고리즘이 손실 함수를 이용해 출력 오차를 측정합니다.
이제 각 출력 연결이 이 오차에 기여하는 정도를 계산합니다.
이 알고리즘은 또 다시 이전 층의 연결 가중치가 이 오차의 기여 정도에 얼마나 기여했는지 측정합니다.
마지막으로 알고리즘은 경사 하강법을 수행해
방금 계산한 오차 그레이디언트를 사용해 네트워크에 있는 모든 연결 가중치를 수정합니다.
이 알고리즘을 잘 작동시키기 위해 논문 저자들은 다층 퍼셉트론 구조의 계단 함수를 시그모이드로 바꿨습니다.
계단 함수에는 수평선밖에 없어서 계산할 그레이디언트가 없기 때문입니다.
역전파 알고리즘은 시그모이드 외에도 다른 활성화 함수와도 사용될 수 있습니다.
널리 쓰이는 두 개의 활성화 함수는 다음과 같습니다.
하이퍼볼릭 탄젠트 함수 (쌍곡 탄젠트 함수): \(tanh(z) = 2\sigma(2z) – 1\), 시그모이드 함수처럼 이 활성화 함수도 S자 모양이고 연속적이며 미분 가능합니다. 출력 범위가 -1에서 1 사이이고, 이 범위는 훈련 초기에 각 층의 출력을 원점 근처로 모으는 경향이 있습니다. 이는 종종 빠른 수렴을 도와줍니다.
ReLU 함수: \(ReLU(z) = max(0, z)\), ReLU 함수는 연속적이지만 \(z = 0\)에서 미분가능하지 않습니다. 그러나 실제로는 잘 작동하고 계산 속도가 빠르다는 장점이 있어 기본 활성화 함수가 되었습니다.
이런 활성화 함수들이 왜 필요할까요?
선형 변환을 여러 개 연결해도 얻을 수 있는 것은 선형 변환뿐이기 때문입니다.
따라서 층 사이에 비선형층을 추가하지 않으면 아무리 층을 많이 쌓아도 하나의 층과 동일해집니다.
이런 층으로는 복잡한 문제를 풀 수 없으므로 활성화 함수가 필요한 것입니다.
여태 봤던 활성화 함수들을 아래 그림에 나타냈습니다.
활성화 함수와 각 함수의 도함수들
회귀를 위한 다층 퍼셉트론
다층 퍼셉트론은 회귀에 사용할 수 있습니다.
값 하나를 예측하는 데 출력 뉴런이 하나만 필요합니다.
이 뉴런의 출력이 예측한 값입니다.
다변량 회귀(동시에 여러 값을 예측하는 경우)에서는 출력 차원마다 출력 뉴런이 하나씩 필요합니다.
일반적으로 회귀용 다층 퍼셉트론을 만들 때 출력 뉴런에 활성화 함수를 사용하지 않고 범위 제한이 되지 않게 합니다.
하지만 출력이 항샹 양수여야한다면 ReLU나 softplus 활성화 함수를 사용할 수 있습니다.
softplus 함수는 ReLU의 변종으로 다음과 같습니다.
\[ softplus(z) = log(1 + exp(z)) \]
이 함수는 z가 작을수록 0에 가까워지고 z가 클수록 z에 가까워집니다.
마지막으로 어떤 범위 안의 값을 예측하고 싶다면
시그모이드 함수나 하이퍼볼릭 탄젠트 함수를 사용하고 레이블의 스케일을 적절한 범위로 조정할 수 있습니다.
훈련에 사용하는 손실 함수는 전형적으로 평균 제곱 오차입니다.
하지만 훈련 세트에 이상치가 많다면 대신 평균 절댓값 오차를 사용할 수 있습니다.
또는 이 둘을 조합한 후버 손실을 사용할 수 있습니다.
아래는 회귀 다층 퍼셉트론의 전형적인 구조입니다.
하이퍼파라미터 일반적인 값 입력 뉴런 수 특성마다 하나 은닉층 수 문제에 따라 다름, 일반적으로 1에서 5 사이 은닉층의 뉴런 수 문제에 따라 다름, 일반적으로 10에서 100 사이 출력 뉴런 수 예측 차원마다 하나 은닉층의 활성화 함수 ReLU(또는 SELU) 출력층의 활성화 함수 없음, 또는 ReLU/softplus나 logistic(sigmoid)/tanh 사용 손실 함수 MSE나 이상치가 있다면 MAE/Huber
분류를 위한 다층 퍼셉트론
다층 퍼셉트론은 분류 작업에도 사용 가능합니다.
이진 분류 문제에서는 로지스틱 활성화 함수를 가진 하나의 출력 뉴런만 필요합니다.
출력은 0과 1 사이의 실수입니다. 이를 양성 클래스에 대한 확률로 해석할 수도 있습니다.
다층 퍼셉트론은 다중 레이블 이진 분류 문제를 쉽게 해결할 수 있습니다.
이 때에는 로지스틱 활성화 함수를 가진 레이블 개수 만큼의 출력 뉴런이 필요합니다.
각 샘플이 여러 클래스 중 한 클래스에만 속할 수 있다면 클래스마다 하나의 출력 뉴런이 필요합니다.
출력층에는 소프트맥스 활성화 함수를 사용해야 합니다.
소프트맥스 함수는 예측 확률을 0과 1 사이로 만들고 더했을 때 1이 되도록 만듭니다.
이를 다중 분류라고 부릅니다.
분류에 사용되는 현대적 다층 퍼셉트론
확률 분포를 예측해야 하므로 손실 함수에는 일반적으로 크로스 엔트로피 손실을 선택하는 것이 좋습니다.
하이퍼 파라미터 이진 분류 다중 레이블 분류 다중 분류 입력층과 은닉층 회귀와 동일 회귀와 동일 회귀와 동일 출력 뉴런 수 1개 레이블마다 1개 클래스마다 1개 출력층의 활성화 함수 로지스틱 함수 로지스틱 함수 소프트맥스 함수 손실 함수 크로스 엔트로피 크로스 엔트로피 크로스 엔트로피
케라스로 다층 퍼셉트론 구현하기
tensorflow 2, tf.keras를 이용하겠습니다.
시퀀셜 API를 사용하여 이미지 분류기 만들기
아래 코드를 참고하세요.
시퀀셜 API를 사용하여 회귀용 다층 퍼셉트론 만들기
아래 코드를 참고하세요.
함수형 API를 사용해 복잡한 모델 만들기
순차적이지 않은 신경망의 한 예는 와이드 & 딥 신경망입니다.
이 신경망은 아래 그림과 같이 입력의 일부 또는 전체가 출력층에 바로 연결됩니다.
이 구조를 사용하면 신경망이 (쌓은 층을 사용한)복잡한 패턴과
(짧은 경로를 사용한)간단한 규칙을 모두 학습할 수 있습니다.
와이드 & 딥 신경망 예시
이런 신경망을 만들어보겠습니다.
아래 그림과 같이 일부 특성은 짧은 경로로 전달하고
다른 특성들은 (중복될 수 있습니다.) 깊은 경로로 전달하고 싶을 수도 있습니다.
여러 개의 입력 다루기
위와 같은 모델을 만들어보겠습니다.
여러 개의 출력이 필요한 경우도 많습니다.
말 그대로 여러 출력이 필요한 작업인 경우
동일한 데이터에서 독립적인 여러 작업을 수행할 경우, 물론 작업마다 새로운 신경망을 훈련할 수 있지만 신경망이 여러 작업에 걸쳐 유용한 특성을 학습할 수 있기 때문에 작업마다 하나의 출력을 가진 단일 신경망을 훈련하는 것이 좀 더 나은 결과를 냅니다.
규제 기법으로 사용하는 경우, 예를 들어 신경망 구조 안에 보조 출력을 추가할 수 있습니다. 보조 출력을 사용해 하위 네트워크가 나머지 네트워크에 의존하지 않고 그 자체로 유용한 것을 학습하는지 확인 가능합니다.
위와 같은 경우들 중 보조 출력을 사용하는 경우를 다뤄보겠습니다.
여러 개의 출력 다루기_보조 출력
위 그림과 같은 모델을 만들어보겠습니다.
서브클래싱 API로 동적 모델 만들기
앞서 다른 시퀀셜 API와 함수형 API는 모두 선언적입니다.
사용할 층과 연결 방식을 먼저 정의하고, 그 다음 모델에 데이터를 주입하여 훈련이나 추론을 할 수 있습니다.
이 방식에는 다음과 같은 장점이 있습니다.
모델을 저장하거나 복사, 공유하기 쉽습니다.
모델의 구조를 출력하거나 분석하기 좋습니다.
프레임워크가 크기를 짐작하고 타입을 확인하여 에러를 일찍 발견할 수 있습니다. (즉, 모델에 데이터가 주입되기 전에)
전체 모델이 층으로 구성된 정적 그래프이므로 디버깅하기도 쉽습니다.
이런 장점들을 많이 갖지만 정적이라는 것은 단점이 되기도 합니다.
어떤 모델은 반복문을 포함하고 다양한 크기를 다뤄야 하며 조건문을 가지는 등
여러 가지 동적인 구조를 필요로 합니다.
이런 경우 좀 더 명령형 프로그래밍 스타일이 필요하다면 서브클래싱 API가 정답입니다.
이를 이용한 모델을 만들어보겠습니다.
함수형 API를 만드는 것과 비슷하지만
Input 클래스의 객체를 만들 필요가 없습니다.
대신 call() 메소드의 inputs 매개변수를 사용합니다.
생성자에 있는 층 구성과 call() 메소드에 있는 정방향 계산을 분리했습니다.
주된 차이점은 call() 메소드 안에서 어떤 계산이든 할 수 있다는 것입니다.
for, if, 텐서플로 저수준 연산 등을 사용할 수 있습니다.
유연성이 높아지는 대신 그에 따른 비용이 발생합니다.
모델 구조각 call() 메소드 안에 숨겨져 있기 때문에
케라스가 이를 쉽게 분석할 수 없습니다.
즉 모델을 저장하거나 복사할 수 없습니다.
summary() 메소드를 호출하면 층의 목록만 나열되고 층 간의 연결 정보를 얻을 수 없습니다.
또한 케라스가 타입과 크기를 미리 확인할 수 없어 실수가 발생하기 쉽습니다.
이런 단점들 때문에 높은 유연성이 필요한 게 아니라면
시퀀셜 API와 함수형 API를 사용하는 게 좋습니다.
[37편] 다층 퍼셉트론 구현하기
이번 포스팅에서는 [34편]~[36편] 내용에서 다룬 다층 퍼셉트론을 파이썬으로 구현한 코드를 소개하고, MNIST의 손글씨 숫자 60,000개의 샘플을 딥러닝 학습을 수행한 후 손글씨 숫자에 대한 인식률을 살펴보는 것으로 하겠습니다.
MNIST 데이터는 다양한 사람들이 직접 쓴 숫자 0~9까지의 이미지 집합이며, 이미지의 크기는 28 x 28 크기로 표준화되어 있습니다. MNIST 데이터는 트레이닝을 위한 60,000개의 손글씨 숫자 이미지 데이터와 테스트를 위한 10,000개의 손글씨 숫자 이미지 데이터로 구성되어 있습니다.
먼저 아래의 링크를 눌러서 MNIST 데이터를 확보합니다.
☞ MNIST 데이터 받기
링크를 눌러 MNIST 데이터 홈페이지에 들어가면 아래와 같은 4개의 데이터 파일이 보일 것입니다.
train-images-idx3-ubyte.gz : training set images
train-labels-idx1-ubyte.gz : training set labels
t10k-images-idx3-ubyte.gz : test set images
t10k-labels-idx1-ubyte.gz : test set labels
이 파일들을 모두 다운로드 받아 특정 디렉토리에 저장한 후, 압축 프로그램을 이용해 압축을 해제합니다.
MNIST 데이터 홈페이지 아랫부분에 보면 이 파일들에 대한 포맷형식이 설명되어 있습니다. 파일 포맷을 요약해보면 다음과 같습니다.
TRAINING SET LABEL FILE (train-labels-idx1-ubyte):
[offset] [type] [value] [description]0000 32 bit integer 0x00000801(2049) magic number (MSB first)
0004 32 bit integer 60000 number of items
0008 unsigned byte ?? label
0009 unsigned byte ?? label
……..
xxxx unsigned byte ?? label
※label 값은 0~9까지임
TRAINING SET IMAGE FILE (train-images-idx3-ubyte):
[offset] [type] [value] [description]0000 32 bit integer 0x00000803(2051) magic number
0004 32 bit integer 60000 number of images
0008 32 bit integer 28 number of rows
0012 32 bit integer 28 number of columns
0016 unsigned byte ?? pixel
0017 unsigned byte ?? pixel
……..
xxxx unsigned byte ?? pixel
※ 픽셀값은 1바이트씩 아래로 쭉 연결됨. 28×28=784바이트 단위로 하나의 손글씨 이미지로 구분되며 pixel값이 0이면 흰색 바탕, 255이면 검정색 숫자 부분을 의미함
테스트를 위한 파일 포맷도 트레이닝 데이터와 마찬가지 포맷입니다. 트레이닝을 위한 라벨 데이터가 저장된 파일의 최초 8바이트에는 아이템 개수 등의 정보가 저장되어 있고 라벨은 9바이트째부터 시작됩니다. 손글씨 숫자 이미지가 저장된 파일의 최초 16바이트에는 이미지 개수, 가로 세로 픽셀수 등의 정보가 저장되어 있고 이미지 픽셀 데이터는 17바이트째부터 시작됩니다.
자, 그럼 아래의 코드를 봅니다.
dl_load_digits.py
위 코드의 load_mnist(path, kind=’train’)는 라벨 데이터가 저장된 파일과 이미지 데이터가 저장된 파일로부터 데이터를 모두 읽어 각각 numpy 배열 labels, images로 저장하여 리턴하는 함수입니다.
참고로 이 포스팅에서는 학습을 위한 데이터가 저장된 폴더는 dl_load_digits.py가 저장된 폴더 아래에 data/mnist 폴더입니다. 따라서 여러분들의 학습 데이터가 저장된 폴더 위치에 맞게 경로를 조정해줘야 한다는 거 잊지마세요~
코드에 등장하는 struct.unpack()은 저의 첫번째 책 ‘암호와 해킹’에서 간략하게 설명되어 있는데, 간단히 요약하여 설명하면, 파이썬의 struct 모듈은 파이썬 바이트 객체로 표현된 C구조체와 파이썬에서 사용하는 값을 상호 변환하는데 사용되는 각종 메쏘드들을 제공합니다.
>>> magic, n = struct.unpack(‘>II’, imgpath.read(8))
이 코드의 의미는 imgpath 파일에서 8바이트 데이터를 big-endian(>)으로 읽고, 읽은 데이터를 unsigned integer(I) 2개로 나누어서 각각 magic, n 변수에 대입하라는 뜻입니다.
이 코드를 실행하면 4개의 MNIST 데이터 파일을 모두 읽어, 트레이닝 이미지 데이터는 X_train, 트레이닝 라벨 데이터는 y_train, 테스트 이미지 데이터는 X_test, 테스트 라벨 데이터는 y_test로 저장하고 이미지 샘플의 개수 정보를 화면에 표시합니다.
코드를 실행하면 다음과 같은 결과가 나오면 데이터를 성공적으로 로드한 것입니다.
학습 샘플수 : 60000, 컬럼수: 784
테스트 샘플수 : 10000, 컬럼수: 784
이제, 아래의 코드를 dl_load_digits.py 아래 부분에 추가합니다.
dl_show_09digits.py
이 코드는 X_train에 저장된 0~9까지 이미지를 화면에 출력하는 코드입니다. 코드를 실행하면 다음과 같은 손글씨 숫자가 화면에 나올 겁니다.
위 코드를 아래와 같이 약간 수정해서 같은 숫자 25개에 대한 이미지를 화면에 출력하도록 해봅니다.
dl_show_samedigits.py
이 코드를 실행하면 아래와 같이 숫자 6에 대한 다양한 손글씨 이미지 25개를 화면에 출력합니다.
dl_show_samedigits.py 코드에서 y_train == 6 부분을 y_train == 5 등으로 바꾸어 다른 숫자들도 확인해보세요. 이로써 우리가 확보한 MNIST 손글씨 데이터가 어떤 식으로 되어있는지 확인을 했네요~
이제는 이 손글씨 데이터를 학습할 다층 퍼셉트론을 파이썬으로 구현하는 것입니다. 이 포스팅에 제시된 대부분의 소스코드는 Sebatian Raschka의 책 “Python Machine Learning”에서 발췌한 것이며 필요시 제가 조금 수정하거나 추가한 코드도 있기도 합니다. 아래에 제시된 MLP 구현 코드도 이 책에서 발췌한 것인데, 딥러닝 성능을 위해 추가적인 알고리즘이 적용되어 있는 제대로 된 다층 퍼셉트론을 구현한 코드입니다.
dl_mlp_class.py
음… 코드가 참 깁니다. 딥러닝의 세계는 쉽지 않은 길입니다. NeuralNetMLP라는 이름의 클래스가 바로 다층 퍼셉트론을 구현한 부분입니다. 코드의 세부적인 내용을 이 포스팅에서 일일이 서술하는 것은 무리일 것 같아서, 함수 단위로 설명을 하도록 합니다.
먼저, NeuralNetMLP 클래스의 초기값을 위해 입력되는 인자들이 굉장히 많습니다. 이 인자들에 대해 가볍게 살펴보는 것으로 시작해봅니다.
n_output:
출력층의 출력값 개수. 손글씨 숫자의 경우 0~9까지 10으로 지정하면 됨
n_features:
입력층에 입력되는 특성값의 개수. 28×28 픽셀의 이미지 데이터이므로 784로 지정하면 됨
n_hidden:
은닉층의 노드 개수. 손글씨 숫자 학습을 위해 50으로 지정할 것임
l1:
L1 정규화를 위한 람다값. 오버피팅 방지를 위한 것임
l2:
L2 정규화를 위한 람다값. 오버피팅 방지를 위한 것임
epochs:
학습 반복 회수
eta:
learning rate η
alpha:
가중치 업데이트를 보다 고속으로 처리하기 위한 모멘텀 학습 파라미터
decrease_const:
학습 수렴률을 향상시키기 위해 learning rate을 학습 반복에 따라 감소시키기 위한 감쇠 상수
처음에는 learning rate을 다소 큰 값으로 잡아 최소값에 빨리 다다르게 한 후, 감쇠 상수를 지속적으로 곱해서 learning rate을 점점 작아지게 할 용도로 사용됨
shuffle:
매 반복마다 트레이닝 데이터를 뒤섞기를 위한 플래그. True이면 뒤섞음
minibatches:
매 학습에 사용되는 무작위로 추출할 트레이닝 데이터의 실제 개수. 확률적 경사하강법 적용 개념임
모집단에서 일정 크기의 표본을 추출하여 결과를 통계적으로 예측하는 것과 비슷한 개념
이것으로 NeuralNetMLP의 초기화를 위한 인자에 대해 설명했습니다. 보면 우리가 아직 다루지 않은 모멘텀 학습 파라미터라든가 감쇠 상수 같은 내용도 있는데, 그냥 이런 것들이 있다는 것만 알고 넘어갑니다.
아무튼 NeuralNetMLP는 [34편], [35편], [36편]에서 다룬 내용을 코드화 한 것으로 볼 수 있습니다.
이제 NeuralNetMLP의 각 함수에 대해 가볍게 설명합니다.
_encode_labels(self, y, k)
출력층 10개 노드에서 출력되는 값이 (1, 0,…0)이면 0, (0, 1, 0,,,)이면 1, (0, 0, …,1)이면 9를 의미하는 것으로 정의함
y는 손글씨 숫자의 라벨링 데이터, k는 출력층의 출력값 개수
_initialize_weights(self)
입력층과 은닉층 사이의 가중치 w1과 은닉층과 출력층 사이의 가중치 w2의 값을 초기화함. 바이어스 항도 포함시킴
_sigmoid(self, z)
z에 대한 시그모이드 함수값을 리턴함. scipy.expit()은 시그모이드 함수임
_sigmoid_gradient(self, z)
z에 대한 시그모이드 함수의 미분값을 리턴함.
_add_bias_unit(self, X, how=’column’)
X에 바이어스 값을 추가해서 X_new로 둠. 행렬 계산의 특성상 입력층에서 은닉층, 은닉층에서 출력층으로의 계산을 위해 how 값을 ‘column’, ‘row’로 지정하여 바이어스를 행에 더하거나, 열에 더하도록 함
_feedforward(self, X, w1, w2)
w1, w2 가중치로 X를 순전파 시킵니다. 순전파한 결과는 a1, z2, a2, z3, a3로 리턴함
_L2_reg(self, lambda_, w1, w2) , _L1_reg(self, lambda_, w1, w2)
L2 정규화와 L1 정규화 값을 리턴함
_get_cost(self, y_enc, output, w1, w2)
로지스틱 비용함수 J 를 리턴함. J 에는 정규화를 위한 값이 추가되었음
_get_gradient(self, a1, a2, a3, z2, y_enc, w1, w2)
역전파 알고리즘을 구현한 함수
predict(self, X)
X에 대한 예측값을 리턴
fit(self, X, y, print_progress=True)
트레이닝 데이터 X, y를 이용해 다층 퍼셉트론을 학습시킴. 학습의 속도를 위해 minibatches로 지정된 개수만큼 데이터를 무작위로 추출하여 학습을 시킴
코드의 세부적인 내용은 언급안했으나, 각 함수들의 역할과 이전 포스팅 [34편]~[36편]에서 다루었던 내용을 참고하여 코드를 다시 한번 보면 코드의 내용을 이해할 수 있을 것입니다.
이 코드를 dl_load_digits.py 맨 마지막 부분에 추가합니다.
이제는 구현한 다층 퍼셉트론으로 60,000개의 데이터에 대해 학습을 수행하는 코드를 볼 차례입니다.
dl_mlp_learning.py
이 코드는 결국 784-50-10 다층 퍼셉트론을 구성하고 50개의 데이터를 무작위로 추출한 후 1000번 반복 학습을 수행하는 코드입니다. 학습을 수행하는데 소요되는 시간은 컴퓨터의 성능에 따라 10~30분정도 소요됩니다. 한번 학습한 것을 또 학습할 수는 없으므로 pickle을 이용해 학습된 mlp 객체를 파일로 저장하여 나중에 다시 불러 사용할 수 있게 합니다.
추가한 코드를 실행합니다. 시간이 걸리므로 잠시 다른 일을 하고 와도 됩니다.
학습이 종료되면 학습 결과가 mlp_digits.pkl로 저장됩니다. 이 파일을 불러오려면 아래의 코드를 활용합니다.
dl_load_mlpobj.py
사용법은 이렇습니다. 여태까지 작성된 코드에서 dlp_mlp_learning.py 코드 부분은 주석 처리해서 나중에 트레이닝 데이터가 갱신되게 되면 재사용할 수 있도록 합니다. 그런 후, 주석 처리된 코드 아랫 부분에 dl_load_mlpobj.py 코드를 추가합니다. 이게 끝입니다. 이젠 10분 이상 걸리는 학습을 더 이상 수행하지 않아도 됩니다.
이제 학습의 결과가 어떠한지 살펴볼까요~. 일단 비용함수 J가 어떤 식으로 변화하는지 그래프로 살펴봅니다. 아래의 코드를 여태까지 작성한 코드 마지막 부분에 추가합니다.
dl_plot_cost1.py
추가한 코드를 실행하면 다음과 같은 결과가 화면에 나옵니다.
이 그래프는 실제로 비용함수의 값이 오르락 내리락 하는 그래프인데 실제로 그렇게 보이지 않네요. 아무튼 비용함수의 값이 오르락 내리락하면서 편차가 심합니다. 하지만 40,000번째 이후에는 오르락 내리락 하면서도 일정한 범위로 수렴한다는 것을 볼 수 있습니다.
그런데 이 녀석은 minibatches의 단위 50개의 데이터를 처리하는 과정에서 매회 비용함수를 계산한 것입니다. x축의 값을 보면 1,000번 반복한 것이 아니라 50,000번 반복한 것으로 나오는 이유입니다. 따라서 50개의 데이터를 처리한 것의 평균 비용함수의 값을 그래프로 나타내 봅니다.
dl_plot_cost1의 코드를 다음과 같이 수정합니다.
dl_plot_cost2.py
수정된 코드를 실행하면 다음과 같은 결과가 나옵니다.
그래프를 보면 800회 학습 이후에 비용함수가 특정값으로 수렴하고 있음을 알 수 있습니다.
이제는 학습된 결과를 살펴보도록 합니다. 아래는 60,000개의 학습 데이터를 이용해 학습을 시키고 학습 데이터에 대한 학습 정확도를 계산하는 코드입니다.
dl_mlp_predict_train.py
이 코드를 실행하면 다음과 같은 결과가 나옵니다.
예측성공/총개수: [58680]/[60000]
딥러닝 정확도: 97.80%
dl_mlp_predict1.py를 조금 수정하여 테스트 데이터에 대한 정확도를 계산해봅니다.
dl_mlp_predict_test.py
이 코드를 실행하면 다음과 같은 결과가 나옵니다.
예측성공/총개수: [9597]/[10000]
딥러닝 정확도: 95.97%
두 개의 결과를 비교해보면 테스트 데이터에 대한 정확도가 트레이닝 데이터에 대한 정확도보다 쪼금 작습니다. 이는 학습 결과가 약간 오버피팅이 되었음을 알 수 있습니다.
그렇다면 어떤 손글씨 숫자들이 제대로 인식이 안되었는지 확인해보죠~
아래의 코드를 여태까지 작성한 코드 마지막에 추가합니다.
위 코드를 추가한 코드를 실행하면 아래와 같은 결과가 화면에 보입니다.
우리가 학습시킨 MLP가 잘못 인식한 숫자들 중 일부입니다. 그런데, 일부 숫자는 사람이 보기에도 구분이 안되는 것이 있습니다. 1), 6), 7), 8), 13), 17), 22), 23), 25) 등은 우리 눈으로 보기에도 헷갈리는 숫자들입니다.
아무튼 이런 데이터들에 대해서는 사용자로 하여금 피드백을 줘서 제대로 된 숫자로 인식하도록 학습시키면 될 것입니다. 사용자의 피드백을 재학습시키는 내용에 대해서는 [22편] 마지막 부분에서 다루었습니다.
만약 여러분들이 직접 쓴 숫자를 여기서 학습한 MLP를 이용해 인식하려고 하면 아래와 같은 로직으로 프로그램을 작성하면 됩니다.
여러분이 손으로 쓴 숫자를 이미지로 저장합니다. 이미지의 크기를 OpenCV의 cv2.resize()를 이용해 28 x 28 크기로 변환합니다. OpenCV의 cv2.threshold()를 이용해 숫자 부분과 배경부분을 검정색과 흰색으로 변환시켜 줍니다. 이렇게 변환된 이미지 픽셀을 numpy로 저장하고 ravel()을 이용해 1차원으로 변형한 후 이 값을 X로 둡니다. y_pred = mlp.predict(X)로 예측값인 y_pred를 확인하면 됩니다.
OpenCV에 대한 자세한 내용은 제 블로그의 OpenCV 강좌를 참조하면 됩니다.
이상으로 다층 퍼셉트론을 이용한 손글씨 숫자를 인식하는 내용은 마무리 하도록 하겠습니다.
다음 포스팅에서는 구현한 역전파 알고리즘의 정확도를 체크하는 방법인 gradient checking에 대해 가볍게 살펴보도록 하고, 이후 포스팅부터는 또 다른 딥러닝 방법인 Convolutional Neural Network(CNN)과 Recurrent Neural Network(RNN)에 대한 내용을 다루도록 하겠습니다.
키워드에 대한 정보 다층 퍼셉트론 예제
다음은 Bing에서 다층 퍼셉트론 예제 주제에 대한 검색 결과입니다. 필요한 경우 더 읽을 수 있습니다.
이 기사는 인터넷의 다양한 출처에서 편집되었습니다. 이 기사가 유용했기를 바랍니다. 이 기사가 유용하다고 생각되면 공유하십시오. 매우 감사합니다!
사람들이 주제에 대해 자주 검색하는 키워드 Ch09_01.다층신경망과 텐서플로(다층신경망이란)01
- 동영상
- 공유
- 카메라폰
- 동영상폰
- 무료
- 올리기
Ch09_01.다층신경망과 #텐서플로(다층신경망이란)01
YouTube에서 다층 퍼셉트론 예제 주제의 다른 동영상 보기
주제에 대한 기사를 시청해 주셔서 감사합니다 Ch09_01.다층신경망과 텐서플로(다층신경망이란)01 | 다층 퍼셉트론 예제, 이 기사가 유용하다고 생각되면 공유하십시오, 매우 감사합니다.