728x90
반응형

RNN 응용

규칙기반 챗봇

  • 라이브러리 정의
    import tensorflow as tf
    ''' 단어사전 만들기 '''
    from tensorflow.keras.preprocessing.text import Tokenizer
    from tensorflow.keras.preprocessing.sequence import pad_sequences
  • 규칙기반 데이터 정의하기 (질문 / 답변)
    - "03_RNN응용에_사용할_규칙기반_데이터셋(질문_답변)"  txt파일 사용

단어사전 만들기

  • 텍스트 데이터를 토큰화하여 단어 사전을 구축하기
    tokenizer = Tokenizer()
    tokenizer
  • 단어에 인덱스 부여하기
    - 질문과 답변을 하나의 데이터로 합쳐서 전체 텍스트 데이터로 사용
    - 이를 기반으로 토크나이저가 단어 사전을 구축하게 됨
    - 각 단어들은 순차적인 인덱스 번호를 부여받게 됨
    - 토크나이저가 인식하는 문장 내에서 단어의 의미 : 띄어쓰기가 없이 연결되어 있으면 하나의 단어로 인지
    - fit_on_texts(텍스트 문장) : 문장 내에서 단어들을 추출하여 순차적 인덱스 부여하기
    tokenizer.fit_on_texts(questions + answers)​
  • 단어별 부여된 인덱스 확인하기
    print("단어 갯수 : ", len(tokenizer.word_index))
    tokenizer.word_index​


  • 신경망에서 사용할 단어의 크기 설정
     - 하나 더 크게 설정해야 함
    - 인덱스 [0:18]이면 17번째까지 불러지므로 전체 값을 부르려면 현재 길이에 +1 해야 나중에 부를때 전체가 불러짐
    vocab_size = len(tokenizer.word_index) + 1
    vocab_size​
  • 질문에 대한 텍스트 문장을 단어사전의 인덱스 번호로 변환하기
    questions_sequences = tokenizer.texts_to_sequences(questions)
    print(len(questions_sequences))
    questions_sequences​
  • 질문 데이터 단어의 길이 통일 시키기(정규화)
    - 잘라낼 max 길이 기준 : 문장들 중 최대 max 단어길이 기준으로
    - maxlen을 넣지 않으면, 문장들의 길이가 가장 긴 것을 기준으로 한다.(default : 알아서 가장 긴 갯수를 찾아낸다)
    - padding="post" : 채우기는 뒤쪽
    questions_padded = pad_sequences(questions_sequences, padding="post")
    print(len(questions_padded))
    questions_padded​


  • 답변에 대한 데이터로 각 단어를 단어사전의 인덱스 번호로 변환하기
    answers_sequences = tokenizer.texts_to_sequences(answers)
    print(len(answers_sequences))
    answers_sequences​
  • 답변 데이터 단어의 길이 통일 시키기(정규화)
    answers_padded = pad_sequences(answers_sequences, padding="post")
    print(len(answers_padded))
    answers_padded

모델 처리

  • 모델 생성 및 계층 추가하기
    ''' <모델 생성하기> '''
    model = tf.keras.Sequential()
    
    '''
    <계층 추가하기>
     - 단어 임베딩(입력계층) : 출력 64
     - Simple Rnn 사용 : 출력 128, 활성화함수 : RelU
    '''
    model.add(tf.keras.layers.Embedding(vocab_size, 64, input_length=questions_padded.shape[1]))
    model.add(tf.keras.layers.SimpleRNN(128, activation="relu"))
    ''' 입력을 복제하는 전처리 계층 : 텍스트에 대한 Encoder와 Decoder를 담당함 '''
    model.add(tf.keras.layers.RepeatVector(answers_padded.shape[1]))
    model.add(tf.keras.layers.SimpleRNN(128, activation="relu", return_sequences=True))
    '''
     - 각 타임별로 동일한 가중치를 적용하도록 처리하며, 
     	전체 시퀀스들의 이전/다음 인덱트 처리 값을 가지고 있다고 보면 됨
     - 예측에 주로 사용되는 계층
     - 최종 출력 계층을 감싸고 있음
    '''
    model.add(tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(vocab_size,
                                                                   activation="softmax")))
    
    model.summary()​


  • 모델 설정 및 훈련하기
    ''' 모델 설정하기 '''
    model.compile(optimizer="adam",
                 loss="sparse_categorical_crossentropy",
                 metrics=["accuracy"])
    
    ''' 모델 훈련하기 '''
    model.fit(questions_padded, answers_padded, epochs=100,
             batch_size=64, verbose=1)​
  • 질문 / 답변 테스트
    ''' 질문/답변 테스트'''
    user_input = "너 이름이 뭐니?"
    
    ''' 새로운 질문 텍스트를 단어사전의 인덱스번호로 변환하기 '''
    input_seq = tokenizer.texts_to_sequences([user_input])
    input_seq
    
    ''' 단어의 길이를 훈련에서 사용한 길이로 통일시키기 (정규화) '''
    padded_seq = pad_sequences(input_seq, padding="post", maxlen=questions_padded.shape[1])
    padded_seq
    
    ''' 예측하기 : 새로운 질문에 대한 답변 추출하기 '''
    pred = model.predict(padded_seq)
    len(pred[0][1])
    
    '''' 답변으로 가장 확률이 높은 값 추출하기 '''
    pred_index = tf.argmax(pred, axis=-1).numpy()[0]
    print(len(pred_index), pred_index)
    
    ''' 시퀀스에 해당하는 텍스트 추출하기
     - 인덱스에 해당하는 실제 텍스트 추출하기
    '''
    response = tokenizer.sequences_to_texts([pred_index])[0]
    response​

답변 함수 만들기

def get_Generate_Response(model, tokenizer, user_input) :

    ''' 새로운 질문 텍스트를 단어사전의 인덱스번호로 변환하기 '''
    input_seq = tokenizer.texts_to_sequences([user_input])
    
    ''' 단어의 길이를 훈련에서 사용한 길이로 통일시키기 (정규화) '''
    padded_seq = pad_sequences(input_seq, padding="post", maxlen=questions_padded.shape[1])

    ''' 예측하기 : 새로운 질문에 대한 답변 추출하기 '''
    pred = model.predict(padded_seq)
    
    '''' 답변으로 가장 확률이 높은 값 추출하기 '''
    pred_index = tf.argmax(pred, axis=-1).numpy()[0]
    
    ''' 시퀀스에 해당하는 텍스트 추출하기
     - 인덱스에 해당하는 실제 텍스트 추출하기
    '''
    response = tokenizer.sequences_to_texts([pred_index])[0]

    return response

질문 받고 응답하기 : 무한반복 만들기

while True : 
    ''' 새로운 질문 입력 받기 '''
    user_input = input("사용자 : ")

    ''' 반복을 종료시키기 '''
    if user_input == "종료" :
        print("채팅 종료")
        break

    ''' 함수 호출하여 질문에 대한 답변 받아오기 '''
    response = get_Generate_Response(model, tokenizer, user_input)

    ''' 답변 출력하기 '''
    print("챗봇 : ", response)

 

728x90
반응형
728x90
반응형

순환신경망(RNN)

📍 순환신경망(Recurrent Neural Network, RNN)
 - RNN은 텍스트 처리를 위해 고안된 모델(계층)
 - 바로 이전의 데이터(텍스트)를 재사용하는 신경망 계층임 - 이전에 진행한 훈련기억을 가지고 다시 훈련하는 방식

📍 순환신경망 종류
 - 심플 순환신경망(Simple RNN)
 - 장기기억 순환신경망(LSTM)
 - 게이트웨이 반복 순환신경망(GRU)

📍 Simple RNN 단점
 - 긴 문장(시퀀스)을 학습하기 어려움
 - 시퀀스가 길 수록 초반의 정보는 점진적으로 희석(소멸)
 - 즉, 멀리 떨어져 있는 단어의 정보를 인식하는데 어려움이 있음
 - 이러한 단점을 보환한 모델이 LSTM과 GRU

📍 LSTM(Long Shot-Term Memory, 장기기억)
 - 단기기억을 오래 기억할 수 있도록 고안된 모델
 - 많은 이전 정보를 기억해야 하기 때문에 훈련 속도가 느리며, 시스템 저장 공간이 많이 필요함

📍 GRU(Gated Recurrent Unit, 게이트 반복 단위)
 - LSTM의 느린 속도를 개선하기 위해 고안된 모델
 - 성능은 LSTM과 유사함

📍 Simle RNN, LSTM, GRU 모두 RMSprop 옵티마이저를 일반적으로 사용
  • 사용 라이브러리
    import tensorflow as tf
    from tensorflow import keras
    
    ''' 영화 감상평에 대한 긍정/부정 데이터셋 '''
    from tensorflow.keras.datasets import imdb
    
    from sklearn.model_selection import train_test_split
    
    ''' 텍스트 길이 정규화 라이브러리 '''
    from tensorflow.keras.preprocessing.sequence import pad_sequences
  • 사용할 데이터 :  IMDB
    ''' 데이터 불러들이기
     - IMDB 데이터 사용, 말뭉치 500개 사용
    '''
    (train_input, train_target), (test_input, test_target) = imdb.load_data(num_words=500)
    
    print(train_input.shape, train_target.shape)
    print(test_input.shape, test_target.shape)​


  • 훈련 : 검증 데이터로 분류하기 (8 : 2)
    ''' train : val = 8 : 2로 분류하기 '''
    
    train_input, val_input, train_target, val_target = train_test_split(train_input, train_target, test_size=0.2, random_state=42)
    print(train_input.shape, train_target.shape)
    print(val_input.shape, val_target.shape)
    print(test_input.shape, test_target.shape)​


  • 텍스트 정규화하기
    - 훈련, 검증, 테스트 데이터 내의 각 문장의 길이를 100으로 통일(정규화) 시키기
    - 왜 100인가? 단어 갯수의 분포를 이용해서 훈련에 사용할 독립변수 각 값들의 길이 기준 정의했을 때, 전체적으로 왼쪽편에 집중되어 있으며, x축 125 정도에 많은 빈도를 나타내고 있음. 따라서, 독립변수 각 값들의 길이를 100으로 통일(정규화)
    - 앞쪽을 제거, 채우기
    - pad_sequences() : 텍스트의 길이를 maxlen 갯수로 통일시키기
    - maxlen보다 작으면 0으로 채우고, 크면 제거한다.

    train_seq = pad_sequences(train_input, maxlen=100)
    
    val_seq = pad_sequences(val_input, maxlen=100)
    
    test_seq = pad_sequences(test_input, maxlen=100)
    
    print(train_seq.shape, train_target.shape)
    print(val_seq.shape, val_target.shape)
    print(test_seq.shape, test_target.shape)

장기기억 순환신경망(LSTM)

  • LSTM 모델 생성하기
    model = keras.Sequential()
    model​
  • 계층 생성 및 모델에 추가하기 
    - 임베딩 계층 추가 : 말뭉치 500, 출력크기 16, 입력크기 100
    - LSTM 계층 추가 : 출력크기 8
    - 출력 계층 추가
    model.add(keras.layers.Embedding(500, 16, input_length=100))
    model.add(keras.layers.LSTM(8))
    model.add(keras.layers.Dense(1, activation="sigmoid"))
    
    model.summary()​


  • 모델 설정하기
    - 학습율 : 0.0001
    - 옵티마이저 : RMSprop
    - RMSprop : 먼 거리는 조금 반영, 가까운 거리는 많이 반영하는 개념을 적용
    rmsprop = keras.optimizers.RMSprop(learning_rate=0.0001)
    model.compile(optimizer=rmsprop,
                 loss="binary_crossentropy",
                 metrics=["accuracy"])​
  • 콜백함수 정의하기
    - 자동 저장 위치 및 파일명 : ./model/best_LSTM_model.h5

    - 자동저장 및 자동 종료 콜백함수 정의하기
    checkpoint_cb = keras.callbacks.ModelCheckpoint("./model/best_LSTM_model.h5")
    
    early_stopping_cb = keras.callbacks.EarlyStopping(patience=3,
                                                     restore_best_weights=True)
    checkpoint_cb, early_stopping_cb
  • 모델 훈련시키기
    - 100번 반복, 배치사이즈 64, 검증 동시 진행
    model.fit(train_seq, train_target,
              epochs=100,
              batch_size=64,
              validation_data=(val_seq, val_target),
              callbacks=[checkpoint_cb, early_stopping_cb])

  • 훈련, 검증, 테스트 성능검증하기
    model.evaluate(train_seq, train_target)
    model.evaluate(val_seq, val_target)
    model.evaluate(test_seq, test_target)


  • LSTM 모델의 드롭아웃 속성(계층아님) 적용하기
    - LSTM 모델(계층)에 드롭아웃 속성 적용, 30% 훈련에서 제외
    - 나머지 모두 위와 동일하게 처리하여 훈련, 검증, 테스트 데이터에 대한 성능검증 진행
    ''' 모델 생성 '''
    model = keras.Sequential()
    
    ''' 계층 생성 '''
    model.add(keras.layers.Embedding(500, 16, input_length=100))
    model.add(keras.layers.LSTM(8, dropout=0.3))
    model.add(keras.layers.Dense(1, activation="sigmoid"))
    
    ''' 모델 설정 '''
    rmsprop = keras.optimizers.RMSprop(learning_rate=0.0001)
    model.compile(optimizer=rmsprop,
                 loss="binary_crossentropy",
                 metrics=["accuracy"])
    
    ''' 콜백함수 정의 '''
    checkpoint_cb = keras.callbacks.ModelCheckpoint("./model/best_LSTM_model.h5")
    early_stopping_cb = keras.callbacks.EarlyStopping(patience=3,
                                                     restore_best_weights=True)
    
    ''' 모델 훈련 '''
    model.fit(train_seq, train_target,
              epochs=100,
              batch_size=64,
              validation_data=(val_seq, val_target),
              callbacks=[checkpoint_cb, early_stopping_cb])​
  • 드롭아웃 속성 적용 시 훈련, 검증, 테스트 성능검증하기
    model.evaluate(train_seq, train_target)
    model.evaluate(val_seq, val_target)
    model.evaluate(test_seq, test_target)​


  • LSTM 2개 연결하기
    - LSTM 2개를 연결할 때는 연속해서 LSTM 계층을 추가해야함
    - 첫번째 LSTM 계층의 속성에는 return_sequences=True 속성을 추가해 준다.
    - 두번째 LSTM은 첫번째 LSTM의 훈련결과를 이어받아서 계속 훈련을 이어나간다.
    ''' 모델 생성 '''
    model = keras.Sequential()
    
    ''' 계층 생성 '''
    model.add(keras.layers.Embedding(500, 16, input_length=100))
    model.add(keras.layers.LSTM(8, dropout=0.3, return_sequences=True))
    model.add(keras.layers.LSTM(8, dropout=0.2))
    model.add(keras.layers.Dense(1, activation="sigmoid"))
    
    ''' 모델 설정 '''
    rmsprop = keras.optimizers.RMSprop(learning_rate=0.0001)
    model.compile(optimizer=rmsprop,
                 loss="binary_crossentropy",
                 metrics=["accuracy"])
    
    ''' 콜백함수 정의 '''
    checkpoint_cb = keras.callbacks.ModelCheckpoint("./model/best_LSTM_model.h5")
    early_stopping_cb = keras.callbacks.EarlyStopping(patience=3,
                                                     restore_best_weights=True)
    
    ''' 모델 훈련 '''
    model.fit(train_seq, train_target,
              epochs=100,
              batch_size=64,
              validation_data=(val_seq, val_target),
              callbacks=[checkpoint_cb, early_stopping_cb])

  • LSTM 2개 연결 시 훈련, 검증, 테스트 성능검증하기

게이트웨이 반복 순환신경망(GRU)

  • GRU 모델
''' 모델 생성 '''
model = keras.Sequential()

''' 계층 생성 '''
model.add(keras.layers.Embedding(500, 16, input_length=100))
model.add(keras.layers.GRU(8))
model.add(keras.layers.Dense(1, activation="sigmoid"))

''' 모델 설정 '''
rmsprop = keras.optimizers.RMSprop(learning_rate=0.0001)
model.compile(optimizer=rmsprop,
             loss="binary_crossentropy",
             metrics=["accuracy"])

''' 콜백함수 정의 '''
checkpoint_cb = keras.callbacks.ModelCheckpoint("./model/best_LSTM_model.h5")
early_stopping_cb = keras.callbacks.EarlyStopping(patience=3,
                                                 restore_best_weights=True)

''' 모델 훈련 '''
history = model.fit(train_seq, train_target,
          epochs=100,
          batch_size=64,
          validation_data=(val_seq, val_target),
          callbacks=[checkpoint_cb, early_stopping_cb])

 

  • 훈련, 검증, 테스트 성능검증하기
model.evaluate(train_seq, train_target)
model.evaluate(val_seq, val_target)
model.evaluate(test_seq, test_target)

 
728x90
반응형
728x90
반응형

순환신경망(RNN)

📍 순환신경망(Recurrent Neural Network, RNN)
 - RNN은 텍스트 처리를 위해 고안된 모델(계층)
 - 바로 이전의 데이터(텍스트)를 재사용하는 신경망 계층임
 - 이전에 진행한 훈련기억을 가지고 다시 훈련하는 방식


📍 순환신경망 종류
 - 심플 순환신경망(Simple RNN)
 - 장기기억 순환신경망(LSTM)
 - 게이트웨이 반복 순환신경망(GRU)
  • 사용 라이브러리
    import tensorflow as tf
    from tensorflow import keras
    
    tf.keras.utils.set_random_seed(42)
    tf.config.experimental.enable_op_determinism()​
  • 사용 데이터셋
    from tensorflow.keras.datasets import imdb​
     💡 IMDB : 영화 리뷰 감상평 데이터
      - 순환신경망에서 대표적으로 사용되는 데이터셋(외국)
      - 케라스에서 영어로된 문장을 정수(숫자)로 변환하여 제공하는 데이터셋
      - 감상평이 긍정과 부정으로 라벨링 되어있음
      - 총 50,000개의 샘플로 되어 있으며, 훈련 및 테스트로 각각 25,000개씩 분리하여 제공됨
  • IMDB 데이터 읽어들이기
    - num_words=500 :  말뭉치 사전의 갯수 500개만 추출하겠다는 의미
     * list 1개 = 문장 1개
     * 5만개의 문장 들어있음
     * 마지막 list는 긍정/부정에 대한 값이 들어있음(0 : 부정, 1 : 긍정)

    imdb.load_data(num_words=500)

    (train_input, train_target), (test_input, test_target) = imdb.load_data(num_words=500)
    print(f"{train_input.shape} / {train_target.shape}")
    print(f"{test_input.shape} / {test_target.shape}")​

    # 문장 1개, 들어있는 단어의 갯수는 218
    # 문장들의 단어의 갯수는 다 다를 것
    print(len(train_input[0]), train_input[0])​


  • 훈련 : 검증 = 8 : 2로 분리하기
    from sklearn.model_selection import train_test_split
    
    train_input, val_input, train_target, val_target = train_test_split(train_input, train_target, test_size=0.2, random_state=42)
    print(f"{train_input.shape} / {train_target.shape}")
    print(f"{val_input.shape} / {val_target.shape}")
    print(f"{test_input.shape} / {test_target.shape}")​


  • 정규화(텍스트 데이터)
     - 텍스트 기반의 데이터인 경우 정규화는 스케일링 처리가 아닌 문자열의 길이를 통일시키는 처리를 진행한다.
     - 훈련 모델은 정해진 행렬의 사이즈를 기준으로 훈련하기 때문이다.
    import numpy as np
    lengths = np.array([len(x) for x in train_input])
    lengths.shape, lengths


  • lengths의 값을 이용해서 전체평균과 중앙값 출력하기
    np.mean(lengths), np.median(lengths)​


  • 시각화
    import matplotlib.pyplot as plt
    from matplotlib import font_manager, rc
    plt.rc("font", family="Malgun Gothic")
    
    plt.title("텍스트 길이 분포 확인")
    plt.hist(lengths)
    plt.xlabel("length(단어 갯수)")
    plt.ylabel("빈도")
    plt.show()​
     중앙값이 평균값보다 낮으면 왼쪽에 평균
단어 갯수의 분포를 이용해서 훈련에 사용할 독립변수 각 값들의 길이 기준 정의
전체적으로 왼쪽편에 집중되어 있으며, x축 125 정도에 많은 빈도를 나타내고 있음
따라서, 독립변수 각 값들의 길이를 100으로 통일(정규화)

259개의 단어 중 100개만 남기고 날리기
앞에서 부터 단어 100개(평가하는 단어를 뒤쪽에 썼을거라는 생각)
단어가 100개가 안되는 문장은 100개가 되도록 빈자리는 0으로 채움

 

  • 각 데이터의 길이를 100으로 통일(정규화) 시키기
    ''' 텍스트 길이 정규화 라이브러리 '''
    from tensorflow.keras.preprocessing.sequence import pad_sequences
    
    ''' 훈련 독립변수 각 데이터 100개로 통일시키기
     - pad_sequences() : 텍스트의 길이를 maxlen 갯수로 통일시키기
     - maxlen보다 작으면 0으로 채우고, 크면 제거한다.
    '''
    train_seq = pad_sequences(train_input, maxlen=100)
    train_seq.shape

  • 검증 데이터도 길이 100으로 통일(정규화) 시키기
    val_seq = pad_sequences(val_input, maxlen=100)
    val_seq.shape​
  • 텍스트 길이 조정 속성(매개변수)
     - truncating
           → 추출 위치(앞 또는 뒤부터)
           → pre 뒤쪽부터 추출하기 (기본값), 앞쪽 제거하기
           → post 앞쪽부터 추출하기, 뒤쪽 제거하기
     - padding
           → 채울 위치(앞 또는 뒤부터)
           → pre 앞쪽을 0으로 채우기 (기본값)
           → post 뒤쪽을 0으로 채우기
    train_seq = pad_sequences(train_input, maxlen=100,
                             truncating="pre",
                             padding="pre")​

Simple RNN(심플 순환신경망)

  • 모델 생성하기
    model = keras.Sequential()
    model​
  • 계층 생성 및 모델에 추가하기
    - input_shape=(100, 500) : 100은 특성 갯수, 500은 말뭉치 갯수
    ''' 계층 생성 및 모델에 추가하기 
     - input_shape=(100, 500) : 100은 특성 갯수, 500은 말뭉치 갯
    '''
    ''' 입력계층이면서 RNN 계층 '''
    model.add(keras.layers.SimpleRNN(8, input_shape=(100, 500)))
    
    ''' 출력계층 '''
    model.add(keras.layers.Dense(1, activation="sigmoid"))

원-핫(One - Hot) 인코딩

📍 RNN에서 사용할 독립변수 처리 방식
- RNN 모델에서는 독립변수의 데이터를 원-핫 인코딩 데이터 또는 임베딩 처리를 통해서 훈련을 시켜야 한다

📍 원-핫(One-Hot) 인코딩 방식
- 각 데이터(값) 중에 1개의 단어당 분석을 위해 500개의 말뭉치와 비교하여야 함
- 이때 비교하기 위해 원-핫 인코딩으로 변환하여 비교하는 방식을 따름
- keras.util.to_categorical() 함수 사용
- 프로그램을 통해 변환해야 함(별도 계층이 존재하지는 않음)
- 각 단어별로 원-핫인코딩 처리가 되기에 데이터가 많아지며, 속도가 느림
- 데이터가 많아지기 떄문에 많은 메모리 공간을 차지함

📍 단어 임베딩(Embedding) 방식
- 원-핫 인코딩의 느린 속도를 개선하기 위하여 개선된 방식(메모리 활용)
- 많은 공간을 사용하지 않음
- keras.layers.Embedding() 계층을 사용함(프로그램 처리 방식이 아님)

 

  • 원-핫 인코딩 데이터로 변환하기
     - to_categorical() : 원-핫 인코딩 함수
     - 말뭉치 갯수만큼의 차원이 발생함 (총 3차원)
    train_oh = keras.utils.to_categorical(train_seq)
    val_oh =  keras.utils.to_categorical(val_seq)
    train_oh.shape

 

 

단어 1개당 500개의 값 생성

train_oh[0][2]는 1번째 문장의 3번째 단어에 대한 500개의 말뭉치를 비교한 리스트를 보여줌

 train_oh[0][2]가 20이므로 리스트에서 20번째 값이 1이고 나머지는 0

 

 

 

 

 

 

 

 

 

 

 

 

  • 모델 설정하기
    - 순환신경망(RNN)에서 주로 사용되는 옵티마이저는 RMSprop
    - RMSprop : 먼 거리는 조금 반영, 가까운 거리는 많이 반영하는 개념을 적용
    rmsprop = keras.optimizers.RMSprop(learning_rate=0.0001)
    model.compile(optimizer=rmsprop,
                 loss="binary_crossentropy",
                 metrics=["accuracy"])
  • 콜백함수 정의하기
    ''' 자동 저장 및 종료하는 콜백함수 정의하기 '''
    model_path = "./model/best_simpleRNN_model.h5"
    
    ''' 모델 자동 저장 콜백함수 '''
    checkpoint_cb = keras.callbacks.ModelCheckpoint(model_path)
    
    ''' 자동 종료 콜백 함수 '''
    early_cb = keras.callbacks.EarlyStopping(patience=3, restore_best_weights = True)
    
    checkpoint_cb, early_cb
  • 모델 훈련하기
    - batch_size : 훈련 시 데이터를 배치사이즈 만큼 잘라서 종속변수와 검증 진행
              → 배치사이즈 만큼 종속변수와 비교 시 틀리게 되면, 다음 배치사이즈에서 오류를 줄여가면서 훈련을 진행하게 된다
              → 배치사이즈의 값을 정의하지 않으면 전체 데이터를 기준으로 종속변수와 비교 및 훈련 반복 시 오류 조정 진행 된다
              → 배치사이즈의 값은 정의된 값은 없으며, 보통 32, 64 정도로 주로 사용함
              → 튜닝 대상 하이퍼파라미터 변수
    history = model.fit(
        train_oh, train_target, epochs=100, batch_size=64,
        validation_data=(val_oh, val_target),
        callbacks=[checkpoint_cb, early_cb]
    )


  • 훈련 및 검증에 대한 손실 곡선 그리기
    plt.plot(history.epoch, history.history["loss"])
    plt.plot(history.epoch, history.history["val_loss"])
    
    plt.xlabel("epoch")
    plt.ylabel("loss")
    plt.grid()
    
    plt.legend(["train", "val"])
    plt.title("train & val loss")
    
    plt.show()​


  • 훈련 및 검증에 대한 정확도 곡선 그리기
    plt.plot(history.epoch, history.history["accuracy"])
    plt.plot(history.epoch, history.history["val_accuracy"])
    
    plt.xlabel("epoch")
    plt.ylabel("accuracy")
    plt.grid()
    
    plt.legend(["train", "val"])
    plt.title("train & val acc")
    plt.show()​


단어 임베딩(Embedding) 방식

  • 모델 생성하기
    model2 = keras.Sequential()
    model2​
  • 계층 생성 및 추가하기
    ''' 입력계층 생성하기(단어임베딩 계층으로 생성)
     - 500 : 말뭉치 갯수
     - 16 : 출력크기(갯수)
     - input_length : 사용할 특성 갯수 (input_shape와 동일)
    '''
    model2.add(keras.layers.Embedding(500, 16, input_length=100))
    
    ''' Simple RNN 계층 추가 '''
    model2.add(keras.layers.SimpleRNN(8))
    
    ''' 출력 계층 추가 '''
    model2.add(keras.layers.Dense(1, activation="sigmoid"))​


  • 모델 설정하기
  • 콜백함수 정의하기
  • 모델 훈련시키기
  • 훈련 및 검증에 대한 손실 곡선 그리기
    4단계 모두 원핫인코딩과 동일

    시각화 결과 

 

  • 성능 평가하기
    ''' 원-핫데이터 모델로 검증데이터 평가하기 '''
    model.evaluate(val_oh, val_target)

    ''' 단어 임베딩 모델로 검증데이터 평가하기 '''
    model2.evaluate(val_seq, val_target)​


  • 테스트 데이터로 원-핫 모델 및 단어 임베딩 모델로 각각 평가하기
    ''' 테스트 데이터도 길이 100으로 통일(정규화) 시키기 '''
    test_seq = pad_sequences(test_input, maxlen=100)
    test_seq.shape
    
    ''' 원핫인코딩 데이터로 변환'''
    test_oh = keras.utils.to_categorical(test_seq)

    ''' 원-핫데이터 모델로 검증데이터 평가하기 '''
    model.evaluate(test_oh, test_target)
    ''' 단어 임베딩 모델로 검증데이터 평가하기 '''
    model2.evaluate(test_seq, test_target)​
728x90
반응형

+ Recent posts