활성화 함수가 필요없는 신경망 Π-Net을 시도했습니다.

소개



CVPR2020에 채택된 다음 논문에서 제안한 새로운 신경망인 $\Pi$-Net을 PyTorch로 구현했습니다.

Chrysos, Grigorios G., et al. "$\Pi-$ nets: Deep Polynomial Neural Networks."arXiv preprint arXiv:2003.03828 (2020).

학습에 사용한 전체 코드는 GitHub 에 있습니다.

Π-Net이란?



$\Pi$-Net에서는 네트워크를 도중에 분기시키고, 다시 합류하는 부분에서 곱셈을 실시합니다.
이렇게하면 출력이 입력 다항식으로 표현됩니다.

보통의 신경망에서는 각 층의 출력에 ReLU나 Sigmoid 등의 활성화 함수를 적용함으로써 비선형성을 갖게 하고 있습니다.
활성화 함수를 사용하지 않으면 네트워크의 계층 수를 아무리 늘려도 입력에 대해서 선형적인 출력 밖에 할 수 없기 때문에 의미가 없습니다.

그러나, $\Pi$-Net에서는 중간층의 출력끼리로 곱셈을 실시하는 것으로 네트워크에 비선형성을 갖게 하고 있기 때문에, 활성화 함수를 사용하지 않아도 다층으로 하는 것으로 높은 표현 능력을 얻는 것 수 있습니다.

논문에서는 몇 가지 네트워크 구조가 제안되었지만, 이번에는 그 중 하나인 다음 구조를 기반으로 구현했습니다.


(논문에서 인용)

Skip-connection이 있어 ResNet과 같은 구조를 하고 있습니다만, 합류하는 부분이 더해지는 것이 아니라 곱셈(아다마르적)이 되어 있습니다.
각 블록에서 이전 블록의 출력이 제곱되기 때문에, 블록을 $N$개 겹치는 것으로 $2^N$다음의 다항식이 되어, 지수적으로 네트워크의 표현 능력이 증가해 갑니다.

구현



위 그림의 블록을 5개 겹쳐 다음과 같은 모델을 썼습니다.
따라서 네트워크 출력은 $ 2 ^ 5 = 32 $ 다음 다항식으로 표현됩니다.
활성화 함수를 전혀 사용하지 않는다는 점에 주목하십시오.

모델
class PolyNet(nn.Module):
    def __init__(self, in_channels=1, n_classes=10):
        super().__init__()
        N = 16
        kwds1 = {"kernel_size": 4, "stride": 2, "padding": 1}
        kwds2 = {"kernel_size": 2, "stride": 1, "padding": 0}
        kwds3 = {"kernel_size": 3, "stride": 1, "padding": 1}
        self.conv11 = nn.Conv2d(in_channels, N, **kwds3)
        self.conv12 = nn.Conv2d(in_channels, N, **kwds3)
        self.conv21 = nn.Conv2d(N, N * 2, **kwds1)
        self.conv22 = nn.Conv2d(N, N * 2, **kwds1)
        self.conv31 = nn.Conv2d(N * 2, N * 4, **kwds1)
        self.conv32 = nn.Conv2d(N * 2, N * 4, **kwds1)
        self.conv41 = nn.Conv2d(N * 4, N * 8, **kwds2)
        self.conv42 = nn.Conv2d(N * 4, N * 8, **kwds2)
        self.conv51 = nn.Conv2d(N * 8, N * 16, **kwds1)
        self.conv52 = nn.Conv2d(N * 8, N * 16, **kwds1)

        self.fc = nn.Linear(N * 16 * 3 * 3, n_classes)

    def forward(self, x):
        h = self.conv11(x) * self.conv12(x)
        h = self.conv21(h) * self.conv22(h)
        h = self.conv31(h) * self.conv32(h)
        h = self.conv41(h) * self.conv42(h)
        h = self.conv51(h) * self.conv52(h)
        h = self.fc(h.flatten(start_dim=1))

        return h

결과



MNIST와 CIFAR-10의 분류를 배웠습니다.

MNIST



Accuracy


Loss


약 99%의 테스트 정밀도입니다!

CIFAR-10



Accuracy


Loss


테스트가 70% 정도의 정밀도입니다만 과학하고 있네요・・・

결론



출력이 입력의 다항식이 되었기 때문에 활성화 함수를 사용하지 않고 학습을 할 수 있었습니다.

블록을 겹쳐서 표현력이 지수적으로 향상된다고 상술했지만,
보통 신경망에서도 층수에 대해 지수적으로 표현력이 향상되는 것으로 알려져 있다.



Montufar, Guido F., et al. "On the number of linear regions of deep neural networks."Advances in neural information processing systems. 2014.  1

좋은 웹페이지 즐겨찾기