티스토리 뷰

인공지능

[인공지능] 심층 신경망(DNN)

rimo (리모) 2022. 9. 20. 14:41

아래 글에 이어 작성된 글입니다.

 

 

[인공지능] 하이퍼 파라미터 (에포크/배치/학습률/옵티마이저/손실함수/활성화함수)

아래 글에 이어 작성된 글입니다. [인공지능] 다층 퍼셉트론 (MLP)과 역전파 알고리즘 아래 글에 이어 작성된 글입니다. [인공지능] 인공신경망의 시작, 퍼셉트론 아래 글에 이어 작성된 글입니다.

munak.tistory.com

 

 

심층신경망인 DNN과 관련 개념들에 대해 다룬 뒤 Keras로 실습합니다.

 


 

심층 신경망(DNN) : Deep Neural Networks

DNN이란 MLP에서 은닉층의 개수를 증가시킨 형태로 여러 개의 은닉층을 가진 신경망을 말합니다. Deep이라는 이름에 걸맞게 몇십 개의 은닉층을 사용하는 모델들이 많습니다. 이런 DNN의 학습 알고리즘을 딥러닝이라고 부릅니다. 추가된 은닉층은 특징을 추출하는 데에 사용되는데요. 층이 깊어질수록 고급 특징을 뽑아내게 됩니다. 때문에 DNN에서는 특징을 인간이 따로 추출할 필요가 없어졌죠.  

 

 

 

 

하지만 단순히 MLP에서 DNN 구조를 완성시킬 수 있는 건 아닙니다. 은닉층을 추가하면서 여러 문제가 발생했기 때문입니다.

 

 

 

그래디언트 소실문제  (Gradient Vanishing)

MLP에서는 주로 시그모이드 함수를 활성화 함수로 사용했었습니다. 하지만 DNN에서는 이 시그모이드 함수로 인해 그래디언트 소실 문제가 발생했는데요. 그래디언트 소실이란 출력층에서 계산된 그래디언트가 역전파 될 때 값이 점점 작아지다 소멸되는 것을 말합니다. 시그모이드 함수의 특성상 아주 큰 양수나 음수가 들어오면 출력이 포화 상태가 되어 0에 수렴하기 때문이죠. 그래서 DNN에서는 활성화 함수로 ReLU나 소프트맥스 함수를 사용해 값을 증폭시켜 이를 방지합니다.

 

 

 

 

활성화 함수에 이어 손실함수 또한 개선할 필요가 있었습니다. MLP에선 손실 함수로 MSE를 사용했었는데요. DNN에서는 손실 함수로 교차 엔트로피(Cross-entropy)를 사용합니다.  특히 분류 문제를 해결할 때 활성화 함수로는 소프트맥스를 손실 함수로는 교차 엔트로피를 선택하면 좋은 성능의 신경망을 구현할 수 있습니다. 

 

 

 

 

가중치 초기화 

이전에는 가중치를 0으로 설정한 뒤 학습을 진행시키는 경우가 많았습니다. 하지만 가중치의 초기값이 성능에 많은 영향을 끼친다는 사실이 밝혀지면서 최적의 가중치를 찾기 위한 연구가 진행되었습니다. 연구에서는 가중치를 너무 큰 숫자로 설정할 경우 가중치가 학습되지 않고 발산해 버리는 것을 확인할 수 있었고, 같은 가중치를 준 노드들은 완전히 동일한 학습을 해 효율이 떨어뜨린다는 결과를 얻을 수 있었습니다. 따라서 가중치는 0.0~1.0 사이(적절히 작은 수)의 난수(동일한 가중치를 가지지 못도록)로 초기화하는 것이 좋습니다.

 

+ 이때 가중치가 발산하며 학습이 되지 않는 현상을 그래디언트 폭발(exploding gradients)이라고 부르며 노드가 동일한 일(학습)을 하는 것을 방지하는 것은 균형 깨뜨리기(breaking th symmetry)라고 합니다.

 

 

 

 

데이터 정규화 (Normalization)

DNN의 신경망은 여러 은닉층을 거치며 일련의 선형/비선형 조합의 활성화 함수들을 통해 학습하게 됩니다. 때문에 숫자 정밀도와 관련된 문제가 발생할 수 있습니다. 이를 피하기 위해 입력값이 대략 -1.0에서 1.0 범위에 있도록 전 처리하는 것이 좋은데, 이것을 데이터 정규화라고 합니다. 데이터 정규화는 여러모로 안정적인 학습을 할 수 있도록 도와주기 때문에  실행해 주는 것이 좋습니다.

 

 

 

 

 

 

 

 

과잉 적합 방지

과잉적합이란 모델이 훈련데이터에만 지나치게 특화되어 실제 데이터에 적용했을 때 좋은 성능을 가지지 못하는 것을 말합니다. 마치 문제가 조금만 변형돼도 풀지 못하는 것처럼 모델이 일반화에 실패하는 경우입니다. 보통 과잉 적합이 발생하면 훈련데이터에 대한 손실 함수값은 감소하지만 검증(테스트) 데이터에 대한 값을 증가하는 모습을 보입니다. MLP의 경우도 과잉적합이 쉽게 발생하여 실제 사례에 적용하기 어려운 경우가 많았습니다. 그럼 과잉적합을 방지하기 위해서는 어떻게 해야할까요?

 

 

1. 조기 종료 (Early Stopping)

검증데이터에 대한  손실이 증가할 경우 에포크가 남았으나 훈련을 종료하는 방법입니다.

 

2. 가중치 규제

연산과정에서 가중치의 값이 너무 커질 경우 판단경계선이 복잡해지고 과잉적합이 일어난다는 연구결과를 바탕으로 한 방법으로, L1규제와 L2규제가 있습니다. 규제를 통해 가중치의 값을 균일하게 만들어 복잡성을 줄이는 방법입니다.

- L1규제: 가중치의 절댓값에 비례하는 비용 추가

- L2규제: 가중치의 제곱에 비례하는 비용 추가. 가중치 감쇠(weight decay)라고도 부른다.

 

3. 드롭아웃 (dropout)

가장 효과적이고 널리 사용되는 방법 중 하나로  몇개의 노드들을 학습과정에서 랜덤하게 제외하는 것을 말합니다. 편향되지 않는 출력 값을 얻을 수 있도록 하여 과잉적합을 방지합니다. 

 

4. 데이터 증강 (data augmentation)

소량의 훈련데이터에서 많은 훈련데이터를 뽑아내는 방법입니다. 훈련데이터 자체가 적을 경우 과잉적합이 일어날 수 있기 때문인데요. 많은 훈련데이터를 준비하는 것이 기본적으로 좋은 방법이지만, 어려울 경우 여러 데이터 증강 기법들을 사용해 훈련데이터를 늘려주는 것이 좋습니다.

 

 

 

 

+ 앙상블(여러 개의 신경망을 독립적으로 학습시킨 후 최적의 모델을 선정)

 

 

 

이처럼 MLP의 문제점을 보완하는 데에 이어 DNN 자체의 성능을 높이기 위한 연구들이 다수 진행되었고 인공신경망은 드디어 빛을 발하며 딥러닝 붐을 일으키는데에 성공합니다. 물론 시기적으로 GPU의 기술의 발전과 겹쳐 DNN의 집약적인 연산을 가능하게 했던 것도 있습니다. (DNN은 상당히 느리고 어마 무시한 연산량을 가져 자원이 많이 소모된다.) 지금 사용되는 여러 인공지능들 모델들은 DNN에 기반하여 개발된 것이 많습니다. 

 

 

 


 

Keras를 이용한 DNN 실습

 

앞서 여러 딥러닝 기법들을 살펴보았습니다. Keras에서는 이를 다양한 API로 지원하고 있습니다.

 

 

 

Keras documentation: Keras API reference

 

keras.io

 

 

 

+ 교차 엔트로피

BinaryCrossentropy는 이진 분류 문제를 해결하는데에 사용되며 CategoricalCrossentropy는 다중 분류 문제를 해결할 때 정답 레이블이 원핫 인코딩으로 제공된다면 사용합니다. SparseCategoricalCrossentropy는 다중 분류 문제를 해결할 때, 정답레이블이 정수로 주어지면 사용합니다. 

 

 

++ 원핫 인코딩이란?

데이터를 0과 한 개의 1의 값으로 표현하는 방법으로 범주형 데이터를 숫자로 표현하기 위해 사용합니다.

#example
class_vector =[2, 6, 6, 1]
  
from tensorflow.keras.utils import to_categorical
output = to_categorical(class_vector, num_classes = 7, dtype ="int32")
print(output)

 

 

 

 

MNIST 필기체 숫자 인식

import matplotlib.pyplot as plt
import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Dense(10, activation='softmax'))


model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

 

 

+ 드롭아웃 적용

import matplotlib.pyplot as plt
import tensorflow as tf

mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten(input_shape=(28,28)))
model.add(tf.keras.layers.Dense(512, activation='relu'))
model.add(tf.keras.layers.Dropout(0.2))	 # 은닉층에 20퍼센트를 트롭아웃
model.add(tf.keras.layers.Dense(10, activation='softmax'))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

 

 

패션 아이템 분류

import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras import datasets, layers, models

fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

plt.imshow(train_images[0])

train_images = train_images / 255.0
test_images = test_images / 255.0

model = models.Sequential()
model.add(layers.Flatten(input_shape=(28, 28)))
model.add(layers.Dense(128, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=5)

test_loss, test_acc = model.evaluate(test_images, test_labels)
print('정확도:', test_acc)

 

 

계획했던 인공지능 관련 이론 정리는 이게 마지막 입니다. CNN이나 YOLO는 연습문제나 실습위주로 작성해 보겠습니다.

감사합니다.

 


공부한 내용을 복습/기록하기 위해 작성한 글이므로 내용에 오류가 있을 수 있습니다.

댓글
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday