데이터&인공지능/자연어처리

자연어 처리 - 딥 러닝을 이용한 자연어 처리 입문(13) _ 딥러닝

csmoon1010 2020. 2. 21. 12:36

08. 딥 러닝(Deep Learning) 개요

wikidocs.net/book/2155

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

- 기본 구조 : 인공 신경망(Artificial Neural Network)

- 초기 신경망(퍼셉트론), 피드 포워드 신경망 언어 모델, 기본적인 케라스 사용법

 

1) 퍼셉트론(Perceptron)

- 딥 러닝 : 인공 신경망을 복잡하게 쌓아 올린 방법

- 퍼셉트론 : 초기 인공 신경망

 

1. 퍼셉트론(Perceptron)

- 다수의 입력으로부터 하나의 결과를 내보냄

- 뉴런과 유사 : 가지돌기(신호) ----(일정치 이상의 크기라면)"신호"----> 축삭돌기

- x : 입력값, W : 가중치(축삭돌기 역할), y : 출력값(인공 뉴런)

- 가중치↑ --> 입력값의 중요도

- 계단 함수 : x1W1+x2W2+ ... + xnWn > 임계치(threshold)이면 1을 출력하고 아니면 0을 출력함

- 편향 : 퍼셉트론의 입력으로 함께 사용되며 입력값1에 가중치 b가 곱해진 형태이다.

- 활성화 함수(Activation Function) : 출력값을 변경시키는 함수 like 계단 함수, 시그모이드 함수, 소프트맥스 함수

 

2. 단층 퍼셉트론(Single-Layer Perceptron)

- 단층 퍼셉트론 : 값을 보내는 단계(입력층_input layer) + 값을 받아서 출력하는 단계(출력층 _ output layer)

- AND, NAND, OR 게이트 쉽게 구현 가능 :

두개의 입력값(x1, x2)와 하나의 출력값(y)  + 두개의 가중치(w1, w2)와 하나의 편향(b) --> 각 게이트의 동작 구현

EX> AND 게이트의 단층 퍼셉트론 식

EX> NAND 게이트의 단층 퍼셉트론 식

EX> OR 게이트의 단층 퍼셉트론 식

EX> XOR 게이트 : 단층 퍼셉트론으로 구현이 불가

- 입력값 두개가 서로 다른 값 --> 1 / 입력값 두개가 서로 같은 값 --> 0

- 단층 퍼셉트론의 성질 : "직선" 하나로 두 영역(0/1)을 나눌 수 있는 문제에 대해서만 구현 가능

--> "선형 영역"에 대해서만 분리 가능 --> 다층 퍼셉트론 필요

3. 다층 퍼셉트론(MultiLayer Perceptron, MLP)

- XOR : 기존의 AND, NAND, OR게이트의 조합 = 퍼셉트론의 층을 더 쌓으면 만들 수 있음.

- 다층 퍼셉트론(MLP) : 입력층 + 은닉층(hidden layer) * N(1개 이상) + 출력층

- 심층 신경망(Deep Neural Network, DNN) : 은닉층이 2개 이상인 신경망

- 학습(training) 단계 : 기계가 가중치를 스스로 찾아내도록 자동화 - 손실 함수(Loss function)과 옵티마이저(Optimizer)를 사용

- 딥 러닝(Deep Learning) : 학습 시키는 인공신경망이 "심층 신경망"인 경우!!

 

2) 인공 신경망(Artificial Neural Network) 훑어보기

1. 피드 포워드 신경망(Feed-Forward Neural Network, FFNN)

- 피드 포워드 신경망 : 입력층에서 출력층 방향으로 연산이 전개되는 신경망 = 순방향 신경망

- 순환 신경망(Recurrent Neural Network, RNN) : 은닉층의 출력값을 출력층으로도 값을 보내지만 동시에 다시 은닉층의 입력으로 사용 --> 09. RNN 챕터

 

2. 전결합층(Fully-connected layer, FC, Dense layer)

- 전결합층(FC) : 어떤 층의 모든 뉴런이 이전 층의 모든 뉴런과 연결돼 있는 층 = 밀집층(Dense layer)

--> keras : Dense()

- 전결합 피드 포워드 신경망(Fully-connected FFNN) : 전결합층만으로 구성된 피드 포워드 신경망

 

3. 활성화 함수(Activation Function)

- 활성화 함수 : 은닉층과 출력층의 뉴런에서 출력값을 결정하는 함수

- 단일 퍼셉트론의 계단함수도 여기에 포함

 

(1) 활성화 함수의 특징 - 비선형 함수(Nonlinear function)

- 선형 함수 :

출력이 입력의 상수배만큼 변하는 함수(직선 1개로 그릴 수 있음)

은닉층을 쌓을 수 없음(여러번 추가해도 1회 추가한 것과 같음) --> 능력 향상 불가

**선형층(linear layer) =투사층(projection layer) : 선형 함수를 사용한 층

     f(x) = Wx + b

- 비선형 함수 : 직선 1개로 그릴 수 없는 함수(ex> 계단 함수)

**비선형층(nonlinear layer) : 일반적인 은닉층. 선형층과 비교하기 위한 용도

(2) 계단 함수(Step function)

(3) 시그모이드 함수(Sigmoid function)와 기울기 소실

- 과정 :

순전파(forward propagation) 연산 --> 손실함수 : 예측값, 실제값의 오차 --> 기울기(gradient) --> 역전파(back propogation)

- 기울기 소실 문제 :

 

역전파 과정에서 0에 가까운 아주 작은 기울기 곱해짐 --> 앞단에 기울기 전달↓(출력층과 먼 은닉층)

--> 매개변수 W의 업데이트 X

즉, 은닉층에서 사용하는 것은 지양

(4) 하이퍼볼릭탄젠트 함수(Hyperbolic tangent function)

: 입력값을 -1~1의 값으로 변환

- 기울기 소실 문제 있음 BUT 0이 중심이므로 반환값의 변화폭이 더 큼!!ㅜ --> 기울기 소실 증상 적음

(5) 렐루 함수(ReLU)

- 인공신경망에서 가장 많이 쓰임

- 수식 : f(x) = max(0,x)

- 깊은 신경망에서 더 잘 작동 : 특정 양수값에 수렴X

- 연산이 아닌 단순 임계값 --> 연산 속도 빠름

- 입력값이 음수 --> 기울기도 0 --> 죽은 렐루

(6) 리키 렐루(Leaky ReLU)

- 죽은 렐루를 보완하기 위한 변형함수

- 입력값이 음수 --> 0.001과 같은 매우 작은 수 반환

- 수식 : f(x) = max(ax, x)     a - 하이퍼파라미터_Leaky 정도를 결정.(default : 0.01)

- 새지만 죽지는 않음

(7) 소프트맥스 함수(Softmax function)

- 분류 문제 : 로지스틱 회귀와 소프트맥스 회귀를 "출력층"에 적용

- 특히 다중 클래스 분류 문제

 

4. 행렬의 곱셈을 이용한 순전파(Forward Propagation)

EX> 케라스로 만드는 인공신경망 : 4 - 8 - 8 - 3

#Forward Propagation
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(8, input_dim = 4, init = 'uniform', activation= 'relu'))
#입력층 : 4, 은닉층:8, 활성화 함수는 relu
model.add(Dense(8, activation = 'relu')) #8인 은닉층 추가, relu
model.add(Dense(3, activation = 'softmax')) #3인 출력층 추가, softmax

- 입력층 ~ 출력층까지 순차적으로 인공신경망의 층 한층씩 추가함.

- 순전파(Forward Propagation) : 인공신경망에서 입력층에서 출력층 방향으로 연산을 진행하는 과정

= 주어진 입력으로부터 "예측값"을 계산하는 과정 = 벡터, 행렬 연산이 층마다 적용

- keras : 내부에서 해줌 / Numpy : 행렬크기 고려 필요

(1) layer 1의 행렬 크기 추정

- (입력행렬) X (가중치 행렬) 가정 & 배치크기 = 1

(2) layer2와 layer 3의 행렬 크기 추정하기

- 위와 같은 과정 반복

- 활성화 함수는 행렬 크기에 영향X

**순전파 진행 --> 오차 계산(예측값VS실제값) --> 가중치, 편향 업데이트(역전파 __ 순전파와 반대로 진행)

**참고 : https://www.youtube.com/watch?v=UJwK6jAStmg

 

3) 딥러닝의 학습방법

- 손실함수, 옵티마이저의 개념과 딥 러닝에의 적용

1. 순전파(Forward Propagation)

: 입력층에서 출력층의 방향으로 예측값의 연산 진행

2. 손실 함수(Loss Function)

: 실제값과 예측값의 차이를 수치화 = 오차

- 오차↑(너무 낮은 확률 or 너무 높은 확률) --> 손실함수 값↑

- 회귀 : 평균제곱오차(MSE) / 분류 : 크로스엔트로피(이진/다중클래스)

- 손실함수 값 최소화 방향으로 W, b 찾아가기

3. 옵티마이저(Optimizer)

- 손실함수의 값을 줄여나가는 방법

- 배치(Batch) : 가중치 등의 매개변수 값을 조정하기 위해 사용하는 데이터의 양(전체 or 일부)

(1) 배치 경사 하강법(Batch Gradient Descent)

- 오차를 구할 때 "전체 데이터"를 고려

- 1번의 에포크에 모든 매개변수 업데이트 한번에 수행 --> 시간, 메모리↑ / 글로벌 미니엄 찾을 수 있음

model.fit(X_train, y_train, batch_size=len(trainX)) #trainX 사이즈만큼 전부

(2) 확률적 경사 하강법(Stochastic Gradient Descent, SGD)

- "랜덤으로 선택한 하나의 데이터"에 대해서만 계산

- 시간, 메모리↓ / 정확도, 변경폭의 불안정성

model.fit(X_train, y_train, batch_size= 1)

(3) 미니 배치 경사 하강법(Mini-Batch Gradient Descent)

- "정해진 양의 데이터"에 대해서만 계산

- 전체보다는 빠르고 SGD보다는 안정적

model.fit(X_train, y_train, batch_size=32) 

(4) 모멘텀(Momentum)

- 관성을 더 해줌

- SGD에서 계산된 접선의 기울기에 한 시점 전의 접선의 기울기값을 일정한 비율만큼 반영

--> 로컬 미니엄 도달하였을 때 기울기 0이라서 끝나지 않고 글로벌 미니엄으로 갈 수 있는 가능성!!

keras.optimizers.SGD(lr = 0.01, momentum = 0.9)

(5) 아다그라드(Adagrad)

- 각 매개변수에 서로 다른 학습률 적용(변화가 많음 --> 학습률↓)

keras.optimizers.Adagrad(lr = 0.01, epsilon = 1e-6)

(6) 알엠에스프롭(RMSprop)

- 아다그라드의 단점 개선 : 나중에 학습률이 지나치게 떨어짐 --> 다른 수식으로 대체

keras.optimizers.RMSprop(lr = 0.001, rho = 0.9, epsilon = 1e-06)

(7) 아담(Adam)

- 알엠에스프롭 + 모멘텀 : 방향과 학습률 두가지 모두 잡음

keras.optimizers.Adam(lr = 0.001, beta_1 = 0.9, beta_2 = 0.999, epsilon = None, decay = 0.0, amsgrad = False)

**cf> 옵티마이저 사용법 : https://keras.io/optimizers/

 

4. 역전파(BackPropagation)

- 위의 경사하강법을 사용하여 가중치를 업데이트하는 과정

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

- 입력층, 은닉층, 출력층

- EX> 2 * 입력 + 2 * 은닉층 뉴럭 + 2 * 출력층 뉴런 / 활성화함수 : 시그모이드 함수

z = 이전층의 모든 입력이 가각의 가중치와 곱해진 값들이 모두 더해진 가중합 --> 시그모이드 함수의 입력

h, o = z가 시그모이드 함수를 지난 후의 값

--> 목표 : 역전파를 통해 모든 가중치 W 업데이트!(단, 편향 b는 고려X)

 

(2) 순전파(Forward Propagation)

- 입력값(파란색) * 가중치 값(빨간색)을 입력층~은닉층 방향으로 계산 한 후 활성화 함수(여기선 시그모이드)에 적용

- 예측값, 실제값의 오차를 손실함수(Loss function)로 계산 --> 여기선 MSE

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

- 출력층 -> 입력층으로 가중치 업데이트

- 역전파 1단계 = 출력층과 출력층 바로 이전의 은닉층(N층) 사이 가중치 업데이트 

- 역전파 2단계 = N층과 N-1층 사이의 가중치 업데이트

- EX> 1단계에서 업데이트 할 가중치 : W5, W6, W7, W8

a. 미분의 연쇄법칙(Chain rule)에 따라 계산 (∂ - 미분기호) : 

가중치 W5 업데이트 시

- Etotal = (순전파 진행 결과 나온 전체 오차값)

- 1번째 항 :

- 2번째 항 : (단, 시그모이드 함수의 미분 - f(x)(1-f(x))

- 3번째 항 : (h1 - sigmoid(z1) = sigmoid(W1x1 + W2x2) , z3 = W5h1 + W6h2)

- 결론 : 경사하강법을 통해 가중치 업데이트. 학습률 0.5로!

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

- 입력층 방향으로 다시 계산 이어감

- EX> 2단계에서 업데이트할 가중치 : W1, W2, W3, W4

- 미분의 연쇄 법칙(Chain rule)이용 :

가중치 W1을 업데이트 시

- 1번째 항

- 2번째 항 : 시그모이드 함수의 미분

- 3번째 항 : z1 = W1x1 + W2x2이므로 W1으로 미분하면 x1

- 결론 : 경사하강법을 통해 가중치 업데이트

(5) 결과 확인

업데이트 된 가중치로 다시 한 번 순전파를 진행 --> 오차 감소 확인!(0.02397190으로 오차 감소!)

4) 과적합(Overfitting)을 막는 방법들

- 과적합(Overfitting) : 훈련 데이터에 대한 정확도는 높지만 새로운 데이터(검증 데이터, 테스트 데이터)에 대해서 제대로 작동 안함 = 훈련 데이터의 노이즈까지 학습 --> 모델의 성능 하락

 

1. 데이터의 양 늘리기

- 데이터의 양이 적음 : 해당 데이터의 특정 패턴, 노이즈까지 암기 --> 과적합 현상 발생 확률 증가

- 데이터의 양이 많음 : 데이터의 일반적인 패턴 학습

 

- 데이터 증식/증강(Data Augmentation) : 의도적으로 기존 데이터를 조금씩 변형, 추가 --> 데이터의 양 늘리는 방법

(cf> 이미지 : 이미지 돌리기, 노이즈 추가, 일부분 수정)

 

2. 모델의 복잡도 줄이기

- 인공 신경망의 복잡도 : 은닉층(hidden layer)의 수, 매개변수의 수 = 모델의 수용력(capacity)

--> 이런 요인들을 통해 복잡도 줄이기

 

3. 가중치 규제(Regularization) 적용하기

- 복잡한 모델을 간단하게 하는 방법

- L1 규제(L1 노름) : 가중치 w들의 절대값 합계를 비용함수에 추가 = λ |w|

- L2 규제(L2 노름) : 모든 가중치 w들의 제곱합을 비용함수에 추가 = 1/2 * λw^2

(단, λ : 규제의 강도를 정하는 하이퍼파라미터 / 클수록 규제를 위해 추가된 항들을 작게 유지하는 것을 우선시)

 

- 두 규제식의 비용 함수 최소화 방법 : 가중치 w들이 값이 작아져야 함

EX> L1규제 : 비용 함수 최소인 가중치, 편향 찾기 + 가중치들의 절대값 합도 최소 --> 가중치가 0 또는 0에 가깝게 작아져야!!

--> 작아진 가중치에 곱해진 특성은 영향이 별로 없음

EX> L2규제(= 가중치 감쇠) : 가중치들의 제곱을 최소화 --> 0에 가까워지는 경향

--> 특성별 영향력 판단, 더 잘 동작!!

 

4. 드롭아웃(Dropout)

- 학습과정에서 신경망의 일부를 사용하지 않는 방법. 드롭아웃 비율만큼은 사용 안함

- "신경망 학습" 시에만 이용. 예측 시에는 이용X

- 특정 뉴런, 조합에만 의존적이지 않도록 하는 효과

- 코드 예시 - Keras

5) 기울기 소실(Gradient Vanishing)과 폭주(Exploding)

- 기울기 소실(Gradient Vanishing) : 깊은 인공 신경망 학습 중 역전파 과정에서 입력층으로 갈 수록 기울기(Gradient)가 점차 작아지는 현상 --> 가중치 업데이트가 X, 최적의 모델 찾기 실패

- 기울기 폭주(Gradient Exploding) : 기울기가 점차 커짐 --> 가중치가 비정상적으로 큰 값, 발산 (순환 신경망 RNN에서 발생)

 

1. ReLU와 ReLU의 변형들

- 시그모이드 함수 : 입력의 절대값이 클수록 출력값이 0또는 1에 수렴 --> 기울기가 0에 가깝

- 역전파 과정 : 전파 시킬 기울기 점차 사라짐 --> 역전파 전달X

- 완화 방법 : 은닉층의 활성화 함수로 ReLU, Leaky ReLU 이용

 

2. 그래디언트 클리핑(Gradient Clipping)

- 기울기 값이 임계값을 넘지 않도록 자름 --> 기울기 폭주 저지

- RNN(순환 신경망)에서 유용

- Keras에서의 이용

from tensorflow.keras import optimizers
Adam = optimizers.Adam(lr = 0.0001, clipnorm = 1.) //clipnorm으로 임계값 지정

 

3. 가중치 초기화(Weight initialization)

- 가중치의 초기값이 훈련 결과에 영향을 주기 때문

(1) 세이비어 초기화(Xavier Initialization) = 글로럿 초기화

- 이전 층의 뉴런 개수(nin)와 다음 층의 뉴런 개수(nout)를 가지고 식을 세움

- (경우1) 균등 분포(Uniform Distribution)로 초기화

- (경우2) 정규 분포(Normal Distribution)로 초기화

- 효과 : 여러 층의 기울기 분산 사이에 균형 맞춤 --> 특정 층이 주목/뒤쳐지는 것 막음

- 단점 : 시그모이드, 하이퍼볼릭 탄젠트(S자형)엔 좋지만 ReLU, ReLU변형함수에는 안 좋음

 

(2) He 초기화(He initialization)

- 다음 층의 뉴런의 수를 반영X

- (경우1) 균등분포로 초기화

- (경우2) 정규분포로 초기화

4. 배치 정규화(Batch Normalization)

- 인공 신경망의 각 층에 들어가는 입력을 평균과 분산으로 정규화

(1) 내부 공변량 변화(Internal Covariate Shift)

- 공변량 변화 : 훈련 데이터의 분포 ≠ 테스트 데이터의 분포

- 내부 공변량 변화 : 층 별로 입력 데이터 분포가 달라지는 현상

(이전층의 가중치 업데이트 --> 현재 층의 입력데이터 분포가 학습시점과 달라짐)

 

(2) 배치 정규화(Batch Normalization)

- 한 번에 들어오는 배치 단위로 정규화

- 각 층의 활성화 함수를 통과하기 전에

- 과정 : 입력에 대해 평균 0으로 정규화 --> 스케일(γ), 시프트(β) 수행

- 수식 : BN(배치 정규화)

- 장점 :

- 단점, 한계:

● 모델을 복잡화(추가 계산 요구) --> 예측 실행 시간이 느려짐

● 미니 배치 크기에 의존적 : 너무 작은 배치 크기 --> 동작X

● RNN 적용 어렵 : 각 시점(time step)마다 다른 통계치 --> 적용 어렵

<--> 보완 : 층 정규화(layer normalization)

 

5. 층 정규화(Layer Normalization)

- 배치 정규화

- 층 정규화