- Convolution의 기초 명령어 Conv2D 예시입니다.
- 딥러닝의 일부로서가 아닌 명령어 자체 기능을 봅니다.
- 무엇을 받아서 무엇으로 바꾸는지 살펴봅니다.
1. 2D Convolution
pyimagesearch: Keras Conv2D and Convolutional Layers
2. Keras의 Conv2D
2.1. 기본 문법
tf.keras.layers.Conv2D
-
공식 홈페이지에 따르면 입출력은 다음과 같습니다.
- 입력 형식 : 4차원 이상의 텐서.
data_format='channel_first'일 때: batch_shape + (channels, rows, cols),
data_format='channel_last'일 때: batch_shape + (rows, cols, channels),
- 출력 형식 : 4차원 이상의 텐서.
data_format='channel_first'일 때: batch_shape + (filters, rows, cols),
data_format='channel_last'일 때: batch_shape + (rows, cols, filters),
-
텐서를 받아 텐서를 출력합니다.
-
입력의 channel 자리가 출력의 filter 자리로 바뀝니다.
-
또한, rows와 columns는 padding, strides 등에 따라 달라질 수 있습니다.
-
텐서를 입력으로 받기 때문에 일반 이미지는 텐서로 변환하여 넣어야 합니다.
2.2. 이미지 입력
1 2 3 4 5 6 7 8 9 10
| %matplotlib inline
import tensorflow as tf from tensorflow.keras import layers
import numpy as np import matplotlib.pyplot as plt
print(tf.__version__) print(tf.keras.__version__)
|
- 실행결과: tensorflow v2.3.1, tf.keras v2.4.0 입니다.
1 2 3 4
| img = plt.imread("./1-conv2d_1.jpg") print(type(img)) print(img.shape) plt.imshow(img)
|
- 실행결과 : numpy array 형식, 1080 x 1080 3 channel(RGB) 이미지입니다.
1 2
| <class 'numpy.ndarray'> (1080, 1080, 3)
|

2.3. Conv2D 적용 (1) 1 filter
tf.convert_to_tensor
1 2 3 4
| img_tf = tf.convert_to_tensor([img], dtype="float32") print(type(img_tf)) print(img_tf.shape) print(img_tf.dtype)
|
- 실행결과 : numpy array가 EagerTensor로 변환되었습니다.
3차원을 4차원으로 만들어주기 위해 []를 씌웠습니다.
1 2 3
| <class 'tensorflow.python.framework.ops.EagerTensor'> (1, 1080, 1080, 3) <dtype: 'float32'>
|
1 2 3 4
| conv_1 = layers.Conv2D(1, 3, padding="same")(img_tf) print(type(conv_1)) print(conv_1.shape) print(conv_1.dtype)
|
- 실행결과 : 1 channel EagerTensor가 출력되었습니다.
1 2 3
| <class 'tensorflow.python.framework.ops.EagerTensor'> (1, 1080, 1080, 1) <dtype: 'float32'>
|
- matplotlib에서 출력하기 위해 다시 numpy로 변환합니다.
- 연산 범위가 0~1을 넘어갈 수 있으므로 normalize 처리를 합니다.
1 2
| conv_1_np = conv_1.numpy() plt.imshow((conv_1_np[0]-conv_1_np[0].min())/(conv_1_np[0].max()-conv_1_np[0].min()), cmap="gist_gray")
|
2.3. Conv2D 적용 (2) 1 filter x 8회
- 랜덤한 커널의 영향을 확인해 보겠습니다.
- Conv2D를 반복해서 실행하며 결과가 바뀌는지 확인합니다.
1 2 3 4 5 6 7 8 9 10
| fig, axes = plt.subplots(ncols=4, nrows=2, figsize=(13, 6)) axs = axes.ravel()
for i, ax in enumerate(axs): conv_1 = layers.Conv2D(1, 3, padding="same")(img_tf) conv_1_np = conv_1.numpy() ax.imshow(conv_1_np[0], cmap="gist_gray") ax.set_title(f"try {i}")
fig.tight_layout()
|
- 실행결과 : 실행할때마다 다른 그림이 나옵니다.

2.3. Conv2D 적용 (3) 16 filter
- 필터의 수를 지정하면 반복된 결과물이 channel로 쌓입니다.
1 2 3 4
| conv_16 = layers.Conv2D(16, 3, padding="same")(img_tf) print(type(conv_16)) print(conv_16.shape) print(conv_16.dtype)
|
- 실행결과 : 16 channel이 출력됩니다.
1 2 3
| <class 'tensorflow.python.framework.ops.EagerTensor'> (1, 1080, 1080, 16) <dtype: 'float32'>
|
1 2 3 4 5 6 7 8 9 10 11
| conv_16_np = conv_16.numpy() conv_16_norm = (conv_16_np[0]-conv_16_np.min())/(conv_16_np.max()-conv_16_np.min())
fig, axes = plt.subplots(ncols=4, nrows=4, figsize=(13, 13)) axs = axes.ravel()
for i, ax in enumerate(axs): ax.imshow(conv_16_norm[:,:,i], cmap="gist_gray") ax.set_title(f"Channel {i}")
fig.tight_layout()
|