저번에는 MLP, CNN을 이용해 입력되는 이미지에 맞는 class를 예측하는 Image Classification에 대해 공부했었다.
이번에는 자율주행을 포함해 여러 분야에서 사용되고 있는 Segmentation, Object Detection/Recognition (분할, 객체 탐지/인식) 에 대해 알아보자.
🌀 Segmentation
분할은 하나의 이미지에서 같은 의미를 가지고 있는 부분을 구분해내는 Task이다.
Image classification에서는 이미지를 하나의 단위로 예측하였다면, Segmentation은 더 낮은 단위로 분류한다.
동일한 의미(사람, 자동차)마다 해당되는 픽셀이 모두 레이블링되어있는 데이터셋을 픽셀 단위에서 레이블을 예측한다.
Semantic Segmentation vs (Semantic) Instance Segmentation
- Semantic Segmentation : 의미적 분할 : 의자는 같은 class로 분류
- Instance Segmentation : 각 의자마다 다른 class로 분류
대표적인 Segmentation Model
FCN (Fully Convolutional Networks)
Segmentation은 픽셀 단위로 분류가 이루어지기 때문에 픽셀의 위치 정보를 끝까지 보존해주어야한다.
기존 CNN에서 사용하였던 FC layer는 위치 정보를 무시한다는 단점이 있다. → Segmentation에 적용하기에 부적절함.
⇒ FCN : CNN의 fully connected layer 부분을 Convolution layer로 대체하였다.
FCN의 구조를 보면,
FCN의 구조
pixelwise classification(픽셀 단위로 분류) 전후로, 갑자기 이미지의 크기가 커진다. 따라서 원래 이미지와 비슷하게 크기를 키워주는 Upsampling을 해주어야한다.
(Upsampling) 기존 Convolution과 달리, Transpose convolution이 적용된다. 각 픽셀에 커널을 곱한 값에 stride를 주어 나타냄으로써, 이미지 크기를 키워나간다.
U-net
U모양으로 되어있다.
Downsampling, upsampling 과정을 이루어져있다. (Encoder, Decoder 과정이라고도 한다.)
데이터를 압축하고 풀어주는 과정을 통해 ‘데이터를 재해석한다’라고 이해하자. (손실이 조금있겠지)
데이터 압축 : Downsampling, 데이터 재해석 : Upsampling
- Downsampling
- convolution, maxpooling을 통해, 이미지의 특징 추출
- Upsampling
- convolution, transpose convolution을 통해 원본 이미지와 비슷한 크기로 복원한다.
downsampling과정에서 발생한 이미지의 특징을 upsampling과정에서 보완해주기 위해 회색 화살표를 추가해준다. upsampling의 차원에 맞게, downsampling에서 나온 feature map을 잘라서 추가 데이터로 concatenate시키고 사용한다.
def unet_model(output_channels):
inputs = tf.keras.layer.Input(shape=[128,128,3]) # 128x128크기의 3개의 색상 채널
x = inputs
# Downsampling : Convolution , Maxpooling layer
skips = down_stack(x)
x = skips[-1] # 마지막 레이어의 출력 저장
skips = reversed(skips[:-1]) # 중간 출력은 skips 변수에 역순으로 저장
# Upsampling : Transpose convolution layer
for up, skip in zip(up_stack, skips):
x = up(x)
# upsampling의 각 층에, Downsampling에서 나온 결과를 concatenate해준다.
concat = tf.keras.layers.Concatenate()
x = concat([x, skips])
# 출력되는 이미지 크기를 동일하게 하기 위해 Transpose Convolution
last = tf.keras.layer.Conv2DTranspose(output_channels=3, strides=2, padding='same')
x = last(x)
return tf.keras.Models(inputs=inputs, outputs=x)
🌀 Object Detection & Recognition
객체 탐지/인식은 전체 이미지에서 레이블에 맞는 객체를 찾아내는 task이다.
Bounding Box를 만든 후, 박스 내의 객체가 속하는 클래스가 무엇인지를 분류한다.
IOU (Intersection over Union)
: 객체 탐지 평가 지표
$$ \small IOU = \frac{overlap\area}{union\ area} $$
많이 겹쳐질수록 잘 탐지한 것이겠지!!
너무 큰 범위를 잡는 문제 해결가능
대표적인 객체 탐지 Model
객체 탐지 모델 발전 과정
어떤 단계를 거쳐 분류가 진행되는지에 따라 2-stage, 1-stage 방식으로 나눌 수 있다.
2-Stage Detector
일련의 알고리즘을 통해 ‘저기에 물체가 있을거야’라고 사각형형태로 제안을 받는다. 저 사각형 안에 들은 것은 ‘무엇’이야라고 예측한다. 객체가 있을만한 곳을 추천받은(Region Proposal) 뒤에 추천받은 Region, 즉 RoI (Region of Interest)에 대해 분류를 수행한다.
Region Proposal, Classification 두 Stage를 거친다.
대표적인 2-stage Detector로는 R-CNN계열 (R-CNN, Fast R-CNN, Faster R-CNN 등)이 있다.
1-Stage Detector
Region proposal과정이 없어 1 stage.
특정 지역 추천 없이, 입력 이미지를 grid등과 같은 작은 공간으로 나눈 뒤, 해당 공간을 탐색해 분류 수행
입력 이미지를 conv층을 통해 특성을 뽑고, 특성 맵을 만들어 바로 각각의 그리드나 특정 위치에 대해 분류를 수행한다.
대표적인 1-stage Detector로는 SSD(Single Shot multibox Detector)계열, YOLO(You Only Look Once) 계열의 모델이 있다.
U-net 모델에서 baseline 모델을 Vgg16을 사용해, pix2pix가 아닌 직접 conv2dtranspose를 사용해 구현해보면서 이해해보자.
img_shape = (128,128,3)
base_model = tf.keras.preprocessing.VGG16(input_shape=img_shape, include_top=False)
# Downsampling
down_stack = tf.keras.Model(inputs=[base_model.input],
outputs=[base_model.get_layer(name='block5_conv3'.output,
base_model.get_layer(name='block4_conv3').output,
base_model.get_layer(name='block3_conv3').output,
base_model.get_layer(name='block2_conv3').output,
base_model.get_layer(name='block1_conv3').output])
down_stack.trainable=True # 가중치가 학습 도중 업데이트
i = tf.keras.input(shape=img_shape) # 입력층
out, out1, out2, out3, out4 = down_stack(i)
out, out1, out2, out3, out4
>> (<KerasTensor: shape=(None, 8, 8, 512) dtype=float32 (created by layer 'model')>,
<KerasTensor: shape=(None, 16, 16, 512) dtype=float32 (created by layer 'model')>,
<KerasTensor: shape=(None, 32, 32, 256) dtype=float32 (created by layer 'model')>,
<KerasTensor: shape=(None, 64, 64, 128) dtype=float32 (created by layer 'model')>,
<KerasTensor: shape=(None, 128, 128, 64) dtype=float32 (created by layer 'model')>)
# Upsampling
out = tf.keras.layers.Conv2DTranspose(512, 3, strides=2, padding='same')(out)
out = tf.keras.layers.Add()([out,out1])
out = tf.keras.layers.Conv2DTranspose(256, 3,strides=2,padding='same')(out)
out = tf.keras.layers.Add()([out,out2])
out = tf.keras.layers.Conv2DTranspose(128, 3,strides=2,padding='same')(out)
out = tf.keras.layers.Add()([out,out3])
out = tf.keras.layers.Conv2DTranspose(64, 3,strides=2,padding='same')(out)
out = tf.keras.layers.Add()([out,out4])
out = tf.keras.layers.Conv2D(3,3, activation='relu', padding='same')(out)
out = tf.keras.layers.Dense(3, activation='softmax')(out)
unet_model = tf.keras.Model(inputs=[i], outputs=[out])
tf.keras.utils.plot_model(unet_model, show_shapes=true)
프로젝트를 하면서 모델이 잘 학습되고있는지, 중간중간 데이터를 넣어보면서 확인하는 것은 좋다.
모델의 예측을 보여주는 함수, 학습 중에 해당 함수를 동작할 수 있도록 Callback을 정의하게 된다. 이 함수를 다음에 프로젝트 시 쓰자!!
def show_predictions(dataset=None, num=1):
# 예측결과 시각화 함수
if dataset:
for image, mask in dataset.atke(num):
pred_mask = model.predict(image)
display([image[0], mask[0], create_mask(pred_mask)])
else:
display([sample_image, sample_mask, create_mask(model.predict(sample_image[tf.newaxis, ...]))])
class DisplayCallback(tf.keras.callbacks.Callback):
# 학습하는 동안 모델의 예측 결과를 시각화하여, 모델이 어떻게 학습되고 있는지 확인
def on_epoch_end(self, epoch, logs=None):
clear_output(wait=True) # 매 epoch 끝날 때마다 이전 출력 결과 지움
show_predictions() # 매 epoch 끝날 때마다 호출됨.
print('\\n에포크 이후 예측 예시 {}\\n'.format(epoch+1))
down_stack.trainable=False : down_stack층을 학습되지 않도록 설정
transfer learning과 같은 상황에서 유용하다. 미리 학습된 가중치를 사용해 새로운 모델을 훈련하는 경우, 모델의 일부 층은 고정되어있어야한다. 따라서, 학습되지 않도록 설정을 하여 미리 학습된 가중치를 변경하지 않고, 새로운 데이터에 맞게 적용하기 위해 해당 층의 학습을 비활성화한다.
Fast R-CNN
기존 R-CNN모델의 문제점
- 학습 시간 오래 걸림
- 3가지의 모델(AlexNet, linear SVM, Bounding box regressor) 독립적 학습시켜, 연산 공유하거나 가중치값 update 불가능
Fast R-CNN은 기존 R-CNN모델보다 말 그대로 ‘Fast’하게, 속도면에서 큰 개선을 보인 모델이다.
- 기존 R-CNN은 20000장의 region proposals를 CNN모델에 각각 독립적으로 학습시켜 많은 시간이 소요된다.
- → Fast R-CNN : 단 1장의 이미지를 입력으로 받아 region proposals의 크기를 warp시킬 필요 없이 RoI pooling(Region of Interest)을 통해(학습 속도 향상) 고정된 크기의 feature vector를 Fully connected layer에 전달한다. 또한 multi-task loss를 사용해 모델을 개별적으로 학습시킬 필요 없이 한번에 학습시킨다!!!!
기존 R-CNN을 개선한 Fast R-CNN의 main idea
- RoI pooling
- Multi-task loss
- Hierarchical Sampling
- Truncated SVD
….
https://herbwood.tistory.com/8논문 참고(Fast R-CNN)
RedNet-30
30은 층 수를 의미하며, 이를 줄이거나 늘리는 것은 연구자의 경험적 근거에 기반해 조절 가능하다.
이것 또한 upsampling, downsampling을 이용한 모델이다.
conv layer(unsampling:압축) , deconv layer(downsampling:데이터 재해석)
해상도를 높이는 기법 : super resolution 도 무시무시한 것 !
여기서 한발자국 더 나가면 생성 모델까지. 그것은 내일 배울 것.
'Machine Learning' 카테고리의 다른 글
[CV 5] AutoEncoder (0) | 2023.05.07 |
---|---|
[CV 4] Object Detection Model - YOLO (0) | 2023.05.07 |
[CV 2] Image Augmentation (0) | 2023.05.07 |
[CV] CNN, Tranfer Learning (0) | 2023.05.07 |
[Neural Networks 4] Hyperparameter Tuning (0) | 2023.04.24 |