[AI] MLP(Multi Layer Perceptron) : Keras

Ik·2022년 7월 25일
0

Data

목록 보기
15/34

Keras

process

  1. 훈련 데이터(입력 텐서, 출력 텐서) 정의
import numpy as np
import tensorflow as tf   # 별칭: tf
from tensorflow.keras import layers   # Layer 클래스들을 제공하는 모듈
from tensorflow import keras
# keras 내부 dataset 사용
(train_image, train_label), (test_image, test_label) = keras.datasets.mnist.load_data()
# data set의 형태, (data 갯수, height, width) 
  1. Layer로 이루어진 네트워크 구조 정의
    • Sequential 방식: 순서대로 쌓아올린 네트워크로 이뤄진 모델을 생성하는 방식
    • Functional API 방식: 다양한 구조의 네트워크로 이뤄진 모델을 생성하는 방식
    • Subclass 방식: 네트워크를 정의하는 클래스를 구현
    • 구조 정의하면서 activation 함수도 정의
      • unit마다 가중치 연산 이후 activation 함수 이용 후에 출력되기 때문에 이 때 정의
     model = keras.Sequential()  # Sequential(순차) 방식으로 모델 생성
     # input Layer
     model.add(keras.layers.InputLayer((28,28)))  # model.add(레이어 객체)
     # hidden Layer
     model.add(keras.layers.Flatten())   # 큰 의미 X, 밑에 layer들이 중요
     model.add(keras.layers.Dense(256, activation='relu'))   # unit 256개
     model.add(keras.layers.Dense(128, activation='relu'))   # unit 128개
     # 여기서 unit = hidden layer의 node수
     # 3. Output Layer 추가, 출력하고자 하는 결과 형태에 따라 unit 수 정함
     model.add(keras.layers.Dense(10, activation='softmax'))
     # 모델 구조 확인
     model.summary()  # Output Shape = (데이터의 개수, 1차원 배열 개수)
     # ex) (None, 784), data 1개당 783개인 1차원 배열로 구성
  2. 모델 Compile(컴파일, 학습할 수 있는 상태로 만들어주는 작업)
    • 모델 학습에 필요한 손실함수(Loss Function), 최적화기법(Optimizer, parameter update), 학습과정을 모니터링할 평가지표(Metrics) 선정
    model.compile(optimizer='adam',     # 최적화 함수, 여긴 adam이라는 알고리즘 사용, 웬만하면 adam 사용
                   loss='categorical_crossentropy',    # loss함수 : cross-entropy
                   metrics=['accuracy'])      # 추가 평가지표 - 정확도
    • 선정한 평가지표를 기준으로 평가 기준에 따라 Data 전처리
    # one hot encdoing
    y_train = keras.utils.to_categorical(train_label)
    • 원활한 학습 위해 Data 전철
    # Feature scaling
    X_train = train_image.astype(np.float32)
    X_train /= 255.0 
  3. 학습, 훈련
    • 학습 데이터를 이용해 모델 학습
    hist = model.fit(X_train, y_train,     # input, output data
                      epochs=10,           # 전체 Train dataset을 몇번 반복해서 학습시킬지 정의, 1번 학습 = 1 epochs
                      batch_size=100,      # Train dataset을 학습시키는 단위로 한번에 지정한 개수(100)씩 끊어서 학습
                      					   # 100개 학습하고 검증, parameter 수정, 100개 학습, 검증, 수정 반복 
                                            # 여기서 한번 학습, 검증 수정하는 과정을 1 step이라 한다
                      validation_split=0.3
                     )
    # hist에 history에 손실 함수 결과, 평가지표 결과 모두 저장된다
      # hist.history['loss'], hist.history['val_loss']
      # hist.history['accuracy'], hist.history['val_accuracy']
  • 모델 그래프 시각화
from tensorflow.keras.utils import plot_model
# to_file : 이용해 파일로 저장하면서 model의 형태 간략하게 볼 수 있다
plot_model(model, to_file='model_shapes.png', show_shapes=True)
  1. 평가
  • test data set으로 평가
test_loss, test_acc = model.evaluate(X_test, y_test)
  • 새로운 데이터 추론
predict(예측할 data의 feature) # 이용해 추론
# ex)
result = model.predict(new_image)

참고

  • 밑에 과정들 Tensorflow 2.4 이후 버전의 경우

Regression(회귀)

  • boston dataset 이용
    • imort
    import numpy as np
    import tensorflow as tf
    from tensorflow import keras
    from tensorflow.keras import layers
    • Data load
    # data load
    (train_X, train_y), (test_X, test_y) = keras.datasets.boston_housing.load_data()
    • hyperparameter 및 변수 선언
      • 한곳에 몰아서 선언하는 것이 좋다
    # hyperparameter
    LEARNING_RATE = 0.001       # 학습률
    N_EPOCHS  = 200             # epoch수 : train dataset 몇번 학습할지 횟수
    N_BATCHS = 32               # batch size : 1 step당 몇개의 data를 학습할지(2의 거듭제곱한 값)
    # 사용할 변수를 미리 선언, 하이퍼파라미터 X
    N_TRAIN = train_X.shape[0]    # train data의 개수
    N_TEST = test_X.shape[0]      # test data의 개수
    • Data 전처리
      • MLP는 선형모델을 기반으로 하므로 Feature Scaling
      from sklearn.preprocessing import StandardScaler
      scaler = StandardScaler()
      X_train = scaler.fit_transform(train_X)
      X_test = scaler.transform(test_X)
    • Data set 생성
      • val dataset 생략
    # shuffle(N_TRAIN) : 입력 데이터의 개수를 입력했으므로 완전 셔플
    # batch : remainder = True, 매번 같은 갯수로 학습하기 위해 
    train_dataset = tf.data.Dataset.from_tensor_slices((X_train, train_y))\
                                  .shuffle(N_TRAIN)\    
                                  .batch(N_BATCHS, drop_remainder=True)   
     # test set의 경우 굳이 섞을 필요 X                             
     test_dataset = tf.data.Dataset.from_tensor_slices((X_test, test_y)).batch(N_BATCHS)
    • 모델 구현
      • 모델 구조 함수
      def create_housing_model():
        model = keras.Sequential()
       # input layer 설정 2가지(여기서는 후자 사용)
        # 1. input layer를 별도로 지정 - model.add(Layers.InputLayer((13,))) InputLayer 생성 => Feature shape 을 지정
        # 2. 첫번째 hidden layer추가하면서 input_shape 속성에 Feature에 shape을 지정
        # hidden layer 추가
        # DenseLayer : units = unit의 개수
        # DenseLayer의 unit수는 점점 개수를 줄여나간다(관례적으로)
        model.add(layers.Dense(units=128, activation='relu', input_shape=(13,)))  # 위에 설정 2번으로 input + hidden 경우라 보면된다
        model.add(layers.Dense(units=64, activation='relu'))
        model.add(layers.Dense(units=32, activation='relu'))
        model.add(layers.Dense(units=16, activation='relu'))
        # output layer 추가
        # 회귀문제에 대한 output layer - units : 추론한 결과값(정답)에 개수에 맞춘다 - 집값 1개 = unit 1개, activation = None : 지정하지않음  
        model.add(layers.Dense(units=1))
        return model
      • 모델 생성 및 컴파일
      # 모델 생성
      model = create_housing_model()
      # 모델 컴파일
      model.compile(optimizer=keras.optimizers.Adam(learning_rate=LEARNING_RATE), loss='mse')
      # 모델 구조 확인
      model.summary()
    • 모델 학습
    hist = model.fit(train_dataset,      # train dataset(tf.data - batch+shuffle) - (X,y)
                   epochs=N_EPOCHS,    # epoch 수 
                   validation_data=test_dataset)   # validation dataset(tf.data) 제공 (X,y)
                                                      # val set 없는 경우 train set으로만 loss 측정
    # Dataset을 이용해서 학습할 경우 validation_split을 사용할 수 없다    
    # hist.history에 loss, val_loss 기록
    • 모델 평가
    loss = model.evaluate(test_dataset)
    print(loss, np.sqrt(loss))
    • 모델 추론(새로운 데이터 이용)
    pred = housing_model.predict(new_data)
    • 모델 저장
    model.save('models/boston_hosing_model')
    • 모델 불러오기
    housing_model = keras.models.load_model('models/boston_hosing_model')
    # 파일로 저장된 모델 불러옴

Classification(분류)

Multi-Class Classification(다중분류)

  • Fashion MNIST Dataset 이용
  • Data load 및 분리
    import numpy as np
    import tensorflow as tf
    from tensorflow import keras
    from tensorflow.keras import layers
    (train_image, train_label), (test_image, test_label) = keras.datasets.fashion_mnist.load_data()
  • val data set 분리
    from sklearn.model_selection import train_test_split
    train_image, val_image, train_label, val_label = train_test_split(train_image, train_label, test_size=0.2, stratify=train_label, random_state=0)
  • hyperparameter 정의
    LEARNING_RATE = 0.001
    N_EPOCHS = 20
    N_BATCHS = 100
    # 각 데이터셋의 데이터 개수를 변수에 저장
    N_TRAIN = train_image.shape[0]
    N_VAL = val_image.shape[0]
    N_TEST = test_image.shape[0]
  • Data encoding
    • label이 10개인 Data이므로 각 class별로 확률을 출력하도록 구현하기 위해 ohe실시
    y_train = keras.utils.to_categorical(train_label)
    y_val = keras.utils.to_categorical(val_label)
    y_test = keras.utils.to_categorical(test_label)
  • Data scaling
    • map보다는 직접 나누는게 효율적
    # 방법 1, 밑에처럼 직접 나눔
    X_train = train_image.astype(np.float32) # /255
    X_val = val_image.astype(np.float32)
    X_test = test_image.astype(np.float32)
    # 방법2, map 함수 사용
    train_dataset = tf.data.Dataset.from_tensor_slices((X_train, y_train))\
                                 .map(lambda x, y : (x/255, y))\
                                 .shuffle(N_TRAIN)\
                                 .batch(N_BATCHS, drop_remainder=True)
    # 검증과 test의 경우 shuffle 필요 X
    val_dataset = tf.data.Dataset.from_tensor_slices((X_val, y_val)).map(lambda x, y:(x/255, y)).batch(N_BATCHS)
    test_dataset = tf.data.Dataset.from_tensor_slices((X_test, y_test)).map(lambda x, y:(x/255, y)).batch(N_BATCHS)
  • 모델 함수 정의
    def create_fashionmnist_model():
      model = keras.Sequential()
      # Hidden Layer
      # 1. Flatten + input_shape을 지정해서 InputLayer를 추가
          # model.add(Layers.InputLayer((28,28))) 밑에 Flatten 사용 함수와는 다른 방법
      model.add(layers.Flatten(input_shape=(28,28)))      # 입력데이터의 shape이 다차원 배열인 경우 1차원 배열로 변환
                                                          # (28,28) ==> (744), DenseLayer의 입력은 1차원이여야기에 
                                                          # 다차원배열형태로 들어간 경우 내적을 할 때 데이터가 분산(행별로 unit에 들어감)되서 학습되는 경우 발생 
                                                              # 하나의 입력이 여러 개의 입력으로 취급되어 여러 출력이 나와버리는 상황 발생(하나의 입력이 들어가고 하나의 출력이 나와야됨)  
      model.add(layers.Dense(units=256, activation='relu'))
      model.add(layers.Dense(units=128, activation='relu'))
      model.add(layers.Dense(units=64, activation='relu'))
      # output layer : 다중분류, unit 수 = class 개수(여기서는 class 10개이므로), 각 unit이 class별 확률 출력, activation 함수 : softmax 
      model.add(layers.Dense(units=10, activation='softmax'))
      return model
  • 모델 생성 및 컴파일 확인
    model = create_fashionmnist_model()
    # 컴파일
    # 다중분류 : Loss = categorical_crossentropy(log loss)
    model.compile(optimizer=keras.optimizers.Adam(learning_rate=LEARNING_RATE), 
                loss='categorical_crossentropy',
                metrics=['accuracy'])   # 평가지표 : accuracy 추가(loss와 accuracy 두개를 검증/평가지표로 확인)  
    # 모델 확인
    model.summary()
  • 모델 학습 및 평가
    # 학습
    hist = model.fit(train_dataset,
                   epochs=N_EPOCHS,
                   validation_data=val_dataset)
    # 평가
    loss, accuracy = model.evaluate(test_dataset)
  • 새로운 데이터 적용
    • class가 10개인 경우의 분류이므로 모델 평가 결과를 10개의 class를 ndarray로 저장했던 형태의 index와 매칭시켜 출력해야한다

Binary Classification(이진분류)

  • 위스콘신 유방암 데이터셋 이용
  • 다중 분류와의 차이점은 출력을 1개에 대한 경우로 할지 여러 개의 경우로 할지
    • output layer의 activation function softmax, sigmoid 차이
    • model loss 측정 categorical_corossentropy, binary_crossentropy 차이
  • 두가지 방법
    • pos일 확률을 출력
    • pos와 neg일 확률 모두 출력, 다중 분류 처리방식으로 해결해야한다

0개의 댓글