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
반응형
728x90
반응형

퍼셉트론 모델

📍 퍼셉트론(Perceptron)
- 인공신경망의 한 종류
- 주로 이진분류 또는 다중분류에 사용되는 초기 인공신경망 모델
- 종속변수가 연속형인 회귀에서는 사용되지 않음(분류에서만 사용)
- 퍼셉트론에는 단층 퍼셉트론과 다층 퍼셉트론이 있음 - 주로 다층 퍼셉트론이 성능이 좋음

📍 단층 퍼셉트론(Single-Layer perceptron, SLP), 인공신경망 층
- 입력층과 출력층으로만 구성되어 있음
- 주로 이진 분류에 사용됨(성능이 낮은 경우, 다층 퍼셉트론으로 사용)
- 선형 활성화 함수(linear)를 사용

📍 다층 퍼셉트론(Multi-Layer perceptron, MLP), 심층신경망 층
- 입력층, 은닉층(1개 이상), 출력층으로 구성됨
- 주로 다중 분류에 사용됨(이진분류도 가능)
- 단층 퍼셉트론보다 높은 성능을 나타냄
- 여러 층(입력, 은닉, 출력)으로 이루어져 있다고 해서 "다층"이라고 칭함
- 은닉층에는 비선형 활성화 함수를 사용함(linear를 제외한 나머지, Sigmoid, RelU 등)
- 발전된 모델들이 현재 사용되는 모델들이며 계속 나오고 있음

 

퍼셉트론 분류데이터 사용

  • 라이브러리 정의
    import padnas as pd
    import numpy as np
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import StandardScaler
    
    ''' 단층 퍼셉트론 모델 '''
    from sklearn.linear_model import Perceptron
    ''' 다층 퍼셉트론 모델 '''
    from sklearn.neural_network import MLPClassifier
    ''' 최적의 하이퍼파라미터 찾기 '''
    from sklearn.model_selection import GridSearchCVR
    ''' 성능평가 '''
    from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
    ''' 시각화 '''
    import matplotlib.pyplot as plt
    import seaborn as sns
  • 데이터 불러들이기
  • 독립변수와 종속변수로 분류하기
  • 정규화하기
  • 훈련 : 검증 : 테스트 = 6 : 2 : 2 로 분리하기
    4가지 모두 이전과 동일하므로 코드 생략

단층 퍼셉트론

  • 단층 퍼셉트론 모델 생성하기
    perceptron_model = Perceptron(random_state=42)
    perceptron_model​


  • 하이퍼파라미터 튜닝할 매개변수 범위 설정
    param_grid = {
        ### 학습률 : 보폭
        "alpha" : [0.0001, 0.001, 0.01],
        ### 반복 횟수(epoch)
        "max_iter" : [100, 500, 1000]
    }
    param_grid


  • GridSearchCV 객체 생성
    grid_search = GridSearchCV(perceptron_model, param_grid, cv=3, scoring="accuracy")
    grid_search​


  • 최적의 하이퍼파라미터 찾기
    grid_search.fit(X_train, y_train)​
  • 최적의 하이퍼파라미터 출력
    grid_search.best_params_​


  • 최적의 모델
    best_model = grid_search.best_estimator_
    best_model​


  • 최적의 모델로 훈련시키기
    best_model.fit(X_train, y_train)​
  • 훈련 및 검증 정확도 확인하기
    score_train = best_model.score(X_train, y_train) 
    score_val = best_model.score(X_val, y_val) 
    score_train, score_val​
    과대/과소는 일어나지 않았지만, 모델자체의 성능이 낮음

  • 정밀도, 재현율, f1, 매트릭스 확인
    ''' 정밀도, 재현율, f1, 매트릭스 확인 '''
    ''' 예측하기 '''
    y_pred = best_model.predict(X_test)
    
    ''' 정밀도 '''
    pre = precision_score(y_test, y_pred)
    
    ''' 재현율 '''
    re = recall_score(y_test, y_pred)
    
    ''' f1-score '''
    f1 = f1_score(y_test, y_pred)
    
    ''' 평가 매트릭스(혼동행렬) '''
    cm = confusion_matrix(y_test, y_pred)
    pre, re, f1, cm

    보통 재현율과 f1은 유사하게 나옴.
    재현율 = 1은 위험한 오류가 없다는 뜻.
    f1이 낮게 나온것은 긍정적 오류가 존재한다는 뜻
    매트릭스 상에서 0을 0으로 맞춘게 하나도 없음 > 문제

  •  혼동행렬 시각화 - 방법 1
    plt.figure(figsize=(8, 4))
    plt.title("Confusion_matrix")
    sns.heatmap(cm, annot=True, fmt="d", cmap="Blues",
                xticklabels=["0", "1"], yticklabels=["0", "1"])
                ### cbar=False 설정시 오른쪽 막대 바 사라짐
    plt.show()


  • 혼동행렬 시각화 - 방법 2
    from sklearn.metrics import ConfusionMatrixDisplay
    disp = ConfusionMatrixDisplay(confusion_matrix =cm)
    disp.plot()



다층 퍼셉트론

  • 다층 퍼셉트론 모델 생성하기
    mlp_model = MLPClassifier(random_state=42)
    mlp_model​
  • 튜닝할 하이퍼파라미터 설정하기
    param_grid = {
        ### hidden_layer_sizes : 은닉계층 정의
        # - (10,) : 은닉계층 1개 사용, 출력크기 10개를 의미함
        # - (10, 10) : 은닉계층 2개 사용, 각각의 출력 크기가 10개라는 의미
        # - (10, 11, 12) : 은닉계층 3개 사용, 각각의 출력 크기는 10, 11, 12
        "hidden_layer_sizes" : [(10,), (50,), (100,)],
        "alpha" : [0.0001, 0.001, 0.01],
        "max_iter" : [1000]
    }
    param_grid​


  • GridSearchCV 객체 생성
    grid_search_mlp = GridSearchCV(mlp_model, param_grid, cv=3, scoring="accuracy")
    grid_search_mlp​


  • 최적의 하이퍼파라미터
    grid_search_mlp.fit(X_train, y_train)​
  • 최적의 하이퍼파리미터 출력
    grid_search_mlp.best_params_​


  • 최적의 모델
    best_model_mlp =grid_search_mlp.best_estimator_
    best_model_mlp​


  • 훈련 및 검증 정확도 확인하기
    score_train = best_model_mlp.score(X_train, y_train) 
    score_val = best_model_mlp.score(X_val, y_val) 
    score_train, score_val​


  • 정밀도, 재현율, f1, 매트릭스 확인
    ''' 예측하기 '''
    y_pred = best_model_mlp.predict(X_test)
    
    ''' 정밀도 '''
    pre = precision_score(y_test, y_pred)
    
    ''' 재현율 '''
    re = recall_score(y_test, y_pred)
    
    ''' f1-score '''
    f1 = f1_score(y_test, y_pred)
    
    ''' 평가 매트릭스(혼동행렬) '''
    cm = confusion_matrix(y_test, y_pred)
    pre, re, f1, cm​


  •  혼동행렬 시각화
    plt.title("Confusion_matrix")
    sns.heatmap(cm, annot=True, fmt="d", cmap="Blues",
                xticklabels=["0", "1"], yticklabels=["0", "1"])
    ### cbar=False 설정시 오른쪽 막대 바 사라짐
    plt.show()

728x90
반응형
728x90
반응형

심층신경망_분류데이터사용

- 입력계층의 출력크기 64
- 은닉계층의 출력크기 32
- 나머지는 ?
- 콜백함수 모두 적용
- 옵티마이저 모두 적용해보기
- 정밀도, 재현율, f1-score, confusion_matrix출력

 

작성한 코

  • 라이브러리 정의
  • import pandas as pd
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    
    import tensorflow as tf
    from tensorflow import keras
    
    from sklearn.metrics import precision_score, recall_score, f1_score, confusion_matrix
    from sklearn.metrics import ConfusionMatrixDisplay
  • 데이터 가져오기
    - 데이터프레임 변수 : data
    - 데이터 읽어들이기
    - 종속변수 : 주택가격
    - 주택가격이 연속형 데이터이므로 회귀데이터
    data = pd.read_csv("./data/08_wine.csv")
    data.head(1)
  • 독립변수(X)와 종속변수(y)로 분리하기
    X = data.iloc[:,:-1]
    y = data["class"]
    X.shape, y.shape
  • 데이터 정규화
    - X_scaled 변수명 사용
    ss = StandardScaler()
    ss.fit(X)
    X_scaled = ss.transform(X)
    X_scaled.shape
  • 훈련 : 테스트 데이터로 분류하기 (8 : 2)
    - 사용 변수 : X_train, X_test, y_train, y_test
    X_train, X_test, y_train, y_test = train_test_split(X_scaled, y,
                                                       test_size=0.2,
                                                       random_state=42)
    print(f"{X_train.shape} : {y_train.shape}")
    print(f"{X_test.shape} : {y_test.shape}")

  • 함수 생성
    def model_d():
        model = keras.models.Sequential()
        model.add(keras.layers.Dense(64,input_shape=(3,),activation='sigmoid'))
        model.add(keras.layers.Dense(32,activation='sigmoid'))
        model.add(keras.layers.Dense(1,activation='sigmoid'))
        return model
    
    def model_f(model, opt, epoch) :
        model.compile(optimizer = opt,
                      loss="binary_crossentropy",
                      metrics="accuracy")
        
        checkpoint_cb = keras.callbacks.ModelCheckpoint(
            "./model/best_model.h5",
            save_best_only = True)
    
        early_stopping_cb = keras.callbacks.EarlyStopping(
            patience=2,
            restore_best_weights=True)
    
        history = model.fit(
            X_train, y_train, epochs=epoch, verbose=1,
            validation_data=(X_test, y_test),
            callbacks=[checkpoint_cb, early_stopping_cb])
    
        return history
  • 함수 호출
    ''' 함수 호출하기 '''
    
    ''' 옵티마이저를 리스트로 정의하기 '''
    optimizers = ["sgd", "adagrad", "rmsprop", "adam"]
    
    history_loss = {}
    history_acc = {}
    
    ''' 옵티마이저의 학습방법을 반복하여 성능 확인하기 '''
    for opt in optimizers :
        print(f"--------------------------{opt}--------------------------")
        model = model_d()
        history = model_f(model, opt, 100)
        history_loss[min(history.history['val_loss'])] = opt
        history_acc[min(history.history['val_accuracy'])]= opt
    print(f"최적의 학습기법 : {history_loss[min(history_loss.keys())]} / 손실율 : {min(history_loss.keys())} ")
    print(f"최적의 학습기법 : {history_acc[max(history_acc.keys())]} / 정확도 : {max(history_acc.keys())}")​


  • 모델 생성
    model = model_d()
    model_f(model, "adam", 100)​
  • 예측하기
    y_pred = model.predict(X_test)
    for i in range(len(y_pred)):
        if y_pred[i] > 0.5:
            y_pred[i] = 1
        else:
            y_pred[i] = 0
    y_pred​


  • 정밀도, 재현율, f1-score, confusion_matrix 출력
    precision = precision_score(y_test,y_pred)
    recall = recall_score(y_test,y_pred)
    f1 = f1_score(y_test,y_pred)
    cm = confusion_matrix(y_test,y_pred)
    print("Precision:", precision)
    print("Recall:", recall)
    print("F1 Score:", f1)
    print("Confusion Matrix:", cm)


  • 오차행렬도 그리기
    disp = ConfusionMatrixDisplay(confusion_matrix =cm)
    disp.plot()

강사님 코드

  • 라이브러리 정의
    import pandas as pd
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import train_test_split
    
    import tensorflow as tf
    from tensorflow.keras.models import Sequential
    from tensorflow.keras.layers import Dense
    
    from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
  • 데이터 불러들이기
    data = pd.read_csv("./data/08_wine.csv")
    data.head(1)​
  • 데이터 정규화
    ss = StandardScaler()
    ss.fit(X)
    X_scaled = ss.transform(X)
    X_scaled.shape
  • 훈련 : 검증 : 테스트 데이터로 분류하기 (6 : 2 : 2)
    X_train, X_temp, y_train, y_temp = train_test_split(X_scaled, y,
                                                       test_size=0.4,
                                                       random_state=42)
    
    X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp,
                                                       test_size=0.5,
                                                       random_state=42)
    
    print(f"훈련 데이터 {X_train.shape} : {y_train.shape}")
    print(f"검증 데이터 {X_val.shape} : {y_val.shape}")
    print(f"테스트 데이터 {X_test.shape} : {y_test.shape}")


  • 모델 생성
    model = Sequential()
    model​
  • 계층 생성
    '''
    입력 은닉 계층에는 softmax빼고 다른 함수 다 들어갈 수 있다.
    softmax는 출력 계층에만 들어간다
    '''
    
    '''
    <입력계층>
     - 64 : 출력크기
     - activation=relu0 : 활성화 함수. relu는 0보다 크면 1, 0보다 작으면 0
     - input_dim=3 : 입력 특성의 갯수 (input_shape 대신에 사용가능)
    '''
    model.add(Dense(64, activation="relu", input_dim=3))
    
    '''
    Dropout은 과대적합 나올때 은닉계층 전에 사용하여 모델을 덜 똑똑하게 만들어버린다.
    은닉계층이 두개라면 은닉계층 전에 사용할 수 있기 때문에 dropout또한 2개 사용 가능하다.
    '''
    
    '''
    <은닉 계층>
    '''
    model.add(Dense(32, activation="relu"))
    
    '''
    <출력 계층>
     - sigmoid : 이진분류이기 때문에 0.5를 기준으로 0 또는 1로 나뉘는 sigmoid 사용
    '''
    model.add(Dense(1, activation="sigmoid"))


  • 모델 설정하기
    ''' 
     - 이진분류 이므로 binary_crossentropy 사용
     - 다중분류 : sparse
     '''
    model.compile(loss="binary_crossentropy",
                 optimizer="adam",
                 metrics=["accuracy"])
  • 모델 훈련시키기
    model.fit(X_train, y_train, epochs=100,
             validation_data=(X_val, y_val))


  • 성능검증
    loss, acc = model.evaluate(X_test, y_test)
    loss, acc


  • 예측하기
    y_pred = model.predict(X_test)
    y_pred
    이 값을 종속변수와 비교하기 위해 1 또는 0으로 바꿔야 함

  • 평가를 위해서 예측값을 종속변수의 범주 형태(0 or 1)로 변환하기
    ''' True = 1, False = 0 '''
    base = 0.5
    binary_pred = (y_pred > base).astype(int)
    binary_pred


  • 성능 평가
    precision = precision_score(y_test, binary_pred)
    recall = recall_score(y_test, binary_pred)
    f1 = f1_score(y_test, binary_pred)
    precision, recall, f1


  • 매트릭스 확인
    conf_matrix = confusion_matrix(y_test, binary_pred)
    conf_matrix

728x90
반응형
728x90
반응형

심층신경망_훈련

지난 수업 복습하기

- 새로운 모델 생성 : model20 변수명 사용
- epoch 20번 반복 수행
- 프로그래스바가 보이도록 훈련시 출력하기
- 손실 및 정확도 곡선 각각 그리기
  • 함수 설정
    def model_fn(a_layer = None):
        model = keras.Sequential()
    
        model.add(keras.layers.Flatten(input_shape=(28, 28)))
        model.add(keras.layers.Dense(100, activation='relu'))
    
        ''' 추가할 은닉계층이 있는 경우만 실행 '''
        if a_layer :
            model.add(a_layer)
            
        model.add(keras.layers.Dense(10, activation='softmax'))
    
        return model
  • 함수 호출
    model20 = model_fn()
  • 모델 설정
    model20.compile(loss = "sparse_categorical_crossentropy",
                  metrics="accuracy")
  • 모델 훈련
    history20 = model20.fit(train_scaled, train_target, epochs=20)
  • 시각화
    ''' 손실률 '''
    plt.title("Epoch20 - Loss")
    plt.plot(history20.epoch, history20.history["loss"])
    plt.xlabel("epoch")
    plt.ylabel("accuracy")
    plt.grid()
    
    plt.savefig("./saveFig/Epoch20-Loss.png")
    plt.show()
    
    ''' 정확도 '''
    plt.title("Epoch20 - Accuracy")
    plt.plot(history20.epoch, history20.history["accuracy"])
    plt.xlabel("epoch")
    plt.ylabel("accuracy")
    plt.grid()
    
    plt.savefig("./saveFig/Epoch20-Accuracy.png")
    plt.show()

  • 훈련에 대한 손실 및 정확도 곡선을 하나의 그래프로 그리기
    plt.figure(figsize=(12, 6))
    
    # 손실률 그래프
    plt.plot(history20.epoch, history20.history["loss"])
    # 정확도 그래프
    plt.plot(history20.epoch, history20.history["accuracy"])
    
    plt.xlabel("Epoch")
    plt.ylabel("Loss & Accuracy")
    plt.grid()
    
    # 범례 추가
    plt.legend(['Loss', 'Accuracy'])
    
    # 제목 설정
    plt.title("Epoch20 - Loss and Accuracy")
    
    # 그래프 저장
    plt.savefig("./saveFig/Epoch20-Loss-Accuracy.png")
    plt.show()

 

훈련 및 검증에 대한 손실 및 정확도 모두 표현하기

  • 함수 호출
    model = model_fn()
  • 모델 설정
    model.compile(loss = "sparse_categorical_crossentropy",
                  metrics="accuracy")
  • 모델 훈련
    '''
     - validation_data : 검증 데이터를 이용해서 성능평가를 동시에 수행함
    '''
    history = model.fit(train_scaled, train_target, epochs=20, verbose=1,
                       validation_data=(val_scaled, val_target))
  • history에서 가져올수 있는 값 확인
    history.history.keys()

훈련에 대한 loss와 검증에 대한 loss 비교하는데 유용

 

  • 시각화 - 손실곡선
    '''
     - 훈련과 검증에 대한 손실(loss) 곡선 그리기
    '''
    
    # 훈련 손실률 그래프
    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_Loss', 'Val_Loss'])
    
    # 제목 설정
    plt.title("Epoch20 - Train_Loss & Val_Loss")
    
    # 그래프 저장
    plt.savefig("./saveFig/Train-Loss-Val-Loss.png")
    plt.show()

 

 

 

- 딥러닝은 손실률을 기준으로 판단한다.

- 훈련 곡선이 검증 곡선 보다 밑에 있어야 과소적합이 일어나지 않는다.

- Epoch가 2인 시점에 두 곡선이 가장 가까우면서 그 이후로 과대적합이 발생하고 있다.

 

 

 

 

 

 

 

  • 시각화 - 정확도 곡선
    '''
     - 훈련과 검증에 대한 정확도(accuracy) 곡선 그리기
    '''
    
    # 훈련 정확도 그래프
    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_Accuracy', 'Val_Accuracy'])
    
    # 제목 설정
    plt.title("Epoch20 - Train_Acc & Val_Acc")
    
    # 그래프 저장
    plt.savefig("./saveFig/Train-Acc-Val-Acc.png")
    plt.show()

 

 

 

- 손실이 과대적합이 일어나면 정확도 또한 과대적합이 일어날 가능성이 높다.

- Epoch가 2인 시점부터 시작하여 과대적합이 일어나고 있다.

 

 

 

 

 

 

 

훈련 및 검증에 대한 손실 및 정확도 표현하여 과적합 여부 확인하기

- model 변수명으로 신규 모델 만들기
- 옵티마이저 adam 사용

- 훈련 및 검증 동시에 훈련시킨 후 손실 및 검증 곡선 그려서 과적합 여부 확인하기
  • 함수 호출하기
    model = model_fn()
  • 모델 설정
    model.compile(
        ### 옵티마이저 정의 : 손실을 줄여나가는 방법
        optimizer="adam",
        ### 손실함수 : 종속변수의 형태에 따라 결정 됨
        loss="sparse_categorical_crossentropy",
        ### 훈련 시 출력할 값 : 정확도 출력
        metrics="accuracy"
    )
  • 모델 훈련
    history = model.fit(train_scaled, train_target, epochs=20, verbose=1,
                       validation_data=(val_scaled, val_target))
  • 시각화 - 손실곡선 & 정확도 곡선
    # 훈련 정확도 그래프
    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_Accuracy', 'Val_Accuracy'])
    
    # 제목 설정
    plt.title("Adam-Train_Acc & Val_Acc")
    
    # 그래프 저장
    plt.savefig("./saveFig/Adam-Train-Acc-Val-Acc.png")
    plt.show()

Epoch 3인 시점에서 두 곡선이 가장 가깝다.

그 이후로는 과대적합이 일어나고 있다.

 

  • Epoch 200번으로 설정하여 모델 훈련 및 시각화
    history = model.fit(train_scaled, train_target, epochs=200, verbose=1,
                       validation_data=(val_scaled, val_target))

 

심층신경망_성능 규제

📍성능 규제
- 성능(과적합 여부 포함)을 높이기 위한 방법
- 보통 전처리 계층을 사용하게 된다.
- 전처리 계층은 훈련에 영향을 미치지 않음

성능 규제 방법 - 드롭 아웃(Dropout())

📍드롭아웃(Dropout)
- 훈련 과정 중 일부 특성들을 랜덤하게 제외 시켜서 과대적합을 해소하는 방법
- 딥러닝에서 자주 사용되는 전처리 계층으로 성능 개선에 효율적으로 사용됨

📍사용방법
- 계층의 중간에 은닉층(hidden layer)으로 추가하여 사용됨
- 훈련에 관여하지 않음 → 데이터에 대한 전처리라고 보면 됨
  • 모델 생성
    ''' Dropout(0.3) : 사용되는 특성 30% 정도를 제외하기 ''' 
    dropout_layer = keras.layers.Dropout(0.3)
    model = model_fn(dropout_layer)
    model.summary()
  • 모델 설정
    model.compile(
        ### 옵티마이저 정의 : 손실을 줄여나가는 방법
        optimizer="adam",
        ### 손실함수 : 종속변수의 형태에 따라 결정 됨
        loss="sparse_categorical_crossentropy",
        ### 훈련 시 출력할 값 : 정확도 출력
        metrics="accuracy"
    )
  • 모델 훈련
    history = model.fit(train_scaled, train_target, epochs=20, verbose=1,
                       validation_data=(val_scaled, val_target))
  • 시각화 - 손실곡선 & 정확도 곡선

더보기

강사님 그래프 설명
손실률은 훈련 곡선이 아래 있어야 함
Epoch 8 시점에서 두 곡선이 가까움
Epoch 7.5를 기점으로 과대적합이 점점 일어나고 있음 > Epoch 8까지가 적당
훈련 곡선이 검증 곡선 위에 있으면 과소적합이 일어남

정확도는 훈련 곡선이 위에 있어야 함
Epoch 10을 기준으로 왼쪽은 과소적합 오른쪽은 과대적합

손실률이 Epoch 8 시점에서 가장 좋게 나타나면 정확도 Epoch 8 시점을 비교해 본다
손실률과 정확도를 비교하여 적절한 Epoch를 찾아내고 그 시점까지로 다시 훈련시킨다.
Epoch 14회 정도 돌리면 가장 적절한 횟수를 찾을 수 있을 것 같다

 

모델 저장 및 복원하기

📍모델 저장하는 방법
- 가중치만 저장하기
        → 모델이 훈련하면서 찾아낸 가중치 값들만 저장하기
        → 모델 자체가 저장되지는 않는다
        → 모델 신규생성 > 저장된 가중치 불러와서 반영 > 예측 진행
        → 별도로 훈련(fit)은 하지 않아도 된다
- 모델 자체 저장하기
        → 저장된 모델을 불러와서 > 예측 진행

가중치 저장 및 불러들이기

  • 가중치 저장하기
    ''' 저장시 사용되는 확장자는 보통 h5를 사용한다 '''
    model.save_weights("./model/model_weight.h5")
  • 저장된 가중치 불러들이기
    ''' 1. 모델 생성 '''
    model_weight = model_fn(keras.layers.Dropout(0.3))
    model_weight.summary()
    
    ''' 2. 가중치 적용하기 '''
    model_weight.load_weights("./model/model_weight.h5")
    
    ''' 이후 부터는 바로 예측으로 사용 '''

모델 자체를 저장 및 불러들이기

  • 모델 자체 저장하기
    model.save("./model/model_all.h5")
  • 모델 자체 불러들이기
    model_all = keras.models.load_model("./model/model_all.h5")
    model_all.summary()
    
    ''' 이후 부터는 바로 예측으로 사용 '''
  • 예측하기
    pred_data = model_all.predict(val_scaled)
    pred_data[0]

    - 종속변수가 10개 이므로 10개의 값이 들어있어야 함 

    - 마지막 출력 값 또한 10개
    •  예측 확인하기
      import numpy as np
      
      np.argmax(pred_data[0]), val_target[0]

      ''' 예측 결과의 모든 행에 대해서 가장 높은 값을 가지는 열의 인덱스 위치 추출 '''
      val_pred = np.argmax(pred_data, axis=1)
      val_pred​
  • 정답갯수, 오답갯수, 정답률, 오답률 출력
    ''' 방법 1 '''
    # 정답 갯수
    correct_count = np.sum(val_pred == val_target)
    # correct_count = len(val_pred[val_pred == val_target])
    
    # 오답 갯수
    incorrect_count = np.sum(val_pred != val_target)
    # incorrect_count = len(val_pred[val_pred != val_target])
    
    # 정답률
    accuracy = correct_count / len(val_target)
    
    # 오답률
    error_rate = incorrect_count / len(val_target)
    
    # 결과 출력
    print("정답 갯수:", correct_count)
    print("오답 갯수:", incorrect_count)
    print("정답률:", accuracy)
    print("오답률:", error_rate)
    
    ''' 방법 2 '''
    correct_count = 0
    incorrect_count = 0
    for i, j in zip(val_pred, val_target):
        if i == j:
            correct_count += 1
        elif i != j :
            incorrect_count +=1
         
    print(f"정답 : {correct_count}")
    print(f"오답 : {incorrect_count}")
    print(f"정답률 : {correct_count / len(val_target)}")
    print(f"오답률 : {incorrect_count / len(val_target)}")

심층신경망_성능 향상

성능 향상 - 콜백(Callback) 함수

📍 콜백함수(Callback Function)
 - 모델 훈련 중에 특정 작업(함수)를 호출할 수 있는 기능
 - 훈련(fit)시에 지정하는 함수를 호출하는 방식
 - 훈련 중에 발생시키는 "이벤트"라고 생각하면 된다
 - 별도의 계층은 아니며, 속성(매개변수)으로 정의된다.

📍 콜백함수 종류
 - ModelCheckpoint()
       : epoch 마다 모델을 저장하는 방식
       : 단, 앞에서 실행된 훈련 성능보다 높아진 경우에만 저장됨
 - EarlyStopping()
       : 훈련이 더이상 좋아지지 않으면 훈련(fit)을 종료시키는 방식
       : 일반적으로 ModelCheckpoint()와 함께 사용

ModelCheckPoint 콜백 함수

  1. 모델 생성하기
    model = model_fn(keras.layers.Dropout(0.3))​
  2. 모델 설정하기
    model.compile(
            ### 옵티마이저 정의 : 손실을 줄여나가는 방법
            optimizer="adam",
            ### 손실함수 : 종속변수의 형태에 따라 결정 됨
            loss="sparse_categorical_crossentropy",
            ### 훈련 시 출력할 값 : 정확도 출력
            metrics="accuracy"
                 )​
  3. 콜백함수 생성하기
    - 훈련(fit) 전에 생성
    - save_best_only = True
         : 이전에 수행한 검증 손실률보다 좋을 떄 마다 훈련모델 자동 저장 시키기
         : 훈련이 종료되면, 가장 좋은 모델만 저장되어 있다.
    - save_best_only = False
         : epoch마다 훈련모델 자동 저장 시키기
    - 저장된 모델은 모델 자체가 저장되는 방식으로 추후 불러들인 후 바로 예측으로 사용 가능
    checkpoint_cb = keras.callbacks.ModelCheckpoint(
        "./model/best_model.h5",
        save_best_only = True
    )​
  4. 모델 훈련하기
    - fit()함수 내에 콜백함수 매개변수에 정의
    history = model.fit(
        train_scaled, train_target, epochs=10, verbose=1,
        validation_data=(val_scaled, val_target),
    
        ### 콜백함수에 대한 매개변수 : 리스트 타입으로 정의
        callbacks=[checkpoint_cb]
    )​
  5. 콜백함수를 통해 저장된 모델 불러들이기
    model_cp_cb = keras.models.load_model("./model/best_model.h5")
    model_cp_cb.summary()
    
    model_cp_cb.evaluate(val_scaled, val_target)​

EarlyStopping 콜백 함수

  1. 모델 생성하기 (이전과 동일)
  2. 모델 설정하기 (이전과 동일)
  3. 콜백함수 생성하기
    - patience=2
         : 더 이상 좋아지지 않는 epoch의 갯수 지정
         : 가장 좋은 시점의 epoch 이후 2번 더 수행 후 그래도 좋아지지 않으면 종료시킨다는 의미
    - restore_best_weights=True : 가장 낮은 검증 손실을 나타낸 모델의 하이퍼파라미터로 모델을 업데이트 시킴
    ''' ModelCheckpoint() '''
    checkpoint_cb = keras.callbacks.ModelCheckpoint(
        "./model/best_model.h5",
        save_best_only = True
    )
    
    ''' EarlyStopping() ''' 
    early_stopping_cb = keras.callbacks.EarlyStopping(
        patience=2,
        restore_best_weights=True
    )​
  4. 모델 훈련시키기
    - fit()함수 내에 콜백함수 매개변수에 정의
    history = model.fit(
        train_scaled, train_target, epochs=100, verbose=1,
        validation_data=(val_scaled, val_target),
    
        ### 콜백함수에 대한 매개변수 : 리스트 타입으로 정의
        callbacks=[checkpoint_cb, early_stopping_cb]
    )​

    Epoch 4 에서 종료. 여기서 -2 한 Epoch 2가 가장 최적화 된 모델로 저장되어 있음

  5. 콜백함수를 통해 저장된 모델 불러들이기
    model_f = keras.models.load_model("./model/best_model.h5")
    model_f.summary()
    
    print(model_f.evaluate(train_scaled, train_target))
    print(model_f.evaluate(val_scaled, val_target))

728x90
반응형
728x90
반응형

심층신경망_훈련

라이브러리 정의

import tensorflow as tf
from tensorflow import keras
from sklearn.model_selection import train_test_split
''' 실행 결과를 동일하게 하기 위한 처리(완전 동일하지 않을 수도 있음) '''
tf.keras.utils.set_random_seed(42)

''' 연산 고정 '''
tf.config.experimental.enable_op_determinism()

 

 

데이터 정의

'''
 - 패션MNIST 데이터 읽어들이기 (훈련 및 테스트 데이터)
 - 정규화 하기
 - 훈련 및 검증 데이터로 분류하기
'''

''' 패션MNIST 데이터 읽어들이기 '''
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
''' 정규화 '''
train_scaled_255 = train_input / 255.0
test_scaled_255 = test_input / 255.0

''' 훈련 및 검증 데이터로 분류하기 '''
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled_255,
                                                                      train_target,
                                                                      test_size=0.2,
                                                                      random_state=42)
print(train_scaled.shape, train_target.shape)
print(val_scaled.shape, val_target.shape)
print(test_scaled_2d.shape, test_target.shape)

 

심층신경망(Deep Neural Network, DNN)

  • 인공신경망(Artificial Neural Networt, ANN) : 계층이 1개인 경우 또는 은닉계층이 없는 경우
  • 심층신경망(Deep Neural Network, DNN) : 은닉계층을 가지고 있는 경우

모델 생성시키는 함수 생성하기

- 함수이름 : model_fn
    → 매개변수 : a_layer 매개변수
           → 은닉계층이 있는 경우 계층자체를 매개변수로 받아서 아래에서 추가
- 모델생성
- 입력층(1차원 전처리계층) 추가
- 100개의 출력을 담당하는 은닉계층 추가, 활성화 함수 "relu"
- 추가할 은닉계층이 있으면 추가, 없으면(None) 건너뛰기
- 출력층
- 모델 반환
  • 함수 생성
def model_fn(a_layer = None):
    model = keras.Sequential()

    model.add(keras.layers.Flatten(28, 28))
    model.add(keras.layers.Dense(100, activation='relu'))

    ''' 추가할 은닉계층이 있는 경우만 실행 '''
    if a_layer :
        model.add(a_layer)
        
    model.add(keras.layers.Dense(10, activation='softmax'))

    return model
  • 함수 호출
model5 = model_fn()
model5
  • 모델 생성계층 확인하기
model5.summary()

 

 

Param = (입력크기 * 출력크기) + 출력크기

78500 = (784 * 100) + 100

1010 = (100 * 10) + 10

 

 

 

 

 

 

 

모델 설정하기(Compile)

model5.compile(loss = "sparse_categorical_crossentropy",
              metrics="accuracy")

 

모델 훈련하기(Fit)

model5.fit(train_scaled, train_target, epochs=5)

  • 훈련 출력방법 지정
    - verbose 출력방법
         → 0은 아무것도 안나옴
         → 1은 프로그래스바와 함께 loss와 accuracy 출력
         → 2는 프로그래스바와 없이 loss와 accuracy만 출력
         → 기본값은 1
history5 = model5.fit(train_scaled, train_target, epochs=5, verbose=2)
print("훈련 끝 >>>>>>>")

 

시각화 하기

''' 시각화 하기 '''
import matplotlib.pyplot as plt

plt.title("Epoch5 - Loss")
plt.plot(history5.epoch, history5.history["loss"])
plt.xlabel("epoch")
plt.ylabel("loss")
plt.grid()

plt.savefig("./saveFig/Epoch5-Loss.png")
plt.show()

plt.title("Epoch5 - Accuracy")
plt.plot(history5.epoch, history5.history["accuracy"])
plt.xlabel("epoch")
plt.ylabel("accuracy")
plt.grid()

plt.savefig("./saveFig/Epoch5-Accuracy.png")
plt.show()

728x90
반응형

+ Recent posts