[튜토리얼2] 맞춤 레이어 설정하기

이번 튜토리얼에서는 tf.keras.Layer 클래스 상속을 통해 모델을 구성하는 레이어를 직접 설정해보는 방법과 기존 정의되어 있는 레이어를 조합하여 모델을 구성하는 방법을 알아볼 것입니다.

#필요한 모듈 임포트하기
import warnings
warnings.filterwarnings(action='ignore')

import tensorflow as tf

목차

  1. 레이어: 유용한 연산자 집합
  2. 사용자 정의 레이어 구현
  3. 모델: 레이어 구성

1. 레이어: 유용한 연산자 집합

머신러닝을 위한 코드를 작성하는 경우, 대부분 개별적인 연산과 변수를 조작하는 것보다는 주로 높은 수준의 추상화 도구를 사용합니다.

많은 머신러닝 모델은 비교적 단순한 레이어(layer)를 조합하고 쌓아서 표현할 수 있습니다. 텐서플로우는 여러 표준형 레이어을 제공하기때문에 처음부터 사용자 고유의 응용 프로그램에 특화된 레이어를 작성하거나 혹은 기존 레이어들을 이용하여 단순 조합만을 통해 쉽게 모델을 만들 수 있습니다.

텐서플로우는 케라스(Keras)의 모든 API를 tf.keras 패키지에 포함하고 있습니다. 케라스 레이어는 모델을 구축하는데 매우 유용합니다.

tf.keras.layers 패키지에서 층은 객체입니다. 레이어를 구성하기 위해 먼저 다음과 같이 간단히 객체를 생성해보겠습니다.

대부분의 layer는 첫번째 인수로 출력 차원(크기) 또는 채널을 가집니다.

layer = tf.keras.layers.Dense(100)

입력 차원의 수(input_shape)는 레이어를 처음 실행할 때 유추할 수 있기 때문에 필요하지 않을 수 있습니다.

그러나 일부 복잡한 모델에서는 수동으로 입력 차원의 수를 제공하는것이 유용할 수 있습니다.

layer = tf.keras.layers.Dense(10, input_shape=(None, 5))
# 층을 사용하려면, 간단하게 호출합니다.
layer(tf.zeros([10, 5]))

layer는 유용한 메서드를 많이 가지고 있습니다. 예를 들어, layer.variables를 사용하여 층안에 있는 모든 변수를 확인할 수 있으며, layer.trainable_variables를 사용하여 훈련 가능한 변수를 확인할 수 있습니다.

완전 연결(fully-connected)층은 가중치(weight)편향(biases) 을 위한 변수(variable)를 가집니다.

layer.variables

또한 변수는 객체의 속성을 통해 편리하게 접근 가능합니다.

layer.kernel, layer.bias

2. 사용자 정의 레이어 구현

사용자 정의 레이어를 구현하는 가장 좋은 방법은 tf.keras.Layer 클래스를 상속하고 다음과 같이 구현하는 것입니다.

변수를 생성하기 위해 build가 호출되길 기다릴 필요는 없으며, 변수를 __init__에 생성할 수도 있습니다. build에 변수를 생성할때의 장점은 레이어가 입력 크기 를 기준으로 변수를 생성할 수 있다는 것입니다. 반면에, __init__에 변수를 생성하는 것은 변수 생성에 필요한 크기가 명시적으로 지정되어야 함을 의미합니다.

class MyDenseLayer(tf.keras.layers.Layer):
    def __init__(self, num_outputs):
        super(MyDenseLayer, self).__init__()
        self.num_outputs = num_outputs

    def build(self, input_shape):
        self.kernel = self.add_variable("kernel",
                                    shape=[int(input_shape[-1]),
                                           self.num_outputs])

    def call(self, input):
        return tf.matmul(input, self.kernel)

layer = MyDenseLayer(10)
print(layer(tf.zeros([10, 5])))
print()
print(layer.trainable_variables)

3. 모델: 기존 레이어 구성

머신러닝 모델의 대부분은 기존의 레이어를 조합하여 구현됩니다. 예를 들어, 레즈넷(resnet)이라는 모델의 Identity Block은 합성곱(convolution), 배치 정규화(batch normalization), 쇼트컷(shortcut) 등으로 구성되어 있습니다.

다른 레이어를 포함한 모델을 만들기 위해 사용하는 메인 클래스는 tf.keras.Model입니다.

다음은 tf.keras.Model을 상속(inheritance)하여 구현한 코드입니다.

class ResnetIdentityBlock(tf.keras.Model):
    def __init__(self, kernel_size, filters):
        super(ResnetIdentityBlock, self).__init__(name='')
        filters1, filters2, filters3 = filters

        self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))
        self.bn2a = tf.keras.layers.BatchNormalization()

        self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')
        self.bn2b = tf.keras.layers.BatchNormalization()

        self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))
        self.bn2c = tf.keras.layers.BatchNormalization()

    def call(self, input_tensor, training=False):
        x = self.conv2a(input_tensor)
        x = self.bn2a(x, training=training)
        x = tf.nn.relu(x)

        x = self.conv2b(x)
        x = self.bn2b(x, training=training)
        x = tf.nn.relu(x)

        x = self.conv2c(x)
        x = self.bn2c(x, training=training)

        x += input_tensor
        return tf.nn.relu(x)


block = ResnetIdentityBlock(1, [1, 2, 3])
print(block(tf.zeros([1, 2, 3, 3])))
print()
print([x.name for x in block.trainable_variables])

그러나 대부분의 경우에, 많은 레이어로 구성된 모델은 단순하게 순서대로 레이어를 하나씩 호출합니다. 이는 tf.keras.Sequential을 사용하여 다음과 같은 간단한 코드로 구현 가능합니다.

my_seq = tf.keras.Sequential([tf.keras.layers.Conv2D(1, (1, 1), input_shape=(None, None, 3)),
                             tf.keras.layers.BatchNormalization(),
                             tf.keras.layers.Conv2D(2, 1, padding='same'),
                             tf.keras.layers.BatchNormalization(),
                             tf.keras.layers.Conv2D(3, (1, 1)),
                             tf.keras.layers.BatchNormalization()])
my_seq(tf.zeros([1, 2, 3, 3]))

Copyright 2018 The TensorFlow Authors.

#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.