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

실습 - 1

1. 신경망 모델 생성
2. 계층 추가하기
 - 1차원 전처리 계층 추가
 - 은닉계층 추가, 활성화함수 relu 사용, 출력크기 100개
 - 최종 출력계층 추가
3. 모델설정하기
 - 옵티마이저는 adam 사용, 학습률 0.1 사용
4. 훈련시키기
 - 훈련횟수 : 50
5. 성능 평가하기
''' 1. 신경망 모델 생성 '''
model = keras.Sequential()
''' 2. 계층 추가하기
 - 1차원 전처리 계층 추가
 - 은닉계층 추가, 활성화함수 relu 사용, 출력크기 100개
 - 최종 출력계층 추가
'''
model.add(
    keras.layers.Flatten(input_shape=(28, 28))
)

model.add(
    keras.layers.Dense(100, activation="relu")
)

model.add(
    keras.layers.Dense(10, activation="softmax")
)
''' 3. 모델설정하기
 - 옵티마이저는 adam 사용, 학습률 0.1 사용
'''
adam = keras.optimizers.Adam(
    learning_rate=0.1
)
model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics="accuracy"
)
''' 4. 훈련시키기 '''
model.fit(train_scaled, train_target, epochs=50)

''' 5. 성능 평가하기 '''
score = model.evaluate(val_scaled, val_target)

print(f"손실율 : {score[0]} / 정확도 : {score[1]}")

 

훈련 횟수가 증가할 수록 정확도가 감소되었기 때문에 훈련율을 0.01로 조정

조정 후 정확도 확인

 

실습 - 2

<실습>
- 옵티마이저에 적용할 학습기법(sgd, adagrad, rmsprop, adam) 중에 가장 좋은 성능을 나타내는 옵티마이저 학습기법 확인하기
- 훈련횟수 : 50회
- 학습률은 기본값 사용
- 은닉계층 relu 사용
- 성능 평가결과를 이용해서 손실율이 가장 낮을 때의 학습방법, 정확도가 가장 높을 때의 학습방법을 각각 출력하기

작성한 코드

''' 1. 신경망 모델 생성 '''
model = keras.Sequential()
''' 2. 계층 추가하기 '''
model.add(keras.layers.Flatten(input_shape=(28, 28)))
model.add(keras.layers.Dense(100, activation="relu"))
model.add(keras.layers.Dense(10, activation="softmax"))

opt = ["sgd", "adagrad", "rmsprop", "adam"]

best_loss_optimizer = None
best_accuracy_optimizer = None
best_loss = float('inf')  # 초기값을 무한대로 설정
best_accuracy = 0.0

for i in opt:
    if i == "sgd":
        optimizer = keras.optimizers.SGD()
    elif i == "adagrad":
        optimizer = keras.optimizers.Adagrad()
    elif i == "rmsprop":
        optimizer = keras.optimizers.RMSprop()    
    else:
        optimizer = keras.optimizers.Adam()
    print(f"-------------------옵티마이저 {i} 시작-------------------")
    model.compile(
        optimizer=optimizer,
        loss="sparse_categorical_crossentropy",
        metrics=["accuracy"]
    )

    model.fit(train_scaled, train_target, epochs=50)

    loss, accuracy = model.evaluate(val_scaled, val_target)
    print(f"손실율 : {loss} / 정확도 : {accuracy}")
    print(f"-------------------옵티마이저 {i} 종료-------------------")

    # 가장 좋은 성능인지 확인
    if loss < best_loss:
        best_loss = loss
        best_loss_optimizer = i

    if accuracy > best_accuracy:
        best_accuracy = accuracy
        best_accuracy_optimizer = i


print("손실율이 가장 낮을 때의 학습방법:", best_loss_optimizer)
print("정확도가 가장 높을 때의 학습방법:", best_accuracy_optimizer)

 

강사님 코드

### 옵티마이저 학습방법 및 반복횟수를 받아서 처리할 함수 정의
def getBestEval(opt, epoch) :
    ''' 모델 생성 '''
    model = keras.Sequential()

    ''' 레이어계층 생성 및 모델에 추가하기 '''
    model.add(keras.layers.Flatten(input_shape=(28, 28)))
    model.add(keras.layers.Dense(100, activation="relu"))
    model.add(keras.layers.Dense(10, activation="softmax"))

    ''' 모델 설정하기 '''
    model.compile(optimizer = opt,
                  loss="sparse_categorical_crossentropy",
                  metrics="accuracy")

    ''' 모델 훈련시키기 '''
    model.fit(train_scaled, train_target, epochs=epoch)

    ''' 성능평가 '''
    score = model.evaluate(val_scaled, val_target)

    ''' 성능결과 반환하기 '''
    return score
''' 함수 호출하기 '''

''' 옵티마이저를 리스트로 정의하기 '''
optimizers = ["sgd", "adagrad", "rmsprop", "adam"]

''' 최고 정확도를 담을 변수 정의 '''
best_acc = 0.0
''' 최고 정확도일 때의 학습방법을 담을 변수 정의 '''
best_acc_opt = ""

''' 최저 손실율를 담을 변수 정의 '''
best_loss = 1.0
''' 최저 손실율일 때의 학습방법을 담을 변수 정의 '''
best_loss_opt = ""

''' 옵티마이저의 학습방법을 반복하여 성능 확인하기 '''
for opt in optimizers :
    print(f"--------------------------{opt}--------------------------")

    ''' 함수 호출 '''
    epoch=10
    rs_score = getBestEval(opt, epoch)

    ''' 가장 높은 정확도와 이 때 학습방법 저장하기 '''
    if best_acc < rs_score[1] :
        best_acc = rs_score[1]
        best_acc_opt = opt

    ''' 가장 낮은 손실율과 이때 학습방법 저장하기 '''
    if best_loss < rs_score[0] :
        best_loss = rs_score[0]
        best_loss_opt = opt

    print()

print('전체 실행 종료 >>>>>>>>>>>>>>>')
print(f"best_acc_opt : {best_acc_opt} / best_acc : {best_acc}")
print(f"best_loss_opt : {best_loss_opt} / best_loss : {best_loss}")

 

728x90
반응형
728x90
반응형

신경망계층 추가방법

 

라이브러리

import tensorflow as tf
from tensorflow import keras

import matplotlib.pyplot as plt
import numpy as np

from sklearn.model_selection import train_test_split

 

데이터 수집 및 정규화

📍 fashion_mnist 데이터를 이용해서 훈련 및 테스트에 대한 독립변수와 종속변수 읽어 들이기
       → 변수는 항상 사용하는 변수명으로 설정
📍 정규화하기
📍 훈련의 독립 및 종속변수를 이용해서 훈련 : 검증 = 8 : 2로 분류하기
  • 데이터수집
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
print(train_input.shape, train_target.shape)
print(test_input.shape, test_target.shape)

 

  • 데이터 스케일링
'''
255로 나누는 이유는 이미지 데이터가 보통 0에서 255 사이의 픽셀 값으로 구성되어 있기 때문이다.
각 픽셀의 값이 0일 때는 최소값, 255일 때는 최대값이므로,
이 값을 0에서 1 사이의 범위로 매핑하기 위해 255로 나누어준다.
이렇게 하면 모든 픽셀 값이 0에서 1 사이의 실수 값으로 정규화된다.
'''
train_scaled_255 = train_input / 255.0
train_scaled_255[0]

test_scaled_255 = test_input / 255.0
test_scaled_255[0]

train_scaled_255.shape, test_scaled_255.shape

 

  • 모델 훈련에 사용하기 위해 2차원으로 변환
train_scaled_2d = train_scaled_255.reshape(-1, 28*28)
test_scaled_2d = test_scaled_255.reshape(-1, 28*28)

 

  • 훈련 : 검증 데이터로 분류하기(8:2)
train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled_2d,
                                                                      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)

 

신경망 모델에 계층(layer) 추가하는 방법 3가지

1. 층을 먼저 만들고, 신경망 모델 생성 시 추가하기

''' 입력계층(Input layer) 생성하기 '''
dense1 = keras.layers.Dense(100, activation="sigmoid", input_shape=(784,))

''' 출력계층(Output layer) 생성하기 '''
dense2 = keras.layers.Dense(10, activation="softmax")

''' 신경망 모델 생성하기 '''
### 여러개를 넣어야 할 때 리스트[] 사용
model = keras.Sequential([dense1, dense2])
model​
''' 입력계층(Input layer) 생성하기 '''
dense1 = keras.layers.Dense(100, activation="sigmoid", input_shape=(784,))

''' 출력계층(Output layer) 생성하기 '''
dense2 = keras.layers.Dense(10, activation="softmax")

''' 신경망 모델 생성하기 '''
### 여러개를 넣어야 할 때 리스트[] 사용
model = keras.Sequential([dense1, dense2])
model
''' 모델 계층 확인하기 '''
model.summary()

 

- Output Shape로 100개를 출력해냄
- 다음 계층(dense_1)이 100개를 입력 계층으로 받음
- 그리고 다시 시그모이드 함수를 이용해 10개로 출력해냄
- dense_1에서 훈련에 관여하고 있는 계층 78500개
- param이 0 이면 훈련에 영향을 미치고 있는 계층이 없다.

 

2. 신경망모델 생성 시 계층(layer)을 함께 추가

''' 모델 생성 및 계층 추가하기 '''
model = keras.Sequential([
    keras.layers.Dense(100, activation="sigmoid",
                       input_shape=(784,), name = "Input-layer"),
                      keras.layers.Dense(10, activation="softmax", name = "Output-layer")],
                         name = "Model-2"
)
model.summary()

 

3. 신경망 모델을 먼저 생성 후, 계층 추가하기

''' 신경망 모델 생성하기
    - 일반적으로 사용되는 방식
    - 위의 1, 2 방법으로 수행 후, 계층을 추가할 필요성이 있을 경우에도 사용됨'''
model = keras.Sequential()

''' 계층 생성 및 모델에 추가하기 '''
model.add(
    keras.layers.Dense(100, activation="sigmoid", input_shape(784,), name="Input-Layer")
)
model.add(
    keras.layers.Dense(10, activation="softmax", name="Output-Layer")
)
model.summary()

모델 설정하기(compile)

''' 손실함수는 다중분류 사용 '''
model.compile(
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

 

모델 훈련하기(fit)

''' 반복횟수 10번 '''
model.fit(train_scaled, train_target, epochs=10)

 

- 마지막에 가장 높은 값이 나오면 epochs를 증가시켜야 한다. 더 높은 정확도가 나올 수 있기 때문이다.

- 기본적으로 100번 정도 실행한다.
- 실행 중간에 가장 높은 값이 나오면 epochs는 그 시점의 횟수가 한계이므로 해당 횟수까지만 돌리면 된다.

 

 

 

 

 

모델 성능 평가하기(evaluate)

''' 성능평가하기(검증) '''
score = model.evaluate(val_scaled, val_target)

''' 손실율과 정확도 출력하기 '''
print(f"손실율 : {score[0]} / 정확도 : {score[1]}")

 훈련 모델과 검증 모델을 비교해 봤을 때 정확도가 높은 편은 아니지만, 

과소/과대에 해당하지 않고 일반화된 모델이라고 볼 수 있다.


신경망계층 성능향상방법

<성능 개선 방법>
 1. 데이터 증가 시키기
 2. 하이퍼파라미터 튜닝
    → 성능이 현저히 낮은 경우에는 튜닝 필요, 일반적으로 딥러닝에서는 디폴트 값을 사용해도 된다.
    → 반복 횟수 증가
    → 계층 추가 또는 제거(일반적으로 추가)
    → 이외 하이퍼파라미터들

 

1. 성능향상 - 은닉 계층(Hidden Layer) 추가

  • 모델 생성하기
model = keras.Sequential()​
  • 입력 계층 추가하기
    - 전처리 계층으로 추가

    - Flatten()
         → 차원축소 전처리 계층(1차원으로 축소)
         → 훈련에 영향을 미치지는 않음
         → 일반적으로 입력계층 다음에 추가하거나 입력계층으로 사용되기도 함
         → 이미지 데이터 처리 시에 주로 사용됨
model.add(
    keras.layers.Flatten(input_shape=(28, 28))
)
  • 중간계층 = 은닉계층(hidden layer) 생성하기
    - Dense() 계층은 모델 성능에 영향을 미침

    - relu : 0보다 크면 1, 0보다 작으면 0
model.add(
    keras.layers.Dense(100, activation="relu")
)
  • 출력 계층(Output Layer) 생성하기
model.add(
    keras.layers.Dense(10, activation="softmax")
)
  • 모델에 추가된 계층 모두 확인하기
model.summary()

  • 모델 설정하기(compile)
''' 손실함수는 다중분류 사용 '''
model.compile(
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

 

 

차원축소하지 않은 정규화된 데이터로 다시 생성 

  • 데이터 불러오기
(train_input, train_target), (test_input, test_target) = keras.datasets.fashion_mnist.load_data()
print(train_input.shape, train_target.shape)
print(test_input.shape, test_target.shape)
  • 데이터 정규화
train_scaled_255 = train_input / 255.0
train_scaled_255[0]

test_scaled_255 = test_input / 255.0
test_scaled_255[0]

train_scaled_255.shape, test_scaled_255.shape
  • 훈련 : 검증 데이터로 분류
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_255.shape, test_target.shape)
  • 모델 훈련하기(fit)
model.fit(train_scaled, train_target, epochs=100)

  • 모델 성능 평가하기(evaluate)   
''' 성능평가하기(검증) '''
score = model.evaluate(val_scaled, val_target)

''' 손실율과 정확도 출력하기 '''
print(f"손실율 : {score[0]} / 정확도 : {score[1]}")

 

2. 성능향상 - 옵티마이저(Optimizer)

  • 모델 설정하기(compile)
  • 옵티마이저(Optimizer)
     옵티마이저 설정 위치 : compile() 시에 설정함
     손실을 줄여나가기 위한 방법을 설정함
     손실을 줄여나가는 방법을 보통 "경사하강법"이라고 칭한다.
     "경사하강법"을 이용한 여러 가지 방법들 중 하나를 선택하는 것이 옵티마이저 선택이다.
     옵티마이저 종류 : SGD(확률적 경사하강법), Adagrad, RMSProp, Adam이 있음
📍 SDG(확률적 경사하강법)
- 현재 위치에서 기울어진 방향을 찾을 때 지그재그 모양으로 탐색해 나가는 방법

📍  Adagrad

- 학습률(보폭)을 적절하게 설정하기 위해 학습율 감소라는 기술을 사용
- 학습 진행 중에 학습률을 줄여가는 방법을 사용
- 처음에는 학습율을 크게 학습하다가, 점점 작게 학습한다는 의미
- 기울기가 유연함


📍 RMSProp
- Adagrad의 단점을 보완한 방법
- Adagrad는 학습량을 점점 작게 학습하기 때문에 학습량이 0이 되어 갱신(학습)되지 않는 시점이 발생할 수 있는 단점이 있음
- 이러한 단점을 보완하여 과거의 기울기 값을 반영하는 방식 사용
- 먼 과거의 기울기(경사) 값은 조금 반영하고, 최근 기울기(경사)를 많이 반영
- Optimizer의 기본값(default)으로 사용됨

📍 Adam
- 공이 굴러가듯이 모멘텀(momentum  관성)과 Adagrad를 융합한 방법
     ** 모멘텀 : 관성과 가속도를 적용하여 이동하던 방향으로 좀 더 유연하게 작동함
- 자주 사용되는 기법으로, 좋은 결과를 얻을 수 있는 방법으로 유명함 
- 메모리 사용이 많은 단점이 있음(과거 데이터를 저장해 놓음)

어떤 걸 써야 하는지 정해져 있지 않음
가장 좋은 건 모멘텀을 적용한 adam
sgd는 가장 초기에 나왔기 때문에 많이 사용하기 않음.
기본값인 RMSProp을 사용하고 adam사용.
하이퍼파라미터 튜닝을 한다면 모두 다 사용해 보는 것을 추천

model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer="sgd",
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

 

  • 모델 훈련하기(fit)
model.fit(train_scaled, train_target, epochs=10)

  • 모델 성능 평가하기(evaluate)   
''' 성능평가하기(검증) '''
score = model.evaluate(val_scaled, val_target)

''' 손실율과 정확도 출력하기 '''
print(f"손실율 : {score[0]} / 정확도 : {score[1]}")

 

옵티마이저에 학습률 적용하기 

  • 학습률을 적용하는 방법
    - 사용되는 4개의 옵티마이저를 객체로 생성하여 learning_rate(학습률) 값을 설정할 수 있음
    - 학습률 : 보폭이라고 생각하면 됨
    - 학습률이 작을수록 보폭이 작다고 보면 됨
    - 가장 손실이 적은 위치를 찾아서 움직이게 됨
    - 이때 가장 손실이 적은 위치는 모델이 스스로 찾아서 움직이게 됨(사람이 관여하지 않음)
    - 학습률의 기본값은 = 0.01을 사용(사용값의 범위 0.1 ~ 0.0001 정도)

  • 과적합을 해소하기 위한 튜닝방법으로 사용됨
    - 과대적합이 일어난 경우 : 학습률을 크게
    - 과소적합이 일어난 경우 : 학습률을 작게
    - 과대/과소를 떠나서, 직접 값의 법위를 적용하여 튜닝을 수행한 후 가장 일반화 시점의 학습률 값을 찾는 것이 중요함

  • 옵티마이저 객체 생성 및 모델 설정
''' 옵티마이저 객체 생성 '''
sgd = keras.optimizers.SGD(learning_rate=0.1)

''' 모델 설정(compile) '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer="sgd",
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)
  • 모델 훈련하기
model.fit(train_scaled, train_target, epochs=50)

  • 모델 성능 평가하기(evaluate)  
''' 성능평가하기(검증) '''
score = model.evaluate(val_scaled, val_target)

''' 손실율과 정확도 출력하기 '''
print(f"손실율 : {score[0]} / 정확도 : {score[1]}")

 

모멘텀(Momentum) 직접 적용하기 

  • 모멘텀(Momentum)
     - 기존의 방향(기울기)을 적용하여 관성을 적용시키는 방법
     - 기본적으로 0.9 이상의 값을 적용시킴
     - 보통 nesterov=True 속성과 함께 사용됨
        → nesterov=True : 모멘텀 방향보다 조금 더 앞서서 경사를 계산하는 방식(미리 체크)
    -  momentum 속성을 사용할 수 있는 옵티마이저 : SGD, RMSProp
''' 옵티마이저 객체 생성 '''
sgd = keras.optimizers.SGD(
    momentum=0.9,
    nesterov=True,
    learning_rate=0.1
)

''' 모델 설정(compile) '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer="sgd",
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)
  • 모델 훈련하기
model.fit(train_scaled, train_target, epochs=50)

  • 모델 성능 평가하기(evaluate)  
''' 성능평가하기(검증) '''
score = model.evaluate(val_scaled, val_target)

''' 손실율과 정확도 출력하기 '''
print(f"손실율 : {score[0]} / 정확도 : {score[1]}")

 

adagrad 

''' adagrad '''
adagrad = keras.optimizers.Adagrad()

''' 모델 설정(compile) '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer=adagrad,
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

''' 또는 '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer="adagrad",
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

 

RMSprod 

''' RMSProd '''
rmsprop = keras.optimizers.RMSprop()

''' 모델 설정(compile) '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer=rmsprop,
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

''' 또는 '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer="rmsprop",
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

Adam  

''' Adam '''
adam = keras.optimizers.Adam()

''' 모델 설정(compile) '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer=adam,
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

''' 또는 '''
model.compile(
    ### 옵티마이저 정의 : 손실을 줄여나가는 방법
    optimizer="adam",
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

 

 

실습

 

https://mzero.tistory.com/127

 

[인공지능][DL] Deep Learning 실습 - 신경망계층 추가방법 및 성능향상방법

실습 - 1 1. 신경망 모델 생성 2. 계층 추가하기 - 1차원 전처리 계층 추가 - 은닉계층 추가, 활성화함수 relu 사용, 출력크기 100개 - 최종 출력계층 추가 3. 모델설정하기 - 옵티마이저는 adam 사용, 학

mzero.tistory.com

 

728x90
반응형
728x90
반응형

DL 시작 전 가상환경 새로 생성하기

1. conda 업데이트
          > conda update -n base conda

2. pip 업데이트
          > python -m pip install --upgrade pip

3. 가상환경 생성하기
          > conda create -n gj_env_ python=3.9
4. 가상환경으로 들어가기(활성화시키기)

          > conda activate gj_env_dl
5. 외부 에디터에서 가상환경 연결(kernel) 하기 위하여 jupyter 설치하기
          > pip install jupyter notebook
6. 커널 생성하기 (base root 가상환경에서 진행)
          > python -m ipykernel install --user --name gj_env_dl --display-name gj_env_dl_kernel
7. 커널 생성 목록 확인하기
          > jupyter kernelspec list
8. 기본 패키지 설치하기( gj_env_dl에서 진행)
          > pip install ipython jupyter matplotlib pandas xlrd seaborn scikit-learn
          > pip install openpyxl
          > pip install folium (지도 시각화)
          > pip install plotly (시각화)
          > pip install xgboost (머신러닝 앙상블 분류모델)
          > pip install nltk (자연어처리)
          > pip install wordcloud
          > pip install JPype1
          > pip install konlpy (/anaconda3/envs/gj_env_dl/Lib/site-packages/konlpy/jvm.py에서 별(*) 표시 삭제)
9. 딥러닝 - 텐서플로우 설치하기( 텐서플로우  설치 후 numpy 설치하면 충돌 난다. 텐서플로우의 numpy가 따로 있다.)
          > pip install tensorflow==2.8.2
10. 딥러닝 - 모델 시각화 라이브러리
          > conda install -c conda-forge pydot graphviz

 

Tensorflow 정상적으로 설치되었는지 확인

> python
>>> from tensorflow import keras
>>> from tensorflow.keras.layers import Dense
>>> dns = keras.Sequential()

>>> dns.add(Dense(units=1, input_shape(1,)))
>>> dns.compile(optimizer="sgd", loss="mse")
>>> dns.summary()

 

인공신경망 훈련 모델 맛보기

🏓라이브러리 불러오기

import tensorflow as tf
from tensorflow import keras

import matplotlib.pyplot as plt
import numpy as np

from sklearn.model_selection import train_test_split

 

🏓랜덤 고정값 설정

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

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

 

데이터 수집

'''
- keras에서 제공해주는 이미지 데이터셋 사용
- MNIST 패션 이미지
- 이미지 데이터는 픽셀 데이터로 이루어져 있다.
'''
# 튜플(독립변수 종속변수) 안에 튜플(훈련데이터, 테스트데이터) 안에 array
(train_input, train_target), (test_train, test_target) = keras.datasets.fashion_mnist.load_data()
print(train_input.shape, train_target.shape)
print(test_train.shape, test_target.shape)

''' 이미지 1개에 대한 데이터 추출
    - 각 데이터는 픽셀값(색상값)
    - 픽셀값(색상값)은 0 ~ 255 (총 256개의 값드로 구성되어 있음)
'''
train_input[0]

 

훈련데이터 10개만 이용해서 데이터를 이미지로 시각화하기

''' 서브플롯 사용 : 이미지 10개를 하나로 시각화 '''
fig, axs = plt.subplots(1, 10, figsize=(10, 10))

''' 훈련데이터 10개에 대한 처리 '''
for i in range(10) : 
    ''' 픽셀데이터를 이미지로 시각화 : imshow() '''
    axs[i].imshow(train_input[i], cmap="gray_r")

    ''' x, y 좌표계 숨기기 '''
    axs[i].axis("off")
plt.show()

''' 종속변수 10개 추출해서 매핑된 값 확인해보기 '''
train_target[:10]

''' 종속변수의 범주값 확인하기 '''
np.unique(train_target, return_counts=True)

 

데이터 스케일링

  • 사용되는 데이터의 특성상 0부터 255까지의 값을 가지고 있음
  • 값의 범위 폭이 크기 때문에 일반화(데이터 스케일링)하여 사용
  • 데이터 스케일링을 수행하는 방법으로 라이브러리를 사용해도 되며, 값의 최댓값을 이용해서 산술 연산을 이용해 데이터 스케일링해도 된다.
  • 데이터 스케일링 수행하기
train_scaled_255 = train_input / 255.0
train_scaled_255[0]

test_scaled_255 = test_input / 255.0
test_scaled_255[0]

train_scaled_255.shape, test_scaled_255.shape

  • 모델 훈련에 사용하기 위해서는 2차원으로 변환 필요
train_scaled_2d = train_scaled_255.reshape(-1, 28*28)
train_scaled_2d.shape

 

훈련 : 검증 데이터로 분리 (8:2)

train_scaled, val_scaled, train_target, val_target = train_test_split(train_scaled_2d,
                                                                      train_target,
                                                                      test_size=0.2,
                                                                      random_state=42)
print(train_scaled.shape, train_target.shape)
print(val_scaled.shape, val_target.shape)

 

인공신경망 모델 훈련시키기 위한 단계

🏓 딥러닝은 계층 구조의 모델로 구성됨

🏓 2. 인공신경망 계층(layer) 생성하기

  • Dense
    → 딥러닝에서 가장 기본적인 계층
    → 모델에 넣어서 훈련을 수행하게 된다.

  • 딥러닝에서 사용하는 용어
    → 특성 : 뉴런이라고도 칭한다.
    → 크기 : 갯수를 의미한다.

  • 딥러닝에서 사용되는 숫자들의 범위
    →  일반적으로 딥러닝에서는 숫자의 범위를 16 ~ 512 또는 32 ~ 512로 사용한다.
    →  높이와 너비를 나타내는 숫자가 있는 경우에는 3x3 또는 5x5를 주로 사용한다.

  • 모델에는 여러개의 계층(layer)이 사용될 수 있다.
    • 첫번째 계층
      → 입력 계층(Input layer)이라고 칭한다.
      → 입력 계층에는 input_shape()가 정의된다.
      → input_shape()에는 독립변수의 열갯수를 정의한다
      → 모델에서 한개의 계층만 사용되는 경우에는 입력 계층이 곧, 출력 계층의 역할까지 수행한다.
                  >> 이 경우에는 출력 크기는 종속변수의 범주 갯수를 정의한다.
                        
    • 중간 계층
      → 은닉 계층(Hidden layer)이라고 칭한다.
      → 은닉 계층은 여러개 사용된다.
      → 은닉 계층의 출력 크기(갯수)는 일정하지 않다.
      → 출력 크기(갯수)는 사람이 정한다.
      출력 크기(갯수)는 다음 은닉계층이 입력 크기(갯수)로 받아서 훈련을 이어가는 방식이다.

    • 마지막 계층
      → 출력 계층(Output layer)이라고 칭한다.
      → 출력 계층에 사용되는 출력 크기는 종속변수의 범주 갯수를 정의한다.
  • units : 특정 계층에서의 출력의 크기(갯수), 결과갯수
    →  딥러닝 모델에는 계층이 여러개 사용될 수 있으며, 마지막 계층에는 units의 갯수는 종속변수 범주의 갯수를 사용한다.
    →  중간에 사용되는 계층을 은닉계층(hidden layer)이라고 칭하며, 중간에 사용되는 계층 간에는 출력 크기를 넘겨받아서 사용된다.
    →  중간 계층의 출력 크기에 따라서 성능에 영향을 미칠 수도 있기 때문에 하이퍼파라미터 튜닝을 진행하는 경우도 있다.
    →  하이퍼파라미터 튜닝은 값을 바꾸면서 여러번 시도하는 방식을 따른다.
        
  • kernel_initializer : 가중치를 초기화하는 방법을 지정
    →  가중치 : 손실을 최소화하기 위해서 모델이 훈련을 반복하는 과정에서 스스로 조정하는 값을 의미함
    →  가중치 초기화 방법 : uniform, normal 방법이 있음
         * uniform : 균일 분포 방법
         * normal : 가우시안 분포(정규 분포) 방법
  • activation : 활성화 함수라고 칭한다.
    →  훈련 시 입력된 특성(뉴런)의 크기를 어떤 형태의 크기로 변환할지를 결정하는 방법 정의
    →  출력계층(Output Layer)에는 해당 종속변수의 특성에 따라 결정됨
             >> 선형형태인 회귀분석의 경우 linear 사용
             >> 범주형태의 분류분석인 경우 Sigmoid, Softmax, ReLU, Tanh, Leaky ReLU 등 사용
                               > 이진분류 : Sigmoid, ReLU, Tanh, Leaky ReLU
                               > 다중분류 : Softmax
    →  입력계층 또는 은닉계층에는 Sigmoid, Softmax, ReLU, Tanh, Leaky ReLU 등이 사용됨

dense = keras.layers.Dense(units=10,
                           kernel_initializer="uniform",
                          activation="softmax",
                          input_shape=(784, )
                          )
dense

🏓 1. 인공신경망 모델 생성하기

model = keras.Sequential(dense)
model

🏓 3 . 모델 설정 단계

  • loss
    → 손실을 줄이기 위해 사용되는 함수 정의
    → 손실함수에는 categorical_crossentropy, binary_crossentropy, sparse_categorical_crossentropy 가 있음
    • categorical_crossentropy : 다중분류 손실함수
      종속변수의 데이터 값이 원-핫인코딩된 형태로 되어있는 경우 사용
      예시 데이터 : [[0, 1, 0], [0, 0, 1], [0, 1, 0], ...]
    • sparse_categorical_crossentropy : 다중분류 손실함수
      종속변수의 데이터 값이 숫자값으로 3개 이상으로 되어있는 경우 사용
      예시 데이터 : [0, 1, 2, 3, 4, ... ]
    • binary_crossentropy : 이진분류 손실함수
      종속변수의 데이터 값이 숫자값으로 2개 정의되어 있는 경우
      예시 데이터 : [0, 1, 1, 0, 0, 1, ... ]
model.compile(
    ### 손실함수 : 종속변수의 형태에 따라 결정 됨
    loss="sparse_categorical_crossentropy",
    ### 훈련 시 출력할 값 : 정확도 출력
    metrics="accuracy"
)

 

 

💡categorical_crossentropy와 관련한 원-핫 인코딩 예제

import numpy as np
from tensorflow.keras.utils import to_categorical

### 임의 데이터 생성
# - randint() : 랜덤하게 정수값을 생성하는 함수
#   --> 첫번째 인자 : 범주의 범위(0~2까지로 3개의 범주를 의미함)
#   --> 두번째 인자 : 몇 개의 랜덤한 범주값을 만들지에 대한 값(10개 생성)
labels = np.random.randint(3, size=(10,))
labels

### 원-핫 인코딩(One-Hot Encoding) 하기
# - to_categorical() : 각각의 값을 범주의 갯수만큼의 리스트로 데이터 생성
#                   : 리스트 내 데이터에서 1이 있는 곳의 인덱스 위치값은 실제 labels의 값과 동일
# - num_classes : unique한 범주의 갯수 정의
one_hot_labels = to_categorical(labels, num_classes=3)
labels, one_hot_labels.shape, one_hot_labels

🏓 4. 모델 훈련시키기

''' epochs : 훈련 반복 횟수(손실함수의 손실률을 계속 줄여나가면서 반복함) ''' 
# model.fit(train_scaled, train_target, epochs=100)
# 정확도가 거의 유사하다면 손실률이 작은 것을 선택한다.
# 91번 loss: 0.4116 - accuracy: 0.8772 와 98번 loss: 0.4140 - accuracy: 0.8774를 비교했을 때 91번 선택
model.fit(train_scaled, train_target, epochs=91)

🏓 5. 모델 성능 검증하기

score = model.evaluate(val_scaled, val_target)
score

 

인공신경망 모델 훈련 순서

  1. 모델 생성 (또는 계층 생성)
  2. 계층 생성 (또는 모델 생성)
  3. 모델 설정 (compile)
  4. 모델 훈련 시키기(fit)
  5. 성능평가(검증, evaluate)

성능 개선 방법

  • 데이터 증가 시키기
  • 하이퍼파라미터 튜닝(일반적으로 딥러닝에서는 디폴트 값을 사용해도 됨)
    성능이 현저히 낮은 경우에는 튜닝 필요
  • 계층을 추가 또는 제거

모델에서 사용한 계층 확인하기

''' 
 - Output Shape() : 출력 크기 (10개 출력) 
 - Param : 계층이 훈련 중에 사용한 총 특성의 갯수
     -> Dense() 계층 계산공식 = (입력크기 + 1) * 출력크기
                             = (784 + 1) * 10 = 7850
'''
model.summary()
# dense계층에서 훈련시킴

은닉계층(Hidden Layer) 추가하기

model.add(
    keras.layers.Dense(
        10,
        kernel_initializer="uniform",
        activation="relu",
        input_shape=(784, )
    )
)
# 훈련
model.fit(train_scaled, train_target, epochs=50)
# 검증
model.evaluate(val_scaled, val_target)
model.summary()

 

첫 dense에서 나온 출력 값 10이 그대로 dense_2로 이 입력값으로 들어감.

dense_2의 Param이 110인 이유?

(10+ 1) * 10 = 110

 

728x90
반응형

+ Recent posts