ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TensorFlow 기초 24 - MNIST datset (손글씨 이미지 데이터)으로 숫자 이미지 분류 모델 작성(다항분류)
    TensorFlow 2022. 12. 6. 16:18

     

     

    # MNIST datset (손글씨 이미지 데이터)으로 숫자 이미지 분류 모델 작성
    # MNIST는 숫자 0부터 9까지의 이미지로 구성된 손글씨 데이터셋입니다.
    # 총 60,000개의 훈련 데이터와 레이블, 총 10,000개의 테스트 데이터와 레이블로 구성되어 있습니다.
    # 레이블은 0부터 9까지 총 10개입니다.
    
    import tensorflow as tf
    import numpy as np
    import sys
    
    (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() # keras.dataset에서 튜플로 반환하므로 ()로 묶었다.
    print(x_train.shape, y_train.shape, x_test.shape, y_test.shape) # (60000, 28, 28) (60000,) (10000, 28, 28) (10000,)
    print(x_train[0], x_train.shape) # (60000, 28, 28)
    print(y_train[0])
    # for i in x_train[0]:
    #     for j in i:
    #         sys.stdout.write('%s  '%j)
    #     sys.stdout.write('\n')
    
    # import matplotlib.pyplot as plt
    # plt.imshow(x_train[0])
    # plt.show()
    
    x_train = x_train.reshape(60000, 784).astype('float32') # reshape함수로 백터로 변환
    x_test = x_test.reshape(10000, 784).astype('float32')   # reshape함수로 백터로 변환
    # print(x_train[0], x_train[0].shape) # (784,)
    
    # feature data를 정규화
    x_train /= 255.0
    x_test /= 255.0
    # print(x_train[0])
    # print(y_train[0], set(y_train))
    
    # label은 원핫 처리 - softmax를 사용하기 때문에
    print(y_train[0])
    y_train = tf.keras.utils.to_categorical(y_train, 10)
    y_test = tf.keras.utils.to_categorical(y_test, 10)
    print(y_train[0])
    
    # train data의 일부를 validation data로 사용하기
    x_val = x_train[50000:60000] # 10000개는 validation
    y_val = y_train[50000:60000]
    
    x_train = x_train[0:50000] # 50000개는 train
    y_train = y_train[0:50000]
    print(x_val.shape, x_train.shape) # (10000, 784) (50000, 784)
    
    # model
    from keras.models import Sequential
    from keras.layers import Dense, Activation, Flatten, Dropout
    
    model = Sequential()
    
    # model.add(Dense(units=128, input_dim=784))
    # model.add(Flatten(input_shape=(28, 28))) # reshape를 하지 않은 경우 Flatten에 의해 784로 변환된다.
    # model.add(Dense())
    # model.add(Activation('relu'))
    # model.add(Dropout(rate=0.2))
    
    """
    model.add(Dense(units=128, input_dim=784))
    model.add(Activation('relu'))
    model.add(Dropout(rate=0.2)) # 20%는 학습에 참여하지 말아라는 의미
    
    model.add(Dense(units=128))
    model.add(Activation('relu'))
    model.add(Dropout(rate=0.2)) # 20%는 학습에 참여하지 말아라는 의미
    
    model.add(Dense(units=10)) # 출력층
    model.add(Activation('softmax'))
    """
    
    model.add(Dense(units=128, input_dim=784, activation='relu'))
    # model.add(Flatten(input_shape=(28, 28))) # reshape를 하지 않은 경우 Flatten에 의해 784로 변환된다.
    model.add(Dropout(rate=0.2)) # 20%는 학습에 참여하지 말아라는 의미
    
    model.add(Dense(units=128, activation='relu'))
    model.add(Dropout(rate=0.2)) # 20%는 학습에 참여하지 말아라는 의미
    
    model.add(Dense(units=10, activation='softmax'))
    
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    print(model.summary())
    
    history = model.fit(x_train, y_train, epochs=10, batch_size=128, validation_data=(x_val, y_val), verbose=0)
    print(history.history.keys())
    print('loss :', history.history['loss'])
    print('val_loss :', history.history['val_loss'])
    print('accuracy :', history.history['accuracy'])
    print('val_accuracy :', history.history['val_accuracy'])
    
    # 시각화
    import matplotlib.pyplot as plt
    plt.plot(history.history['loss'], label='loss')
    plt.plot(history.history['val_loss'], label='val_loss')
    plt.xlabel('epochs')
    plt.legend()
    plt.show()
    
    plt.plot(history.history['accuracy'], label='accuracy')
    plt.plot(history.history['val_accuracy'], label='val_accuracy')
    plt.xlabel('epochs')
    plt.legend()
    plt.show()
    
    # 모델 평가
    score = model.evaluate(x_test, y_test, batch_size=128, verbose=0)
    print('final loss :',score[0])
    print('final accuracy :',score[1])
    
    model.save('cla7_model.hdf5') # 확장자를 보고 model이라고 판단 가능하다.
    
    # 여기서부터는 저장된 모델로 새로운 데이터에 대한 이미지 분류 작업 진행
    mymodel = tf.keras.models.load_model('cla7_model.hdf5')
    
    pred = mymodel.predict(x_train[:1])
    print('pred :', pred) # 확률값이 출력
    print('예측값 :', np.argmax(pred, 1)) # 확률값 중 가장 큰 인덱스를 분류 결과로 얻음
    print('실제값 :', y_train[:1])
    print('실제값 :', np.argmax(y_train[:1], 1))
    
    
    
    
    <console>
    (60000, 28, 28) (60000,) (10000, 28, 28) (10000,)
    [[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   3  18  18  18 126 136
      175  26 166 255 247 127   0   0   0   0]
     [  0   0   0   0   0   0   0   0  30  36  94 154 170 253 253 253 253 253
      225 172 253 242 195  64   0   0   0   0]
     [  0   0   0   0   0   0   0  49 238 253 253 253 253 253 253 253 253 251
       93  82  82  56  39   0   0   0   0   0]
     [  0   0   0   0   0   0   0  18 219 253 253 253 253 253 198 182 247 241
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0  80 156 107 253 253 205  11   0  43 154
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0  14   1 154 253  90   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0 139 253 190   2   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0  11 190 253  70   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0  35 241 225 160 108   1
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0  81 240 253 253 119
       25   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0  45 186 253 253
      150  27   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  16  93 252
      253 187   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 249
      253 249  64   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0  46 130 183 253
      253 207   2   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0  39 148 229 253 253 253
      250 182   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0  24 114 221 253 253 253 253 201
       78   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0  23  66 213 253 253 253 253 198  81   2
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0  18 171 219 253 253 253 253 195  80   9   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0  55 172 226 253 253 253 253 244 133  11   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0 136 253 253 253 212 135 132  16   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]
     [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
        0   0   0   0   0   0   0   0   0   0]] (60000, 28, 28)
    5
    5
    [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
    (10000, 784) (50000, 784)
    Model: "sequential"
    _________________________________________________________________
     Layer (type)                Output Shape              Param #   
    =================================================================
     dense (Dense)               (None, 128)               100480    
                                                                     
     dropout (Dropout)           (None, 128)               0         
                                                                     
     dense_1 (Dense)             (None, 128)               16512     
                                                                     
     dropout_1 (Dropout)         (None, 128)               0         
                                                                     
     dense_2 (Dense)             (None, 10)                1290      
                                                                     
    =================================================================
    Total params: 118,282
    Trainable params: 118,282
    Non-trainable params: 0
    _________________________________________________________________
    None
    dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
    loss : [0.4403969943523407, 0.19961883127689362, 0.1470498889684677, 0.11703752726316452, 0.09893597662448883, 0.08715160936117172, 0.07764007151126862, 0.06841342151165009, 0.06573114544153214, 0.061331573873758316]
    val_loss : [0.17090469598770142, 0.12302819639444351, 0.10522539913654327, 0.09100259095430374, 0.08063910156488419, 0.07660463452339172, 0.07578850537538528, 0.08383689075708389, 0.0760139748454094, 0.07369726896286011]
    accuracy : [0.8688200116157532, 0.9401599764823914, 0.9548599720001221, 0.9643200039863586, 0.9691600203514099, 0.9724799990653992, 0.9759799838066101, 0.9785199761390686, 0.9789800047874451, 0.9796599745750427]
    val_accuracy : [0.949999988079071, 0.9624999761581421, 0.9692000150680542, 0.9729999899864197, 0.9764000177383423, 0.9771000146865845, 0.9785000085830688, 0.9764000177383423, 0.9781000018119812, 0.978600025177002]
    final loss : 0.06710246950387955
    final accuracy : 0.9785000085830688
    
    1/1 [==============================] - ETA: 0s
    1/1 [==============================] - 0s 41ms/step
    pred : [[4.0980396e-14 8.1789928e-08 6.1205583e-09 3.1447946e-03 5.4112692e-18
      9.9685502e-01 1.8860232e-12 3.5345428e-11 3.6873602e-13 2.6834346e-08]]
    예측값 : [5]
    실제값 : [[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]]
    실제값 : [5]

    reshape를 하지 않은 경우 Flatten 함수에 의해 784로 변환된다.(28, 28)

     

    Drop-out은 어떤 특정한 설명변수 Feature만을 과도하게 집중하여 학습함으로써 발생할 수 있는 과대적합(Overfitting)을 방지하기 위해 사용한다. 히든레이어에만 부여한다.

     

     

    loss, val_loss 시각화

     

     

    acc, val_acc 시각화

     

     

    댓글

Designed by Tistory.