딥러닝(AI학습 39)

이유진·2024년 7월 8일

--21.CNN 합성곱신경망 구성요소.ipynb--

CNN 합성곱 신경망 구성요소

Convolution Neural Network

합성곱 Convolution

"""
Dense layer 에는 뉴런마다 입력개수 만큼의 가중치(weight) 가 있었고, "모든 입력"에 가중치를 '곱'했다.
그리고 절편(b) 를 추가하여 출력값을 냈다.

"합성곱" 은 입력데이터 전체에 가중치를 적용하는게 아닌, '일부'에 가중치를 곱함.
"""
None

"""
여기에서 중요한 것은 첫번째 합성곱에 사용된 가중치 w1~w3 와 절편 b 가 두번째 합성곱에도 동일하게 사용됩니다.
이렇게 '한칸씩 이동' 하면서 출력을 만드는 것이 '합성곱' 입니다.
여기에서는 이 뉴런의 가중치가 3개이기 때문에 모두 '8개의 출력'이 만들어집니다

 10개의 입력 x  뉴런의 가중치가 3개  => 8개의 출력(8번의 계산)

"""
None

  • CNN 의 필터 (filter) 혹은 커널(kernel)

CNN 에서 뉴런을 '필터(filter)' 라 부른다. (뉴런 개수를 이야기 할 때 주로 필터라 부르고)

혹은 커널(kernel)이라고 부름. (주로 weight 를 칭할 때 커널이라 부름.)

합성곱은 1차원 뿐 아니라 2차원 입력에도 적용 할 수 있다.

  • 특성 맵 (feature map)

입력 (5,5), 필터(3,3) => 합성곱 출력(3,3) <- 합성곱 출력도 2차원이다!

입력 (5,5), 필터(4,4) => 합성곱 출력(2.2) <- 마치 압축된 느낌!

이와 같이 합성곱 계산을 통해 얻은 출력을 '특성 맵(feature map) 이라 한다!

합성곱 층에서는 '여러개의 필터' 사용 가능!

입력 (4,4)

필터 (3,3)가 1개 => (2,2)

필터 (3,3)가 3개 => (2,2,3)

합성곱에 있는 필터의 가중치 (kernel)도 모두 다르다.

학습 시작시 랜덤으로 초기화 되어 시작.

데이터 준비

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os

import tensorflow as tf
from tensorflow import keras

tf.keras.utils.set_random_seed(42)
tf.config.experimental.enable_op_determinism()

from sklearn.model_selection import train_test_split

(train_input, train_target), (test_input, test_target) = \
keras.datasets.fashion_mnist.load_data()

CNN 에서 입력은 (batch, height, width, channel) 형태 이어야 한다

train_scaled = train_input.reshape(-1, 28, 28, 1) / 255.0

train_scaled, val_scaled, train_target, val_target = train_test_split(
train_scaled, train_target, test_size=0.2, random_state=42)

Conv2d

  • keras 의 합성곱 층

tf.keras.layers.Conv2D()

https://www.tensorflow.org/api_docs/python/tf/keras/layers/Conv2D

tf.keras.layers.Conv2D(
    filters, kernel_size, strides=(1, 1), padding='valid',
    data_format=None, dilation_rate=(1, 1), groups=1, activation=None,
    use_bias=True, kernel_initializer='glorot_uniform',
    bias_initializer='zeros', kernel_regularizer=None,
    bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
    bias_constraint=None, **kwargs
)

filters=, kernel_size=

keras.layers.Conv2D(filters=10, kernel_size=(3,3), activation='relu')

filters= : 필터의 개수 (*필수)

kernel_size = : 필터에 사용할 커널의 크기 (*필수)

보통 (3,3) 이나 (5,5) 크기가 권장된다.

activation= : 활성화 함수 (기본값: None)

padding=

(4,4) 입력에 (3,3) 커널을 합성곱 하면 => (2,2) 특성맵

커널크기를 (3,3)을 유지하면서 입력과 동일한 (4,4) 특성맵을 만들 수 있나?

원본입력보다 마치 더 큰 입력에 합성곱 하는 척 해야한다.

아래 그림

입력 배열의 주위에 가상의 원소로 채우는것을 '패딩(padding)' 이라고 함

실제 입력값이 아니기 때문에 패딩은 '0' 으로 채워진다.

입력 (5,5) padding=1 을 주어 (3,3) 커널을 합성곱 하면 (5,5) 특성맵 출력


  • padding:

    • zero padding을 만들 것인지. VALID는 Padding이 없고, SAME은 Padding이 있음 (사이즈에도 영향을 줌)

    • 값이 'SAME' 이면 겉에 zero padding 을 넣어 이미지 사이즈의 변화가 없다. 합성곱에서 많이 사용되는 방식

      -'VALID' 이면 padding 없구, 이미지 사이즈 변화 받는다


패딩을 사용하는 이유

ppt 이미지 참조

keras.layers.Conv2D(10, kernel_size=3, activation='relu', padding='same')

입력이 (5,5) => (5,5,10)

strides=

이동의 크기

keras.layers.Conv2D(10, kernel_size=3, activation='relu',
padding='same', strides=1) # strides=(1,1) 과 동일

  • stride 와 padding 조합 예




★ '입력크기', '필터개수', '커널크기', '패딩크기', '스트라이드크기' 가 주어졌을때

출력의 크기가 어떻게 되는지 계산 할 수 있어야 한다.

Pooling (풀링)

  • MaxPooling2D
  • AveragePooling2D

풀링 (pooling)은 합성곱 층에서 만든 특성 맵의 가로 세로 크기를 줄이는 역할 수행

중요한 것만 추출!

그러나 '특성맵의 개수'는 줄이지 않습니다.

풀링 층의 출력도 특성 맵 (feature map) 이라고 부른다.

풀링 층에는 가중치가 없다.

Pooling Layer

  • Max pool 과 stride 예

tf.keras.layers.MaxPool2D

https://www.tensorflow.org/api_docs/python/tf/keras/layers/MaxPool2D

tf.keras.layers.MaxPool2D(
    pool_size=(2, 2), strides=None, padding='valid', data_format=None,
    **kwargs
)
  • strides 값이 None 으로 주어지면 pool_size 와 동일한 크기로 stride 한다

keras.layers.MaxPooling2D(pool_size=2) # pool_size=(2,2)

AveragePooling2D <- 보통은 Max pooling 사용한다.

평균하게 되면 중요 정보들이 희석될 수 있기 때문에.

합성곱 신경망의 전체 구조

Feature Extraction & Classification

컬러 이미지를 사용한 합성곱

FashionMNIST 는 흑백 이미지라 2차원으로 표현이 가능하지만

컬러 이미지는 RGB 채널이 있으니 3차원으로 표현된다.

가령 입력이 (4,4)가 아니라 (4,4,3) 이 된다. <- 마지막 3이 채널차원 크기

이 경우 합성곱은 어떻게 수행될까?

필터도 채널 차원 필요

색상차원이 있는 입력에서 합성곱을 수행하기 위해서는 필터도 가로, 세로 뿐 아니라 채널차원도 필요

(편의상 채널 차원을 '깊이'라고 부르겠습니다)

즉 필터의 크기가 (3,3)이 아니라 (3,3,3) 이 된다.

입력 (10, 10, 3)

필터 (3, 3, 3) x 5개

합성곱 결과 (8, 8, 5)

입력 (8, 8, 5)

필터 (3, 3, 5) x 10개

합성곱 결과 (6, 6, 10)

"""
keras 의 합성곱 층은 항상 이렇게 3차원 입력을 기대합니다.
만약 패션 MNIST 데이터처럼 graysacle 이미지일 경우에는 깊이 차원이 1인 3차원 배열로 변환하여 전달해야 합니다

(height, width) -> (height, width, channel) 형태!

예를 들어 (28, 28) 크기의 2차원 배열을 (28, 28, 1) 크기의 3차원 배열로 변환합니다.
원소 개수는 동일하면서 차원만 맞춘거죠.
"""
None

"""
합성곱층 - 풀링층 다음에 또 다시 합성곱 층이 올때

예를 들어 첫번째 합성곱 층의 필터개수가 3개라고 가정하여 첫번째 풀링 층을 통과한 특성 맵의 크기가 (6,6,3) 라고 해보죠
(즉 다음층의 입력으로 전달될 값에 '3번째 차원'이 추가되었다!)

그러면!
두번째 합성곱 층에서 필터의 너비와 높이가 각각 3이라면. 이 필터의 커널 크기는 (3, 3, 3)가 되어야 합니다.
왜냐하면 입력의 '깊이'와 필터의 '깊이'는 같아야 하기 때문입니다.

아래 그림처럼 (3 x 3 x 3 = 27 개의 가중치를 곱하고 절편을 더한) 이 합성곱의 결과는 1개의 출력을 만듭니다.

두번째 합성곱 층의 필터 개수가 2개라면 만들어진 특성맵의 크기는 (4,4,2)이 될겁니다.

만약 필터 개수가 10개라면 특성맵의 크기는 (4,4,10) 이 될것이다.
합성곱 신경망은 너비와 높이는 점점 줄어들고 깊이는 점점 깊어지는 것이 특징입니다.
그리고 마지막 출력층 전에 특성맵을 모두 펼쳐서 밀집층의 입력으로 사용하게 되는 겁니다.

★ 이를 이해해야 나중에 합성곱 신경망의 모델 파라미터를 계산할수 있습니다!!
"""
None

예시) (6, 6, 3) 크기 입력과 (3, 3, 3) 크기 커널의 합성곱

profile
독해지자

0개의 댓글