다운로드
작성자: admin 작성일시: 2019-11-07 15:23:23 조회수: 75 다운로드: 7
카테고리: 머신 러닝 태그목록:

A.2 전치 합성곱

전치 합성곱(transpose convolution)은 입력 이미지의 크기를 증가시키면서 이미지 필터링을 하는 방법 중 하나다. 이미지 크기를 증가시키기 위해 스트라이드(stride)가 사용된다.

  1. 스트라이드 크기만큼 곱한 크기로 이미지를 늘린다.
  2. 빈 공간에는 0을 넣는다.
  3. 늘어난 이미지를 필터로 합성곱을 하면서 이동시킨다.

1, 2번 과정으로 이미지 크기를 늘리고 3번 과정을 통해 합성곱을 실행한다. 그림으로 표시하면 다음과 같다.

전치 합성곱을 한 결과 이미지의 크기는 다음과 같다. 여기에서는 가로 크기만 보였다. 세로 크기도 마찬가지 공식이 적용된다.

  • same 패딩의 경우
출력 이미지 가로 크기 = 입력 이미지 가로 크기 x 가로 스트라이드
  • valid 패딩의 경우
출력 이미지 가로 크기 = (입력 이미지 가로 크기 - 1) x 가로 스트라이드 + 필터 가로크기

tensorflow를 사용한 전치 합성곱

tensorflow에서는 tf.nn.conv2d_transpose 명령으로 전치 합성곱을 계산할 수 있다.

In [3]:
import tensorflow as tf
tf.__version__
Out:
'2.0.0'

예제 입력 이미지는 2x2 크기다. 채널 수는 1, 배치 크기도 1로 하면 텐서 모양은 [batch, height, width, in_channels] = 1x2x2x1이 된다.

In [4]:
x = tf.constant(np.arange(1, 5).reshape((1, 2, 2, 1)), dtype=tf.float32)
print(x.shape)
tf.squeeze(x).numpy()
(1, 2, 2, 1)
Out:
array([[1., 2.],
       [3., 4.]], dtype=float32)

예제 필터의 크기도 3x3이다. 출력채널이 하나이므로 텐서모양은 [height, width, output_channels, in_channels] = 3x3x1x1이다.

In [5]:
f = tf.constant(np.ones(9).reshape((3, 3, 1, 1)), dtype=tf.float32)
print(f.shape)
tf.squeeze(f).numpy()
(3, 3, 1, 1)
Out:
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]], dtype=float32)

이 경우 출력 크기는 다음과 같다.

  • valid 패딩의 경우 = (2 - 1) x 2 + 3 = 5
  • same 패딩의 경우 = 2 x 2 = 4
In [6]:
conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 5, 5, 1), strides=[1, 2, 2, 1], padding='VALID')
print(conv.shape)
tf.squeeze(conv).numpy()
(1, 5, 5, 1)
Out:
array([[ 1.,  1.,  3.,  2.,  2.],
       [ 1.,  1.,  3.,  2.,  2.],
       [ 4.,  4., 10.,  6.,  6.],
       [ 3.,  3.,  7.,  4.,  4.],
       [ 3.,  3.,  7.,  4.,  4.]], dtype=float32)
In [7]:
conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')
print(conv.shape)
tf.squeeze(conv).numpy()
(1, 4, 4, 1)
Out:
array([[ 1.,  1.,  3.,  2.],
       [ 1.,  1.,  3.,  2.],
       [ 4.,  4., 10.,  6.],
       [ 3.,  3.,  7.,  4.]], dtype=float32)

keras를 사용한 전치 합성곱

keras에서는 Conv2DTranspose 레이어를 사용하여 구현한다.

In [8]:
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Conv2DTranspose

model = Sequential()
model.add(Conv2DTranspose(filters=1, kernel_size=(3, 3), strides=(2, 2), input_shape=(2, 2, 1), padding="valid"))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_transpose (Conv2DTran (None, 5, 5, 1)           10        
=================================================================
Total params: 10
Trainable params: 10
Non-trainable params: 0
_________________________________________________________________

set_weights 명령으로 필터 가중치를 설정한다.

In [9]:
bias = np.array([0])
weights = [f, bias]
model.set_weights(weights)
weights[0].shape
Out:
TensorShape([3, 3, 1, 1])

predict 메서드로 출력을 계산한다.

In [10]:
y = model.predict(x)
np.squeeze(y)
Out:
array([[ 1.,  1.,  3.,  2.,  2.],
       [ 1.,  1.,  3.,  2.,  2.],
       [ 4.,  4., 10.,  6.,  6.],
       [ 3.,  3.,  7.,  4.,  4.],
       [ 3.,  3.,  7.,  4.,  4.]], dtype=float32)

질문/덧글

아직 질문이나 덧글이 없습니다. 첫번째 글을 남겨주세요!