강의자료/머신러닝

[딥러닝실습] 이미지 분류(CNN) II-Conv2D을 이용한 딥러닝 학습

파아란 기쁨 2022. 9. 1. 12:57
목표

컨볼루션에 대한 이해와 컨볼루션 레이어의 사용법을 이해합니다.

실습하기

지난시간에 CNN의 구조를 살펴 보았습니다.

CNN의 레이어는 크게 두가지 부분으로 나뉘는 부분에 대해 살펴 보았습니다.

1. Convolution/Pooling : 메커니즘은 이미지를 형상으로 분할하고 분석

2. FC(Fully Connected Layer) : 이미지를 분류/설명하는 데 적합하게 예측

지난시간에는 Fully Connected Layer 부분을 Flatten을 이용하여 2차원 배열의 데이터를 1차원 배열의 데이터로 변환하여 학습하는 모델을 만들어 보았습니다.

오늘은 컨볼루션 부분에 대해 살펴 보겠습니다.

먼저 실습하기 전에 컨볼루션에 대한 부분을 살펴 보겠습니다.

컨볼루션이란

컨볼루션(Convolution)은 합성곱이라고 하며 다음과 같이 정의 됩니다.

두개의 함수 f와 g가 있을 때 두 함수의 합성곱을 수학기로호는 f*g 와 같이 표시하며 하나의 함수를 반전,전이시킨 다음 다른 하나의 함수와 곱한 결과를 적분하는 것을 의미합니다.

이것을 기호로 표시하면 다음과 같이 표시를 할 수 있습니다.

일단 컨볼루션의 수학적 내용을 살펴 보기 전에 컨볼루션이 어떤 기능을 수행하는지 살펴 봅시다.

출처: 생활코딩

 

4개의 이미지를 살펴 보면 모두 동그라미가 있다는 특징을 살펴 볼 수 있습니다.

동그라미의 특징을 표로 나타내면 다음과 같습니다.

출처:생활코딩

 

동그라미 갯수가 9,6,0 은 1개,8은 2개 이며 위쪽에 동그라미가 있는 것은 9,8, 아래쪽에 동그라미가 있는 것은 8,6 입니다.

이미지상에 어떤 특징이 어느 부분에서 나타나는지 알 수 있다면 그 이미지를 분류하는데 매우 유용합니다.

 

이미지에서 특정한 패턴의 특징이 어디서 나타나는지를 확인하는 도구가 있는데 이것이 바로 컨볼루션(Convolution)입니다.

 

컨볼루션 또는 합성곱이라고 하는 이 연산은 이미지처리와 신호처리 분야에서 매우 유명한 도구입니다.

방금 전에 보았던것과 같이 이미지의 특징을 추출하는데 사용되고 있습니다.

 

여기 4라는 이미지가 있습니다.

오른쪽 이미지는 왼쪽의 필터를 가지고 컨볼루션을 한 결과 입니다.  흰색 부분은 숫자가 255에 가까운 것이고 검은색은 숫자가 0 에 가까운 것입니다.

이렇게 나타난 오른쪽 이미지를 특징맵(feature map) 이라고 부릅니다.

 

위의 이미지는 세로선을 기준으로 필터를 이용해 특징맵을 만들었습니다.

이렇게 필터 하나가 특징맵 하나를 만들게 됩니다.

 

위의 이미지는 input 된 이미지를 우하향 방향의 사선으로 찾은 특징맵과 우상향 방향의 사선으로 찾은 특징맵으로 만들어 지는 것을 확인 할 수 있습니다.

하얗게 나타나는 부분이 찾고 싶은 특징이 많은 부분을 의미합니다.

그렇다면 컨볼루션을 적용한 딥러닝 코드를 확인해 봅시다.

###########################
# 데이터를 준비하고
(독립, 종속), _ = tf.keras.datasets.mnist.load_data()
독립 = 독립.reshape(60000, 28, 28, 1)
종속 = pd.get_dummies(종속)
print(독립.shape, 종속.shape)

여기서 지난 시간에 독립변수를 60000 * 784 로 바꾸었던과 다르게

독립 = 독립.reshape(60000, 28, 28, 1)

위와 같이 60000 * 28 * 28 * 1 로 바꾸는 것을 확인 할 수 있습니다.

컨볼루션은 3차원 형태의 데이터를 입력으로 받기 때문입니다.

이처럼 각 라이브러리의 특징에 맞춰서 데이터를 변환해 주어야 합니다.

 

다음은 모델의 구조를 만드는 부분을 살펴 봅시다.

 

###########################
# 모델을 만들고
X = tf.keras.layers.Input(shape=[28, 28, 1])
H = tf.keras.layers.Conv2D(3, kernel_size=5, activation='swish')(X)
H = tf.keras.layers.Conv2D(6, kernel_size=5, activation='swish')(H)
H = tf.keras.layers.Flatten()(H)
H = tf.keras.layers.Dense(84, activation='swish')(H)
Y = tf.keras.layers.Dense(10, activation='softmax')(H)
model = tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy', metrics='accuracy')

여기서 빨간색 부분이 Convolution을 사용하는 부분입니다.

Convolution 레이어를 2개층 추가 한 모습입니다.

 

Convolution 을 사용할때 우리가 다음을 결정해야 됩니다.

1. 필터셋을 몇개 사용할 것인가?

2. 필터셋의 사이즈를 얼마로 할것인가?

위의 예에서는 첫번째 레이어에서는 필터셋을 3개, 두번째 레이어에서는 필터셋을 6개 사용한 예입니다.

또한 필터셋의 사이즈는 첫번째 레이어, 두번째 레이어 모두 5의 크기를 사용한 예입니다.(kernel_size 로 설정합니다.)

첫번째 레이어는 특징맵 3개,즉 3채널의 특징맵을 사용했고 두번째 레이어는 6채널의 특징맵을 사용했습니다.

이렇게 만들어진 특징맵을 Flatten 을 이용해서 한줄로 펼친 후 즉 표로 만든 후에 학습하는 것을 알 수 있습니다.

필터의 이해

컨볼루션을 이해하기 위해서는 필터를 이해하는 것이 중요합니다.

필터는 다음과 같습니다.

1. 필터셋은 3차원 형태로 된 가중치의 모음

2. 필터셋 하나는 앞선 레이어의 결과인 "특징맵" 전체를 봅니다.

3. 필터셋 개수만큼 특징맵을 만듭니다.

위의 예를 봅시다.

필터셋 하나가 (5,5,?) 형태의 특징맵을 만듭니다.

 

만약 입력 데이터가 다음과 같은 흑백 이미지 라면

28*28*1 형태의 이미지 입력이 들어 온다고 하면 특징맵은 (5,5,1) 형태를 생성하게 되고

32 * 32 * 3 과 같은 형태의 이미지 입력이 들어 온다고 하면 특징맵은 (5,5,3) 형태를 생성하게 됩니다.

따라서 위의 예에서 특징맵 전체의 모양은 (3,5,5,?) 또는 (6,5,5,?) 과 같은 형태가 됩니다.

이러한 것을 필터셋으로 표현했지만 실무에서는 이러한 여러개의 필터의 모음을 필터라고 합니다.

위의 내용을 그림으로 이해하면 다음과 같습니다.

28*28*1 형태의 이미지를 3 * (5,5,1) 형태의 필터를 거쳐서 (24,24,3) 크기의 특징맵을 추출합니다.

여기서 4만큼 줄었는데요~ 필터의 사이즈가 (5,5) 라서 사이즈-1 크기인 4만큼 크기가 줄어 듭니다.

그 다음 (24,24,3) 크기의 특징맵을 6 * (5,5,3) 형태의 필터를 거쳐서 (20,20,6) 크기의 특징맵을 추출합니다.

이렇게 컨볼루션 2개 레이어를 추가한 의미는 다음과 같습니다.

"0부터 9까지 중 어느 숫자인지 판단하기 위해 가장 좋은 특징맵 6개를 찾아줘"

컨볼루션실습

위에서 배운 컨볼루션을 이용해서 실습하는 예를 살펴 보겠습니다.

###########################
# 데이터를 준비하고
(독립, 종속), _ = tf.keras.datasets.mnist.load_data()
독립 = 독립.reshape(60000, 28, 28, 1)
종속 = pd.get_dummies(종속)
print(독립.shape, 종속.shape)

###########################
# 모델을 만들고
X = tf.keras.layers.Input(shape=[28, 28, 1])
H = tf.keras.layers.Conv2D(3, kernel_size=5, activation='swish')(X)
H = tf.keras.layers.Conv2D(6, kernel_size=5, activation='swish')(H)
H = tf.keras.layers.Flatten()(H)
H = tf.keras.layers.Dense(84, activation='swish')(H)
Y = tf.keras.layers.Dense(10, activation='softmax')(H)
model = tf.keras.models.Model(X, Y)
model.compile(loss='categorical_crossentropy', metrics='accuracy')

###########################
# 모델을 학습하고
model.fit(독립, 종속, epochs=10)

###########################
# 모델을 이용합니다.
pred = model.predict(독립[0:5])
print(pd.DataFrame(pred).round(2))

# 정답 확인
print(종속[0:5])

# 모델 확인
model.summary()

나온결과와 정답 데이터

모델을 살펴 보면 28*28*1 인 이미지 데이터를 컨볼루션을 거치면서 24*24*3 의 특징 맵을 만들고

이 맵을 이용하여 20*20*6의 특징맵을 생성후 flatten 을 거쳐서 2400 짜리 1차원 배열 값으로 변환하여 학습하는 모델을 확인 할 수 있습니다.

 

컨볼루션 연산의 이해

8*8*1 의 이미지의 값을 x1~x64 까지로 값을 매겨 봅시다.

3*3*1 의 필터를 준비한 후 w1~w2 까지의 값으로 매겨 봅시다.

6*6 사이즈의 특징맵에 y1~y36 까지의 값으로 매겨 놓습니다.

 

이때 특징맵은 다음과 같은 연산에 의해 일어 납니다.

y1 = x1 * w1 + x2 * w2 + x3 * w3 +

       x9 * w4 + x10 * w5 + x11 * w6 +

       x17 * x7 + x18 * w8 + x19 * w9

지난시간에 살펴 보았던 다음 이미지를 보시죠~

이렇게 9개의 영역을 특징맵의 한개의 영역으로 만들어 주게 됩니다. 

즉 원본의 이미지에서 필터 사이즈 만큼 해당 위치의 값을 곱해 주면서 특징맵의 위치에 적게 됩니다.

따라서 특징맵은 필터 사이즈 보다 1 작은 수만큼 빠진 크기가 됩니다.

y2를 연산하는 경우는 다음과 같이 연산을 하겠네요.

실제로 연산되는 예를 살펴 봅시다.

4라고 하는 이미지에 우리가 정의한 필터를 적용한 예입니다.

먼저 첫번째 구간은 1의 값이 나옵니다.

이것을 하나씩 이동하면서 모두 구하면 다음과 같은 특징맵이 추출됩니다.

이것을 이미지로 표현하면 다음과 같이 보입니다.

가로선이 있는 부분이 하얗게 표시 됩니다.

 

이때 필터값을 우리가 정의해서 찾아 주었는데~

컨볼루션 에서는 컴퓨터가 이러한 필터값을 적절하게 찾아 주게 됩니다.

 

<출처>

https://opentutorials.org/module/5268/29787

사업자 정보 표시
원당컴퓨터학원 | 기희경 | 인천 서구 당하동 1028-2 장원프라자 502호 | 사업자 등록번호 : 301-96-83080 | TEL : 032-565-5497 | Mail : icon001@naver.com | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기