본문 바로가기

하루 30분 컴퓨터 비전 공부하기

CV(1) 이미지 데이터 다루기 기초와 MLP

1. 이미지 데이터 이해하기 

  • 1. 인간의 이미지 인식 vs 컴퓨터의 이미지 인식
    • 이미지 데이터 안의 정보는 하나의 픽셀 그 자체가 아닌 주변의 여러개의 픽셀과의 관계를 통해서 드러납니다. 
      관계 : 같다/ 다르다 를 가지고 픽셀이 의미를 가짐 
    • 유사성을 비교함으로써 우리는 정보를 얻을 수 있다. 
  • 이미지, 영상 
    이미지는 크게 두가지로 나눔 
    1. single object
    - 고양이로 분류하는 classification, 고양이가 이미지의 어디에 있는지 localization함 
    - bounding box로 위치를 지정해줌

 

  • 2. multiple objects
    - bounding box로 물체를 구분한 후, 각 물체를 classifiaction함 
    ➞ localization과 classification을 동시에 하는 것을 object Detection이라고 함
  • segmentation : 픽셀 수준에서의 의미를 찾는 태스크입니다. 
    object detection에서 더 나아가 배경과 물체를 분활시켜 주는 것 
    semantic Segmenataion : 배경과 물체를 구별해줌
    instance segmentation : 각 개별 개체들을 구별해줌 

 

2. 다층 퍼센트론 (MLP)

https://blog.naver.com/PostView.naver?blogId=paulcyp&logNo=222196466606&parentCategoryNo=&categoryNo=25&viewDate=&isShowPopularPosts=false&from=postView

  • 딥러닝이란: input layer와 output layer사이의 hidden layer가 점점 깊어지는 것을 의미한다. 
  • 뉴련의 작동방식
    • 정보를 외부로 부터 받아들이고 
    • 받아들인 정보를 조합하여
    • 조합한 정보를 다른 뉴런에게 전달함 
    • but, 조합한것을 그대로 전달하진 않음 
    • 중요하다고 생각하는 것만 남음 (특정 임계값은 넘은 정보만 다음 뉴런으로 전달)
  • 단일 뉴런의 작동원리를 모사하여 퍼셉트론으로 구현함
  • 퍼셉트론 : 입력변수의 값들에 대한 가중합에 대해 활성함수를 적용하여 최종결과물을 생성
  • 단일 퍼셉트론의 구조 및 역할

    • 데이터를 입력으로 받아 각 값에 가중치를 줌 
    • 가중치를 모두 조합
    • 조합한 값을 활성함수를 통해 비선형성을 줄 수 있다. (들어온 input이 변형이 되어 나간다.)
    • 예측되어 나온 y값과 실제 값을 사용해 loss를 구할 수 있음
    • back- propagation을 사용하여 loss값을 전달하여 w값을 업데이트 함.
    • w값이 변경되면서 loss를 줄여나감 

 

  • 많은 hidden layer의 효과 
    • 분류 경계면이 복잡해 지는 것을 알 수 있다. 
    • 이렇게 되면 더 세부적인 분류가 가능해 진다. 
    • Representation learning을 수행한다.
      • 사람이 찾을 수 없었던 패턴을 파악할 수 있음 
      •  Representation을 통해서 원래 데이터가 존재하는 공간을 변경하는 것을  Representation learning이라고 한다.
      • Representation learning을 통해 원래 데이터가 존재하는 공간을 변경한다.
      • Training하는 과정에서 task를 수행하는데에 가장 적합한 공간 구조를 Representation 하게 된다. 

https://ang-love-chang.tistory.com/26

 

  • 실습 
# 데이터를 import
import sys
import tensorflow as tf
import numpy as np

# MNIST 데이터셋 불러오기
(X_train, Y_train), (X_test, Y_test) = tf.keras.datasets.mnist.load_data()

# shape 확인하기
print(X_train.shape) # 28 x 28의 이미지가 60,000장
print(Y_train.shape) ## [ 5, 1, 2, 3, 4, 4,   .... ]
print("학습셋 이미지 수 : %d 개" % (X_train.shape[0]))
print("테스트셋 이미지 수 : %d 개" % (X_test.shape[0]))

# MNIST 데이터를 시각화하기 
import matplotlib.pyplot as plt
print(Y_train[0])
plt.imshow(X_train[0], cmap='Greys') # 흑백 이미지로 확인
plt.show()

# MLP 구조 만들기 

# MLP 구조에 적절한 input의 형태로 변형하기
## reshape()을 사용하여 2차원의 데이터를 1차원으로 변형
## 1차원으로 변형함과 동시에 Normalization
X_train = X_train.reshape(X_train.shape[0], 784).astype('float32') # 28 x 28= 784
X_test = X_test.reshape(X_test.shape[0], 784).astype('float32')

# Label 값을 One-hot encoding 하기 
# Multi-Class Classfication이므로 keras.utils.to_categorical을 사용
Y_train = tf.keras.utils.to_categorical(Y_train)
Y_test = tf.keras.utils.to_categorical(Y_test)

# 모델 설계하기 
input_layer = tf.keras.layers.Input(shape=(784,)) # input layer, input의 사이즈에 맞게 shape을 지정하는 것이 중요
x = tf.keras.layers.Dense(512, activation='relu')(input_layer) # hidden layer 1, 512개의 perceptron으로 구성된 fully connted layer, activation 함수는 relu
x = tf.keras.layers.Dense(512, activation='relu')(x) # hidden layer 2

# 분류해야 하는 class 0~9 (10개) -> 따라서 최종 layer의 perceptron은 10개
out_layer= tf.keras.layers.Dense(10, activation='softmax')(x)

model = tf.keras.Model(inputs=[input_layer], outputs=[out_layer])

# 모델의 loss 함수, optimizer, metric을 설정하고 모델을 compile
loss=tf.keras.losses.categorical_crossentropy
optimizer = tf.keras.optimizers.Adam(learning_rate = 0.001)
metric=tf.keras.metrics.categorical_accuracy
model.compile(loss = loss,
              optimizer = optimizer,
              metrics = [metric])
    
              
# MLP 모델 Training 하기

# validation_data 옵션으로 테스트 데이터만 넣어주어서 검증 데이터 분류가 가능
history = model.fit(X_train, Y_train, validation_split=0.2, epochs=30, batch_size=1000, verbose=1)
print(history.history.keys())

# Training loss 확인하기
loss = history.history['loss']
print(loss)

# 학습된 모델의 성능 확인하기
'''
model.evaluate() 함수에 test 데이터를 입력시켜서 모델의 정확도를 확인
'''
# Test 데이터를 통해서 정확도 확인하기
print("\n Test Accuracy: %.4f" % (model.evaluate(X_test, Y_test)[1]))

# 그래프로 표현
x_len = np.arange(len(val_loss))
plt.plot(x_len, val_loss, marker='.', c="red", label='validation loss')
plt.plot(x_len, loss, marker='.', c="blue", label='training loss')

# 그래프에 그리드를 주고 레이블을 표시
plt.legend(loc='upper right')
# plt.axis([0, 20, 0, 0.35])
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

 

  • 데이터에 변형주기 
# 이미지 회전 변환 메트릭스 구하기 
M= cv2.getRotationMatrix2D((20, 25), 20, 1)  ## 회전 변환 Matrix 생성

# 이미지 이동 변환 메트릭스 구하기
M[0, 2] = M[0, 2] + 3
M[1, 2] = M[1, 2] + 3

# 이미지 변환 메트릭스 적용
test_image = cv2.warpAffine(X_train[5], M, (28, 28))  ## image에 matrix 곱

 

  • MLP 모델의 한계 
    • 이미지를 조금만 변형하면 제대로 분류해내지 못한다는 것을 알 수 있음 
    • 2D 이미지를 1D로 바꾸어 학습을 하는 과정에서 픽셀관의 관계성이 사라지면서 패턴을 찾기가 힘들어짐
    • 하나의 픽셀을 가지고 의미를 찾아내기는 어려움 
    • so, 이미지 데이터와 MLP구조의 불합치를 알 수 있다.