본문 바로가기

데이터 사이언스/머신러닝

[NIPA AI 교육/응용] 07. 다양한 신경망

1. 이미지 처리를 위한 데이터 전처리

  • 컴퓨터에게 이미지는 각 픽셀 값을 가진 숫자 배열로 인식
  • 모두 같은 크기를 갖는 이미지로 통일하는 것이 이미지 처리를 위한 데이터 전처리의 핵심
  • 가로, 세로의 픽셀 사이즈를 표현하는 해상도를 통일
  • 색을 표현하는 방식 통일(RGB, HSV, Gray-scale, Binary...)
  • 차원 추가 함수 / axis = -1 이면, 어떤 데이터가 data가 들어오든 마지막 축의 index 의미
    tf.expand_dims(data, axis)​

2. 이미지 처리를 위한 딥러닝 모델

2.1. 기존 다층 퍼셉트론 기반 신경망의 이미지 처리 방식

  • 극도로 많은 수의 파라미터 필요
  • 이미지에 변화가 있는 경우, 분류 성능이 많이 떨어질 수 있음

2.2. 합성곱 신경망(CNN; Convolution Neural Network)

  • 작은 필터를 순환시키는 방식
  • 이미지의 패턴이 아닌 특징을 중점으로 인식
  • 입력 이미지의 특징을 추출, 분류하는 과정으로 동작
  • 합성곱 신경망의 구조 = (CNN;Convolution Layer + Pooling Layer) + (FC;Fully-Connected Layer)
    • Convolution Layer는 특징을 찾아내줌
  • 이미지에서 어떠한 특징이 있는지를 구하는 과정
  • 필터가 이미지를 이동하며 새로운 이미지(피쳐맵)를 생성
# CNN layer

# filters : 필터(커널)의 개수, kernel_size : 필터(커널)의 크기
# activation: 활성화 함수
# padding : 이미지가 필터를 거칠 때 그 크기가 줄어드는 것을 방지하기 
# 위해 가장자리에 0의 값을 가지는 픽셀을 넣을 것인지 말 것인지를 결정하는 변수. SAME / VALID
tf.keras.layers.Conv2D(filters, kernel_size, activation, padding)

 

  • 평가 방법
    model.evaluate(X, Y)​
  • 예측 방법
    model.predict_classes(X)​
# 실습 코드

import logging, os
logging.disable(logging.WARNING)
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"

# 동일한 실행 결과 확인을 위한 코드입니다.
np.random.seed(123)
tf.random.set_seed(123)


# MNIST 데이터 세트를 불러옵니다.
mnist = tf.keras.datasets.mnist

# MNIST 데이터 세트를 Train set과 Test set으로 나누어 줍니다.
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()    

# Train 데이터 5000개와 Test 데이터 1000개를 사용합니다.
train_images, train_labels = train_images[:5000], train_labels[:5000]
test_images, test_labels = test_images[:1000], test_labels[:1000]

# CNN 모델의 입력으로 사용할 수 있도록 (샘플개수, 가로픽셀, 세로픽셀, 1) 형태로 변환합니다.
train_images = tf.expand_dims(train_images, -1)
test_images = tf.expand_dims(test_images, -1)


"""
1. CNN 모델을 설정합니다.
   분류 모델에 맞게 마지막 레이어의 노드 수는 10개, activation 함수는 'softmax'로 설정합니다.
"""
model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(filters = 32, kernel_size = (3,3), activation = 'relu', padding = 'SAME', input_shape = (28,28,1)),
    tf.keras.layers.MaxPool2D(padding = 'SAME'),
    tf.keras.layers.Conv2D(filters = 32, kernel_size = (3,3), activation = 'relu', padding = 'SAME'),
    tf.keras.layers.MaxPool2D(padding = 'SAME'),
    tf.keras.layers.Conv2D(filters = 32, kernel_size = (3,3), activation = 'relu', padding = 'SAME'),
    tf.keras.layers.MaxPool2D(padding = 'SAME'),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(64, activation = 'relu'),
    tf.keras.layers.Dense(10, activation = 'softmax')
])

# CNN 모델 구조를 출력합니다.
print(model.summary())

# CNN 모델의 학습 방법을 설정합니다.
model.compile(loss = 'sparse_categorical_crossentropy',
              optimizer = 'adam',
              metrics = ['accuracy'])
              
# 학습을 수행합니다. 
history = model.fit(train_images, train_labels, epochs = 20, batch_size = 512)

# 학습 결과를 출력합니다.
Visulaize([('CNN', history)], 'loss')

"""
3. 평가용 데이터를 활용하여 모델을 평가합니다.
   loss와 accuracy를 계산하고 loss, test_acc에 저장합니다.
"""
loss, test_acc = model.evaluate(test_images, test_labels, verbose = 0)

"""
4. 평가용 데이터에 대한 예측 결과를 predictions에 저장합니다.
"""
predictions = model.predict_classes(test_images)

# 모델 평가 및 예측 결과를 출력합니다.
print('\nTest Loss : {:.4f} | Test Accuracy : {}'.format(loss, test_acc))
print('예측한 Test Data 클래스 : ',predictions[:10])

# 평가용 데이터에 대한 레이어 결과를 시각화합니다.
Plotter(test_images, model)

3. 피쳐맵의 크기 변형

3.1. Padding

  • 원본 이미지의 상하좌우에 한 줄씩 추가

3.2. Striding

  • 필터를 이동시키는 거리(Stride) 설정

4. Pooling Layer

  • 이미지의 왜곡 영향(노이즈)를 축소하는 과정
  • 즉, 처리할 맵(이미지) 크기를 줄여주며, 이를 N번 반복함
  • 반복할 때마다 줄어든 영역에서의 특징을 찾게 되고, 영역의 크기는 작아졌기 때문에 빠른 학습이 가능해짐
  • Max Pooling, Average Pooling이 있으며, Max Pooling이 자주 사용

5. Fully Connected Layer

  • 추출된 특징을 사용하여 이미지를 분류