CNN with TF low level

iissaacc·2022년 5월 4일
0

Prologue

tf 공식문서를 보면 subclassing으로 layer block을 구성하고 model을 만드는 방법이 나와있다. 거기다가 tf.keras.layers에 있는 것들은 tf.nn에도 같은 기능을 하도록 구현하고 있다. low level에서는 결국 tf.nn이 돌아갈 거라고 생각은 했지만 그러려니 하면서 넘겨왔다. 그러다 소스코드를 봤는데 있어야 되나 싶은 조건문들이 많이 붙어있었고 이걸 다 걷어내고 싶었다.

그래서 굳이 해보는 subclassing을 활용한 ResNet구현. 단, tf.keras에서 상속은 받고 시작하기로 한다. 나중에는 이것도 덜어내고 순수 tf로만 구현하고 싶기는 하다. 여기서 전체 코드를 쓰면 너무 길어지므로 subclassing을 어떻게 활용하는지에 대해서 서술하고 세부코드는 링크로 대체한다.

Custom layer

먼저 custom layer를 만드는 것을 개괄적으로 보면 이렇게 생겼다.

class CustomLayer(tf.keras.layers.Layer):
    def __init__(self,...):
        super().__init__()
        ...

    def build(self, input_shape):
        super().build(input_shape)
        self.weight = self.add_weight(...)

    def call(self, X):
        ...
        return x

기본적으로 build에서 weight의 모양과 크기, 범위를 초기화하고 여기에 필요한 변수들은 __init__에서 선언한다. call에서 layer의 입력값과 함께 연산하는 algorithm을 짜도록 정해놨다. 이런 식으로 Conv2d, BatchNorm, FC layer를 만들면 ResBlock을 만들 수 있다.

  • ReLU는 clipping이나 음수에 대해 기울기를 따로 주지 않으므로 따로 구현하지 않고 ResBlock을 연산할 때 강제할 수 있도록 한다.
  • GAPtf.maht.reduce_mean을 활용하는 것으로 대체할 수 있으므로 따로 구현하지 않았다.

Custom block

class CustomBlock(tf.keras.Model):
    def __init__(self,...):
        super().__init__()
        ...

    def call(self, X):
        ...
        return x

필요한 layer들은 __init__에서 불러와서 call에서 layer들을 용도에 맞게 쓰면 된다. tf.keras.Model을 상속받을지, tf.keras.layers.Layer를 상속받을지 생각해보면 쓸 수 있는 메서드가 달라서 그때 그때 상황에 맞는 것을 고르면 되는 것 같다.

Custom model

class CustomModel(tf.keras.Model):
    def __init__(self,...):
        super().__init__()
        ...

    def call(self, X):
        ...
        return x

이렇게 model을 만드는 건 subblock을 만드는 것과 크게 다르지 않다.

Epilogue

원래는 model구현까지가 목표였지만 하는 김에 training loop, LR scheduler, dataloader까지 그냥 구현해봤다. 하는 내내 어차피 tf.keras를 쓰면 편하고 빠르게 구현할 수 있는데 굳이 이렇게 해야 하나 싶다가 빠르게 구현해서 시험한 다음에 고도화하면서 이렇게 뜯어고치면 되지 않을까하는 걸로 고쳐먹기로 했다.

0개의 댓글