본문 바로가기
  • 데이터에 가치를 더하다, 서영석입니다.
공부하는 습관을 들이자/Deep Learning (NLP,LLM)

[딥러닝 자연어처리] 8-5. (6) 기울기 소실과 폭주 - 07) 케라스 훑어보기

by 꿀먹은데이터 2023. 12. 20.

딥러닝을 이용한 자연어처리 입문 #8-5. (6) 기울기 소실과 폭주 - 07) 케라스 훑어보기

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

  • 기울기 소실 : 역전파 과정에서 입력층으로 갈수록 기울기가 점차적으로 작아지는 현상
  • ⇒  입력층에 가까운 층들에서 가중치들이 업데이트가 제대로 되지 않음
  • 기울기 폭주 : 기울기가 점차 커져 가중치들이 비정상적으로 큰 값이 되는 현상

1) ReLU와 ReLU의 변형들

  • 시그모이드 함수를 사용할 때 0 또는 1에 수렴하면서 기울기가 0에 가까워짐 → 기울기 소실
  • ⇒ 은닉층의 활성화 함수로 ReLU 나 Leaky ReLU를 사용

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

  • 기울기 폭주를 막기 위해 임계값을 넘지 않도록 값을 감소시킴
from tensorflow.keras import optimizers

Adam = optimizers.Adam(lr=0.0001, clipnorm=1.)

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

(1) 세이비어 초기화(Xavier Initialization)

  • 균등 분포 또는 정규 분포로 초기화함
  • 시그모이드 함수나 하이퍼볼릭 탄젠트 함수 같은 S자 형태인 활성화 함수에 유용함

(2) He 초기화(He initialization)

  • 세이비어 초기화와 비슷하지만 다음 층의 뉴런 수를 반영하지 않음
  • ReLU 계열 함수에서 유용함

4) 배치 정규화(Batch Normalization)

  • 인공 신경망의 각 층에 들어가는 입력을 평균과 분산으로 정규화하는 방법
  • 각 층에서 활성화 함수를 통과하기 전에 수행
  • 입력에 대해 평균을 0으로 만들고, 정규화 → 이후 스케일과 시프트 수행

-효과-

  • 가중치 초기화에 덜 민감해짐
  • 학습 속도를 개선시킴
  • 과적합을 방지하는 효과

-한계-

  • 복잡해지고 테스트 시 실행 시간이 느려짐
  • 미니 배치 크기에 의존적 → 너무 작은 배치 크기에서는 잘 작동하지 않음
  • RNN에 적용하기 어려움 → 각 시점마다 통계치가 다르기 때문

5) 층 정규화(Layer Normalization)

  • 배치 정규화 → 동일한 특성 개수들을 가진 샘플들을 정규화

층 정규화

7. 케라스 훑어보기

1) 전처리(Preprocessing)

Tokenizer() : 토큰화와 정수 인코딩을 위해 사용

from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences

tokenizer = Tokenizer()
train_text = "The earth is an awesome place live"

# 단어 집합 생성
tokenizer.fit_on_texts([train_text])

# 정수 인코딩
sub_text = "The earth is an great place live"
sequences = tokenizer.texts_to_sequences([sub_text])[0]

print("정수 인코딩 : ",sequences)
print("단어 집합 : ",tokenizer.word_index)
  • 정수 인코딩 : [1, 2, 3, 4, 6, 7] 단어 집합 : {'the': 1, 'earth': 2, 'is': 3, 'an': 4, 'awesome': 5, 'place': 6, 'live': 7}
  • pad_sequence() : 샘플의 길이가 서로 다를 때, 입력으로 사용하려면 샘플의 길이를 동일하게 맞춰야함
  • → 정해준 길이보다 길이가 길면 일부 자르고 짧으면 0으로 채움
pad_sequences([[1, 2, 3], [3, 4, 5, 6], [7, 8]], maxlen=3, padding='pre')
  • maxlen = 모든 데이터에 대해서 정규화 할 길이
  • padding = 'pre'를 선택하면 앞에 0을 채우고 'post'를 선택하면 뒤에 0을 채움
  • array ([[1, 2, 3], [4, 5, 6], [0, 7, 8]], dtype=int32)

2) 워드 임베딩(Word Embedding)

  • 텍스트 내의 단어들을 밀집 벡터로 만드는 것

Embedding() : 정수 인코딩이 된 단어들을 입력을 받아서 임베딩을 수행

# 1. 토큰화
tokenized_text = [['Hope', 'to', 'see', 'you', 'soon'], ['Nice', 'to', 'see', 'you', 'again']]

# 2. 각 단어에 대한 정수 인코딩
encoded_text = [[0, 1, 2, 3, 4],[5, 1, 2, 3, 6]]

# 3. 위 정수 인코딩 데이터가 아래의 임베딩 층의 입력이 된다.
vocab_size = 7
embedding_dim = 2
Embedding(vocab_size, embedding_dim, input_length=5)

3) 모델링(Modeling)

  • Sequential() : 모델 선언뒤 model.add()로 층을 추가함
#전결합층을 추가하는 예시
model = Sequential()
model.add(Dense(1, input_dim=3, activation='relu'))

model = Sequential()
model.add(Dense(8, input_dim=4, activation='relu')) #8이 은닉층의 뉴런
model.add(Dense(1, activation='sigmoid')) # 출력층

  • summary() : 모델의 정보를 요약
  • model.summary()

4) 컴파일(Compile)과 훈련(Training)

  • compile() : 모델을 기계가 이해할 수 있도록 컴파일 → 손실 함수와 옵티마이저, 메트릭 함수를 선택
from tensorflow.keras.layers import SimpleRNN, Embedding, Dense
from tensorflow.keras.models import Sequential

vocab_size = 10000
embedding_dim = 32
hidden_units = 32

model = Sequential()
model.add(Embedding(vocab_size, embedding_dim))
model.add(SimpleRNN(hidden_units))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
  • fit() : 모델을 학습 (오차로부터 매개 변수를 업데이트시키는 과정)
model.fit(X_train, y_train, epochs=10, batch_size=32)
  • validation_data(x_val, y_val) = 검증 데이터(validation data)를 사용, 각 에포크마다 검증 데이터의 정확도나 오차를 함께 출력하여 훈련이 잘 되고 있는지 보여줌
  • validation_split=0.2 훈련 데이터에서 일정 비율 분리하여 검증 데이터로 사용
  • verbose = 학습 중 출력 되는 문구 설정

5) 평가(Evaluation)와 예측(Prediction)

  • evaluate() : 테스트 데이터를 통해 학습한 모델에 대한 정확도를 평가
  • predict() : 임의의 입력에 대한 모델의 출력값을 확인
model.evaluate(X_test, y_test, batch_size=32)
model.predict(X_input, batch_size=32)

6) 모델의 저장(Save)과 로드(Load)

  • save() : 모델을 hdf5 파일에 저장
  • load_model() : 저장해둔 모델을 불러옴