ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Tensorflow Convolution Neural Network 예시 코드(CNN, MNIST DataSet)
    Data Science/Tensorflow 2022. 10. 26. 22:04
    반응형

    1. 기본 세팅

    1.1 라이브러리

    import tensorflow as tf
    import numpy as np
    import matplotlib.pyplot as plt
    import random
    import os
    from sklearn.model_selection import train_test_split
    from tensorflow.keras import Model, layers

     

    1.2 랜덤시드 고정

    매번 동일한 결과를 가져오기 위한 랜덤시드 고정

    random.seed(1)
    np.random.seed(1)
    tf.random.set_seed(1)

    1.3 GPU 세팅

    os.environ["CUDA_VISIBLE_DEVICES"]="0"
    gpus = tf.config.experimental.list_physical_devices('GPU')
    if gpus:
        try:
            tf.config.experimental.set_memory_growth(gpus[0], True)
        except RuntimeError as e:
            print(e)

    2. Data Load

    본 포스팅에서 사용되는 MNIST 데이터셋은 손으로 쓰여진 0~9 숫자들의 이미지를 가지는 데이터셋이다.

    출처 위키백과 MNIST 데이터베이스

    tf.keras.datasets.mnist.load_data()를 통해서 MNIST 데이터셋을 받아올 수 있다.

    train set 60000개, test set 10000개의 이미지로 구성되어 있다.

    각 이미지는 28*28 픽셀로 이루어져있으며, 각 픽셀에는 해당하는 색정보가 숫자로 들어있다.

    (색정보는 0~255의 숫자로 표현된다.)

    2.1 데이터 로드 및 분할

    이번 포스팅에서는 데이터셋을 Train/Validation/Test로 분할한다.

    (x_train_val, y_train_val),(x_test, y_test) = tf.keras.datasets.mnist.load_data()
    
    x_train, x_valid, y_train, y_valid = train_test_split(x_train_val, y_train_val, test_size= 0.2, shuffle=True, stratify = y_train_val, random_state=34)
    
    print(x_train.shape) #=> (48000, 28, 28) 
    print(y_train.shape) #=> (48000,)
    print(x_train[0].shape) #=> (28, 28) 이미지 한장 크기
    
    print(x_valid.shape) #=> (12000, 28, 28)
    print(x_test.shape) #=> (10000, 28, 28)

    2.2 데이터 확인해보기

    plt.imshow(x_train[1])
    plt.show()

    3. 데이터 전처리(Data Preprocessing)

    3.1 class 수 및 데이터 수 파악

    num_classes = len(set(y_train)) # MNIST는 10개의 class를 가진다.
    print(num_classes) #=> 10

    3.2 데이터 형타입 변환 및 Scaling

    float16, float32, float64에서 뒤의 숫자는 저장용량을 의미한다. (16bits, 32bits, 64bits)

    float32를 사용할시 64대비 적은 메모리용량을 차지하며 연산속도가 빨라진다.

    반면, 그만큼의 자세한 숫자표시를 할수 없기에 해결하고자하는 문제가 필요로하는 정확성과 가용한 하드웨어 자원을 고려하여 선택하면 된다.

    MNIST 데이터는 픽셀별로 0~255의 숫자가 들어있기에, 255로 나누게되면 Min-Max Scaling과 동일한 효과를 낼수 있다.

    # Scale to [0,1]
    x_train = x_train.astype('float32') / 255
    x_valid = x_valid.astype('float32') / 255
    x_test = x_test.astype('float32') / 255

    3.3 이미지 차원변환(Reshape)

    CNN을 사용하기 앞서, 데이터를 적합한 차원형태로 변환한다.

    채널이라는 개념이 등장하는데, 대표적으로 색을 나타내는 rgb를 사용할경우 3채널의 입력 데이터를 받게된다.

    (red에 해당하는 28*28 1채널, green에 해당하는 28*28 1채널, blue에 해당하는 28*28 1채널, 도합 3채널)

    본 포스팅에서 사용하는 MNIST 데이터셋은 1채널짜리 데이터이다.

    # input shape: (data수, image_width, image_height, channel_num)
    image_w, image_h = x_train.shape[1], x_train.shape[2]
    
    x_train = x_train.reshape(-1, image_w, image_h, 1)
    x_valid = x_valid.reshape(-1, image_w, image_h, 1)
    x_test = x_test.reshape(-1, image_w, image_h, 1)
    
    print(x_train.shape, x_valid.shape, x_test.shape) 
    #=> (48000, 28, 28, 1) (12000, 28, 28, 1) (10000, 28, 28, 1)
    print(y_train.shape, y_valid.shape, y_test.shape) 
    #=> (48000,) (12000,) (10000,)

    4. Model 생성

    # layers.Conv2D( 생성할 커널수, 커널사이즈, 커널이동거리, 패딩방법지정, 활성화함수지정, 입력데이터 차원정보(첫레이어일때만) )
    # layers.MaxPool2D( 커널사이즈, 커널이동거리, 패딩방법지정 )
    # layers.Dense( 노드수, 활성화함수지정 )
    
    class CNN(Model):
        def __init__(self):
            super(CNN, self).__init__()
            self.conv1 = layers.Conv2D(32, (3,3), strides=1, padding='same', activation='relu', input_shape=(28,28,1))
            self.maxpool1 = layers.MaxPool2D((3,3), strides=2, padding='same')
            
            self.conv2 = layers.Conv2D(64, (3,3), strides=1, padding='same', activation='relu')
            self.maxpool2 = layers.MaxPool2D((3,3), strides=2, padding='same')
            
            self.flatten = layers.Flatten()
            self.fc1 = layers.Dense(128, activation='relu')
            self.fc2 = layers.Dense(10, activation='softmax')
            
    
        def call(self, x):
            x = self.conv1(x)
            x = self.maxpool1(x)
            x = self.conv2(x)
            x = self.maxpool2(x)
            x = self.flatten(x)
            x = self.fc1(x)
            x = self.fc2(x)
    
            return x
    cnn = CNN(num_classes)

    4.2 모델 컴파일(Model Complie)

    Tensorflow의 Model class를 상속받았기 때문에 complie을 통해서 모델 학습을 위한 손실함수, 최적화함수, 평가지표를 설정할수 있다.

    학습률(learning rate)는 최적화함수에서 설정 가능하다.

    cnn.compile(loss = 'sparse_categorical_crossentropy', 
                optimizer = tf.keras.optimizers.SGD(learning_rate=0.1), 
                metrics = ['accuracy'])

    4.3 모델 학습

    history = cnn.fit(x_train, y_train,
                      epochs=5, # 반복학습 횟수
                      batch_size=128, # 1epoch에 모든 데이터를 한번에 돌리는게 아닌, batch로 나누어 돌림
                      validation_data=(x_test, y_test)) # 검증셋

    그림에서 총 5번의 반복학습이 이루어진것을 확인할수 있다.

    375/375의 의미는 총 375개의 batch로 나누어져 학습된것을 알수 있다.

    history 변수에 모델의 학습이력이 저장되어 추후 확인 가능하다.

    history.history

    5번 반복학습동안의 train/validation의 loss 및 accuracy를 확인할수 있다.

    5. 모델 테스트

    test set에 대한 loss와 accuracy를 반확한다.

    cnn.evaluate(x_test, y_test)

    반응형

    댓글

Designed by Tistory.