[Tensorflow Keras] 레이어를 구현해보자.

Robert Lee·2021년 10월 5일
2

Deep Learning

목록 보기
2/5

🔊 목차

  • 기본 레이어 개념을 이해하고 구현해본다.
    • 컨볼루션 Conv Layer
    • 플래튼 Flatten Layer
    • 폴링 Pooling Layer

🥕 환경

  • 파이썬 3.7
  • 텐서플로우 2.6
  • 케라스 2.6

😐 기본 레이어 이해

우리는 앞서 딥러닝과 뉴럴 네트워크의 차이를 알아보았다.

그리고 뉴럴 네트워크 구현 최소 단위인 레이어 Layer 가 필요하다고 했다.

여기서는 Conv Layer Pooling Layer Flatten Layer 를 다뤄보도록 하겠다.

❝ 해당 개념은 링크의 동영상을 보는 것을 추천한다. ❞


🏅 Conv Layer <링크>

우리가 이미지 분류를 잘하려면 특징 Feautre 을 잘 파악해야 할 것이다.

❝ 뉴럴 네트워크에서 이미지 특징을 어떻게 뽑아낼 수 있을까 ? ❞


그에 대한 대답으로

❝ Conv Layer 의 필터를 사용하면 된다. ❞


컨볼루션망 CNN, Convolutional Neural Network 을 들어본 경험이 있다면

이미지 분류를 잘하는 모델로 기억할 것이다.

❝ 그렇다. 이미지를 잘 분류하려면 Conv Layer 가 필요하다. ❞


컨볼루션 Conv Layer 에는 필터 Filter 와 커널 Kernel 개념이 존재한다.

❝ 필터란 몇개의 특징으로 출력을 만들어 낼 것인가 ? 를 의미한다. ❞


즉 해당 이미지를 판단하기 위해 가장 좋은 특징맵 Feature Map N 개를 찾아낸다.


또한 특징맵을 한개를 만들어가는 과정에서 커널 Kernel 개념이 사용된다.

이미지 크기가 5 by 5 이고 커널 크기가 3 또는 (3, 3) 인 그림을 살펴보자.


출처 - jjeongil.tistory.com

고정된 커널 크기에 따라 곱셈 연산을 하고 이를 모두 더한값을 기록한다.


이제 tf.keras.layers.Conv2D() 이용하여 3 = (3, 3) 커널로 이루어진 32 개의 필터를 만들어보자.

import tensorflow as tf

input_layer = tf.keras.layers.Input(
    shape=(200, 200, 3), name='input_layer'
)

conv_layer = tf.keras.layers.Conv2D(
    filters=32, kernel_size=(3, 3), activation='relu', name='conv_layer'
)(input_layer)

output_layer = tf.keras.layers.Dense(
    units=2, activation='softmax', name='output_layer'
)(conv_layer)

model = tf.keras.models.Model(input_layer, output_layer)

model.summary()
_________________________________________________________________
Layer (type)               Output Shape                  Param # 
=================================================================
input_layer (InputLayer)   [(None, 200, 200, 3)]               0 
_________________________________________________________________
conv_layer (Conv2D)        (None, 198, 198, 32)              896 
_________________________________________________________________
output_layer (Dense)       (None, 198, 198, 2)                66
=================================================================
Total params: 962                                                
Trainable params: 962                                            
Non-trainable params: 0                                          
_________________________________________________________________

그리고 다음과 같은 특징맵 Feature Map 을 얻을 수 있을 것이다.

여기서 특징맵은 200 - (3 - 1) by 200 - (3 - 1) 의 크기로 32 개가 출력된다.

한장의 사진은 (1, 200, 200, 3) 크기로 컨볼루션에 입력되어 (32, 198, 198, 3) 크기로 출력된다.


출처 - ricardodeazambuja.com/deep_learning

🥈 Flatten Layer <링크>

먼저 플래튼 Flatten 의 사전적 의미는 다음과 같다.

flatten [ˈflætn]
1. (동사) 납작 [반반] 해지다, 납작하게 [반반하게] 만들다
옥스퍼드 영한사전


플래튼을 사용하는 이유는 단순하다.


우리는 <강아지, 고양이> 이미지 분류 Classification 를 할 예정이라면

1 차원 배열로 출력해야 한다. <두개 값으로 나와야 한다.>

❝ 이미지 1 의 예측값 예시 = [ 강아지 확률, 고양이 확률 ] = [ 90 % , 10 % ] ❞


그러나 우리는 3 차원 이상 배열 Tensor 을 이용해 특징을 찾아가고 있다.

그러므로 플래튼이 없다면 3 차원으로 출력이 될 것이다.


다음 그림의 출력 Output Shape 을 살펴보자.

_________________________________________________________________
Layer (type)               Output Shape                  Param # 
=================================================================
input_layer (InputLayer)   [(None, 200, 200, 3)]               0 
_________________________________________________________________
conv_layer (Conv2D)        (None, 198, 198, 32)              896 
_________________________________________________________________
output_layer (Dense)       (None, 198, 198, 2)                66 
=================================================================

자 이제 텐서플로우 tf.keras.layers.Flatten() 을 통해 일자로 평평하게 만들어보자.

단순 1 차원 배열 Array 로 만드는 것이므로 파라미터는 필요 없다.

import tensorflow as tf

input_layer = tf.keras.layers.Input(
    shape=(200, 200, 3), name='input_layer'
)

conv_layer = tf.keras.layers.Conv2D(
    filters=32, kernel_size=(3, 3), activation='relu', name='conv_layer'
)(input_layer)

faltten_layer = tf.keras.layers.Flatten(name='flatten_layer')(conv_layer)

output_layer = tf.keras.layers.Dense(
    units=2, activation='softmax', name='output_layer'
)(faltten_layer)

model = tf.keras.models.Model(input_layer, output_layer)

model.summary()
_________________________________________________________________
Layer (type)               Output Shape                  Param # 
=================================================================
input_layer (InputLayer)   [(None, 200, 200, 3)]               0 
_________________________________________________________________
flatten_layer (Flatten)    (None, 1254528)                     0 
_________________________________________________________________
conv_layer (Conv2D)        (None, 198, 198, 32)              896 
_________________________________________________________________
output_layer (Dense)       (None, 2)                     2509058 
=================================================================
Total params: 2,509,954                                          
Trainable params: 2,509,954                                      
Non-trainable params: 0                                          
_________________________________________________________________

즉 플래튼을 적용하면 정상적으로 <강아지, 고양이> = [0.9, 0.1] 또는

<강아지, 고양이, 호랑이> = [0.9, 0.0, 0.1] 출력이 가능하다.


🥉 Pooling Layer <링크>

마지막으로 살펴볼 레이어는 풀링 Pooling Layer 이다.

풀링은 Sub Sampling 으로 불리며 이미지 데이터를 작은 크기로 줄여주는 역할을 한다.


풀링에는 대표적으로 Max Pooling LayerAverage Pooling Layer 있다.

다음 그림은 Max Pooling Layer 을 나타내며 풀링 크기 Pooling Size(2, 2) 이다.


출처 - medium.com/parva.shah808

Max Pooling 풀링 크기에 마춰 해당 픽셀 중 가장 큰 값을 기록한다.

❝ 다시 말해 Max Pooling 을 사용하면 가장 두드러진 특징만을 기록할 수 있다. ❞


❝ 그렇다면 Average Pooling 의 특징은 무엇일까 ? 고민해보고 이포스트 하단을 읽어보자. ❞


그리고 문득 아래와 같은 질문을 할 수 있다.

❝ 이미지 데이터를 작은 크기로 만들 필요가 있을까 ? 왜 그래야만 하는거지 ? ❞


우리는 컨볼루션 Conv Layer 를 바탕으로 이미지 특징을 찾아내고

플래튼 Flatten Layer 으로 일자로 만든 뒤에 확률 형태로 출력을 하였다.

풀링이 없는 뉴럴 네트워크를 구성해도 되지만

최적화 해야되는 파라미터 Parameter 개수가 많아질 것이다.

❝ 파라미터가 많다는 의미 오버피팅, 학습시간 등 문제를 야기한다는 뜻이다. ❞

만약 풀링 Pooling 이 없다면

아래 그림과 같이 2,509,954 개의 파라미터를 찾아야 된다.

_________________________________________________________________
Layer (type)               Output Shape                  Param # 
=================================================================
input_layer (InputLayer)   [(None, 200, 200, 3)]               0 
_________________________________________________________________
conv_layer (Conv2D)        (None, 198, 198, 32)              896 
_________________________________________________________________
flatten_layer (Flatten)    (None, 1254528)                     0 
_________________________________________________________________
output_layer (Dense)       (None, 2)                     2509058 
=================================================================
Total params: 2,509,954                                          
Trainable params: 2,509,954                                      
Non-trainable params: 0                                          
_________________________________________________________________

그래서 우리는 파라미터를 줄이기 위해 Pooling 을 한다.

그리고 Pooling Layerconv_layer 다음에 위치하는 것이 일반적이다.

특징을 찾은 이후에 풀링으로 이미지 크기를 줄인다.


이제 tf.keras.layers.MaxPool2D() 를 바탕으로 Pooling Layer 를 구현해보자.

import tensorflow as tf

input_layer = tf.keras.layers.Input(
    shape=(200, 200, 3), name='input_layer'
)

conv_layer = tf.keras.layers.Conv2D(
    filters=32, kernel_size=(3, 3), activation='relu', name='conv_layer'
)(input_layer)

pool_layer = tf.keras.layers.MaxPool2D(
    pool_size=(3, 3), name='pool_layer'
)(conv_layer)

faltten_layer = tf.keras.layers.Flatten(name='flatten_layer')(pool_layer)

output_layer = tf.keras.layers.Dense(
    units=2, activation='softmax', name='output_layer'
)(faltten_layer)

model = tf.keras.models.Model(input_layer, output_layer)

model.summary()
_________________________________________________________________
Layer (type)               Output Shape                  Param # 
=================================================================
input_layer (InputLayer)   [(None, 200, 200, 3)]               0 
_________________________________________________________________
conv_layer (Conv2D)        (None, 198, 198, 32)              896 
_________________________________________________________________
pool_layer (MaxPooling2D)  (None, 66, 66, 32)                  0 
_________________________________________________________________
flatten_layer (Flatten)    (None, 139392)                      0 
_________________________________________________________________
output_layer (Dense)       (None, 2)                      278786 
=================================================================
Total params: 279,682                                            
Trainable params: 279,682                                        
Non-trainable params: 0                                          
_________________________________________________________________

위 결과와 같이 풀링 Pooling Layer 를 적용하면

279,682 개 파라미터를 최적화 시키면 된다.

만약 풀링이 없다면 2,509,954 파라미터를 찾아야 될 것이다.


추가로 FC 레이어 Fully Connected Layer 에 대해 알아보자.

❝ FC 레이어는 일렬로 펴진 층과 모든 노드가 연결된 구간을 이야기한다. ❞


지금 우리가 만든 모델에도 FC 레이어가 존재한다.

일자로 평평하게 만든 플래튼 Flatten Layer 과 마지막 출력을 위한 Dense Layer 합친 구간을 말한다.


또한 뉴럴 네트워크 깊이에 따라 플래튼과 출력 사이에 한개 이상 Dense Layer 를 위치시킬 수 있다.

통상적으로 이 부분을 은닉층 Hidden Layer 이라 부르는 것 같다.


이제 우리는 레이어에 대해 간략하게 이해를 하였다.

그러나 막상 레이어를 사용 시에 고려해야할 점들이 존재한다.

예를 들어 다음과 같은 질문이 될 수 있다.

❝ Max Pooling 과 Average Pooling 중에 어떤것을 사용하여야 하는가 ? ❞

다음 포스트에서는 몇가지 레이어 Layer 를 비교해 보고자 한다.


🍀 참고

profile
Hi. Hello World.

0개의 댓글